[go: nahoru, domu]

Merge "Implement DataStore.CorruptionHandler" into androidx-master-dev
diff --git a/activity/activity-ktx/api/1.2.0-alpha06.ignore b/activity/activity-ktx/api/1.2.0-alpha06.ignore
new file mode 100644
index 0000000..762b574
--- /dev/null
+++ b/activity/activity-ktx/api/1.2.0-alpha06.ignore
@@ -0,0 +1,7 @@
+// Baseline format: 1.0
+ChangedType: androidx.activity.ActivityViewModelLazyKt#viewModels(androidx.activity.ComponentActivity, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>):
+    Method androidx.activity.ActivityViewModelLazyKt.viewModels has changed return type from kotlin.Lazy<VM> to kotlin.Lazy<? extends VM>
+
+
+InvalidNullConversion: androidx.activity.ActivityViewModelLazyKt#viewModels(androidx.activity.ComponentActivity, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>):
+    Attempted to remove @NonNull annotation from method androidx.activity.ActivityViewModelLazyKt.viewModels(androidx.activity.ComponentActivity,kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>)
diff --git a/activity/activity-ktx/api/1.2.0-alpha06.txt b/activity/activity-ktx/api/1.2.0-alpha06.txt
new file mode 100644
index 0000000..7ece866
--- /dev/null
+++ b/activity/activity-ktx/api/1.2.0-alpha06.txt
@@ -0,0 +1,27 @@
+// Signature format: 3.0
+package androidx.activity {
+
+  public final class ActivityViewModelLazyKt {
+    method @MainThread public static inline <reified VM> kotlin.Lazy<? extends VM>! viewModels(androidx.activity.ComponentActivity, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer = null);
+  }
+
+  public final class 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);
+  }
+
+}
+
+package androidx.activity.result {
+
+  public final class ActivityResultCallerKt {
+    method public static inline <I, O> kotlin.jvm.functions.Function0<kotlin.Unit> registerForActivityResult(androidx.activity.result.ActivityResultCaller, androidx.activity.result.contract.ActivityResultContract<I,O> contract, I? input, androidx.activity.result.ActivityResultRegistry registry, kotlin.jvm.functions.Function1<? super O,kotlin.Unit> callback);
+    method public static inline <I, O> kotlin.jvm.functions.Function0<kotlin.Unit> registerForActivityResult(androidx.activity.result.ActivityResultCaller, androidx.activity.result.contract.ActivityResultContract<I,O> contract, I? input, kotlin.jvm.functions.Function1<? super O,kotlin.Unit> callback);
+  }
+
+  public final class ActivityResultLauncherKt {
+    method public static void launch(androidx.activity.result.ActivityResultLauncher<java.lang.Void>, androidx.core.app.ActivityOptionsCompat? options = null);
+    method public static void launchUnit(androidx.activity.result.ActivityResultLauncher<kotlin.Unit>, androidx.core.app.ActivityOptionsCompat? options = null);
+  }
+
+}
+
diff --git a/activity/activity-ktx/api/public_plus_experimental_1.2.0-alpha06.txt b/activity/activity-ktx/api/public_plus_experimental_1.2.0-alpha06.txt
new file mode 100644
index 0000000..7ece866
--- /dev/null
+++ b/activity/activity-ktx/api/public_plus_experimental_1.2.0-alpha06.txt
@@ -0,0 +1,27 @@
+// Signature format: 3.0
+package androidx.activity {
+
+  public final class ActivityViewModelLazyKt {
+    method @MainThread public static inline <reified VM> kotlin.Lazy<? extends VM>! viewModels(androidx.activity.ComponentActivity, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer = null);
+  }
+
+  public final class 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);
+  }
+
+}
+
+package androidx.activity.result {
+
+  public final class ActivityResultCallerKt {
+    method public static inline <I, O> kotlin.jvm.functions.Function0<kotlin.Unit> registerForActivityResult(androidx.activity.result.ActivityResultCaller, androidx.activity.result.contract.ActivityResultContract<I,O> contract, I? input, androidx.activity.result.ActivityResultRegistry registry, kotlin.jvm.functions.Function1<? super O,kotlin.Unit> callback);
+    method public static inline <I, O> kotlin.jvm.functions.Function0<kotlin.Unit> registerForActivityResult(androidx.activity.result.ActivityResultCaller, androidx.activity.result.contract.ActivityResultContract<I,O> contract, I? input, kotlin.jvm.functions.Function1<? super O,kotlin.Unit> callback);
+  }
+
+  public final class ActivityResultLauncherKt {
+    method public static void launch(androidx.activity.result.ActivityResultLauncher<java.lang.Void>, androidx.core.app.ActivityOptionsCompat? options = null);
+    method public static void launchUnit(androidx.activity.result.ActivityResultLauncher<kotlin.Unit>, androidx.core.app.ActivityOptionsCompat? options = null);
+  }
+
+}
+
diff --git a/activity/activity-ktx/api/res-1.2.0-alpha06.txt b/activity/activity-ktx/api/res-1.2.0-alpha06.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/activity/activity-ktx/api/res-1.2.0-alpha06.txt
diff --git a/activity/activity-ktx/api/restricted_1.2.0-alpha06.ignore b/activity/activity-ktx/api/restricted_1.2.0-alpha06.ignore
new file mode 100644
index 0000000..762b574
--- /dev/null
+++ b/activity/activity-ktx/api/restricted_1.2.0-alpha06.ignore
@@ -0,0 +1,7 @@
+// Baseline format: 1.0
+ChangedType: androidx.activity.ActivityViewModelLazyKt#viewModels(androidx.activity.ComponentActivity, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>):
+    Method androidx.activity.ActivityViewModelLazyKt.viewModels has changed return type from kotlin.Lazy<VM> to kotlin.Lazy<? extends VM>
+
+
+InvalidNullConversion: androidx.activity.ActivityViewModelLazyKt#viewModels(androidx.activity.ComponentActivity, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>):
+    Attempted to remove @NonNull annotation from method androidx.activity.ActivityViewModelLazyKt.viewModels(androidx.activity.ComponentActivity,kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>)
diff --git a/activity/activity-ktx/api/restricted_1.2.0-alpha06.txt b/activity/activity-ktx/api/restricted_1.2.0-alpha06.txt
new file mode 100644
index 0000000..7ece866
--- /dev/null
+++ b/activity/activity-ktx/api/restricted_1.2.0-alpha06.txt
@@ -0,0 +1,27 @@
+// Signature format: 3.0
+package androidx.activity {
+
+  public final class ActivityViewModelLazyKt {
+    method @MainThread public static inline <reified VM> kotlin.Lazy<? extends VM>! viewModels(androidx.activity.ComponentActivity, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer = null);
+  }
+
+  public final class 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);
+  }
+
+}
+
+package androidx.activity.result {
+
+  public final class ActivityResultCallerKt {
+    method public static inline <I, O> kotlin.jvm.functions.Function0<kotlin.Unit> registerForActivityResult(androidx.activity.result.ActivityResultCaller, androidx.activity.result.contract.ActivityResultContract<I,O> contract, I? input, androidx.activity.result.ActivityResultRegistry registry, kotlin.jvm.functions.Function1<? super O,kotlin.Unit> callback);
+    method public static inline <I, O> kotlin.jvm.functions.Function0<kotlin.Unit> registerForActivityResult(androidx.activity.result.ActivityResultCaller, androidx.activity.result.contract.ActivityResultContract<I,O> contract, I? input, kotlin.jvm.functions.Function1<? super O,kotlin.Unit> callback);
+  }
+
+  public final class ActivityResultLauncherKt {
+    method public static void launch(androidx.activity.result.ActivityResultLauncher<java.lang.Void>, androidx.core.app.ActivityOptionsCompat? options = null);
+    method public static void launchUnit(androidx.activity.result.ActivityResultLauncher<kotlin.Unit>, androidx.core.app.ActivityOptionsCompat? options = null);
+  }
+
+}
+
diff --git a/activity/activity/api/1.2.0-alpha06.txt b/activity/activity/api/1.2.0-alpha06.txt
new file mode 100644
index 0000000..a57478dd
--- /dev/null
+++ b/activity/activity/api/1.2.0-alpha06.txt
@@ -0,0 +1,232 @@
+// Signature format: 3.0
+package androidx.activity {
+
+  public class ComponentActivity extends android.app.Activity implements androidx.activity.result.ActivityResultCaller androidx.activity.result.ActivityResultRegistryOwner androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.activity.OnBackPressedDispatcherOwner androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
+    ctor public ComponentActivity();
+    ctor @ContentView public ComponentActivity(@LayoutRes int);
+    method public final androidx.activity.result.ActivityResultRegistry getActivityResultRegistry();
+    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 @CallSuper protected void onActivityResult(int, int, android.content.Intent?);
+    method @Deprecated @CallSuper public void onRequestPermissionsResult(int, String![], int[]);
+    method @Deprecated public Object? onRetainCustomNonConfigurationInstance();
+    method public final Object? onRetainNonConfigurationInstance();
+    method public final <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerForActivityResult(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultRegistry, androidx.activity.result.ActivityResultCallback<O!>);
+    method public final <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerForActivityResult(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+    method @Deprecated public void startActivityForResult(android.content.Intent!, int);
+    method @Deprecated public void startActivityForResult(android.content.Intent!, int, android.os.Bundle?);
+    method @Deprecated public void startIntentSenderForResult(android.content.IntentSender!, int, android.content.Intent?, int, int, int) throws android.content.IntentSender.SendIntentException;
+    method @Deprecated public void startIntentSenderForResult(android.content.IntentSender!, int, android.content.Intent?, int, int, int, android.os.Bundle?) throws android.content.IntentSender.SendIntentException;
+  }
+
+  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();
+  }
+
+}
+
+package androidx.activity.result {
+
+  public final class ActivityResult implements android.os.Parcelable {
+    ctor public ActivityResult(int, android.content.Intent?);
+    method public int describeContents();
+    method public android.content.Intent? getData();
+    method public int getResultCode();
+    method public static String resultCodeToString(int);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<androidx.activity.result.ActivityResult!> CREATOR;
+  }
+
+  public interface ActivityResultCallback<O> {
+    method public void onActivityResult(O!);
+  }
+
+  public interface ActivityResultCaller {
+    method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerForActivityResult(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+    method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerForActivityResult(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultRegistry, androidx.activity.result.ActivityResultCallback<O!>);
+  }
+
+  public abstract class ActivityResultLauncher<I> {
+    ctor public ActivityResultLauncher();
+    method public void launch(I!);
+    method public abstract void launch(I!, androidx.core.app.ActivityOptionsCompat?);
+    method @MainThread public abstract void unregister();
+  }
+
+  public abstract class ActivityResultRegistry {
+    ctor public ActivityResultRegistry();
+    method @MainThread public final boolean dispatchResult(int, int, android.content.Intent?);
+    method @MainThread public final <O> boolean dispatchResult(int, O!);
+    method @MainThread public abstract <I, O> void invoke(int, androidx.activity.result.contract.ActivityResultContract<I!,O!>, I!, androidx.core.app.ActivityOptionsCompat?);
+    method public final void onRestoreInstanceState(android.os.Bundle?);
+    method public final void onSaveInstanceState(android.os.Bundle);
+    method public final <I, O> androidx.activity.result.ActivityResultLauncher<I!> register(String, androidx.lifecycle.LifecycleOwner, androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+    method public final <I, O> androidx.activity.result.ActivityResultLauncher<I!> register(String, androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+  }
+
+  public interface ActivityResultRegistryOwner {
+    method public androidx.activity.result.ActivityResultRegistry getActivityResultRegistry();
+  }
+
+  public final class IntentSenderRequest implements android.os.Parcelable {
+    method public int describeContents();
+    method public android.content.Intent? getFillInIntent();
+    method public int getFlagsMask();
+    method public int getFlagsValues();
+    method public android.content.IntentSender getIntentSender();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<androidx.activity.result.IntentSenderRequest!> CREATOR;
+  }
+
+  public static final class IntentSenderRequest.Builder {
+    ctor public IntentSenderRequest.Builder(android.content.IntentSender);
+    ctor public IntentSenderRequest.Builder(android.app.PendingIntent);
+    method public androidx.activity.result.IntentSenderRequest build();
+    method public androidx.activity.result.IntentSenderRequest.Builder setFillInIntent(android.content.Intent?);
+    method public androidx.activity.result.IntentSenderRequest.Builder setFlags(int, int);
+  }
+
+}
+
+package androidx.activity.result.contract {
+
+  public abstract class ActivityResultContract<I, O> {
+    ctor public ActivityResultContract();
+    method public abstract android.content.Intent createIntent(android.content.Context, I!);
+    method public androidx.activity.result.contract.ActivityResultContract.SynchronousResult<O!>? getSynchronousResult(android.content.Context, I!);
+    method public abstract O! parseResult(int, android.content.Intent?);
+  }
+
+  public static final class ActivityResultContract.SynchronousResult<T> {
+    ctor public ActivityResultContract.SynchronousResult(T!);
+    method public T! getValue();
+  }
+
+  public final class ActivityResultContracts {
+  }
+
+  public static class ActivityResultContracts.CreateDocument extends androidx.activity.result.contract.ActivityResultContract<java.lang.String,android.net.Uri> {
+    ctor public ActivityResultContracts.CreateDocument();
+    method @CallSuper public android.content.Intent createIntent(android.content.Context, String);
+    method public final androidx.activity.result.contract.ActivityResultContract.SynchronousResult<android.net.Uri!>? getSynchronousResult(android.content.Context, String);
+    method public final android.net.Uri? parseResult(int, android.content.Intent?);
+  }
+
+  public static class ActivityResultContracts.GetContent extends androidx.activity.result.contract.ActivityResultContract<java.lang.String,android.net.Uri> {
+    ctor public ActivityResultContracts.GetContent();
+    method @CallSuper public android.content.Intent createIntent(android.content.Context, String);
+    method public final androidx.activity.result.contract.ActivityResultContract.SynchronousResult<android.net.Uri!>? getSynchronousResult(android.content.Context, String);
+    method public final android.net.Uri? parseResult(int, android.content.Intent?);
+  }
+
+  public static class ActivityResultContracts.GetMultipleContents extends androidx.activity.result.contract.ActivityResultContract<java.lang.String,java.util.List<android.net.Uri>> {
+    ctor public ActivityResultContracts.GetMultipleContents();
+    method @CallSuper public android.content.Intent createIntent(android.content.Context, String);
+    method public final androidx.activity.result.contract.ActivityResultContract.SynchronousResult<java.util.List<android.net.Uri!>!>? getSynchronousResult(android.content.Context, String);
+    method public final java.util.List<android.net.Uri!> parseResult(int, android.content.Intent?);
+  }
+
+  public static class ActivityResultContracts.OpenDocument extends androidx.activity.result.contract.ActivityResultContract<java.lang.String[],android.net.Uri> {
+    ctor public ActivityResultContracts.OpenDocument();
+    method @CallSuper public android.content.Intent createIntent(android.content.Context, String![]);
+    method public final androidx.activity.result.contract.ActivityResultContract.SynchronousResult<android.net.Uri!>? getSynchronousResult(android.content.Context, String![]);
+    method public final android.net.Uri? parseResult(int, android.content.Intent?);
+  }
+
+  public static class ActivityResultContracts.OpenDocumentTree extends androidx.activity.result.contract.ActivityResultContract<android.net.Uri,android.net.Uri> {
+    ctor public ActivityResultContracts.OpenDocumentTree();
+    method @CallSuper public android.content.Intent createIntent(android.content.Context, android.net.Uri?);
+    method public final androidx.activity.result.contract.ActivityResultContract.SynchronousResult<android.net.Uri!>? getSynchronousResult(android.content.Context, android.net.Uri?);
+    method public final android.net.Uri? parseResult(int, android.content.Intent?);
+  }
+
+  public static class ActivityResultContracts.OpenMultipleDocuments extends androidx.activity.result.contract.ActivityResultContract<java.lang.String[],java.util.List<android.net.Uri>> {
+    ctor public ActivityResultContracts.OpenMultipleDocuments();
+    method @CallSuper public android.content.Intent createIntent(android.content.Context, String![]);
+    method public final androidx.activity.result.contract.ActivityResultContract.SynchronousResult<java.util.List<android.net.Uri!>!>? getSynchronousResult(android.content.Context, String![]);
+    method public final java.util.List<android.net.Uri!>? parseResult(int, android.content.Intent?);
+  }
+
+  public static final class ActivityResultContracts.PickContact extends androidx.activity.result.contract.ActivityResultContract<java.lang.Void,android.net.Uri> {
+    ctor public ActivityResultContracts.PickContact();
+    method public android.content.Intent createIntent(android.content.Context, Void?);
+    method public android.net.Uri? parseResult(int, android.content.Intent?);
+  }
+
+  public static final class ActivityResultContracts.RequestMultiplePermissions extends androidx.activity.result.contract.ActivityResultContract<java.lang.String[],java.util.Map<java.lang.String,java.lang.Boolean>> {
+    ctor public ActivityResultContracts.RequestMultiplePermissions();
+    method public android.content.Intent createIntent(android.content.Context, String![]);
+    method public androidx.activity.result.contract.ActivityResultContract.SynchronousResult<java.util.Map<java.lang.String!,java.lang.Boolean!>!>? getSynchronousResult(android.content.Context, String![]?);
+    method public java.util.Map<java.lang.String!,java.lang.Boolean!> parseResult(int, android.content.Intent?);
+    field public static final String ACTION_REQUEST_PERMISSIONS = "androidx.activity.result.contract.action.REQUEST_PERMISSIONS";
+    field public static final String EXTRA_PERMISSIONS = "androidx.activity.result.contract.extra.PERMISSIONS";
+    field public static final String EXTRA_PERMISSION_GRANT_RESULTS = "androidx.activity.result.contract.extra.PERMISSION_GRANT_RESULTS";
+  }
+
+  public static final class ActivityResultContracts.RequestPermission extends androidx.activity.result.contract.ActivityResultContract<java.lang.String,java.lang.Boolean> {
+    ctor public ActivityResultContracts.RequestPermission();
+    method public android.content.Intent createIntent(android.content.Context, String);
+    method public androidx.activity.result.contract.ActivityResultContract.SynchronousResult<java.lang.Boolean!>? getSynchronousResult(android.content.Context, String?);
+    method public Boolean parseResult(int, android.content.Intent?);
+  }
+
+  public static final class ActivityResultContracts.StartActivityForResult extends androidx.activity.result.contract.ActivityResultContract<android.content.Intent,androidx.activity.result.ActivityResult> {
+    ctor public ActivityResultContracts.StartActivityForResult();
+    method public android.content.Intent createIntent(android.content.Context, android.content.Intent);
+    method public androidx.activity.result.ActivityResult parseResult(int, android.content.Intent?);
+    field public static final String EXTRA_ACTIVITY_OPTIONS_BUNDLE = "androidx.activity.result.contract.extra.ACTIVITY_OPTIONS_BUNDLE";
+  }
+
+  public static final class ActivityResultContracts.StartIntentSenderForResult extends androidx.activity.result.contract.ActivityResultContract<androidx.activity.result.IntentSenderRequest,androidx.activity.result.ActivityResult> {
+    ctor public ActivityResultContracts.StartIntentSenderForResult();
+    method public android.content.Intent createIntent(android.content.Context, androidx.activity.result.IntentSenderRequest);
+    method public androidx.activity.result.ActivityResult parseResult(int, android.content.Intent?);
+    field public static final String ACTION_INTENT_SENDER_REQUEST = "androidx.activity.result.contract.action.INTENT_SENDER_REQUEST";
+    field public static final String EXTRA_INTENT_SENDER_REQUEST = "androidx.activity.result.contract.extra.INTENT_SENDER_REQUEST";
+    field public static final String EXTRA_SEND_INTENT_EXCEPTION = "androidx.activity.result.contract.extra.SEND_INTENT_EXCEPTION";
+  }
+
+  public static class ActivityResultContracts.TakePicture extends androidx.activity.result.contract.ActivityResultContract<android.net.Uri,java.lang.Boolean> {
+    ctor public ActivityResultContracts.TakePicture();
+    method @CallSuper public android.content.Intent createIntent(android.content.Context, android.net.Uri);
+    method public final androidx.activity.result.contract.ActivityResultContract.SynchronousResult<java.lang.Boolean!>? getSynchronousResult(android.content.Context, android.net.Uri);
+    method public final Boolean parseResult(int, android.content.Intent?);
+  }
+
+  public static class ActivityResultContracts.TakePicturePreview extends androidx.activity.result.contract.ActivityResultContract<java.lang.Void,android.graphics.Bitmap> {
+    ctor public ActivityResultContracts.TakePicturePreview();
+    method @CallSuper public android.content.Intent createIntent(android.content.Context, Void?);
+    method public final androidx.activity.result.contract.ActivityResultContract.SynchronousResult<android.graphics.Bitmap!>? getSynchronousResult(android.content.Context, Void?);
+    method public final android.graphics.Bitmap? parseResult(int, android.content.Intent?);
+  }
+
+  public static class ActivityResultContracts.TakeVideo extends androidx.activity.result.contract.ActivityResultContract<android.net.Uri,android.graphics.Bitmap> {
+    ctor public ActivityResultContracts.TakeVideo();
+    method @CallSuper public android.content.Intent createIntent(android.content.Context, android.net.Uri);
+    method public final androidx.activity.result.contract.ActivityResultContract.SynchronousResult<android.graphics.Bitmap!>? getSynchronousResult(android.content.Context, android.net.Uri);
+    method public final android.graphics.Bitmap? parseResult(int, android.content.Intent?);
+  }
+
+}
+
diff --git a/activity/activity/api/api_lint.ignore b/activity/activity/api/api_lint.ignore
index 64382c3..d22641b 100644
--- a/activity/activity/api/api_lint.ignore
+++ b/activity/activity/api/api_lint.ignore
@@ -1,12 +1,12 @@
 // Baseline format: 1.0
-CallbackMethodName: androidx.activity.OnBackPressedCallback:
-    Callback method names must follow the on<Something> style: setEnabled
-
-
 ForbiddenSuperClass: androidx.activity.ComponentActivity:
     ComponentActivity should not extend `Activity`. Activity subclasses are impossible to compose. Expose a composable API instead.
 
 
+KotlinOperator: androidx.activity.result.ActivityResultRegistry#invoke(int, androidx.activity.result.contract.ActivityResultContract<I,O>, I, androidx.core.app.ActivityOptionsCompat):
+    Method can be invoked with function call syntax from Kotlin: `invoke` (this is usually desirable; just make sure it makes sense for this type of object)
+
+
 MissingNullability: androidx.activity.ComponentActivity#startActivityForResult(android.content.Intent, int) parameter #0:
     Missing nullability on parameter `intent` in method `startActivityForResult`
 MissingNullability: androidx.activity.ComponentActivity#startActivityForResult(android.content.Intent, int, android.os.Bundle) parameter #0:
diff --git a/activity/activity/api/public_plus_experimental_1.2.0-alpha06.txt b/activity/activity/api/public_plus_experimental_1.2.0-alpha06.txt
new file mode 100644
index 0000000..4053dc1
--- /dev/null
+++ b/activity/activity/api/public_plus_experimental_1.2.0-alpha06.txt
@@ -0,0 +1,231 @@
+// Signature format: 3.0
+package androidx.activity {
+
+  public class ComponentActivity extends androidx.core.app.ComponentActivity implements androidx.activity.result.ActivityResultCaller androidx.activity.result.ActivityResultRegistryOwner androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.activity.OnBackPressedDispatcherOwner androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
+    ctor public ComponentActivity();
+    ctor @ContentView public ComponentActivity(@LayoutRes int);
+    method public final androidx.activity.result.ActivityResultRegistry getActivityResultRegistry();
+    method public androidx.lifecycle.ViewModelProvider.Factory getDefaultViewModelProviderFactory();
+    method @Deprecated public Object? getLastCustomNonConfigurationInstance();
+    method public final androidx.activity.OnBackPressedDispatcher getOnBackPressedDispatcher();
+    method public final androidx.savedstate.SavedStateRegistry getSavedStateRegistry();
+    method public androidx.lifecycle.ViewModelStore getViewModelStore();
+    method @Deprecated @CallSuper protected void onActivityResult(int, int, android.content.Intent?);
+    method @Deprecated @CallSuper public void onRequestPermissionsResult(int, String![], int[]);
+    method @Deprecated public Object? onRetainCustomNonConfigurationInstance();
+    method public final Object? onRetainNonConfigurationInstance();
+    method public final <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerForActivityResult(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultRegistry, androidx.activity.result.ActivityResultCallback<O!>);
+    method public final <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerForActivityResult(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+    method @Deprecated public void startActivityForResult(android.content.Intent!, int);
+    method @Deprecated public void startActivityForResult(android.content.Intent!, int, android.os.Bundle?);
+    method @Deprecated public void startIntentSenderForResult(android.content.IntentSender!, int, android.content.Intent?, int, int, int) throws android.content.IntentSender.SendIntentException;
+    method @Deprecated public void startIntentSenderForResult(android.content.IntentSender!, int, android.content.Intent?, int, int, int, android.os.Bundle?) throws android.content.IntentSender.SendIntentException;
+  }
+
+  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();
+  }
+
+}
+
+package androidx.activity.result {
+
+  public final class ActivityResult implements android.os.Parcelable {
+    ctor public ActivityResult(int, android.content.Intent?);
+    method public int describeContents();
+    method public android.content.Intent? getData();
+    method public int getResultCode();
+    method public static String resultCodeToString(int);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<androidx.activity.result.ActivityResult!> CREATOR;
+  }
+
+  public interface ActivityResultCallback<O> {
+    method public void onActivityResult(O!);
+  }
+
+  public interface ActivityResultCaller {
+    method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerForActivityResult(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+    method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerForActivityResult(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultRegistry, androidx.activity.result.ActivityResultCallback<O!>);
+  }
+
+  public abstract class ActivityResultLauncher<I> {
+    ctor public ActivityResultLauncher();
+    method public void launch(I!);
+    method public abstract void launch(I!, androidx.core.app.ActivityOptionsCompat?);
+    method @MainThread public abstract void unregister();
+  }
+
+  public abstract class ActivityResultRegistry {
+    ctor public ActivityResultRegistry();
+    method @MainThread public final boolean dispatchResult(int, int, android.content.Intent?);
+    method @MainThread public final <O> boolean dispatchResult(int, O!);
+    method @MainThread public abstract <I, O> void invoke(int, androidx.activity.result.contract.ActivityResultContract<I!,O!>, I!, androidx.core.app.ActivityOptionsCompat?);
+    method public final void onRestoreInstanceState(android.os.Bundle?);
+    method public final void onSaveInstanceState(android.os.Bundle);
+    method public final <I, O> androidx.activity.result.ActivityResultLauncher<I!> register(String, androidx.lifecycle.LifecycleOwner, androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+    method public final <I, O> androidx.activity.result.ActivityResultLauncher<I!> register(String, androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+  }
+
+  public interface ActivityResultRegistryOwner {
+    method public androidx.activity.result.ActivityResultRegistry getActivityResultRegistry();
+  }
+
+  public final class IntentSenderRequest implements android.os.Parcelable {
+    method public int describeContents();
+    method public android.content.Intent? getFillInIntent();
+    method public int getFlagsMask();
+    method public int getFlagsValues();
+    method public android.content.IntentSender getIntentSender();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<androidx.activity.result.IntentSenderRequest!> CREATOR;
+  }
+
+  public static final class IntentSenderRequest.Builder {
+    ctor public IntentSenderRequest.Builder(android.content.IntentSender);
+    ctor public IntentSenderRequest.Builder(android.app.PendingIntent);
+    method public androidx.activity.result.IntentSenderRequest build();
+    method public androidx.activity.result.IntentSenderRequest.Builder setFillInIntent(android.content.Intent?);
+    method public androidx.activity.result.IntentSenderRequest.Builder setFlags(int, int);
+  }
+
+}
+
+package androidx.activity.result.contract {
+
+  public abstract class ActivityResultContract<I, O> {
+    ctor public ActivityResultContract();
+    method public abstract android.content.Intent createIntent(android.content.Context, I!);
+    method public androidx.activity.result.contract.ActivityResultContract.SynchronousResult<O!>? getSynchronousResult(android.content.Context, I!);
+    method public abstract O! parseResult(int, android.content.Intent?);
+  }
+
+  public static final class ActivityResultContract.SynchronousResult<T> {
+    ctor public ActivityResultContract.SynchronousResult(T!);
+    method public T! getValue();
+  }
+
+  public final class ActivityResultContracts {
+  }
+
+  public static class ActivityResultContracts.CreateDocument extends androidx.activity.result.contract.ActivityResultContract<java.lang.String,android.net.Uri> {
+    ctor public ActivityResultContracts.CreateDocument();
+    method @CallSuper public android.content.Intent createIntent(android.content.Context, String);
+    method public final androidx.activity.result.contract.ActivityResultContract.SynchronousResult<android.net.Uri!>? getSynchronousResult(android.content.Context, String);
+    method public final android.net.Uri? parseResult(int, android.content.Intent?);
+  }
+
+  public static class ActivityResultContracts.GetContent extends androidx.activity.result.contract.ActivityResultContract<java.lang.String,android.net.Uri> {
+    ctor public ActivityResultContracts.GetContent();
+    method @CallSuper public android.content.Intent createIntent(android.content.Context, String);
+    method public final androidx.activity.result.contract.ActivityResultContract.SynchronousResult<android.net.Uri!>? getSynchronousResult(android.content.Context, String);
+    method public final android.net.Uri? parseResult(int, android.content.Intent?);
+  }
+
+  public static class ActivityResultContracts.GetMultipleContents extends androidx.activity.result.contract.ActivityResultContract<java.lang.String,java.util.List<android.net.Uri>> {
+    ctor public ActivityResultContracts.GetMultipleContents();
+    method @CallSuper public android.content.Intent createIntent(android.content.Context, String);
+    method public final androidx.activity.result.contract.ActivityResultContract.SynchronousResult<java.util.List<android.net.Uri!>!>? getSynchronousResult(android.content.Context, String);
+    method public final java.util.List<android.net.Uri!> parseResult(int, android.content.Intent?);
+  }
+
+  public static class ActivityResultContracts.OpenDocument extends androidx.activity.result.contract.ActivityResultContract<java.lang.String[],android.net.Uri> {
+    ctor public ActivityResultContracts.OpenDocument();
+    method @CallSuper public android.content.Intent createIntent(android.content.Context, String![]);
+    method public final androidx.activity.result.contract.ActivityResultContract.SynchronousResult<android.net.Uri!>? getSynchronousResult(android.content.Context, String![]);
+    method public final android.net.Uri? parseResult(int, android.content.Intent?);
+  }
+
+  public static class ActivityResultContracts.OpenDocumentTree extends androidx.activity.result.contract.ActivityResultContract<android.net.Uri,android.net.Uri> {
+    ctor public ActivityResultContracts.OpenDocumentTree();
+    method @CallSuper public android.content.Intent createIntent(android.content.Context, android.net.Uri?);
+    method public final androidx.activity.result.contract.ActivityResultContract.SynchronousResult<android.net.Uri!>? getSynchronousResult(android.content.Context, android.net.Uri?);
+    method public final android.net.Uri? parseResult(int, android.content.Intent?);
+  }
+
+  public static class ActivityResultContracts.OpenMultipleDocuments extends androidx.activity.result.contract.ActivityResultContract<java.lang.String[],java.util.List<android.net.Uri>> {
+    ctor public ActivityResultContracts.OpenMultipleDocuments();
+    method @CallSuper public android.content.Intent createIntent(android.content.Context, String![]);
+    method public final androidx.activity.result.contract.ActivityResultContract.SynchronousResult<java.util.List<android.net.Uri!>!>? getSynchronousResult(android.content.Context, String![]);
+    method public final java.util.List<android.net.Uri!>? parseResult(int, android.content.Intent?);
+  }
+
+  public static final class ActivityResultContracts.PickContact extends androidx.activity.result.contract.ActivityResultContract<java.lang.Void,android.net.Uri> {
+    ctor public ActivityResultContracts.PickContact();
+    method public android.content.Intent createIntent(android.content.Context, Void?);
+    method public android.net.Uri? parseResult(int, android.content.Intent?);
+  }
+
+  public static final class ActivityResultContracts.RequestMultiplePermissions extends androidx.activity.result.contract.ActivityResultContract<java.lang.String[],java.util.Map<java.lang.String,java.lang.Boolean>> {
+    ctor public ActivityResultContracts.RequestMultiplePermissions();
+    method public android.content.Intent createIntent(android.content.Context, String![]);
+    method public androidx.activity.result.contract.ActivityResultContract.SynchronousResult<java.util.Map<java.lang.String!,java.lang.Boolean!>!>? getSynchronousResult(android.content.Context, String![]?);
+    method public java.util.Map<java.lang.String!,java.lang.Boolean!> parseResult(int, android.content.Intent?);
+    field public static final String ACTION_REQUEST_PERMISSIONS = "androidx.activity.result.contract.action.REQUEST_PERMISSIONS";
+    field public static final String EXTRA_PERMISSIONS = "androidx.activity.result.contract.extra.PERMISSIONS";
+    field public static final String EXTRA_PERMISSION_GRANT_RESULTS = "androidx.activity.result.contract.extra.PERMISSION_GRANT_RESULTS";
+  }
+
+  public static final class ActivityResultContracts.RequestPermission extends androidx.activity.result.contract.ActivityResultContract<java.lang.String,java.lang.Boolean> {
+    ctor public ActivityResultContracts.RequestPermission();
+    method public android.content.Intent createIntent(android.content.Context, String);
+    method public androidx.activity.result.contract.ActivityResultContract.SynchronousResult<java.lang.Boolean!>? getSynchronousResult(android.content.Context, String?);
+    method public Boolean parseResult(int, android.content.Intent?);
+  }
+
+  public static final class ActivityResultContracts.StartActivityForResult extends androidx.activity.result.contract.ActivityResultContract<android.content.Intent,androidx.activity.result.ActivityResult> {
+    ctor public ActivityResultContracts.StartActivityForResult();
+    method public android.content.Intent createIntent(android.content.Context, android.content.Intent);
+    method public androidx.activity.result.ActivityResult parseResult(int, android.content.Intent?);
+    field public static final String EXTRA_ACTIVITY_OPTIONS_BUNDLE = "androidx.activity.result.contract.extra.ACTIVITY_OPTIONS_BUNDLE";
+  }
+
+  public static final class ActivityResultContracts.StartIntentSenderForResult extends androidx.activity.result.contract.ActivityResultContract<androidx.activity.result.IntentSenderRequest,androidx.activity.result.ActivityResult> {
+    ctor public ActivityResultContracts.StartIntentSenderForResult();
+    method public android.content.Intent createIntent(android.content.Context, androidx.activity.result.IntentSenderRequest);
+    method public androidx.activity.result.ActivityResult parseResult(int, android.content.Intent?);
+    field public static final String ACTION_INTENT_SENDER_REQUEST = "androidx.activity.result.contract.action.INTENT_SENDER_REQUEST";
+    field public static final String EXTRA_INTENT_SENDER_REQUEST = "androidx.activity.result.contract.extra.INTENT_SENDER_REQUEST";
+    field public static final String EXTRA_SEND_INTENT_EXCEPTION = "androidx.activity.result.contract.extra.SEND_INTENT_EXCEPTION";
+  }
+
+  public static class ActivityResultContracts.TakePicture extends androidx.activity.result.contract.ActivityResultContract<android.net.Uri,java.lang.Boolean> {
+    ctor public ActivityResultContracts.TakePicture();
+    method @CallSuper public android.content.Intent createIntent(android.content.Context, android.net.Uri);
+    method public final androidx.activity.result.contract.ActivityResultContract.SynchronousResult<java.lang.Boolean!>? getSynchronousResult(android.content.Context, android.net.Uri);
+    method public final Boolean parseResult(int, android.content.Intent?);
+  }
+
+  public static class ActivityResultContracts.TakePicturePreview extends androidx.activity.result.contract.ActivityResultContract<java.lang.Void,android.graphics.Bitmap> {
+    ctor public ActivityResultContracts.TakePicturePreview();
+    method @CallSuper public android.content.Intent createIntent(android.content.Context, Void?);
+    method public final androidx.activity.result.contract.ActivityResultContract.SynchronousResult<android.graphics.Bitmap!>? getSynchronousResult(android.content.Context, Void?);
+    method public final android.graphics.Bitmap? parseResult(int, android.content.Intent?);
+  }
+
+  public static class ActivityResultContracts.TakeVideo extends androidx.activity.result.contract.ActivityResultContract<android.net.Uri,android.graphics.Bitmap> {
+    ctor public ActivityResultContracts.TakeVideo();
+    method @CallSuper public android.content.Intent createIntent(android.content.Context, android.net.Uri);
+    method public final androidx.activity.result.contract.ActivityResultContract.SynchronousResult<android.graphics.Bitmap!>? getSynchronousResult(android.content.Context, android.net.Uri);
+    method public final android.graphics.Bitmap? parseResult(int, android.content.Intent?);
+  }
+
+}
+
diff --git a/activity/activity/api/res-1.2.0-alpha06.txt b/activity/activity/api/res-1.2.0-alpha06.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/activity/activity/api/res-1.2.0-alpha06.txt
diff --git a/activity/activity/api/restricted_1.2.0-alpha06.txt b/activity/activity/api/restricted_1.2.0-alpha06.txt
new file mode 100644
index 0000000..4053dc1
--- /dev/null
+++ b/activity/activity/api/restricted_1.2.0-alpha06.txt
@@ -0,0 +1,231 @@
+// Signature format: 3.0
+package androidx.activity {
+
+  public class ComponentActivity extends androidx.core.app.ComponentActivity implements androidx.activity.result.ActivityResultCaller androidx.activity.result.ActivityResultRegistryOwner androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.activity.OnBackPressedDispatcherOwner androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
+    ctor public ComponentActivity();
+    ctor @ContentView public ComponentActivity(@LayoutRes int);
+    method public final androidx.activity.result.ActivityResultRegistry getActivityResultRegistry();
+    method public androidx.lifecycle.ViewModelProvider.Factory getDefaultViewModelProviderFactory();
+    method @Deprecated public Object? getLastCustomNonConfigurationInstance();
+    method public final androidx.activity.OnBackPressedDispatcher getOnBackPressedDispatcher();
+    method public final androidx.savedstate.SavedStateRegistry getSavedStateRegistry();
+    method public androidx.lifecycle.ViewModelStore getViewModelStore();
+    method @Deprecated @CallSuper protected void onActivityResult(int, int, android.content.Intent?);
+    method @Deprecated @CallSuper public void onRequestPermissionsResult(int, String![], int[]);
+    method @Deprecated public Object? onRetainCustomNonConfigurationInstance();
+    method public final Object? onRetainNonConfigurationInstance();
+    method public final <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerForActivityResult(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultRegistry, androidx.activity.result.ActivityResultCallback<O!>);
+    method public final <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerForActivityResult(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+    method @Deprecated public void startActivityForResult(android.content.Intent!, int);
+    method @Deprecated public void startActivityForResult(android.content.Intent!, int, android.os.Bundle?);
+    method @Deprecated public void startIntentSenderForResult(android.content.IntentSender!, int, android.content.Intent?, int, int, int) throws android.content.IntentSender.SendIntentException;
+    method @Deprecated public void startIntentSenderForResult(android.content.IntentSender!, int, android.content.Intent?, int, int, int, android.os.Bundle?) throws android.content.IntentSender.SendIntentException;
+  }
+
+  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();
+  }
+
+}
+
+package androidx.activity.result {
+
+  public final class ActivityResult implements android.os.Parcelable {
+    ctor public ActivityResult(int, android.content.Intent?);
+    method public int describeContents();
+    method public android.content.Intent? getData();
+    method public int getResultCode();
+    method public static String resultCodeToString(int);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<androidx.activity.result.ActivityResult!> CREATOR;
+  }
+
+  public interface ActivityResultCallback<O> {
+    method public void onActivityResult(O!);
+  }
+
+  public interface ActivityResultCaller {
+    method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerForActivityResult(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+    method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerForActivityResult(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultRegistry, androidx.activity.result.ActivityResultCallback<O!>);
+  }
+
+  public abstract class ActivityResultLauncher<I> {
+    ctor public ActivityResultLauncher();
+    method public void launch(I!);
+    method public abstract void launch(I!, androidx.core.app.ActivityOptionsCompat?);
+    method @MainThread public abstract void unregister();
+  }
+
+  public abstract class ActivityResultRegistry {
+    ctor public ActivityResultRegistry();
+    method @MainThread public final boolean dispatchResult(int, int, android.content.Intent?);
+    method @MainThread public final <O> boolean dispatchResult(int, O!);
+    method @MainThread public abstract <I, O> void invoke(int, androidx.activity.result.contract.ActivityResultContract<I!,O!>, I!, androidx.core.app.ActivityOptionsCompat?);
+    method public final void onRestoreInstanceState(android.os.Bundle?);
+    method public final void onSaveInstanceState(android.os.Bundle);
+    method public final <I, O> androidx.activity.result.ActivityResultLauncher<I!> register(String, androidx.lifecycle.LifecycleOwner, androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+    method public final <I, O> androidx.activity.result.ActivityResultLauncher<I!> register(String, androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+  }
+
+  public interface ActivityResultRegistryOwner {
+    method public androidx.activity.result.ActivityResultRegistry getActivityResultRegistry();
+  }
+
+  public final class IntentSenderRequest implements android.os.Parcelable {
+    method public int describeContents();
+    method public android.content.Intent? getFillInIntent();
+    method public int getFlagsMask();
+    method public int getFlagsValues();
+    method public android.content.IntentSender getIntentSender();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<androidx.activity.result.IntentSenderRequest!> CREATOR;
+  }
+
+  public static final class IntentSenderRequest.Builder {
+    ctor public IntentSenderRequest.Builder(android.content.IntentSender);
+    ctor public IntentSenderRequest.Builder(android.app.PendingIntent);
+    method public androidx.activity.result.IntentSenderRequest build();
+    method public androidx.activity.result.IntentSenderRequest.Builder setFillInIntent(android.content.Intent?);
+    method public androidx.activity.result.IntentSenderRequest.Builder setFlags(int, int);
+  }
+
+}
+
+package androidx.activity.result.contract {
+
+  public abstract class ActivityResultContract<I, O> {
+    ctor public ActivityResultContract();
+    method public abstract android.content.Intent createIntent(android.content.Context, I!);
+    method public androidx.activity.result.contract.ActivityResultContract.SynchronousResult<O!>? getSynchronousResult(android.content.Context, I!);
+    method public abstract O! parseResult(int, android.content.Intent?);
+  }
+
+  public static final class ActivityResultContract.SynchronousResult<T> {
+    ctor public ActivityResultContract.SynchronousResult(T!);
+    method public T! getValue();
+  }
+
+  public final class ActivityResultContracts {
+  }
+
+  public static class ActivityResultContracts.CreateDocument extends androidx.activity.result.contract.ActivityResultContract<java.lang.String,android.net.Uri> {
+    ctor public ActivityResultContracts.CreateDocument();
+    method @CallSuper public android.content.Intent createIntent(android.content.Context, String);
+    method public final androidx.activity.result.contract.ActivityResultContract.SynchronousResult<android.net.Uri!>? getSynchronousResult(android.content.Context, String);
+    method public final android.net.Uri? parseResult(int, android.content.Intent?);
+  }
+
+  public static class ActivityResultContracts.GetContent extends androidx.activity.result.contract.ActivityResultContract<java.lang.String,android.net.Uri> {
+    ctor public ActivityResultContracts.GetContent();
+    method @CallSuper public android.content.Intent createIntent(android.content.Context, String);
+    method public final androidx.activity.result.contract.ActivityResultContract.SynchronousResult<android.net.Uri!>? getSynchronousResult(android.content.Context, String);
+    method public final android.net.Uri? parseResult(int, android.content.Intent?);
+  }
+
+  public static class ActivityResultContracts.GetMultipleContents extends androidx.activity.result.contract.ActivityResultContract<java.lang.String,java.util.List<android.net.Uri>> {
+    ctor public ActivityResultContracts.GetMultipleContents();
+    method @CallSuper public android.content.Intent createIntent(android.content.Context, String);
+    method public final androidx.activity.result.contract.ActivityResultContract.SynchronousResult<java.util.List<android.net.Uri!>!>? getSynchronousResult(android.content.Context, String);
+    method public final java.util.List<android.net.Uri!> parseResult(int, android.content.Intent?);
+  }
+
+  public static class ActivityResultContracts.OpenDocument extends androidx.activity.result.contract.ActivityResultContract<java.lang.String[],android.net.Uri> {
+    ctor public ActivityResultContracts.OpenDocument();
+    method @CallSuper public android.content.Intent createIntent(android.content.Context, String![]);
+    method public final androidx.activity.result.contract.ActivityResultContract.SynchronousResult<android.net.Uri!>? getSynchronousResult(android.content.Context, String![]);
+    method public final android.net.Uri? parseResult(int, android.content.Intent?);
+  }
+
+  public static class ActivityResultContracts.OpenDocumentTree extends androidx.activity.result.contract.ActivityResultContract<android.net.Uri,android.net.Uri> {
+    ctor public ActivityResultContracts.OpenDocumentTree();
+    method @CallSuper public android.content.Intent createIntent(android.content.Context, android.net.Uri?);
+    method public final androidx.activity.result.contract.ActivityResultContract.SynchronousResult<android.net.Uri!>? getSynchronousResult(android.content.Context, android.net.Uri?);
+    method public final android.net.Uri? parseResult(int, android.content.Intent?);
+  }
+
+  public static class ActivityResultContracts.OpenMultipleDocuments extends androidx.activity.result.contract.ActivityResultContract<java.lang.String[],java.util.List<android.net.Uri>> {
+    ctor public ActivityResultContracts.OpenMultipleDocuments();
+    method @CallSuper public android.content.Intent createIntent(android.content.Context, String![]);
+    method public final androidx.activity.result.contract.ActivityResultContract.SynchronousResult<java.util.List<android.net.Uri!>!>? getSynchronousResult(android.content.Context, String![]);
+    method public final java.util.List<android.net.Uri!>? parseResult(int, android.content.Intent?);
+  }
+
+  public static final class ActivityResultContracts.PickContact extends androidx.activity.result.contract.ActivityResultContract<java.lang.Void,android.net.Uri> {
+    ctor public ActivityResultContracts.PickContact();
+    method public android.content.Intent createIntent(android.content.Context, Void?);
+    method public android.net.Uri? parseResult(int, android.content.Intent?);
+  }
+
+  public static final class ActivityResultContracts.RequestMultiplePermissions extends androidx.activity.result.contract.ActivityResultContract<java.lang.String[],java.util.Map<java.lang.String,java.lang.Boolean>> {
+    ctor public ActivityResultContracts.RequestMultiplePermissions();
+    method public android.content.Intent createIntent(android.content.Context, String![]);
+    method public androidx.activity.result.contract.ActivityResultContract.SynchronousResult<java.util.Map<java.lang.String!,java.lang.Boolean!>!>? getSynchronousResult(android.content.Context, String![]?);
+    method public java.util.Map<java.lang.String!,java.lang.Boolean!> parseResult(int, android.content.Intent?);
+    field public static final String ACTION_REQUEST_PERMISSIONS = "androidx.activity.result.contract.action.REQUEST_PERMISSIONS";
+    field public static final String EXTRA_PERMISSIONS = "androidx.activity.result.contract.extra.PERMISSIONS";
+    field public static final String EXTRA_PERMISSION_GRANT_RESULTS = "androidx.activity.result.contract.extra.PERMISSION_GRANT_RESULTS";
+  }
+
+  public static final class ActivityResultContracts.RequestPermission extends androidx.activity.result.contract.ActivityResultContract<java.lang.String,java.lang.Boolean> {
+    ctor public ActivityResultContracts.RequestPermission();
+    method public android.content.Intent createIntent(android.content.Context, String);
+    method public androidx.activity.result.contract.ActivityResultContract.SynchronousResult<java.lang.Boolean!>? getSynchronousResult(android.content.Context, String?);
+    method public Boolean parseResult(int, android.content.Intent?);
+  }
+
+  public static final class ActivityResultContracts.StartActivityForResult extends androidx.activity.result.contract.ActivityResultContract<android.content.Intent,androidx.activity.result.ActivityResult> {
+    ctor public ActivityResultContracts.StartActivityForResult();
+    method public android.content.Intent createIntent(android.content.Context, android.content.Intent);
+    method public androidx.activity.result.ActivityResult parseResult(int, android.content.Intent?);
+    field public static final String EXTRA_ACTIVITY_OPTIONS_BUNDLE = "androidx.activity.result.contract.extra.ACTIVITY_OPTIONS_BUNDLE";
+  }
+
+  public static final class ActivityResultContracts.StartIntentSenderForResult extends androidx.activity.result.contract.ActivityResultContract<androidx.activity.result.IntentSenderRequest,androidx.activity.result.ActivityResult> {
+    ctor public ActivityResultContracts.StartIntentSenderForResult();
+    method public android.content.Intent createIntent(android.content.Context, androidx.activity.result.IntentSenderRequest);
+    method public androidx.activity.result.ActivityResult parseResult(int, android.content.Intent?);
+    field public static final String ACTION_INTENT_SENDER_REQUEST = "androidx.activity.result.contract.action.INTENT_SENDER_REQUEST";
+    field public static final String EXTRA_INTENT_SENDER_REQUEST = "androidx.activity.result.contract.extra.INTENT_SENDER_REQUEST";
+    field public static final String EXTRA_SEND_INTENT_EXCEPTION = "androidx.activity.result.contract.extra.SEND_INTENT_EXCEPTION";
+  }
+
+  public static class ActivityResultContracts.TakePicture extends androidx.activity.result.contract.ActivityResultContract<android.net.Uri,java.lang.Boolean> {
+    ctor public ActivityResultContracts.TakePicture();
+    method @CallSuper public android.content.Intent createIntent(android.content.Context, android.net.Uri);
+    method public final androidx.activity.result.contract.ActivityResultContract.SynchronousResult<java.lang.Boolean!>? getSynchronousResult(android.content.Context, android.net.Uri);
+    method public final Boolean parseResult(int, android.content.Intent?);
+  }
+
+  public static class ActivityResultContracts.TakePicturePreview extends androidx.activity.result.contract.ActivityResultContract<java.lang.Void,android.graphics.Bitmap> {
+    ctor public ActivityResultContracts.TakePicturePreview();
+    method @CallSuper public android.content.Intent createIntent(android.content.Context, Void?);
+    method public final androidx.activity.result.contract.ActivityResultContract.SynchronousResult<android.graphics.Bitmap!>? getSynchronousResult(android.content.Context, Void?);
+    method public final android.graphics.Bitmap? parseResult(int, android.content.Intent?);
+  }
+
+  public static class ActivityResultContracts.TakeVideo extends androidx.activity.result.contract.ActivityResultContract<android.net.Uri,android.graphics.Bitmap> {
+    ctor public ActivityResultContracts.TakeVideo();
+    method @CallSuper public android.content.Intent createIntent(android.content.Context, android.net.Uri);
+    method public final androidx.activity.result.contract.ActivityResultContract.SynchronousResult<android.graphics.Bitmap!>? getSynchronousResult(android.content.Context, android.net.Uri);
+    method public final android.graphics.Bitmap? parseResult(int, android.content.Intent?);
+  }
+
+}
+
diff --git a/activity/activity/src/main/java/androidx/activity/result/contract/ActivityResultContracts.java b/activity/activity/src/main/java/androidx/activity/result/contract/ActivityResultContracts.java
index cb1497d..7212de8 100644
--- a/activity/activity/src/main/java/androidx/activity/result/contract/ActivityResultContracts.java
+++ b/activity/activity/src/main/java/androidx/activity/result/contract/ActivityResultContracts.java
@@ -47,7 +47,7 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 
@@ -486,7 +486,9 @@
 
         @NonNull
         static List<Uri> getClipDataUris(@NonNull Intent intent) {
-            HashSet<Uri> resultSet = new HashSet<>();
+            // Use a LinkedHashSet to maintain any ordering that may be
+            // present in the ClipData
+            LinkedHashSet<Uri> resultSet = new LinkedHashSet<>();
             if (intent.getData() != null) {
                 resultSet.add(intent.getData());
             }
diff --git a/appcompat/appcompat-resources/src/androidTest/java/androidx/appcompat/content/res/AppCompatResourcesTestCase.java b/appcompat/appcompat-resources/src/androidTest/java/androidx/appcompat/content/res/AppCompatResourcesTestCase.java
index 917ea00..46fd67d 100644
--- a/appcompat/appcompat-resources/src/androidTest/java/androidx/appcompat/content/res/AppCompatResourcesTestCase.java
+++ b/appcompat/appcompat-resources/src/androidTest/java/androidx/appcompat/content/res/AppCompatResourcesTestCase.java
@@ -18,10 +18,13 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
 import android.content.Context;
 import android.content.res.ColorStateList;
+import android.graphics.drawable.Drawable;
 
+import androidx.appcompat.graphics.drawable.MyDrawable;
 import androidx.appcompat.resources.test.R;
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -59,4 +62,11 @@
     public void testGetAnimatedStateListDrawable() {
         assertNotNull(AppCompatResources.getDrawable(mContext, R.drawable.asl_heart));
     }
+
+    @Test
+    public void testGetCustomDrawable() {
+        Drawable custom = AppCompatResources.getDrawable(mContext, R.drawable.my_drawable);
+        assertNotNull(custom);
+        assertTrue(custom instanceof MyDrawable);
+    }
 }
diff --git a/appcompat/appcompat-resources/src/androidTest/java/androidx/appcompat/graphics/drawable/MyDrawable.java b/appcompat/appcompat-resources/src/androidTest/java/androidx/appcompat/graphics/drawable/MyDrawable.java
new file mode 100644
index 0000000..b0be5f9
--- /dev/null
+++ b/appcompat/appcompat-resources/src/androidTest/java/androidx/appcompat/graphics/drawable/MyDrawable.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.appcompat.graphics.drawable;
+
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.drawable.Drawable;
+
+/**
+ * Simple custom drawable.
+ */
+public class MyDrawable extends Drawable {
+    private final Paint mPaint;
+
+    public MyDrawable() {
+        mPaint = new Paint();
+        mPaint.setARGB(255, 255, 0, 0);
+        mPaint.setAntiAlias(true);
+    }
+
+    @Override
+    public void draw(Canvas canvas) {
+        // Get the drawable's bounds
+        int width = getBounds().width();
+        int height = getBounds().height();
+        float radius = Math.min(width, height) / 2;
+
+        // Draw a red circle in the center
+        canvas.drawCircle(width / 2, height / 2, radius, mPaint);
+    }
+
+    @Override
+    public void setAlpha(int alpha) {
+        // This method is required
+    }
+
+    @Override
+    public void setColorFilter(ColorFilter colorFilter) {
+        // This method is required
+    }
+
+    @Override
+    public int getOpacity() {
+        return PixelFormat.OPAQUE;
+    }
+}
diff --git a/appcompat/appcompat-resources/src/androidTest/res/drawable/my_drawable.xml b/appcompat/appcompat-resources/src/androidTest/res/drawable/my_drawable.xml
new file mode 100644
index 0000000..567c210
--- /dev/null
+++ b/appcompat/appcompat-resources/src/androidTest/res/drawable/my_drawable.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2020 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<drawable xmlns:android="http://schemas.android.com/apk/res/android"
+    class="androidx.appcompat.graphics.drawable.MyDrawable"
+    android:color="#ffff0000" />
diff --git a/appcompat/appcompat-resources/src/main/java/androidx/appcompat/widget/ResourceManagerInternal.java b/appcompat/appcompat-resources/src/main/java/androidx/appcompat/widget/ResourceManagerInternal.java
index 9033007c..c35d8e6 100644
--- a/appcompat/appcompat-resources/src/main/java/androidx/appcompat/widget/ResourceManagerInternal.java
+++ b/appcompat/appcompat-resources/src/main/java/androidx/appcompat/widget/ResourceManagerInternal.java
@@ -36,7 +36,6 @@
 import androidx.annotation.DrawableRes;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
 import androidx.annotation.RestrictTo;
 import androidx.appcompat.graphics.drawable.AnimatedStateListDrawableCompat;
 import androidx.appcompat.resources.R;
@@ -106,6 +105,7 @@
             manager.addDelegate("vector", new VdcInflateDelegate());
             manager.addDelegate("animated-vector", new AvdcInflateDelegate());
             manager.addDelegate("animated-selector", new AsldcInflateDelegate());
+            manager.addDelegate("drawable", new DrawableDelegate());
         }
     }
 
@@ -533,7 +533,6 @@
         }
     }
 
-    @RequiresApi(11)
     static class AsldcInflateDelegate implements InflateDelegate {
         @Override
         public Drawable createFromXmlInner(@NonNull Context context, @NonNull XmlPullParser parser,
@@ -547,4 +546,30 @@
             }
         }
     }
+
+    static class DrawableDelegate implements InflateDelegate {
+        @Override
+        public Drawable createFromXmlInner(@NonNull Context context, @NonNull XmlPullParser parser,
+                @NonNull AttributeSet attrs, @Nullable Resources.Theme theme) {
+            String className = attrs.getClassAttribute();
+            if (className != null) {
+                try {
+                    Class<? extends Drawable> drawableClass =
+                            DrawableDelegate.class.getClassLoader().loadClass(className)
+                                    .asSubclass(Drawable.class);
+                    Drawable drawable = drawableClass.getDeclaredConstructor().newInstance();
+                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+                        drawable.inflate(context.getResources(), parser, attrs, theme);
+                    } else {
+                        drawable.inflate(context.getResources(), parser, attrs);
+                    }
+                    return drawable;
+                } catch (Exception e) {
+                    Log.e("DrawableDelegate", "Exception while inflating <drawable>", e);
+                    return null;
+                }
+            }
+            return null;
+        }
+    }
 }
diff --git a/appcompat/appcompat/api/1.3.0-alpha01.txt b/appcompat/appcompat/api/1.3.0-alpha01.txt
index aed2d02..e06cc21 100644
--- a/appcompat/appcompat/api/1.3.0-alpha01.txt
+++ b/appcompat/appcompat/api/1.3.0-alpha01.txt
@@ -517,9 +517,11 @@
     ctor public AppCompatEditText(android.content.Context);
     ctor public AppCompatEditText(android.content.Context, android.util.AttributeSet?);
     ctor public AppCompatEditText(android.content.Context, android.util.AttributeSet?, int);
+    method public androidx.core.widget.RichContentReceiverCompat<android.widget.TextView!>? getRichContentReceiverCompat();
     method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportBackgroundTintList();
     method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
     method public void setBackgroundDrawable(android.graphics.drawable.Drawable!);
+    method public void setRichContentReceiverCompat(androidx.core.widget.RichContentReceiverCompat<android.widget.TextView!>?);
     method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
     method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
     method public void setTextAppearance(android.content.Context!, int);
diff --git a/appcompat/appcompat/api/api_lint.ignore b/appcompat/appcompat/api/api_lint.ignore
index 039f065..fd01b04 100644
--- a/appcompat/appcompat/api/api_lint.ignore
+++ b/appcompat/appcompat/api/api_lint.ignore
@@ -17,6 +17,12 @@
     Use ListenableFuture (library), or a combination of Consumer<T>, Executor, and CancellationSignal (platform) instead of java.util.concurrent.Future (parameter future in androidx.appcompat.widget.AppCompatTextView.setTextFuture(java.util.concurrent.Future<androidx.core.text.PrecomputedTextCompat> future))
 
 
+BuilderSetStyle: androidx.appcompat.app.AlertDialog.Builder#create():
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.appcompat.app.AlertDialog.Builder.create()
+BuilderSetStyle: androidx.appcompat.app.AlertDialog.Builder#show():
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.appcompat.app.AlertDialog.Builder.show()
+
+
 ContextFirst: androidx.appcompat.app.AppCompatDelegate#createView(android.view.View, String, android.content.Context, android.util.AttributeSet) parameter #2:
     Context is distinct, so it must be the first argument (method `createView`)
 
diff --git a/appcompat/appcompat/api/current.txt b/appcompat/appcompat/api/current.txt
index aed2d02..e06cc21 100644
--- a/appcompat/appcompat/api/current.txt
+++ b/appcompat/appcompat/api/current.txt
@@ -517,9 +517,11 @@
     ctor public AppCompatEditText(android.content.Context);
     ctor public AppCompatEditText(android.content.Context, android.util.AttributeSet?);
     ctor public AppCompatEditText(android.content.Context, android.util.AttributeSet?, int);
+    method public androidx.core.widget.RichContentReceiverCompat<android.widget.TextView!>? getRichContentReceiverCompat();
     method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportBackgroundTintList();
     method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
     method public void setBackgroundDrawable(android.graphics.drawable.Drawable!);
+    method public void setRichContentReceiverCompat(androidx.core.widget.RichContentReceiverCompat<android.widget.TextView!>?);
     method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
     method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
     method public void setTextAppearance(android.content.Context!, int);
diff --git a/appcompat/appcompat/api/public_plus_experimental_1.3.0-alpha01.txt b/appcompat/appcompat/api/public_plus_experimental_1.3.0-alpha01.txt
index 6f176e4..b48b85b 100644
--- a/appcompat/appcompat/api/public_plus_experimental_1.3.0-alpha01.txt
+++ b/appcompat/appcompat/api/public_plus_experimental_1.3.0-alpha01.txt
@@ -517,9 +517,11 @@
     ctor public AppCompatEditText(android.content.Context);
     ctor public AppCompatEditText(android.content.Context, android.util.AttributeSet?);
     ctor public AppCompatEditText(android.content.Context, android.util.AttributeSet?, int);
+    method public androidx.core.widget.RichContentReceiverCompat<android.widget.TextView!>? getRichContentReceiverCompat();
     method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportBackgroundTintList();
     method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
     method public void setBackgroundDrawable(android.graphics.drawable.Drawable!);
+    method public void setRichContentReceiverCompat(androidx.core.widget.RichContentReceiverCompat<android.widget.TextView!>?);
     method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
     method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
     method public void setTextAppearance(android.content.Context!, int);
diff --git a/appcompat/appcompat/api/public_plus_experimental_current.txt b/appcompat/appcompat/api/public_plus_experimental_current.txt
index 6f176e4..b48b85b 100644
--- a/appcompat/appcompat/api/public_plus_experimental_current.txt
+++ b/appcompat/appcompat/api/public_plus_experimental_current.txt
@@ -517,9 +517,11 @@
     ctor public AppCompatEditText(android.content.Context);
     ctor public AppCompatEditText(android.content.Context, android.util.AttributeSet?);
     ctor public AppCompatEditText(android.content.Context, android.util.AttributeSet?, int);
+    method public androidx.core.widget.RichContentReceiverCompat<android.widget.TextView!>? getRichContentReceiverCompat();
     method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportBackgroundTintList();
     method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
     method public void setBackgroundDrawable(android.graphics.drawable.Drawable!);
+    method public void setRichContentReceiverCompat(androidx.core.widget.RichContentReceiverCompat<android.widget.TextView!>?);
     method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
     method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
     method public void setTextAppearance(android.content.Context!, int);
diff --git a/appcompat/appcompat/api/restricted_1.3.0-alpha01.txt b/appcompat/appcompat/api/restricted_1.3.0-alpha01.txt
index 10b05b7..d722032 100644
--- a/appcompat/appcompat/api/restricted_1.3.0-alpha01.txt
+++ b/appcompat/appcompat/api/restricted_1.3.0-alpha01.txt
@@ -1398,9 +1398,11 @@
     ctor public AppCompatEditText(android.content.Context);
     ctor public AppCompatEditText(android.content.Context, android.util.AttributeSet?);
     ctor public AppCompatEditText(android.content.Context, android.util.AttributeSet?, int);
+    method public androidx.core.widget.RichContentReceiverCompat<android.widget.TextView!>? getRichContentReceiverCompat();
     method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportBackgroundTintList();
     method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
     method public void setBackgroundDrawable(android.graphics.drawable.Drawable!);
+    method public void setRichContentReceiverCompat(androidx.core.widget.RichContentReceiverCompat<android.widget.TextView!>?);
     method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
     method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
     method public void setTextAppearance(android.content.Context!, int);
diff --git a/appcompat/appcompat/api/restricted_current.txt b/appcompat/appcompat/api/restricted_current.txt
index 10b05b7..d722032 100644
--- a/appcompat/appcompat/api/restricted_current.txt
+++ b/appcompat/appcompat/api/restricted_current.txt
@@ -1398,9 +1398,11 @@
     ctor public AppCompatEditText(android.content.Context);
     ctor public AppCompatEditText(android.content.Context, android.util.AttributeSet?);
     ctor public AppCompatEditText(android.content.Context, android.util.AttributeSet?, int);
+    method public androidx.core.widget.RichContentReceiverCompat<android.widget.TextView!>? getRichContentReceiverCompat();
     method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.res.ColorStateList? getSupportBackgroundTintList();
     method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
     method public void setBackgroundDrawable(android.graphics.drawable.Drawable!);
+    method public void setRichContentReceiverCompat(androidx.core.widget.RichContentReceiverCompat<android.widget.TextView!>?);
     method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
     method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
     method public void setTextAppearance(android.content.Context!, int);
diff --git a/appcompat/appcompat/src/androidTest/AndroidManifest.xml b/appcompat/appcompat/src/androidTest/AndroidManifest.xml
index 99fab52..59cf853 100644
--- a/appcompat/appcompat/src/androidTest/AndroidManifest.xml
+++ b/appcompat/appcompat/src/androidTest/AndroidManifest.xml
@@ -99,6 +99,11 @@
             android:theme="@style/Theme.TextColors"/>
 
         <activity
+            android:name="androidx.appcompat.widget.AppCompatEditTextRichContentReceiverActivity"
+            android:label="@string/app_compat_edit_text_rich_content_receiver_activity"
+            android:theme="@style/Theme.AppCompat.Light"/>
+
+        <activity
             android:name="androidx.appcompat.widget.AppCompatButtonAutoSizeActivity"
             android:label="@string/app_compat_button_auto_size_activity"
             android:theme="@style/Theme.AppCompat.Light"/>
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatEditTextRichContentReceiverActivity.java b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatEditTextRichContentReceiverActivity.java
new file mode 100644
index 0000000..9601ac1
--- /dev/null
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatEditTextRichContentReceiverActivity.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package androidx.appcompat.widget;
+
+import androidx.appcompat.test.R;
+import androidx.appcompat.testutils.BaseTestActivity;
+
+public class AppCompatEditTextRichContentReceiverActivity extends BaseTestActivity {
+    @Override
+    protected int getContentViewLayoutResId() {
+        return R.layout.appcompat_edittext_richcontentreceiver_activity;
+    }
+}
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatEditTextRichContentReceiverTest.java b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatEditTextRichContentReceiverTest.java
new file mode 100644
index 0000000..5f68405
--- /dev/null
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatEditTextRichContentReceiverTest.java
@@ -0,0 +1,489 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.appcompat.widget;
+
+import static androidx.core.widget.RichContentReceiverCompat.FLAG_CONVERT_TO_PLAIN_TEXT;
+import static androidx.core.widget.RichContentReceiverCompat.SOURCE_CLIPBOARD;
+import static androidx.core.widget.RichContentReceiverCompat.SOURCE_INPUT_METHOD;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.argThat;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import android.content.ClipData;
+import android.content.ClipDescription;
+import android.content.ClipboardManager;
+import android.content.Context;
+import android.net.Uri;
+import android.os.Build;
+import android.text.SpannableStringBuilder;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputConnection;
+import android.view.inputmethod.InputContentInfo;
+import android.widget.TextView;
+
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.test.R;
+import androidx.core.view.inputmethod.EditorInfoCompat;
+import androidx.core.view.inputmethod.InputConnectionCompat;
+import androidx.core.view.inputmethod.InputContentInfoCompat;
+import androidx.core.widget.RichContentReceiverCompat;
+import androidx.core.widget.TextViewRichContentReceiverCompat;
+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.rule.ActivityTestRule;
+
+import com.google.common.collect.ImmutableSet;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentMatcher;
+import org.mockito.Mockito;
+
+import java.util.Set;
+
+@MediumTest
+@RunWith(AndroidJUnit4.class)
+public class AppCompatEditTextRichContentReceiverTest {
+    private static final Set<String> ALL_TEXT_AND_IMAGE_MIME_TYPES = ImmutableSet.of(
+            "text/*", "image/*");
+
+    @Rule
+    public final ActivityTestRule<AppCompatEditTextRichContentReceiverActivity> mActivityTestRule =
+            new ActivityTestRule<>(AppCompatEditTextRichContentReceiverActivity.class);
+
+    private Context mContext;
+    private AppCompatEditText mEditText;
+    private RichContentReceiverCompat<TextView> mMockReceiver;
+    private ClipboardManager mClipboardManager;
+
+    @UiThreadTest
+    @Before
+    public void before() {
+        AppCompatActivity activity = mActivityTestRule.getActivity();
+        mContext = activity;
+        mEditText = activity.findViewById(R.id.edit_text_default_values);
+
+        mMockReceiver = Mockito.mock(RichContentReceiverCompat.class);
+
+        mClipboardManager = (ClipboardManager) mContext.getSystemService(Context.CLIPBOARD_SERVICE);
+
+        // Clear the clipboard
+        if (Build.VERSION.SDK_INT >= 28) {
+            mClipboardManager.clearPrimaryClip();
+        } else {
+            mClipboardManager.setPrimaryClip(ClipData.newPlainText("", ""));
+        }
+    }
+
+    // ============================================================================================
+    // Tests to verify APIs/accessors/defaults related to RichContentReceiver.
+    // ============================================================================================
+
+    @UiThreadTest
+    @Test
+    public void testGetAndSetRichContentReceiverCompat() throws Exception {
+        // Verify that by default the getter returns null.
+        assertThat(mEditText.getRichContentReceiverCompat()).isNull();
+
+        // Verify that after setting a custom receiver, the getter returns it.
+        TextViewRichContentReceiverCompat receiver = new TextViewRichContentReceiverCompat() {};
+        mEditText.setRichContentReceiverCompat(receiver);
+        assertThat(mEditText.getRichContentReceiverCompat()).isSameInstanceAs(receiver);
+
+        // Verify that the receiver can be reset by passing null.
+        mEditText.setRichContentReceiverCompat(null);
+        assertThat(mEditText.getRichContentReceiverCompat()).isNull();
+    }
+
+    @UiThreadTest
+    @Test
+    public void testOnCreateInputConnection_nullEditorInfo() throws Exception {
+        setTextAndCursor("xz", 1);
+        try {
+            mEditText.onCreateInputConnection(null);
+            Assert.fail("Expected NullPointerException");
+        } catch (NullPointerException expected) {
+        }
+    }
+
+    @UiThreadTest
+    @Test
+    public void testOnCreateInputConnection_noReceiver() throws Exception {
+        setTextAndCursor("xz", 1);
+
+        // Call onCreateInputConnection() and assert that contentMimeTypes is not set.
+        EditorInfo editorInfo = new EditorInfo();
+        InputConnection ic = mEditText.onCreateInputConnection(editorInfo);
+        assertThat(ic).isNotNull();
+        assertThat(EditorInfoCompat.getContentMimeTypes(editorInfo)).isEqualTo(new String[0]);
+    }
+
+    @UiThreadTest
+    @Test
+    public void testOnCreateInputConnection_withReceiver() throws Exception {
+        setTextAndCursor("xz", 1);
+
+        // Setup: Configure the receiver to a custom impl.
+        Set<String> receiverMimeTypes = ImmutableSet.of("text/plain", "image/png", "video/mp4");
+        when(mMockReceiver.getSupportedMimeTypes()).thenReturn(receiverMimeTypes);
+        mEditText.setRichContentReceiverCompat(mMockReceiver);
+
+        // Call onCreateInputConnection() and assert that contentMimeTypes is set from the receiver.
+        EditorInfo editorInfo = new EditorInfo();
+        InputConnection ic = mEditText.onCreateInputConnection(editorInfo);
+        assertThat(ic).isNotNull();
+        verify(mMockReceiver, times(1)).getSupportedMimeTypes();
+        verifyNoMoreInteractions(mMockReceiver);
+        assertThat(EditorInfoCompat.getContentMimeTypes(editorInfo))
+                .isEqualTo(receiverMimeTypes.toArray(new String[0]));
+    }
+
+    // ============================================================================================
+    // Tests to verify that the receiver callback is invoked for all the appropriate user
+    // interactions:
+    // * Paste from clipboard ("Paste" and "Paste as plain text" actions)
+    // * Content insertion from IME
+    // ============================================================================================
+
+    @UiThreadTest
+    @Test
+    public void testPaste_noReceiver() throws Exception {
+        setTextAndCursor("xz", 1);
+
+        // Setup: Copy text to the clipboard.
+        ClipData clip = ClipData.newPlainText("test", "y");
+        clip = copyToClipboard(clip);
+
+        // Trigger the "Paste" action. This should execute the platform paste handling, so the
+        // content should be inserted according to whatever behavior is implemented in the OS
+        // version that's running.
+        boolean result = triggerContextMenuAction(android.R.id.paste);
+        assertThat(result).isTrue();
+        if (Build.VERSION.SDK_INT <= 20) {
+            // The platform code on Android K and earlier had logic to insert a space before and
+            // after the pasted content (if no space was already present). See
+            // https://cs.android.com/android/platform/superproject/+/android-4.4.4_r2:frameworks/base/core/java/android/widget/TextView.java;l=8526,8527,8528,8545,8546
+            assertTextAndCursorPosition("x y z", 3);
+        } else {
+            assertTextAndCursorPosition("xyz", 2);
+        }
+    }
+
+    @UiThreadTest
+    @Test
+    public void testPaste_withReceiver() throws Exception {
+        setTextAndCursor("xz", 1);
+
+        // Setup: Copy text to the clipboard.
+        ClipData clip = ClipData.newPlainText("test", "y");
+        clip = copyToClipboard(clip);
+
+        // Setup: Configure to use the mock receiver.
+        mEditText.setRichContentReceiverCompat(mMockReceiver);
+
+        // Trigger the "Paste" action and assert that the custom receiver was executed.
+        triggerContextMenuAction(android.R.id.paste);
+        verify(mMockReceiver, times(1)).onReceive(
+                eq(mEditText), clipEq(clip), eq(SOURCE_CLIPBOARD), eq(0));
+        verifyNoMoreInteractions(mMockReceiver);
+    }
+
+    @UiThreadTest
+    @Test
+    public void testPaste_withReceiver_resultBoolean() throws Exception {
+        setTextAndCursor("xz", 1);
+
+        // Setup: Copy text to the clipboard.
+        ClipData clip = ClipData.newPlainText("test", "y");
+        clip = copyToClipboard(clip);
+
+        // Setup: Configure to use the mock receiver.
+        mEditText.setRichContentReceiverCompat(mMockReceiver);
+
+        // Trigger the "Paste" action and assert that the boolean result is true regardless of
+        // the receiver's return value.
+        when(mMockReceiver.onReceive(eq(mEditText), eq(clip), eq(SOURCE_CLIPBOARD),
+                eq(FLAG_CONVERT_TO_PLAIN_TEXT))).thenReturn(true);
+        boolean result = triggerContextMenuAction(android.R.id.paste);
+        assertThat(result).isTrue();
+
+        when(mMockReceiver.onReceive(eq(mEditText), eq(clip), eq(SOURCE_CLIPBOARD),
+                eq(FLAG_CONVERT_TO_PLAIN_TEXT))).thenReturn(false);
+        result = triggerContextMenuAction(android.R.id.paste);
+        assertThat(result).isTrue();
+    }
+
+    @UiThreadTest
+    @Test
+    public void testPaste_withReceiver_unsupportedMimeType() throws Exception {
+        setTextAndCursor("xz", 1);
+
+        // Setup: Copy a URI to the clipboard with a MIME type that's not supported by the receiver.
+        ClipData clip = new ClipData("test", new String[]{"video/mp4"},
+                new ClipData.Item("text", null, Uri.parse("content://com.example/path")));
+        clip = copyToClipboard(clip);
+
+        // Setup: Configure to use the mock receiver.
+        mEditText.setRichContentReceiverCompat(mMockReceiver);
+
+        // Trigger the "Paste" action and assert that the custom receiver was executed. This
+        // confirms that the receiver is invoked (give a chance to handle the content via some
+        // fallback) even if the MIME type of the content is not one of the receiver's supported
+        // MIME types.
+        triggerContextMenuAction(android.R.id.paste);
+        verify(mMockReceiver, times(1)).onReceive(
+                eq(mEditText), clipEq(clip), eq(SOURCE_CLIPBOARD), eq(0));
+        verifyNoMoreInteractions(mMockReceiver);
+    }
+
+    @SdkSuppress(minSdkVersion = 23) // The action "Paste as plain text" was added in SDK 23.
+    @UiThreadTest
+    @Test
+    public void testPasteAsPlainText_noReceiver() throws Exception {
+        setTextAndCursor("xz", 1);
+
+        // Setup: Copy HTML to the clipboard.
+        ClipData clip = ClipData.newHtmlText("test", "*y*", "<b>y</b>");
+        clip = copyToClipboard(clip);
+
+        // Trigger the "Paste as plain text" action. This should execute the platform paste
+        // handling, so the content should be inserted according to whatever behavior is implemented
+        // in the OS version that's running.
+        boolean result = triggerContextMenuAction(android.R.id.pasteAsPlainText);
+        assertThat(result).isTrue();
+        assertTextAndCursorPosition("x*y*z", 4);
+    }
+
+    @UiThreadTest
+    @Test
+    public void testPasteAsPlainText_withReceiver() throws Exception {
+        setTextAndCursor("xz", 1);
+
+        // Setup: Copy text to the clipboard.
+        ClipData clip = ClipData.newPlainText("test", "y");
+        clip = copyToClipboard(clip);
+
+        // Setup: Configure to use the mock receiver.
+        mEditText.setRichContentReceiverCompat(mMockReceiver);
+
+        // Trigger the "Paste as plain text" action and assert that the custom receiver was
+        // executed.
+        triggerContextMenuAction(android.R.id.pasteAsPlainText);
+        verify(mMockReceiver, times(1)).onReceive(
+                eq(mEditText), clipEq(clip),
+                eq(SOURCE_CLIPBOARD), eq(FLAG_CONVERT_TO_PLAIN_TEXT));
+        verifyNoMoreInteractions(mMockReceiver);
+    }
+
+    @UiThreadTest
+    @Test
+    public void testPasteAsPlainText_withReceiver_unsupportedMimeType() throws Exception {
+        setTextAndCursor("xz", 1);
+
+        // Setup: Copy a URI to the clipboard with a MIME type that's not supported by the receiver.
+        ClipData clip = new ClipData("test", new String[]{"video/mp4"},
+                new ClipData.Item("text", null, Uri.parse("content://com.example/path")));
+        clip = copyToClipboard(clip);
+
+        // Setup: Configure to use the mock receiver.
+        mEditText.setRichContentReceiverCompat(mMockReceiver);
+
+        // Trigger the "Paste as plain text" action and assert that the custom receiver was
+        // executed. This confirms that the receiver is invoked (given a chance to handle the
+        // content via some fallback) even if the MIME type of the content is not one of the
+        // receiver's supported MIME types.
+        triggerContextMenuAction(android.R.id.pasteAsPlainText);
+        verify(mMockReceiver, times(1)).onReceive(
+                eq(mEditText), clipEq(clip),
+                eq(SOURCE_CLIPBOARD), eq(FLAG_CONVERT_TO_PLAIN_TEXT));
+        verifyNoMoreInteractions(mMockReceiver);
+    }
+
+    @UiThreadTest
+    @Test
+    public void testImeCommitContent_noReceiver() throws Exception {
+        setTextAndCursor("xz", 1);
+
+        // Trigger the IME's commitContent() call and assert its outcome.
+        boolean result = triggerImeCommitContentViaCompat("image/png");
+        assertThat(result).isFalse();
+        assertTextAndCursorPosition("xz", 1);
+    }
+
+    @UiThreadTest
+    @Test
+    public void testImeCommitContent_withReceiver() throws Exception {
+        setTextAndCursor("xz", 1);
+
+        // Setup: Configure the receiver to a custom impl that supports all text and images.
+        when(mMockReceiver.getSupportedMimeTypes()).thenReturn(ALL_TEXT_AND_IMAGE_MIME_TYPES);
+        mEditText.setRichContentReceiverCompat(mMockReceiver);
+
+        // Trigger the IME's commitContent() call and assert that the custom receiver was executed.
+        triggerImeCommitContentViaCompat("image/png");
+        verify(mMockReceiver, times(1)).getSupportedMimeTypes();
+        verify(mMockReceiver, times(1)).onReceive(
+                eq(mEditText), any(ClipData.class), eq(SOURCE_INPUT_METHOD), eq(0));
+        verifyNoMoreInteractions(mMockReceiver);
+    }
+
+    @UiThreadTest
+    @Test
+    public void testImeCommitContent_withReceiver_resultBoolean() throws Exception {
+        setTextAndCursor("xz", 1);
+
+        // Setup: Configure the receiver to a custom impl that supports all text and images.
+        when(mMockReceiver.getSupportedMimeTypes()).thenReturn(ALL_TEXT_AND_IMAGE_MIME_TYPES);
+        mEditText.setRichContentReceiverCompat(mMockReceiver);
+
+        // Trigger the IME's commitContent() call, once when the mock receiver is configured to
+        // return true and once when the mock receiver is configured to return false.
+        when(mMockReceiver.onReceive(eq(mEditText), any(ClipData.class), eq(SOURCE_INPUT_METHOD),
+                eq(0))).thenReturn(true);
+        boolean result1 = triggerImeCommitContentViaCompat("image/png");
+        when(mMockReceiver.onReceive(eq(mEditText), any(ClipData.class), eq(SOURCE_INPUT_METHOD),
+                eq(0))).thenReturn(false);
+        boolean result2 = triggerImeCommitContentViaCompat("image/png");
+        verify(mMockReceiver, times(2)).onReceive(
+                eq(mEditText), any(ClipData.class), eq(SOURCE_INPUT_METHOD), eq(0));
+        if (Build.VERSION.SDK_INT >= 25) {
+            // On SDK 25 and above, the boolean result should match the return value from the
+            // receiver.
+            assertThat(result1).isTrue();
+            assertThat(result2).isFalse();
+        } else {
+            // On SDK 24 and below, commitContent() is handled via
+            // InputConnection.performPrivateCommand(). This ends up returning true whenever the
+            // command is sent, regardless of the return value of the underlying operation.
+            // Relevant code links:
+            // https://osscs.corp.google.com/androidx/platform/frameworks/support/+/androidx-master-dev:core/core/src/main/java/androidx/core/view/inputmethod/InputConnectionCompat.java;l=294;drc=0c365e84832f5ec5e393be28ab1c618eb18bab1e
+            // https://cs.android.com/android/platform/superproject/+/android-7.0.0_r6:frameworks/base/core/java/com/android/internal/widget/EditableInputConnection.java;l=168
+            assertThat(result1).isTrue();
+            assertThat(result2).isTrue();
+        }
+    }
+
+    @UiThreadTest
+    @Test
+    public void testImeCommitContent_withReceiver_unsupportedMimeType() throws Exception {
+        setTextAndCursor("xz", 1);
+
+        // Setup: Configure the receiver to a custom impl that supports all text and images.
+        when(mMockReceiver.getSupportedMimeTypes()).thenReturn(ALL_TEXT_AND_IMAGE_MIME_TYPES);
+        mEditText.setRichContentReceiverCompat(mMockReceiver);
+
+        // Trigger the IME's commitContent() call and assert that the custom receiver was not
+        // executed. This is because InputConnectionCompat.commitContent() checks the supported MIME
+        // types before proceeding.
+        triggerImeCommitContentViaCompat("video/mp4");
+        verify(mMockReceiver, times(1)).getSupportedMimeTypes();
+        verifyNoMoreInteractions(mMockReceiver);
+    }
+
+    @SdkSuppress(minSdkVersion = 25) // InputConnection.commitContent() was added in SDK 25.
+    @UiThreadTest
+    @Test
+    public void testImeCommitContent_direct_withReceiver_unsupportedMimeType() throws Exception {
+        setTextAndCursor("xz", 1);
+
+        // Setup: Configure the receiver to a custom impl that supports all text and images.
+        when(mMockReceiver.getSupportedMimeTypes()).thenReturn(ALL_TEXT_AND_IMAGE_MIME_TYPES);
+        mEditText.setRichContentReceiverCompat(mMockReceiver);
+
+        // Trigger the IME's commitContent() call and assert that the custom receiver was executed.
+        triggerImeCommitContentDirect("video/mp4");
+        verify(mMockReceiver, times(1)).getSupportedMimeTypes();
+        verify(mMockReceiver, times(1)).onReceive(
+                eq(mEditText), any(ClipData.class), eq(SOURCE_INPUT_METHOD), eq(0));
+        verifyNoMoreInteractions(mMockReceiver);
+    }
+
+    private boolean triggerContextMenuAction(final int actionId) {
+        return mEditText.onTextContextMenuItem(actionId);
+    }
+
+    private boolean triggerImeCommitContentViaCompat(String mimeType) {
+        final InputContentInfoCompat contentInfo = new InputContentInfoCompat(
+                Uri.parse("content://com.example/path"),
+                new ClipDescription("from test", new String[]{mimeType}),
+                Uri.parse("https://example.com"));
+        EditorInfo editorInfo = new EditorInfo();
+        InputConnection ic = mEditText.onCreateInputConnection(editorInfo);
+        return InputConnectionCompat.commitContent(ic, editorInfo, contentInfo, 0, null);
+    }
+
+    private boolean triggerImeCommitContentDirect(String mimeType) {
+        final InputContentInfo contentInfo = new InputContentInfo(
+                Uri.parse("content://com.example/path"),
+                new ClipDescription("from test", new String[]{mimeType}),
+                Uri.parse("https://example.com"));
+        EditorInfo editorInfo = new EditorInfo();
+        InputConnection ic = mEditText.onCreateInputConnection(editorInfo);
+        return ic.commitContent(contentInfo, 0, null);
+    }
+
+    private void setTextAndCursor(final String text, final int cursorPosition) {
+        mEditText.requestFocus();
+        SpannableStringBuilder ssb = new SpannableStringBuilder(text);
+        mEditText.setText(ssb);
+        mEditText.setSelection(cursorPosition);
+        assertThat(mEditText.hasFocus()).isTrue();
+        assertTextAndCursorPosition(text, cursorPosition);
+    }
+
+    private void assertTextAndCursorPosition(String expectedText, int cursorPosition) {
+        assertThat(mEditText.getText().toString()).isEqualTo(expectedText);
+        assertThat(mEditText.getSelectionStart()).isEqualTo(cursorPosition);
+        assertThat(mEditText.getSelectionEnd()).isEqualTo(cursorPosition);
+    }
+
+    private ClipData copyToClipboard(final ClipData clip) {
+        mClipboardManager.setPrimaryClip(clip);
+        ClipData primaryClip = mClipboardManager.getPrimaryClip();
+        assertThat(primaryClip).isNotNull();
+        return primaryClip;
+    }
+
+    private static ClipData clipEq(ClipData expected) {
+        return argThat(new ClipDataArgumentMatcher(expected));
+    }
+
+    private static class ClipDataArgumentMatcher implements ArgumentMatcher<ClipData> {
+        private final ClipData mExpected;
+
+        private ClipDataArgumentMatcher(ClipData expected) {
+            this.mExpected = expected;
+        }
+
+        @Override
+        public boolean matches(ClipData actual) {
+            return mExpected.getItemAt(0).getText().equals(actual.getItemAt(0).getText());
+        }
+    }
+}
diff --git a/appcompat/appcompat/src/androidTest/res/layout/appcompat_edittext_richcontentreceiver_activity.xml b/appcompat/appcompat/src/androidTest/res/layout/appcompat_edittext_richcontentreceiver_activity.xml
new file mode 100644
index 0000000..b1c4421
--- /dev/null
+++ b/appcompat/appcompat/src/androidTest/res/layout/appcompat_edittext_richcontentreceiver_activity.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2020 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<ScrollView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/container"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical">
+
+        <androidx.appcompat.widget.AppCompatEditText
+            android:id="@+id/edit_text_default_values"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"/>
+    </LinearLayout>
+</ScrollView>
diff --git a/appcompat/appcompat/src/androidTest/res/values/strings.xml b/appcompat/appcompat/src/androidTest/res/values/strings.xml
index bd41846..21d1659 100644
--- a/appcompat/appcompat/src/androidTest/res/values/strings.xml
+++ b/appcompat/appcompat/src/androidTest/res/values/strings.xml
@@ -57,6 +57,7 @@
     <string name="app_compat_text_view_activity">AppCompat text view</string>
     <string name="app_compat_text_view_auto_size_activity">AppCompat text view auto-size</string>
     <string name="app_compat_edit_text_activity">AppCompat edit text</string>
+    <string name="app_compat_edit_text_rich_content_receiver_activity">AppCompat edit text rich content receiver</string>
     <string name="app_compat_button_auto_size_activity">AppCompat button auto-size</string>
     <string name="sample_text1">Sample text 1</string>
     <string name="sample_text2">Sample text 2</string>
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegate.java b/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegate.java
index d53d632..514bda6 100644
--- a/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegate.java
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegate.java
@@ -92,7 +92,7 @@
  * retained until the Activity is destroyed.</p>
  */
 public abstract class AppCompatDelegate {
-    static final boolean DEBUG = false;
+    static final boolean DEBUG = true;
     static final String TAG = "AppCompatDelegate";
 
     /**
@@ -578,6 +578,9 @@
                 if (sDefaultNightMode != mode) {
                     sDefaultNightMode = mode;
                     applyDayNightToActiveDelegates();
+                } else if (DEBUG) {
+                    Log.d(TAG, String.format("Not applying changes, sDefaultNightMode already %d",
+                            mode));
                 }
                 break;
             default:
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegateImpl.java b/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegateImpl.java
index 17471b0..8ff2f65 100644
--- a/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegateImpl.java
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegateImpl.java
@@ -2518,10 +2518,12 @@
             // attachBaseContext() + createConfigurationContext() code path.
             // Else, we need to use updateConfiguration() before we're 'created' (below)
             if (DEBUG) {
-                Log.d(TAG, "updateForNightMode. Recreating Activity: " + mHost);
+                Log.d(TAG, "updateForNightMode attempting to recreate Activity: " + mHost);
             }
             ActivityCompat.recreate((Activity) mHost);
             handled = true;
+        } else if (DEBUG) {
+            Log.d(TAG, "updateForNightMode not recreating Activity: " + mHost);
         }
 
         if (!handled && currentNightMode != newNightMode) {
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatEditText.java b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatEditText.java
index a6a64b3..3982161 100644
--- a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatEditText.java
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatEditText.java
@@ -17,7 +17,11 @@
 package androidx.appcompat.widget;
 
 import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX;
+import static androidx.core.widget.RichContentReceiverCompat.FLAG_CONVERT_TO_PLAIN_TEXT;
+import static androidx.core.widget.RichContentReceiverCompat.SOURCE_CLIPBOARD;
 
+import android.content.ClipData;
+import android.content.ClipboardManager;
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.graphics.PorterDuff;
@@ -30,6 +34,7 @@
 import android.view.inputmethod.InputConnection;
 import android.view.textclassifier.TextClassifier;
 import android.widget.EditText;
+import android.widget.TextView;
 
 import androidx.annotation.DrawableRes;
 import androidx.annotation.NonNull;
@@ -38,6 +43,8 @@
 import androidx.annotation.RestrictTo;
 import androidx.appcompat.R;
 import androidx.core.view.TintableBackgroundView;
+import androidx.core.view.inputmethod.InputConnectionCompat;
+import androidx.core.widget.RichContentReceiverCompat;
 import androidx.core.widget.TextViewCompat;
 
 /**
@@ -48,6 +55,10 @@
  *     {@link androidx.core.view.ViewCompat}.</li>
  *     <li>Allows setting of the background tint using {@link R.attr#backgroundTint} and
  *     {@link R.attr#backgroundTintMode}.</li>
+ *     <li>Allows setting a custom {@link RichContentReceiverCompat receiver callback} in order to
+ *     handle insertion of content (e.g. pasting text or an image from the clipboard). This callback
+ *     provides the opportunity to implement app-specific handling such as creating an attachment
+ *     when an image is pasted.</li>
  * </ul>
  *
  * <p>This will automatically be used when you use {@link EditText} in your layouts
@@ -60,6 +71,8 @@
     private final AppCompatBackgroundHelper mBackgroundTintHelper;
     private final AppCompatTextHelper mTextHelper;
     private final AppCompatTextClassifierHelper mTextClassifierHelper;
+    @Nullable
+    private RichContentReceiverCompat<TextView> mRichContentReceiverCompat;
 
     public AppCompatEditText(@NonNull Context context) {
         this(context, null);
@@ -190,10 +203,23 @@
         }
     }
 
+    /**
+     * If a {@link #setRichContentReceiverCompat receiver callback} is set, the returned
+     * {@link InputConnection} will use it to handle calls to {@link InputConnection#commitContent}.
+     *
+     * {@inheritDoc}
+     */
     @Override
     public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
-        return AppCompatHintHelper.onCreateInputConnection(super.onCreateInputConnection(outAttrs),
-                outAttrs, this);
+        InputConnection ic = super.onCreateInputConnection(outAttrs);
+        ic = AppCompatHintHelper.onCreateInputConnection(ic, outAttrs, this);
+        if (ic != null && mRichContentReceiverCompat != null) {
+            mRichContentReceiverCompat.populateEditorInfoContentMimeTypes(ic, outAttrs);
+            InputConnectionCompat.OnCommitContentListener callback =
+                    mRichContentReceiverCompat.buildOnCommitContentListener(this);
+            ic = InputConnectionCompat.createWrapper(ic, outAttrs, callback);
+        }
+        return ic;
     }
 
     /**
@@ -235,4 +261,65 @@
         }
         return mTextClassifierHelper.getTextClassifier();
     }
+
+    /**
+     * If a {@link #setRichContentReceiverCompat receiver callback} is set, uses it to execute the
+     * "Paste" and "Paste as plain text" menu actions.
+     *
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean onTextContextMenuItem(int id) {
+        if (mRichContentReceiverCompat == null) {
+            return super.onTextContextMenuItem(id);
+        }
+        if (id == android.R.id.paste || id == android.R.id.pasteAsPlainText) {
+            ClipboardManager cm = (ClipboardManager) getContext().getSystemService(
+                    Context.CLIPBOARD_SERVICE);
+            ClipData clip = cm == null ? null : cm.getPrimaryClip();
+            if (clip != null) {
+                int flags = (id == android.R.id.paste) ? 0 : FLAG_CONVERT_TO_PLAIN_TEXT;
+                mRichContentReceiverCompat.onReceive(this, clip, SOURCE_CLIPBOARD, flags);
+            }
+            return true;
+        }
+        return super.onTextContextMenuItem(id);
+    }
+
+    /**
+     * Returns the callback that handles insertion of content into this view (e.g. pasting from
+     * the clipboard). See {@link #setRichContentReceiverCompat} for more info.
+     *
+     * @return The callback that this view is using to handle insertion of content. Returns
+     * {@code null} if no callback is configured, in which case the platform behavior of the
+     * {@link EditText} component will be used for content insertion.
+     */
+    @Nullable
+    public RichContentReceiverCompat<TextView> getRichContentReceiverCompat() {
+        return mRichContentReceiverCompat;
+    }
+
+    /**
+     * Sets the callback to handle insertion of content into this view.
+     *
+     * <p>"Content" and "rich content" here refers to both text and non-text: plain text, styled
+     * text, HTML, images, videos, audio files, etc. The callback configured here should typically
+     * extend from {@link androidx.core.widget.TextViewRichContentReceiverCompat} to provide
+     * consistent behavior for text content.
+     *
+     * <p>This callback will be invoked for the following scenarios:
+     * <ol>
+     *     <li>Paste from the clipboard (e.g. "Paste" or "Paste as plain text" action in the
+     *     insertion/selection menu)
+     *     <li>Content insertion from the keyboard ({@link InputConnection#commitContent})
+     * </ol>
+     *
+     * @param receiver The callback to use. This can be {@code null} to clear any previously set
+     *                 callback (the platform behavior of the {@link EditText} component will then
+     *                 be used).
+     */
+    public void setRichContentReceiverCompat(
+            @Nullable RichContentReceiverCompat<TextView> receiver) {
+        mRichContentReceiverCompat = receiver;
+    }
 }
diff --git a/autofill/autofill/api/api_lint.ignore b/autofill/autofill/api/api_lint.ignore
new file mode 100644
index 0000000..d0b566f
--- /dev/null
+++ b/autofill/autofill/api/api_lint.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+SetterReturnsThis: androidx.autofill.inline.UiVersions.StylesBuilder#addStyle(androidx.autofill.inline.UiVersions.Style):
+    Methods must return the builder object (return type androidx.autofill.inline.UiVersions.StylesBuilder instead of void): method androidx.autofill.inline.UiVersions.StylesBuilder.addStyle(androidx.autofill.inline.UiVersions.Style)
diff --git a/biometric/biometric/build.gradle b/biometric/biometric/build.gradle
index 60b8f6c..1c26102 100644
--- a/biometric/biometric/build.gradle
+++ b/biometric/biometric/build.gradle
@@ -1,6 +1,5 @@
 import static androidx.build.dependencies.DependenciesKt.*
 import androidx.build.LibraryGroups
-import androidx.build.LibraryVersions
 import androidx.build.Publish
 
 plugins {
@@ -9,11 +8,12 @@
 }
 
 dependencies {
+    api("androidx.activity:activity:1.1.0")
     api("androidx.annotation:annotation:1.1.0")
     api("androidx.appcompat:appcompat:1.1.0")
-    api("androidx.core:core:1.1.0")
-    api("androidx.fragment:fragment:1.1.0")
-    api(project(":lifecycle:lifecycle-viewmodel"))
+    api("androidx.core:core:1.2.0")
+    api("androidx.fragment:fragment:1.2.4")
+    api("androidx.lifecycle:lifecycle-viewmodel:2.2.0")
 
     testImplementation(ANDROIDX_TEST_CORE)
     testImplementation(ANDROIDX_TEST_RUNNER)
diff --git a/biometric/biometric/src/main/java/androidx/biometric/BiometricFragment.java b/biometric/biometric/src/main/java/androidx/biometric/BiometricFragment.java
index 409a620..d1633e0 100644
--- a/biometric/biometric/src/main/java/androidx/biometric/BiometricFragment.java
+++ b/biometric/biometric/src/main/java/androidx/biometric/BiometricFragment.java
@@ -224,8 +224,8 @@
     void cleanup() {
         mShowing = false;
         FragmentActivity activity = getActivity();
-        if (getFragmentManager() != null) {
-            getFragmentManager().beginTransaction().detach(this).commitAllowingStateLoss();
+        if (isAdded()) {
+            getParentFragmentManager().beginTransaction().detach(this).commitAllowingStateLoss();
         }
         Utils.maybeFinishHandler(activity);
     }
diff --git a/biometric/biometric/src/main/java/androidx/biometric/FingerprintDialogFragment.java b/biometric/biometric/src/main/java/androidx/biometric/FingerprintDialogFragment.java
index 69f1fbe..15c3281 100644
--- a/biometric/biometric/src/main/java/androidx/biometric/FingerprintDialogFragment.java
+++ b/biometric/biometric/src/main/java/androidx/biometric/FingerprintDialogFragment.java
@@ -395,7 +395,7 @@
 
     /** Attempts to dismiss this fragment while avoiding potential crashes. */
     private void dismissSafely() {
-        if (getFragmentManager() != null) {
+        if (isAdded()) {
             dismissAllowingStateLoss();
         } else {
             Log.e(TAG, "Failed to dismiss fingerprint dialog fragment. Fragment manager was null.");
diff --git a/browser/browser/api/api_lint.ignore b/browser/browser/api/api_lint.ignore
index b23baec..a4d5f5e 100644
--- a/browser/browser/api/api_lint.ignore
+++ b/browser/browser/api/api_lint.ignore
@@ -57,8 +57,10 @@
     Must avoid boxed primitives (`java.lang.Integer`)
 
 
-CallbackMethodName: androidx.browser.customtabs.CustomTabsCallback:
-    Callback method names must follow the on<Something> style: extraCallback
+BuilderSetStyle: androidx.browser.customtabs.CustomTabsIntent.Builder#enableUrlBarHiding():
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.browser.customtabs.CustomTabsIntent.Builder.enableUrlBarHiding()
+BuilderSetStyle: androidx.browser.trusted.TrustedWebActivityIntentBuilder#buildCustomTabsIntent():
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.browser.trusted.TrustedWebActivityIntentBuilder.buildCustomTabsIntent()
 
 
 ConcreteCollection: androidx.browser.browseractions.BrowserActionsIntent#openBrowserAction(android.content.Context, android.net.Uri, int, java.util.ArrayList<androidx.browser.browseractions.BrowserActionItem>, android.app.PendingIntent) parameter #3:
@@ -77,6 +79,10 @@
     Listeners should always be at end of argument list (method `newSession`)
 
 
+OptionalBuilderConstructorAgrument: androidx.browser.customtabs.CustomTabsIntent.Builder#Builder(androidx.browser.customtabs.CustomTabsSession) parameter #0:
+    Builder constructor arguments must be mandatory (i.e. not @Nullable): parameter session in androidx.browser.customtabs.CustomTabsIntent.Builder(androidx.browser.customtabs.CustomTabsSession session)
+
+
 PublicTypedef: androidx.browser.customtabs.CustomTabsService.Relation:
     Don't expose @IntDef: Relation must be hidden.
 PublicTypedef: androidx.browser.customtabs.CustomTabsService.Result:
diff --git a/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt b/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt
index 91f795a..af29b9f 100644
--- a/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt
@@ -20,7 +20,7 @@
  * The list of versions codes of all the libraries in this project.
  */
 object LibraryVersions {
-    val ACTIVITY = Version("1.2.0-alpha05")
+    val ACTIVITY = Version("1.2.0-alpha06")
     val ADS_IDENTIFIER = Version("1.0.0-alpha04")
     val ANNOTATION = Version("1.2.0-alpha01")
     val ANNOTATION_EXPERIMENTAL = Version("1.1.0-alpha01")
@@ -58,7 +58,7 @@
     val EMOJI = Version("1.2.0-alpha01")
     val ENTERPRISE = Version("1.1.0-alpha01")
     val EXIFINTERFACE = Version("1.3.0-alpha02")
-    val FRAGMENT = Version("1.3.0-alpha05")
+    val FRAGMENT = Version("1.3.0-alpha06")
     val FUTURES = Version("1.1.0-beta01")
     val GRIDLAYOUT = Version("1.1.0-alpha01")
     val HEIFWRITER = Version("1.1.0-alpha01")
diff --git a/buildSrc/src/main/kotlin/androidx/build/metalava/MetalavaRunner.kt b/buildSrc/src/main/kotlin/androidx/build/metalava/MetalavaRunner.kt
index 3580d2a..161803c 100644
--- a/buildSrc/src/main/kotlin/androidx/build/metalava/MetalavaRunner.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/metalava/MetalavaRunner.kt
@@ -112,6 +112,10 @@
         "NotCloseable",
         "SamShouldBeLast",
         "MissingJvmstatic",
+        "CallbackMethodName",
+        "GetterOnBuilder",
+        "StaticFinalBuilder",
+        "MissingGetterMatchingBuilder",
 
         // We should only treat these as warnings
         "IntentBuilderName",
diff --git a/buildSrc/src/main/kotlin/androidx/build/metalava/UpdateBaselineTasks.kt b/buildSrc/src/main/kotlin/androidx/build/metalava/UpdateBaselineTasks.kt
index 06b03c5..04120e0 100644
--- a/buildSrc/src/main/kotlin/androidx/build/metalava/UpdateBaselineTasks.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/metalava/UpdateBaselineTasks.kt
@@ -132,6 +132,8 @@
             baselineFile
         )
         args += listOf(
+            "--baseline",
+            baselineFile.toString(),
             "--check-compatibility:api:released",
             prevApi.toString(),
             "--source-files",
@@ -171,7 +173,6 @@
     return mutableListOf(
         "--update-baseline",
         baselineFile.toString(),
-        "--baseline", baselineFile.toString(),
         "--pass-baseline-updates",
         "--delete-empty-baselines",
         "--format=v3",
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/Camera2ImplConfig.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/Camera2ImplConfig.java
index f026cde..42b79fa 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/Camera2ImplConfig.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/impl/Camera2ImplConfig.java
@@ -29,6 +29,7 @@
 import androidx.camera.core.impl.MutableConfig;
 import androidx.camera.core.impl.MutableOptionsBundle;
 import androidx.camera.core.impl.OptionsBundle;
+import androidx.camera.core.impl.ReadableConfig;
 
 import java.util.HashSet;
 import java.util.Set;
@@ -36,7 +37,7 @@
 /**
  * Internal shared implementation details for camera 2 interop.
  */
-public final class Camera2ImplConfig implements Config {
+public final class Camera2ImplConfig implements ReadableConfig {
 
     /** @hide */
     @RestrictTo(Scope.LIBRARY)
@@ -202,43 +203,12 @@
         return mConfig.retrieveOption(CAMERA_EVENT_CALLBACK_OPTION, valueIfMissing);
     }
 
-    // Start of the default implementation of Config
-    // *********************************************************************************************
-
-    // Implementations of Config default methods
-
-    @Override
-    public boolean containsOption(@NonNull Option<?> id) {
-        return mConfig.containsOption(id);
-    }
-
-    @Override
-    @Nullable
-    public <ValueT> ValueT retrieveOption(@NonNull Option<ValueT> id) {
-        return mConfig.retrieveOption(id);
-    }
-
-    @Override
-    @Nullable
-    public <ValueT> ValueT retrieveOption(@NonNull Option<ValueT> id,
-            @Nullable ValueT valueIfMissing) {
-        return mConfig.retrieveOption(id, valueIfMissing);
-    }
-
-    @Override
-    public void findOptions(@NonNull String idStem, @NonNull OptionMatcher matcher) {
-        mConfig.findOptions(idStem, matcher);
-    }
-
-    @Override
     @NonNull
-    public Set<Option<?>> listOptions() {
-        return mConfig.listOptions();
+    @Override
+    public Config getConfig() {
+        return mConfig;
     }
 
-    // End of the default implementation of Config
-    // *********************************************************************************************
-
     /**
      * Builder for creating {@link Camera2ImplConfig} instance.
      *
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CameraControl.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CameraControl.java
index ade6c1f..6222e11 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CameraControl.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CameraControl.java
@@ -282,9 +282,10 @@
         return cropRect;
     }
 
+    @Override
     @WorkerThread
     @NonNull
-    Rect getSensorRect() {
+    public Rect getSensorRect() {
         return Preconditions.checkNotNull(
                 mCameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE));
     }
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/MeteringRepeatingConfig.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/MeteringRepeatingConfig.java
index 6268999..f38d5d6 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/MeteringRepeatingConfig.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/MeteringRepeatingConfig.java
@@ -17,10 +17,10 @@
 package androidx.camera.camera2.internal;
 
 import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
 import androidx.camera.core.CameraSelector;
 import androidx.camera.core.UseCase;
 import androidx.camera.core.impl.CaptureConfig;
+import androidx.camera.core.impl.Config;
 import androidx.camera.core.impl.MutableConfig;
 import androidx.camera.core.impl.MutableOptionsBundle;
 import androidx.camera.core.impl.OptionsBundle;
@@ -28,7 +28,6 @@
 import androidx.camera.core.impl.UseCaseConfig;
 import androidx.camera.core.internal.TargetConfig;
 
-import java.util.Set;
 import java.util.UUID;
 
 /**
@@ -43,168 +42,10 @@
         mConfig = config;
     }
 
-    // Start of the default implementation of Config
-    // *********************************************************************************************
-
-    // Implementations of Config default methods
-
-    @Override
-    public boolean containsOption(@NonNull Option<?> id) {
-        return mConfig.containsOption(id);
-    }
-
-    @Nullable
-    @Override
-    public <ValueT> ValueT retrieveOption(@NonNull Option<ValueT> id) {
-        return mConfig.retrieveOption(id);
-    }
-
-    @Nullable
-    @Override
-    public <ValueT> ValueT retrieveOption(@NonNull Option<ValueT> id,
-            @Nullable ValueT valueIfMissing) {
-        return mConfig.retrieveOption(id, valueIfMissing);
-    }
-
-    @Override
-    public void findOptions(@NonNull String idSearchString, @NonNull OptionMatcher matcher) {
-        mConfig.findOptions(idSearchString, matcher);
-    }
-
     @NonNull
     @Override
-    public Set<Option<?>> listOptions() {
-        return mConfig.listOptions();
-    }
-
-    // Implementations of TargetConfig default methods
-
-    @Nullable
-    @Override
-    public Class<MeteringRepeating> getTargetClass(
-            @Nullable Class<MeteringRepeating> valueIfMissing) {
-        @SuppressWarnings("unchecked") // Value should only be added via Builder#setTargetClass()
-                Class<MeteringRepeating> storedClass =
-                (Class<MeteringRepeating>) retrieveOption(
-                        OPTION_TARGET_CLASS,
-                        valueIfMissing);
-        return storedClass;
-    }
-
-    @NonNull
-    @Override
-    public Class<MeteringRepeating> getTargetClass() {
-        @SuppressWarnings("unchecked") // Value should only be added via Builder#setTargetClass()
-                Class<MeteringRepeating> storedClass =
-                (Class<MeteringRepeating>) retrieveOption(
-                        OPTION_TARGET_CLASS);
-        return storedClass;
-    }
-
-    @Nullable
-    @Override
-    public String getTargetName(@Nullable String valueIfMissing) {
-        return retrieveOption(OPTION_TARGET_NAME, valueIfMissing);
-    }
-
-    @NonNull
-    @Override
-    public String getTargetName() {
-        return retrieveOption(OPTION_TARGET_NAME);
-    }
-
-
-
-    // Implementations of UseCaseConfig default methods
-
-    @Nullable
-    @Override
-    public SessionConfig getDefaultSessionConfig(@Nullable SessionConfig valueIfMissing) {
-        return retrieveOption(OPTION_DEFAULT_SESSION_CONFIG, valueIfMissing);
-    }
-
-    @NonNull
-    @Override
-    public SessionConfig getDefaultSessionConfig() {
-        return retrieveOption(OPTION_DEFAULT_SESSION_CONFIG);
-    }
-
-    @Nullable
-    @Override
-    public CaptureConfig getDefaultCaptureConfig(@Nullable CaptureConfig valueIfMissing) {
-        return retrieveOption(OPTION_DEFAULT_CAPTURE_CONFIG, valueIfMissing);
-    }
-
-    @NonNull
-    @Override
-    public CaptureConfig getDefaultCaptureConfig() {
-        return retrieveOption(OPTION_DEFAULT_CAPTURE_CONFIG);
-    }
-
-    @Nullable
-    @Override
-    public SessionConfig.OptionUnpacker getSessionOptionUnpacker(
-            @Nullable SessionConfig.OptionUnpacker valueIfMissing) {
-        return retrieveOption(OPTION_SESSION_CONFIG_UNPACKER, valueIfMissing);
-    }
-
-    @NonNull
-    @Override
-    public SessionConfig.OptionUnpacker getSessionOptionUnpacker() {
-        return retrieveOption(OPTION_SESSION_CONFIG_UNPACKER);
-    }
-
-    @Nullable
-    @Override
-    public CaptureConfig.OptionUnpacker getCaptureOptionUnpacker(
-            @Nullable CaptureConfig.OptionUnpacker valueIfMissing) {
-        return retrieveOption(OPTION_CAPTURE_CONFIG_UNPACKER, valueIfMissing);
-    }
-
-    @NonNull
-    @Override
-    public CaptureConfig.OptionUnpacker getCaptureOptionUnpacker() {
-        return retrieveOption(OPTION_CAPTURE_CONFIG_UNPACKER);
-    }
-
-    @Override
-    public int getSurfaceOccupancyPriority(int valueIfMissing) {
-        return retrieveOption(OPTION_SURFACE_OCCUPANCY_PRIORITY, valueIfMissing);
-    }
-
-    @Override
-    public int getSurfaceOccupancyPriority() {
-        return retrieveOption(OPTION_SURFACE_OCCUPANCY_PRIORITY);
-    }
-
-    @Nullable
-    @Override
-    public CameraSelector getCameraSelector(@Nullable CameraSelector valueIfMissing) {
-        return retrieveOption(OPTION_CAMERA_SELECTOR, valueIfMissing);
-    }
-
-    @NonNull
-    @Override
-    public CameraSelector getCameraSelector() {
-        return retrieveOption(OPTION_CAMERA_SELECTOR);
-    }
-
-    @Nullable
-    @Override
-    public UseCase.EventCallback getUseCaseEventCallback(
-            @Nullable UseCase.EventCallback valueIfMissing) {
-        return retrieveOption(OPTION_USE_CASE_EVENT_CALLBACK, valueIfMissing);
-    }
-
-    @NonNull
-    @Override
-    public UseCase.EventCallback getUseCaseEventCallback() {
-        return retrieveOption(OPTION_USE_CASE_EVENT_CALLBACK);
-    }
-
-    @Override
-    public int getInputFormat() {
-        return retrieveOption(OPTION_INPUT_FORMAT);
+    public Config getConfig() {
+        return mConfig;
     }
 
     /** Builder for an empty Config */
@@ -344,6 +185,5 @@
         }
 
     }
-
 }
 
diff --git a/camera/camera-core/api/api_lint.ignore b/camera/camera-core/api/api_lint.ignore
index 075bc7c..71e1926 100644
--- a/camera/camera-core/api/api_lint.ignore
+++ b/camera/camera-core/api/api_lint.ignore
@@ -1,3 +1,11 @@
 // Baseline format: 1.0
+BuilderSetStyle: androidx.camera.core.CameraSelector.Builder#requireLensFacing(int):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.camera.core.CameraSelector.Builder.requireLensFacing(int)
+BuilderSetStyle: androidx.camera.core.CameraXConfig.Builder#fromConfig(androidx.camera.core.CameraXConfig):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.camera.core.CameraXConfig.Builder.fromConfig(androidx.camera.core.CameraXConfig)
+BuilderSetStyle: androidx.camera.core.FocusMeteringAction.Builder#disableAutoCancel():
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.camera.core.FocusMeteringAction.Builder.disableAutoCancel()
+
+
 TopLevelBuilder: androidx.camera.core.ExtendableBuilder:
     Builder should be defined as inner class: androidx.camera.core.ExtendableBuilder
diff --git a/camera/camera-core/build.gradle b/camera/camera-core/build.gradle
index b9ab7e4..0615e08 100644
--- a/camera/camera-core/build.gradle
+++ b/camera/camera-core/build.gradle
@@ -37,7 +37,8 @@
     implementation(AUTO_VALUE_ANNOTATIONS)
 
     annotationProcessor(AUTO_VALUE)
-    
+
+    testImplementation(KOTLIN_STDLIB)
     testImplementation(ANDROIDX_TEST_CORE)
     testImplementation(ANDROIDX_TEST_RUNNER)
     testImplementation(JUNIT)
@@ -55,9 +56,7 @@
     androidTestImplementation(TRUTH)
     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 project(":camera:camera-testing"), {
-        exclude group: "androidx.camera", module: "camera-core"
-    }
+    androidTestImplementation(project(":camera:camera-testing"))
     androidTestImplementation(KOTLIN_STDLIB)
     androidTestImplementation(KOTLIN_COROUTINES_ANDROID)
     androidTestImplementation(project(":concurrent:concurrent-futures-ktx"))
diff --git a/camera/camera-core/src/androidTest/java/androidx/camera/core/FakeOtherUseCaseConfig.java b/camera/camera-core/src/androidTest/java/androidx/camera/core/FakeOtherUseCaseConfig.java
index a4f9844..8b6a9bc 100644
--- a/camera/camera-core/src/androidTest/java/androidx/camera/core/FakeOtherUseCaseConfig.java
+++ b/camera/camera-core/src/androidTest/java/androidx/camera/core/FakeOtherUseCaseConfig.java
@@ -17,7 +17,6 @@
 package androidx.camera.core;
 
 import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
 import androidx.camera.core.impl.CaptureConfig;
 import androidx.camera.core.impl.Config;
@@ -28,12 +27,10 @@
 import androidx.camera.core.impl.SessionConfig;
 import androidx.camera.core.impl.UseCaseConfig;
 
-import java.util.Set;
 import java.util.UUID;
 
 /** A fake configuration for {@link FakeOtherUseCase}. */
-public class FakeOtherUseCaseConfig
-        implements UseCaseConfig<FakeOtherUseCase> {
+public class FakeOtherUseCaseConfig implements UseCaseConfig<FakeOtherUseCase> {
 
     private final Config mConfig;
 
@@ -41,146 +38,10 @@
         mConfig = config;
     }
 
-    // Start of the default implementation of Config
-    // *********************************************************************************************
-
-    // Implementations of Config default methods
-
-    /** @hide */
-    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    @Override
-    public boolean containsOption(@NonNull Option<?> id) {
-        return mConfig.containsOption(id);
-    }
-
-    /** @hide */
-    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    @Override
-    @Nullable
-    public <ValueT> ValueT retrieveOption(@NonNull Option<ValueT> id) {
-        return mConfig.retrieveOption(id);
-    }
-
-    /** @hide */
-    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    @Override
-    @Nullable
-    public <ValueT> ValueT retrieveOption(@NonNull Option<ValueT> id,
-            @Nullable ValueT valueIfMissing) {
-        return mConfig.retrieveOption(id, valueIfMissing);
-    }
-
-    /** @hide */
-    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    @Override
-    public void findOptions(@NonNull String idStem, @NonNull OptionMatcher matcher) {
-        mConfig.findOptions(idStem, matcher);
-    }
-
-    /** @hide */
-    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    @Override
     @NonNull
-    public Set<Option<?>> listOptions() {
-        return mConfig.listOptions();
-    }
-
-    // Implementations of TargetConfig default methods
-
     @Override
-    @Nullable
-    public Class<FakeOtherUseCase> getTargetClass(
-            @Nullable Class<FakeOtherUseCase> valueIfMissing) {
-        @SuppressWarnings("unchecked") // Value should only be added via Builder#setTargetClass()
-                Class<FakeOtherUseCase> storedClass = (Class<FakeOtherUseCase>) retrieveOption(
-                OPTION_TARGET_CLASS,
-                valueIfMissing);
-        return storedClass;
-    }
-
-    @Override
-    @NonNull
-    public Class<FakeOtherUseCase> getTargetClass() {
-        @SuppressWarnings("unchecked") // Value should only be added via Builder#setTargetClass()
-                Class<FakeOtherUseCase> storedClass = (Class<FakeOtherUseCase>) retrieveOption(
-                OPTION_TARGET_CLASS);
-        return storedClass;
-    }
-
-    @Override
-    @Nullable
-    public String getTargetName(@Nullable String valueIfMissing) {
-        return retrieveOption(OPTION_TARGET_NAME, valueIfMissing);
-    }
-
-    @Override
-    @NonNull
-    public String getTargetName() {
-        return retrieveOption(OPTION_TARGET_NAME);
-    }
-
-    /** @hide */
-    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    @Override
-    @Nullable
-    public SessionConfig getDefaultSessionConfig(@Nullable SessionConfig valueIfMissing) {
-        return retrieveOption(OPTION_DEFAULT_SESSION_CONFIG, valueIfMissing);
-    }
-
-    // Implementations of UseCaseConfig default methods
-
-    /** @hide */
-    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    @Override
-    @NonNull
-    public SessionConfig getDefaultSessionConfig() {
-        return retrieveOption(OPTION_DEFAULT_SESSION_CONFIG);
-    }
-
-    @Override
-    @Nullable
-    public CaptureConfig getDefaultCaptureConfig(@Nullable CaptureConfig valueIfMissing) {
-        return retrieveOption(OPTION_DEFAULT_CAPTURE_CONFIG, valueIfMissing);
-    }
-
-    @Override
-    @NonNull
-    public CaptureConfig getDefaultCaptureConfig() {
-        return retrieveOption(OPTION_DEFAULT_CAPTURE_CONFIG);
-    }
-
-    /** @hide */
-    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    @Override
-    @Nullable
-    public SessionConfig.OptionUnpacker getSessionOptionUnpacker(
-            @Nullable SessionConfig.OptionUnpacker valueIfMissing) {
-        return retrieveOption(OPTION_SESSION_CONFIG_UNPACKER, valueIfMissing);
-    }
-
-    /** @hide */
-    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    @Override
-    @NonNull
-    public SessionConfig.OptionUnpacker getSessionOptionUnpacker() {
-        return retrieveOption(OPTION_SESSION_CONFIG_UNPACKER);
-    }
-
-    /** @hide */
-    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    @Override
-    @Nullable
-    public CaptureConfig.OptionUnpacker getCaptureOptionUnpacker(
-            @Nullable CaptureConfig.OptionUnpacker valueIfMissing) {
-        return retrieveOption(OPTION_CAPTURE_CONFIG_UNPACKER, valueIfMissing);
-    }
-
-    /** @hide */
-    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    @Override
-    @NonNull
-    public CaptureConfig.OptionUnpacker getCaptureOptionUnpacker() {
-        return retrieveOption(OPTION_CAPTURE_CONFIG_UNPACKER);
+    public Config getConfig() {
+        return mConfig;
     }
 
     /** @hide */
@@ -195,49 +56,11 @@
         return retrieveOption(OPTION_SURFACE_OCCUPANCY_PRIORITY);
     }
 
-    /** @hide */
-    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    @Override
-    @Nullable
-    public CameraSelector getCameraSelector(@Nullable CameraSelector valueIfMissing) {
-        return retrieveOption(OPTION_CAMERA_SELECTOR, valueIfMissing);
-    }
-
-    /** @hide */
-    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    @Override
-    @NonNull
-    public CameraSelector getCameraSelector() {
-        return retrieveOption(OPTION_CAMERA_SELECTOR);
-    }
-
-    /** @hide */
-    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    @Override
-    @Nullable
-    public UseCase.EventCallback getUseCaseEventCallback(
-            @Nullable UseCase.EventCallback valueIfMissing) {
-        return retrieveOption(OPTION_USE_CASE_EVENT_CALLBACK, valueIfMissing);
-    }
-
-    /** @hide */
-    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    @Override
-    @NonNull
-    public UseCase.EventCallback getUseCaseEventCallback() {
-        return retrieveOption(OPTION_USE_CASE_EVENT_CALLBACK);
-    }
-
-    // Implementations of ImageInputConfig default methods
-
     @Override
     public int getInputFormat() {
         return ImageFormatConstants.INTERNAL_DEFINED_IMAGE_FORMAT_PRIVATE;
     }
 
-    // End of the default implementation of Config
-    // *********************************************************************************************
-
     /** Builder for an empty Config */
     public static final class Builder implements
             UseCaseConfig.Builder<FakeOtherUseCase, FakeOtherUseCaseConfig,
diff --git a/camera/camera-core/src/androidTest/java/androidx/camera/core/SurfaceRequestTest.java b/camera/camera-core/src/androidTest/java/androidx/camera/core/SurfaceRequestTest.java
index b0effe5..422d9b7 100644
--- a/camera/camera-core/src/androidTest/java/androidx/camera/core/SurfaceRequestTest.java
+++ b/camera/camera-core/src/androidTest/java/androidx/camera/core/SurfaceRequestTest.java
@@ -23,10 +23,12 @@
 import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.verify;
 
+import android.graphics.Rect;
 import android.util.Size;
 import android.view.Surface;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.camera.core.impl.utils.executor.CameraXExecutors;
 import androidx.camera.testing.fakes.FakeCameraInfoInternal;
 import androidx.core.content.ContextCompat;
@@ -47,6 +49,7 @@
 public final class SurfaceRequestTest {
 
     private static final Size FAKE_SIZE = new Size(0, 0);
+    private static final Rect FAKE_VIEW_PORT_RECT = new Rect(0, 0, 640, 480);
     private static final Consumer<SurfaceRequest.Result> NO_OP_RESULT_LISTENER = ignored -> {
     };
     private static final Surface MOCK_SURFACE = mock(Surface.class);
@@ -187,8 +190,29 @@
         verify(listener, timeout(500)).run();
     }
 
+    @Test
+    public void createSurfaceRequestWithViewPort_viewPortIsSet() {
+        assertThat(createNewRequest(FAKE_SIZE, FAKE_VIEW_PORT_RECT).getViewPortRect()).isEqualTo(
+                FAKE_VIEW_PORT_RECT);
+    }
+
+    @Test
+    public void createSurfaceRequestWithNullViewPort_viewPortIsFullSurface() {
+        // Arrange.
+        Size size = new Size(200, 100);
+
+        // Assert.
+        assertThat(createNewRequest(size, null).getViewPortRect()).isEqualTo(
+                new Rect(0, 0, size.getWidth(), size.getHeight()));
+    }
+
     private SurfaceRequest createNewRequest(@NonNull Size size) {
-        SurfaceRequest request = new SurfaceRequest(size, new FakeCameraInfoInternal());
+        return createNewRequest(size, FAKE_VIEW_PORT_RECT);
+    }
+
+    private SurfaceRequest createNewRequest(@NonNull Size size, @Nullable Rect viewPortRect) {
+        SurfaceRequest request = new SurfaceRequest(size, new FakeCameraInfoInternal(),
+                viewPortRect);
         mSurfaceRequests.add(request);
         return request;
     }
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 98acfd3..0f720f8 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
@@ -292,6 +292,7 @@
             @NonNull UseCase... useCases) {
         Threads.checkMainThread();
         CameraX cameraX = checkInitialized();
+        // TODO(b/153096869): override UseCase's target rotation.
 
         UseCaseGroupLifecycleController useCaseGroupLifecycleController =
                 cameraX.getOrCreateUseCaseGroup(lifecycleOwner);
@@ -355,7 +356,19 @@
                 originalUseCases,
                 Arrays.asList(useCases));
 
-        // TODO(b/153096869): calculates crop rect using viewPort.
+        if (viewPort != null) {
+            // Calculate crop rect if view port is provided.
+            Map<UseCase, Rect> cropRectMap = calculateViewPortRects(
+                    camera.getCameraControlInternal().getSensorRect(),
+                    viewPort.getAspectRatio(),
+                    camera.getCameraInfoInternal().getSensorRotationDegrees(
+                            viewPort.getRotation()),
+                    viewPort.getScaleType(),
+                    suggestedResolutionsMap);
+            for (UseCase useCase : useCases) {
+                useCase.setViewPortCropRect(cropRectMap.get(useCase));
+            }
+        }
 
         // At this point the binding will succeed since all the calculations are done
         // Do all binding related work
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/CameraXConfig.java b/camera/camera-core/src/main/java/androidx/camera/core/CameraXConfig.java
index c313920..9a8200f 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/CameraXConfig.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/CameraXConfig.java
@@ -32,7 +32,6 @@
 import androidx.camera.core.impl.UseCaseConfigFactory;
 import androidx.camera.core.internal.TargetConfig;
 
-import java.util.Set;
 import java.util.UUID;
 import java.util.concurrent.Executor;
 
@@ -53,7 +52,7 @@
  * @see androidx.camera.lifecycle
  * @see CameraXConfig.Builder
  */
-public final class CameraXConfig implements TargetConfig<CameraX>, Config {
+public final class CameraXConfig implements TargetConfig<CameraX> {
 
     /**
      * An interface which can be implemented to provide the configuration for CameraX.
@@ -163,103 +162,22 @@
         return mConfig.retrieveOption(OPTION_SCHEDULER_HANDLER, valueIfMissing);
     }
 
-    // Start of the default implementation of Config
-    // *********************************************************************************************
-
-    // Implementations of Config default methods
-
     /** @hide */
     @RestrictTo(Scope.LIBRARY_GROUP)
-    @Override
-    public boolean containsOption(@NonNull Option<?> id) {
-        return mConfig.containsOption(id);
-    }
-
-
-    /** @hide */
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Override
-    @Nullable
-    public <ValueT> ValueT retrieveOption(@NonNull Option<ValueT> id) {
-        return mConfig.retrieveOption(id);
-    }
-
-    /** @hide */
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Override
-    @Nullable
-    public <ValueT> ValueT retrieveOption(@NonNull Option<ValueT> id,
-            @Nullable ValueT valueIfMissing) {
-        return mConfig.retrieveOption(id, valueIfMissing);
-    }
-
-    /** @hide */
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Override
-    public void findOptions(@NonNull String idStem, @NonNull OptionMatcher matcher) {
-        mConfig.findOptions(idStem, matcher);
-    }
-
-    /** @hide */
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Override
     @NonNull
-    public Set<Option<?>> listOptions() {
-        return mConfig.listOptions();
-    }
-
-    // Implementations of TargetConfig default methods
-
-    /** @hide */
-    @RestrictTo(Scope.LIBRARY_GROUP)
     @Override
-    @Nullable
-    public Class<CameraX> getTargetClass(
-            @Nullable Class<CameraX> valueIfMissing) {
-        @SuppressWarnings("unchecked") // Value should only be added via Builder#setTargetClass()
-                Class<CameraX> storedClass = (Class<CameraX>) retrieveOption(
-                OPTION_TARGET_CLASS,
-                valueIfMissing);
-        return storedClass;
+    public Config getConfig() {
+        return mConfig;
     }
 
-    /** @hide */
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Override
-    @NonNull
-    public Class<CameraX> getTargetClass() {
-        @SuppressWarnings("unchecked") // Value should only be added via Builder#setTargetClass()
-                Class<CameraX> storedClass = (Class<CameraX>) retrieveOption(
-                OPTION_TARGET_CLASS);
-        return storedClass;
-    }
-
-    /** @hide */
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Override
-    @Nullable
-    public String getTargetName(@Nullable String valueIfMissing) {
-        return retrieveOption(OPTION_TARGET_NAME, valueIfMissing);
-    }
-
-    /** @hide */
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Override
-    @NonNull
-    public String getTargetName() {
-        return retrieveOption(OPTION_TARGET_NAME);
-    }
-
-    // End of the default implementation of Config
-    // *********************************************************************************************
-
     /** A builder for generating {@link CameraXConfig} objects. */
     public static final class Builder
             implements TargetConfig.Builder<CameraX, CameraXConfig.Builder> {
 
         private final MutableOptionsBundle mMutableConfig;
 
-        /** Creates a new Builder object.
+        /**
+         * Creates a new Builder object.
          *
          * @hide
          */
@@ -299,7 +217,6 @@
          * Sets the {@link CameraFactory} implementation for the application.
          *
          * @hide
-         * @param cameraFactory
          */
         @RestrictTo(Scope.LIBRARY_GROUP)
         @NonNull
@@ -366,8 +283,8 @@
          * used in applications with very specific threading requirements. If not set, CameraX
          * will create and use an optimized default internal handler.
          *
-         * @see #setCameraExecutor(Executor)
          * @hide
+         * @see #setCameraExecutor(Executor)
          */
         @RestrictTo(Scope.LIBRARY_GROUP)
         @NonNull
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 fcc3103..a3bd3a0 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
@@ -368,7 +368,13 @@
     public void setAnalyzer(@NonNull Executor executor, @NonNull Analyzer analyzer) {
         synchronized (mAnalysisLock) {
             mImageAnalysisAbstractAnalyzer.open();
-            mImageAnalysisAbstractAnalyzer.setAnalyzer(executor, analyzer);
+            mImageAnalysisAbstractAnalyzer.setAnalyzer(executor, image -> {
+                if (getViewPortCropRect() != null) {
+                    image.setViewPortRect(getViewPortCropRect());
+                    image.setCropRect(getViewPortCropRect());
+                }
+                analyzer.analyze(image);
+            });
             if (mSubscribedAnalyzer == null) {
                 notifyActive();
             }
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 6cb252b..bdf786e 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
@@ -44,6 +44,7 @@
 import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.graphics.ImageFormat;
+import android.graphics.Rect;
 import android.location.Location;
 import android.media.Image;
 import android.media.ImageReader;
@@ -743,7 +744,7 @@
 
         mPendingImageCaptureRequests.offer(
                 new ImageCaptureRequest(relativeRotation, getJpegQuality(), targetRatio,
-                        listenerExecutor, callback));
+                        getViewPortCropRect(), listenerExecutor, callback));
 
         issueImageCaptureRequests();
     }
@@ -1872,6 +1873,8 @@
 
         AtomicBoolean mDispatched = new AtomicBoolean(false);
 
+        private final Rect mViewPortCropRect;
+
         /**
          * @param rotationDegrees The degrees to rotate the image buffer from sensor
          *                        coordinates into the final output coordinate space.
@@ -1883,6 +1886,7 @@
                 @RotationValue int rotationDegrees,
                 @IntRange(from = 1, to = 100) int jpegQuality,
                 Rational targetRatio,
+                @Nullable Rect viewPortCropRect,
                 @NonNull Executor executor,
                 @NonNull OnImageCapturedCallback callback) {
             mRotationDegrees = rotationDegrees;
@@ -1893,6 +1897,7 @@
                         + "positive");
             }
             mTargetRatio = targetRatio;
+            mViewPortCropRect = viewPortCropRect;
             mListenerExecutor = executor;
             mCallback = callback;
         }
@@ -1943,7 +1948,12 @@
 
             // Update the crop rect aspect ratio after it has been rotated into the buffer
             // orientation
-            if (mTargetRatio != null) {
+            if (mViewPortCropRect != null) {
+                // ViewPort rect has higher priority than the custom aspect ratio.
+                dispatchedImageProxy.setViewPortRect(mViewPortCropRect);
+                dispatchedImageProxy.setCropRect(mViewPortCropRect);
+            } else if (mTargetRatio != null) {
+                // Fall back to custom aspect ratio if view port is not available.
                 Rational dispatchRatio = mTargetRatio;
                 if ((dispatchRotation % 180) != 0) {
                     dispatchRatio = new Rational(
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 d49aef2..c430306 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
@@ -188,7 +188,7 @@
         }
 
         final SurfaceRequest surfaceRequest = new SurfaceRequest(resolution,
-                getBoundCamera().getCameraInfo());
+                getBoundCamera().getCameraInfo(), getViewPortCropRect());
         setUpSurfaceProviderWrap(surfaceRequest);
 
         if (captureProcessor != null) {
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/SurfaceRequest.java b/camera/camera-core/src/main/java/androidx/camera/core/SurfaceRequest.java
index 61f47d7..ef9338c 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/SurfaceRequest.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/SurfaceRequest.java
@@ -56,6 +56,7 @@
 
     private final Size mResolution;
     private final CameraInfo mCameraInfo;
+    private final Rect mViewPortRect;
 
     // For the camera to retrieve the surface from the user
     @SuppressWarnings("WeakerAccess") /*synthetic accessor */
@@ -70,6 +71,16 @@
     // cancellation listeners.
     private final CallbackToFutureAdapter.Completer<Void> mRequestCancellationCompleter;
 
+    /**
+     * Creates a new surface request with the given resolution.
+     *
+     * @hide
+     */
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    public SurfaceRequest(@NonNull Size resolution, @NonNull CameraInfo cameraInfo) {
+        this(resolution, cameraInfo, null);
+    }
+
     private DeferrableSurface mInternalDeferrableSurface;
 
     /**
@@ -78,10 +89,16 @@
      * @hide
      */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    public SurfaceRequest(@NonNull Size resolution, @NonNull CameraInfo cameraInfo) {
+    public SurfaceRequest(
+            @NonNull Size resolution,
+            @NonNull CameraInfo cameraInfo,
+            @Nullable Rect viewPortRect) {
         super();
         mResolution = resolution;
         mCameraInfo = cameraInfo;
+        // Use full surface rect if viewPortRect is null.
+        mViewPortRect = viewPortRect != null ? viewPortRect : new Rect(0, 0, resolution.getWidth(),
+                resolution.getHeight());
 
         // To ensure concurrency and ordering, operations are chained. Completion can only be
         // triggered externally by the top-level completer (mSurfaceCompleter). The other future
@@ -248,8 +265,8 @@
      */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     @NonNull
-    public Rect getCropRect() {
-        throw new UnsupportedOperationException("Not implemented.");
+    public Rect getViewPortRect() {
+        return mViewPortRect;
     }
 
     /**
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/UseCase.java b/camera/camera-core/src/main/java/androidx/camera/core/UseCase.java
index 489887c..4d172c3 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/UseCase.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/UseCase.java
@@ -16,7 +16,10 @@
 
 package androidx.camera.core;
 
+import android.graphics.Rect;
+import android.media.ImageReader;
 import android.util.Size;
+import android.view.Surface;
 
 import androidx.annotation.GuardedBy;
 import androidx.annotation.NonNull;
@@ -56,11 +59,16 @@
     private SessionConfig mAttachedSessionConfig = SessionConfig.defaultEmptySessionConfig();
 
     /**
-     * A map of the names of the {@link android.hardware.camera2.CameraDevice} to the surface
-     * resolution that have been attached to this UseCase
+     * The resolution assigned to the {@link UseCase} based on the attached camera.
      */
     private Size mAttachedResolution;
 
+    /**
+     * The crop rect calculated at the time of binding based on {@link ViewPort}.
+     */
+    @Nullable
+    private Rect mViewPortCropRect;
+
     private State mState = State.INACTIVE;
 
     private UseCaseConfig<?> mUseCaseConfig;
@@ -96,7 +104,7 @@
      */
     @RestrictTo(Scope.LIBRARY_GROUP)
     @Nullable
-    protected UseCaseConfig.Builder<?, ?, ?> getDefaultBuilder(@Nullable CameraInfo cameraInfo) {
+    protected Builder<?, ?, ?> getDefaultBuilder(@Nullable CameraInfo cameraInfo) {
         return null;
     }
 
@@ -119,7 +127,7 @@
     @RestrictTo(Scope.LIBRARY_GROUP)
     protected final void updateUseCaseConfig(@NonNull UseCaseConfig<?> useCaseConfig) {
         // Attempt to retrieve builder containing defaults for this use case's config
-        UseCaseConfig.Builder<?, ?, ?> defaultBuilder =
+        Builder<?, ?, ?> defaultBuilder =
                 getDefaultBuilder(
                         getBoundCamera() == null ? null : getBoundCamera().getCameraInfo());
 
@@ -143,7 +151,7 @@
     @NonNull
     protected UseCaseConfig<?> applyDefaults(
             @NonNull UseCaseConfig<?> userConfig,
-            @Nullable UseCaseConfig.Builder<?, ?, ?> defaultConfigBuilder) {
+            @Nullable Builder<?, ?, ?> defaultConfigBuilder) {
         if (defaultConfigBuilder == null) {
             // No default builder was retrieved, return config directly
             return userConfig;
@@ -205,6 +213,7 @@
 
     /**
      * Get the current {@link SessionConfig}.
+     *
      * @hide
      */
     @RestrictTo(Scope.LIBRARY_GROUP)
@@ -317,7 +326,8 @@
      * @hide
      */
     @RestrictTo(Scope.LIBRARY_GROUP)
-    public void clear() {}
+    public void clear() {
+    }
 
     /**
      * Called use case is unbound from lifecycle or the bound lifecycle is destroyed.
@@ -331,7 +341,8 @@
      * @hide
      */
     @RestrictTo(Scope.LIBRARY_GROUP)
-    public void onDestroy() {}
+    public void onDestroy() {
+    }
 
     /** @hide */
     @RestrictTo(Scope.LIBRARY_GROUP)
@@ -390,12 +401,12 @@
      * Called when binding new use cases via {@code CameraX#bindToLifecycle(LifecycleOwner,
      * CameraSelector, UseCase...)}.
      *
-     * <p>Override to create necessary objects like {@link android.media.ImageReader} depending
+     * <p>Override to create necessary objects like {@link ImageReader} depending
      * on the resolution.
      *
      * @param suggestedResolution The suggested resolution that depends on camera
-     *                               device capability and what and how many use cases will be
-     *                               bound.
+     *                            device capability and what and how many use cases will be
+     *                            bound.
      * @return The resolution that finally used to create the SessionConfig to
      * attach to the camera device.
      * @hide
@@ -494,6 +505,27 @@
     }
 
     /**
+     * Sets the view port crop rect calculated at the time of binding.
+     *
+     * @hide
+     */
+    @RestrictTo(Scope.LIBRARY_GROUP)
+    protected void setViewPortCropRect(@Nullable Rect viewPortCropRect) {
+        mViewPortCropRect = viewPortCropRect;
+    }
+
+    /**
+     * Gets the view port crop rect.
+     *
+     * @hide
+     */
+    @RestrictTo(Scope.LIBRARY_GROUP)
+    @Nullable
+    protected Rect getViewPortCropRect() {
+        return mViewPortCropRect;
+    }
+
+    /**
      * Get image format for the use case.
      *
      * @return image format for the use case
@@ -549,7 +581,7 @@
          * camera.
          *
          * <p>Updating certain parameters of the use case require a full reset of the camera. This
-         * includes updating the {@link android.view.Surface} used by the use case.
+         * includes updating the {@link Surface} used by the use case.
          */
         void onUseCaseReset(@NonNull UseCase useCase);
     }
@@ -559,7 +591,7 @@
      *
      * @hide
      */
-    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    @RestrictTo(Scope.LIBRARY_GROUP)
     public interface EventCallback {
 
         /**
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/impl/CameraControlInternal.java b/camera/camera-core/src/main/java/androidx/camera/core/impl/CameraControlInternal.java
index 7e57571..8eacc77 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/impl/CameraControlInternal.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/impl/CameraControlInternal.java
@@ -87,6 +87,12 @@
      */
     void submitCaptureRequests(@NonNull List<CaptureConfig> captureConfigs);
 
+    /**
+     * Gets the full sensor rect.
+     */
+    @NonNull
+    Rect getSensorRect();
+
     CameraControlInternal DEFAULT_EMPTY_INSTANCE = new CameraControlInternal() {
         @Override
         public void setCropRegion(@Nullable Rect crop) {
@@ -131,6 +137,12 @@
 
         @NonNull
         @Override
+        public Rect getSensorRect() {
+            return new Rect();
+        }
+
+        @NonNull
+        @Override
         public ListenableFuture<FocusMeteringResult> startFocusAndMetering(
                 @NonNull FocusMeteringAction action) {
             return Futures.immediateFuture(FocusMeteringResult.emptyInstance());
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/impl/ImageAnalysisConfig.java b/camera/camera-core/src/main/java/androidx/camera/core/impl/ImageAnalysisConfig.java
index bf9b060..c414fe3 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/impl/ImageAnalysisConfig.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/impl/ImageAnalysisConfig.java
@@ -18,27 +18,16 @@
 
 import android.graphics.ImageFormat;
 import android.media.ImageReader;
-import android.util.Pair;
-import android.util.Rational;
-import android.util.Size;
-import android.view.Surface;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
 import androidx.annotation.RestrictTo.Scope;
-import androidx.camera.core.AspectRatio;
-import androidx.camera.core.CameraSelector;
 import androidx.camera.core.ImageAnalysis;
 import androidx.camera.core.ImageAnalysis.BackpressureStrategy;
 import androidx.camera.core.ImageReaderProxyProvider;
-import androidx.camera.core.UseCase;
 import androidx.camera.core.internal.ThreadConfig;
 
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.Executor;
-
 /**
  * Configuration for an image analysis use case.
  */
@@ -67,6 +56,12 @@
         mConfig = config;
     }
 
+    @NonNull
+    @Override
+    public Config getConfig() {
+        return mConfig;
+    }
+
     /**
      * Retrieves the backpressure strategy applied to the image producer to deal with scenarios
      * where images may be produced faster than they can be analyzed.
@@ -138,95 +133,6 @@
         return retrieveOption(OPTION_IMAGE_READER_PROXY_PROVIDER, null);
     }
 
-    // Start of the default implementation of Config
-    // *********************************************************************************************
-
-    // Implementations of Config default methods
-
-    @Override
-    public boolean containsOption(@NonNull Option<?> id) {
-        return mConfig.containsOption(id);
-    }
-
-    @Override
-    @Nullable
-    public <ValueT> ValueT retrieveOption(@NonNull Option<ValueT> id) {
-        return mConfig.retrieveOption(id);
-    }
-
-    @Override
-    @Nullable
-    public <ValueT> ValueT retrieveOption(@NonNull Option<ValueT> id,
-            @Nullable ValueT valueIfMissing) {
-        return mConfig.retrieveOption(id, valueIfMissing);
-    }
-
-    @Override
-    public void findOptions(@NonNull String idStem, @NonNull OptionMatcher matcher) {
-        mConfig.findOptions(idStem, matcher);
-    }
-
-    @Override
-    @NonNull
-    public Set<Option<?>> listOptions() {
-        return mConfig.listOptions();
-    }
-
-    // Implementations of TargetConfig default methods
-
-    @Override
-    @Nullable
-    public Class<ImageAnalysis> getTargetClass(
-            @Nullable Class<ImageAnalysis> valueIfMissing) {
-        @SuppressWarnings("unchecked") // Value should only be added via Builder#setTargetClass()
-                Class<ImageAnalysis> storedClass =
-                (Class<ImageAnalysis>) retrieveOption(
-                        OPTION_TARGET_CLASS,
-                        valueIfMissing);
-        return storedClass;
-    }
-
-    @Override
-    @NonNull
-    public Class<ImageAnalysis> getTargetClass() {
-        @SuppressWarnings("unchecked") // Value should only be added via Builder#setTargetClass()
-                Class<ImageAnalysis> storedClass =
-                (Class<ImageAnalysis>) retrieveOption(
-                        OPTION_TARGET_CLASS);
-        return storedClass;
-    }
-
-    /**
-     * Retrieves the name of the target object being configured.
-     *
-     * <p>The name should be a value that can uniquely identify an instance of the object being
-     * configured.
-     *
-     * @param valueIfMissing The value to return if this configuration option has not been set.
-     * @return The stored value or <code>valueIfMissing</code> if the value does not exist in this
-     * configuration.
-     */
-    @Override
-    @Nullable
-    public String getTargetName(@Nullable String valueIfMissing) {
-        return retrieveOption(OPTION_TARGET_NAME, valueIfMissing);
-    }
-
-    /**
-     * Retrieves the name of the target object being configured.
-     *
-     * <p>The name should be a value that can uniquely identify an instance of the object being
-     * configured.
-     *
-     * @return The stored value, if it exists in this configuration.
-     * @throws IllegalArgumentException if the option does not exist in this configuration.
-     */
-    @Override
-    @NonNull
-    public String getTargetName() {
-        return retrieveOption(OPTION_TARGET_NAME);
-    }
-
     /**
      * Retrieves the format of the image that is fed as input.
      *
@@ -236,285 +142,4 @@
     public int getInputFormat() {
         return ImageFormat.YUV_420_888;
     }
-
-    // Implementations of ImageOutputConfig default methods
-
-    /**
-     * Retrieves the aspect ratio of the target intending to use images from this configuration.
-     *
-     * <p>This is the ratio of the target's width to the image's height, where the numerator of the
-     * provided {@link Rational} corresponds to the width, and the denominator corresponds to the
-     * height.
-     *
-     * @param valueIfMissing The value to return if this configuration option has not been set.
-     * @return The stored value or <code>valueIfMissing</code> if the value does not exist in this
-     * configuration.
-     */
-    @Override
-    @Nullable
-    public Rational getTargetAspectRatioCustom(@Nullable Rational valueIfMissing) {
-        return retrieveOption(OPTION_TARGET_ASPECT_RATIO_CUSTOM, valueIfMissing);
-    }
-
-    /**
-     * Retrieves the aspect ratio of the target intending to use images from this configuration.
-     *
-     * <p>This is the ratio of the target's width to the image's height, where the numerator of the
-     * provided {@link Rational} corresponds to the width, and the denominator corresponds to the
-     * height.
-     *
-     * @return The stored value, if it exists in this configuration.
-     * @throws IllegalArgumentException if the option does not exist in this configuration.
-     */
-    @NonNull
-    @Override
-    public Rational getTargetAspectRatioCustom() {
-        return retrieveOption(OPTION_TARGET_ASPECT_RATIO_CUSTOM);
-    }
-
-    @Override
-    public boolean hasTargetAspectRatio() {
-        return containsOption(OPTION_TARGET_ASPECT_RATIO);
-    }
-
-    /**
-     * Retrieves the aspect ratio of the target intending to use images from this configuration.
-     *
-     * @return The stored value, if it exists in this configuration.
-     * @throws IllegalArgumentException if the option does not exist in this configuration.
-     */
-    @AspectRatio.Ratio
-    @Override
-    public int getTargetAspectRatio() {
-        return retrieveOption(OPTION_TARGET_ASPECT_RATIO);
-    }
-
-    /**
-     * Retrieves the rotation of the target intending to use images from this configuration.
-     *
-     * <p>This is one of four valid values: {@link Surface#ROTATION_0}, {@link Surface#ROTATION_90},
-     * {@link Surface#ROTATION_180}, {@link Surface#ROTATION_270}. Rotation values are relative to
-     * the device's "natural" rotation, {@link Surface#ROTATION_0}.
-     *
-     * @param valueIfMissing The value to return if this configuration option has not been set.
-     * @return The stored value or <code>valueIfMissing</code> if the value does not exist in this
-     * configuration.
-     */
-    @Override
-    @RotationValue
-    public int getTargetRotation(int valueIfMissing) {
-        return retrieveOption(OPTION_TARGET_ROTATION, valueIfMissing);
-    }
-
-    /**
-     * Retrieves the rotation of the target intending to use images from this configuration.
-     *
-     * <p>This is one of four valid values: {@link Surface#ROTATION_0}, {@link Surface#ROTATION_90},
-     * {@link Surface#ROTATION_180}, {@link Surface#ROTATION_270}. Rotation values are relative to
-     * the device's "natural" rotation, {@link Surface#ROTATION_0}.
-     *
-     * @return The stored value, if it exists in this configuration.
-     * @throws IllegalArgumentException if the option does not exist in this configuration.
-     */
-    @Override
-    @RotationValue
-    public int getTargetRotation() {
-        return retrieveOption(OPTION_TARGET_ROTATION);
-    }
-
-    /**
-     * Retrieves the resolution of the target intending to use from this configuration.
-     *
-     * @param valueIfMissing The value to return if this configuration option has not been set.
-     * @return The stored value or <code>valueIfMissing</code> if the value does not exist in this
-     * configuration.
-     */
-    @Override
-    @Nullable
-    public Size getTargetResolution(@Nullable Size valueIfMissing) {
-        return retrieveOption(ImageOutputConfig.OPTION_TARGET_RESOLUTION, valueIfMissing);
-    }
-
-    /**
-     * Retrieves the resolution of the target intending to use from this configuration.
-     *
-     * @return The stored value, if it exists in this configuration.
-     * @throws IllegalArgumentException if the option does not exist in this configuration.
-     */
-    @Override
-    @NonNull
-    public Size getTargetResolution() {
-        return retrieveOption(ImageOutputConfig.OPTION_TARGET_RESOLUTION);
-    }
-
-    /**
-     * Retrieves the default resolution of the target intending to use from this configuration.
-     *
-     * @param valueIfMissing The value to return if this configuration option has not been set.
-     * @return The stored value or <code>valueIfMissing</code> if the value does not exist in this
-     * configuration.
-     */
-    @Nullable
-    @Override
-    public Size getDefaultResolution(@Nullable Size valueIfMissing) {
-        return retrieveOption(ImageOutputConfig.OPTION_DEFAULT_RESOLUTION, valueIfMissing);
-    }
-
-    /**
-     * Retrieves the default resolution of the target intending to use from this configuration.
-     *
-     * @return The stored value, if it exists in this configuration.
-     * @throws IllegalArgumentException if the option does not exist in this configuration.
-     */
-    @NonNull
-    @Override
-    public Size getDefaultResolution() {
-        return retrieveOption(ImageOutputConfig.OPTION_DEFAULT_RESOLUTION);
-    }
-
-    @Override
-    @Nullable
-    public Size getMaxResolution(@Nullable Size valueIfMissing) {
-        return retrieveOption(OPTION_MAX_RESOLUTION, valueIfMissing);
-    }
-
-    @Override
-    @NonNull
-    public Size getMaxResolution() {
-        return retrieveOption(OPTION_MAX_RESOLUTION);
-    }
-
-    @Override
-    @Nullable
-    public List<Pair<Integer, Size[]>> getSupportedResolutions(
-            @Nullable List<Pair<Integer, Size[]>> valueIfMissing) {
-        return retrieveOption(OPTION_SUPPORTED_RESOLUTIONS, valueIfMissing);
-    }
-
-    @Override
-    @NonNull
-    public List<Pair<Integer, Size[]>> getSupportedResolutions() {
-        return retrieveOption(OPTION_SUPPORTED_RESOLUTIONS);
-    }
-
-    // Implementations of ThreadConfig default methods
-
-    /**
-     * Returns the executor that will be used for background tasks.
-     *
-     * @param valueIfMissing The value to return if this configuration option has not been set.
-     * @return The stored value or <code>valueIfMissing</code> if the value does not exist in this
-     * configuration.
-     */
-    @Override
-    @Nullable
-    public Executor getBackgroundExecutor(@Nullable Executor valueIfMissing) {
-        return retrieveOption(OPTION_BACKGROUND_EXECUTOR, valueIfMissing);
-    }
-
-    /**
-     * Returns the executor that will be used for background tasks.
-     *
-     * @return The stored value, if it exists in this configuration.
-     * @throws IllegalArgumentException if the option does not exist in this configuration.
-     */
-    @Override
-    @NonNull
-    public Executor getBackgroundExecutor() {
-        return retrieveOption(OPTION_BACKGROUND_EXECUTOR);
-    }
-
-    // Implementations of UseCaseConfig default methods
-
-    @Override
-    @Nullable
-    public SessionConfig getDefaultSessionConfig(@Nullable SessionConfig valueIfMissing) {
-        return retrieveOption(OPTION_DEFAULT_SESSION_CONFIG, valueIfMissing);
-    }
-
-    @Override
-    @NonNull
-    public SessionConfig getDefaultSessionConfig() {
-        return retrieveOption(OPTION_DEFAULT_SESSION_CONFIG);
-    }
-
-    @Override
-    @Nullable
-    public SessionConfig.OptionUnpacker getSessionOptionUnpacker(
-            @Nullable SessionConfig.OptionUnpacker valueIfMissing) {
-        return retrieveOption(OPTION_SESSION_CONFIG_UNPACKER, valueIfMissing);
-    }
-
-    @Override
-    @NonNull
-    public SessionConfig.OptionUnpacker getSessionOptionUnpacker() {
-        return retrieveOption(OPTION_SESSION_CONFIG_UNPACKER);
-    }
-
-    @Override
-    @Nullable
-    public CaptureConfig getDefaultCaptureConfig(@Nullable CaptureConfig valueIfMissing) {
-        return retrieveOption(OPTION_DEFAULT_CAPTURE_CONFIG, valueIfMissing);
-    }
-
-    @Override
-    @NonNull
-    public CaptureConfig getDefaultCaptureConfig() {
-        return retrieveOption(OPTION_DEFAULT_CAPTURE_CONFIG);
-    }
-
-    @Override
-    @Nullable
-    public CaptureConfig.OptionUnpacker getCaptureOptionUnpacker(
-            @Nullable CaptureConfig.OptionUnpacker valueIfMissing) {
-        return retrieveOption(OPTION_CAPTURE_CONFIG_UNPACKER, valueIfMissing);
-    }
-
-    @Override
-    @NonNull
-    public CaptureConfig.OptionUnpacker getCaptureOptionUnpacker() {
-        return retrieveOption(OPTION_CAPTURE_CONFIG_UNPACKER);
-    }
-
-    @Override
-    public int getSurfaceOccupancyPriority(int valueIfMissing) {
-        return retrieveOption(OPTION_SURFACE_OCCUPANCY_PRIORITY, valueIfMissing);
-    }
-
-    @Override
-    public int getSurfaceOccupancyPriority() {
-        return retrieveOption(OPTION_SURFACE_OCCUPANCY_PRIORITY);
-    }
-
-    /** @hide */
-    @RestrictTo(Scope.LIBRARY)
-    @Override
-    @Nullable
-    public CameraSelector getCameraSelector(@Nullable CameraSelector valueIfMissing) {
-        return retrieveOption(OPTION_CAMERA_SELECTOR, valueIfMissing);
-    }
-
-    /** @hide */
-    @RestrictTo(Scope.LIBRARY)
-    @Override
-    @NonNull
-    public CameraSelector getCameraSelector() {
-        return retrieveOption(OPTION_CAMERA_SELECTOR);
-    }
-
-    @Override
-    @Nullable
-    public UseCase.EventCallback getUseCaseEventCallback(
-            @Nullable UseCase.EventCallback valueIfMissing) {
-        return retrieveOption(OPTION_USE_CASE_EVENT_CALLBACK, valueIfMissing);
-    }
-
-    @Override
-    @NonNull
-    public UseCase.EventCallback getUseCaseEventCallback() {
-        return retrieveOption(OPTION_USE_CASE_EVENT_CALLBACK);
-    }
-
-    // End of the default implementation of Config
-    // *********************************************************************************************
 }
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/impl/ImageCaptureConfig.java b/camera/camera-core/src/main/java/androidx/camera/core/impl/ImageCaptureConfig.java
index 9c19af5..f7b499c 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/impl/ImageCaptureConfig.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/impl/ImageCaptureConfig.java
@@ -17,32 +17,21 @@
 package androidx.camera.core.impl;
 
 import android.graphics.ImageFormat;
-import android.util.Pair;
-import android.util.Rational;
-import android.util.Size;
-import android.view.Surface;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
-import androidx.camera.core.AspectRatio;
-import androidx.camera.core.CameraSelector;
 import androidx.camera.core.ImageCapture;
 import androidx.camera.core.ImageCapture.CaptureMode;
 import androidx.camera.core.ImageReaderProxyProvider;
-import androidx.camera.core.UseCase;
 import androidx.camera.core.internal.IoConfig;
 
-import java.util.List;
-import java.util.Set;
 import java.util.concurrent.Executor;
 
 /**
  * Configuration for an image capture use case.
  */
-public final class ImageCaptureConfig
-        implements UseCaseConfig<ImageCapture>,
-        ImageOutputConfig,
+public final class ImageCaptureConfig implements UseCaseConfig<ImageCapture>, ImageOutputConfig,
         IoConfig {
 
     // Option Declarations:
@@ -74,6 +63,12 @@
         mConfig = config;
     }
 
+    @NonNull
+    @Override
+    public Config getConfig() {
+        return mConfig;
+    }
+
     /**
      * Returns whether a {@link CaptureMode} option has been set in this configuration.
      *
@@ -217,255 +212,6 @@
         return retrieveOption(OPTION_IMAGE_READER_PROXY_PROVIDER, null);
     }
 
-    // Start of the default implementation of Config
-    // *********************************************************************************************
-
-    // Implementations of Config default methods
-
-    @Override
-    public boolean containsOption(@NonNull Option<?> id) {
-        return mConfig.containsOption(id);
-    }
-
-    @Override
-    @Nullable
-    public <ValueT> ValueT retrieveOption(@NonNull Option<ValueT> id) {
-        return mConfig.retrieveOption(id);
-    }
-
-    @Override
-    @Nullable
-    public <ValueT> ValueT retrieveOption(@NonNull Option<ValueT> id,
-            @Nullable ValueT valueIfMissing) {
-        return mConfig.retrieveOption(id, valueIfMissing);
-    }
-
-    @Override
-    public void findOptions(@NonNull String idStem, @NonNull OptionMatcher matcher) {
-        mConfig.findOptions(idStem, matcher);
-    }
-
-    @Override
-    @NonNull
-    public Set<Option<?>> listOptions() {
-        return mConfig.listOptions();
-    }
-
-    // Implementations of TargetConfig default methods
-
-    @Override
-    @Nullable
-    public Class<ImageCapture> getTargetClass(
-            @Nullable Class<ImageCapture> valueIfMissing) {
-        @SuppressWarnings("unchecked") // Value should only be added via Builder#setTargetClass()
-                Class<ImageCapture> storedClass =
-                (Class<ImageCapture>) retrieveOption(
-                        OPTION_TARGET_CLASS,
-                        valueIfMissing);
-        return storedClass;
-    }
-
-    @Override
-    @NonNull
-    public Class<ImageCapture> getTargetClass() {
-        @SuppressWarnings("unchecked") // Value should only be added via Builder#setTargetClass()
-                Class<ImageCapture> storedClass =
-                (Class<ImageCapture>) retrieveOption(
-                        OPTION_TARGET_CLASS);
-        return storedClass;
-    }
-
-    /**
-     * Retrieves the name of the target object being configured.
-     *
-     * <p>The name should be a value that can uniquely identify an instance of the object being
-     * configured.
-     *
-     * @param valueIfMissing The value to return if this configuration option has not been set.
-     * @return The stored value or <code>valueIfMissing</code> if the value does not exist in this
-     * configuration.
-     */
-    @Override
-    @Nullable
-    public String getTargetName(@Nullable String valueIfMissing) {
-        return retrieveOption(OPTION_TARGET_NAME, valueIfMissing);
-    }
-
-    /**
-     * Retrieves the name of the target object being configured.
-     *
-     * <p>The name should be a value that can uniquely identify an instance of the object being
-     * configured.
-     *
-     * @return The stored value, if it exists in this configuration.
-     * @throws IllegalArgumentException if the option does not exist in this configuration.
-     */
-    @Override
-    @NonNull
-    public String getTargetName() {
-        return retrieveOption(OPTION_TARGET_NAME);
-    }
-
-    // Implementations of ImageOutputConfig default methods
-
-    /**
-     * Retrieves the aspect ratio of the target intending to use images from this configuration.
-     *
-     * <p>This is the ratio of the target's width to the image's height, where the numerator of the
-     * provided {@link Rational} corresponds to the width, and the denominator corresponds to the
-     * height.
-     *
-     * @param valueIfMissing The value to return if this configuration option has not been set.
-     * @return The stored value or <code>valueIfMissing</code> if the value does not exist in this
-     * configuration.
-     */
-    @Override
-    @Nullable
-    public Rational getTargetAspectRatioCustom(@Nullable Rational valueIfMissing) {
-        return retrieveOption(OPTION_TARGET_ASPECT_RATIO_CUSTOM, valueIfMissing);
-    }
-
-    /**
-     * Retrieves the aspect ratio of the target intending to use images from this configuration.
-     *
-     * <p>This is the ratio of the target's width to the image's height, where the numerator of the
-     * provided {@link Rational} corresponds to the width, and the denominator corresponds to the
-     * height.
-     *
-     * @return The stored value, if it exists in this configuration.
-     * @throws IllegalArgumentException if the option does not exist in this configuration.
-     */
-    @NonNull
-    @Override
-    public Rational getTargetAspectRatioCustom() {
-        return retrieveOption(OPTION_TARGET_ASPECT_RATIO_CUSTOM);
-    }
-
-    @Override
-    public boolean hasTargetAspectRatio() {
-        return containsOption(OPTION_TARGET_ASPECT_RATIO);
-    }
-
-    /**
-     * Retrieves the aspect ratio of the target intending to use images from this configuration.
-     *
-     * @return The stored value, if it exists in this configuration.
-     * @throws IllegalArgumentException if the option does not exist in this configuration.
-     */
-    @AspectRatio.Ratio
-    @Override
-    public int getTargetAspectRatio() {
-        return retrieveOption(OPTION_TARGET_ASPECT_RATIO);
-    }
-
-    /**
-     * Retrieves the rotation of the target intending to use images from this configuration.
-     *
-     * <p>This is one of four valid values: {@link Surface#ROTATION_0}, {@link Surface#ROTATION_90},
-     * {@link Surface#ROTATION_180}, {@link Surface#ROTATION_270}. Rotation values are relative to
-     * the device's "natural" rotation, {@link Surface#ROTATION_0}.
-     *
-     * @param valueIfMissing The value to return if this configuration option has not been set.
-     * @return The stored value or <code>valueIfMissing</code> if the value does not exist in this
-     * configuration.
-     */
-    @Override
-    @RotationValue
-    public int getTargetRotation(int valueIfMissing) {
-        return retrieveOption(OPTION_TARGET_ROTATION, valueIfMissing);
-    }
-
-    /**
-     * Retrieves the rotation of the target intending to use images from this configuration.
-     *
-     * <p>This is one of four valid values: {@link Surface#ROTATION_0}, {@link Surface#ROTATION_90},
-     * {@link Surface#ROTATION_180}, {@link Surface#ROTATION_270}. Rotation values are relative to
-     * the device's "natural" rotation, {@link Surface#ROTATION_0}.
-     *
-     * @return The stored value, if it exists in this configuration.
-     * @throws IllegalArgumentException if the option does not exist in this configuration.
-     */
-    @Override
-    @RotationValue
-    public int getTargetRotation() {
-        return retrieveOption(OPTION_TARGET_ROTATION);
-    }
-
-    /**
-     * Retrieves the resolution of the target intending to use from this configuration.
-     *
-     * @param valueIfMissing The value to return if this configuration option has not been set.
-     * @return The stored value or <code>valueIfMissing</code> if the value does not exist in this
-     * configuration.
-     */
-    @Override
-    @Nullable
-    public Size getTargetResolution(@Nullable Size valueIfMissing) {
-        return retrieveOption(ImageOutputConfig.OPTION_TARGET_RESOLUTION, valueIfMissing);
-    }
-
-    /**
-     * Retrieves the resolution of the target intending to use from this configuration.
-     *
-     * @return The stored value, if it exists in this configuration.
-     * @throws IllegalArgumentException if the option does not exist in this configuration.
-     */
-    @Override
-    @NonNull
-    public Size getTargetResolution() {
-        return retrieveOption(ImageOutputConfig.OPTION_TARGET_RESOLUTION);
-    }
-
-    /**
-     * Retrieves the default resolution of the target intending to use from this configuration.
-     *
-     * @param valueIfMissing The value to return if this configuration option has not been set.
-     * @return The stored value or <code>valueIfMissing</code> if the value does not exist in this
-     * configuration.
-     */
-    @Nullable
-    @Override
-    public Size getDefaultResolution(@Nullable Size valueIfMissing) {
-        return retrieveOption(OPTION_DEFAULT_RESOLUTION, valueIfMissing);
-    }
-
-    /**
-     * Retrieves the default resolution of the target intending to use from this configuration.
-     *
-     * @return The stored value, if it exists in this configuration.
-     * @throws IllegalArgumentException if the option does not exist in this configuration.
-     */
-    @NonNull
-    @Override
-    public Size getDefaultResolution() {
-        return retrieveOption(OPTION_DEFAULT_RESOLUTION);
-    }
-
-    @Override
-    @Nullable
-    public Size getMaxResolution(@Nullable Size valueIfMissing) {
-        return retrieveOption(OPTION_MAX_RESOLUTION, valueIfMissing);
-    }
-
-    @Override
-    @NonNull
-    public Size getMaxResolution() {
-        return retrieveOption(OPTION_MAX_RESOLUTION);
-    }
-
-    @Override
-    @Nullable
-    public List<Pair<Integer, Size[]>> getSupportedResolutions(
-            @Nullable List<Pair<Integer, Size[]>> valueIfMissing) {
-        return retrieveOption(OPTION_SUPPORTED_RESOLUTIONS, valueIfMissing);
-    }
-
-    @Override
-    @NonNull
-    public List<Pair<Integer, Size[]>> getSupportedResolutions() {
-        return retrieveOption(OPTION_SUPPORTED_RESOLUTIONS);
-    }
-
     // Implementations of IO default methods
 
     /**
@@ -502,94 +248,4 @@
     public Executor getIoExecutor() {
         return retrieveOption(OPTION_IO_EXECUTOR);
     }
-
-    // Implementations of UseCaseConfig default methods
-
-    @Override
-    @Nullable
-    public SessionConfig getDefaultSessionConfig(@Nullable SessionConfig valueIfMissing) {
-        return retrieveOption(OPTION_DEFAULT_SESSION_CONFIG, valueIfMissing);
-    }
-
-    @Override
-    @NonNull
-    public SessionConfig getDefaultSessionConfig() {
-        return retrieveOption(OPTION_DEFAULT_SESSION_CONFIG);
-    }
-
-    @Override
-    @Nullable
-    public CaptureConfig getDefaultCaptureConfig(@Nullable CaptureConfig valueIfMissing) {
-        return retrieveOption(OPTION_DEFAULT_CAPTURE_CONFIG, valueIfMissing);
-    }
-
-    @Override
-    @NonNull
-    public CaptureConfig getDefaultCaptureConfig() {
-        return retrieveOption(OPTION_DEFAULT_CAPTURE_CONFIG);
-    }
-
-    @Override
-    @Nullable
-    public SessionConfig.OptionUnpacker getSessionOptionUnpacker(
-            @Nullable SessionConfig.OptionUnpacker valueIfMissing) {
-        return retrieveOption(OPTION_SESSION_CONFIG_UNPACKER, valueIfMissing);
-    }
-
-    @Override
-    @NonNull
-    public SessionConfig.OptionUnpacker getSessionOptionUnpacker() {
-        return retrieveOption(OPTION_SESSION_CONFIG_UNPACKER);
-    }
-
-    @Override
-    @Nullable
-    public CaptureConfig.OptionUnpacker getCaptureOptionUnpacker(
-            @Nullable CaptureConfig.OptionUnpacker valueIfMissing) {
-        return retrieveOption(OPTION_CAPTURE_CONFIG_UNPACKER, valueIfMissing);
-    }
-
-    @Override
-    @NonNull
-    public CaptureConfig.OptionUnpacker getCaptureOptionUnpacker() {
-        return retrieveOption(OPTION_CAPTURE_CONFIG_UNPACKER);
-    }
-
-    @Override
-    public int getSurfaceOccupancyPriority(int valueIfMissing) {
-        return retrieveOption(OPTION_SURFACE_OCCUPANCY_PRIORITY, valueIfMissing);
-    }
-
-    @Override
-    public int getSurfaceOccupancyPriority() {
-        return retrieveOption(OPTION_SURFACE_OCCUPANCY_PRIORITY);
-    }
-
-    @Override
-    @Nullable
-    public CameraSelector getCameraSelector(@Nullable CameraSelector valueIfMissing) {
-        return retrieveOption(OPTION_CAMERA_SELECTOR, valueIfMissing);
-    }
-
-    @Override
-    @NonNull
-    public CameraSelector getCameraSelector() {
-        return retrieveOption(OPTION_CAMERA_SELECTOR);
-    }
-
-    @Override
-    @Nullable
-    public UseCase.EventCallback getUseCaseEventCallback(
-            @Nullable UseCase.EventCallback valueIfMissing) {
-        return retrieveOption(OPTION_USE_CASE_EVENT_CALLBACK, valueIfMissing);
-    }
-
-    @Override
-    @NonNull
-    public UseCase.EventCallback getUseCaseEventCallback() {
-        return retrieveOption(OPTION_USE_CASE_EVENT_CALLBACK);
-    }
-
-    // End of the default implementation of Config
-    // *********************************************************************************************
 }
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/impl/ImageInputConfig.java b/camera/camera-core/src/main/java/androidx/camera/core/impl/ImageInputConfig.java
index 3e5d563..225e6e6 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/impl/ImageInputConfig.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/impl/ImageInputConfig.java
@@ -19,7 +19,7 @@
 import androidx.camera.core.Camera;
 
 /** Configuration containing options for configuring the input image data of a pipeline. */
-public interface ImageInputConfig {
+public interface ImageInputConfig extends ReadableConfig {
     Config.Option<Integer> OPTION_INPUT_FORMAT =
             Config.Option.create("camerax.core.imageInput.inputFormat", int.class);
 
@@ -37,5 +37,7 @@
      * code 0x22 for internal corresponding format HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED.
      * Therefore, setting 0x22 as default image format.
      */
-    int getInputFormat();
+    default int getInputFormat() {
+        return retrieveOption(OPTION_INPUT_FORMAT);
+    }
 }
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/impl/ImageOutputConfig.java b/camera/camera-core/src/main/java/androidx/camera/core/impl/ImageOutputConfig.java
index 5d9c4a4..25bf123 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/impl/ImageOutputConfig.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/impl/ImageOutputConfig.java
@@ -26,7 +26,6 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.camera.core.AspectRatio;
-import androidx.camera.core.impl.Config.Option;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -35,7 +34,7 @@
 /**
  * Configuration containing options for configuring the output image data of a pipeline.
  */
-public interface ImageOutputConfig {
+public interface ImageOutputConfig extends ReadableConfig {
     /**
      * Default aspect ratio for portrait and landscape
      */
@@ -102,7 +101,9 @@
      * configuration.
      */
     @Nullable
-    Rational getTargetAspectRatioCustom(@Nullable Rational valueIfMissing);
+    default Rational getTargetAspectRatioCustom(@Nullable Rational valueIfMissing) {
+        return retrieveOption(OPTION_TARGET_ASPECT_RATIO_CUSTOM, valueIfMissing);
+    }
 
     /**
      * Retrieves the aspect ratio of the target intending to use images from this configuration.
@@ -115,7 +116,9 @@
      * @throws IllegalArgumentException if the option does not exist in this configuration.
      */
     @NonNull
-    Rational getTargetAspectRatioCustom();
+    default Rational getTargetAspectRatioCustom() {
+        return retrieveOption(OPTION_TARGET_ASPECT_RATIO_CUSTOM);
+    }
 
     /**
      * Verifies whether the aspect ratio of the target intending to use images from this
@@ -123,7 +126,9 @@
      *
      * @return true is the value exists in this configuration, false otherwise.
      */
-    boolean hasTargetAspectRatio();
+    default boolean hasTargetAspectRatio() {
+        return containsOption(OPTION_TARGET_ASPECT_RATIO);
+    }
 
     /**
      * Retrieves the aspect ratio of the target intending to use images from this configuration.
@@ -132,7 +137,9 @@
      * @throws IllegalArgumentException if the option does not exist in this configuration.
      */
     @AspectRatio.Ratio
-    int getTargetAspectRatio();
+    default int getTargetAspectRatio() {
+        return retrieveOption(OPTION_TARGET_ASPECT_RATIO);
+    }
 
     /**
      * Retrieves the rotation of the target intending to use images from this configuration.
@@ -146,7 +153,9 @@
      * configuration.
      */
     @RotationValue
-    int getTargetRotation(int valueIfMissing);
+    default int getTargetRotation(int valueIfMissing) {
+        return retrieveOption(OPTION_TARGET_ROTATION, valueIfMissing);
+    }
 
     /**
      * Retrieves the rotation of the target intending to use images from this configuration.
@@ -159,7 +168,9 @@
      * @throws IllegalArgumentException if the option does not exist in this configuration.
      */
     @RotationValue
-    int getTargetRotation();
+    default int getTargetRotation() {
+        return retrieveOption(OPTION_TARGET_ROTATION);
+    }
 
     /**
      * Retrieves the resolution of the target intending to use from this configuration.
@@ -169,7 +180,9 @@
      * configuration.
      */
     @Nullable
-    Size getTargetResolution(@Nullable Size valueIfMissing);
+    default Size getTargetResolution(@Nullable Size valueIfMissing) {
+        return retrieveOption(ImageOutputConfig.OPTION_TARGET_RESOLUTION, valueIfMissing);
+    }
 
     /**
      * Retrieves the resolution of the target intending to use from this configuration.
@@ -178,7 +191,9 @@
      * @throws IllegalArgumentException if the option does not exist in this configuration.
      */
     @NonNull
-    Size getTargetResolution();
+    default Size getTargetResolution() {
+        return retrieveOption(ImageOutputConfig.OPTION_TARGET_RESOLUTION);
+    }
 
     /**
      * Retrieves the default resolution of the target intending to use from this configuration.
@@ -188,7 +203,9 @@
      * configuration.
      */
     @Nullable
-    Size getDefaultResolution(@Nullable Size valueIfMissing);
+    default Size getDefaultResolution(@Nullable Size valueIfMissing) {
+        return retrieveOption(OPTION_DEFAULT_RESOLUTION, valueIfMissing);
+    }
 
     /**
      * Retrieves the default resolution of the target intending to use from this configuration.
@@ -197,7 +214,9 @@
      * @throws IllegalArgumentException if the option does not exist in this configuration.
      */
     @NonNull
-    Size getDefaultResolution();
+    default Size getDefaultResolution() {
+        return retrieveOption(OPTION_DEFAULT_RESOLUTION);
+    }
 
     /**
      * Retrieves the max resolution limitation of the target intending to use from this
@@ -208,7 +227,9 @@
      * configuration.
      */
     @Nullable
-    Size getMaxResolution(@Nullable Size valueIfMissing);
+    default Size getMaxResolution(@Nullable Size valueIfMissing) {
+        return retrieveOption(OPTION_MAX_RESOLUTION, valueIfMissing);
+    }
 
     /**
      * Retrieves the max resolution limitation of the target intending to use from this
@@ -218,7 +239,9 @@
      * @throws IllegalArgumentException if the option does not exist in this configuration.
      */
     @NonNull
-    Size getMaxResolution();
+    default Size getMaxResolution() {
+        return retrieveOption(OPTION_MAX_RESOLUTION);
+    }
 
     /**
      * Retrieves the supported resolutions can be used by the target from this configuration.
@@ -232,8 +255,10 @@
      * configuration.
      */
     @Nullable
-    List<Pair<Integer, Size[]>> getSupportedResolutions(
-            @Nullable List<Pair<Integer, Size[]>> valueIfMissing);
+    default List<Pair<Integer, Size[]>> getSupportedResolutions(
+            @Nullable List<Pair<Integer, Size[]>> valueIfMissing) {
+        return retrieveOption(OPTION_SUPPORTED_RESOLUTIONS, valueIfMissing);
+    }
 
     /**
      * Retrieves the supported resolutions can be used by the target from this configuration.
@@ -246,7 +271,9 @@
      * @throws IllegalArgumentException if the option does not exist in this configuration.
      */
     @NonNull
-    List<Pair<Integer, Size[]>> getSupportedResolutions();
+    default List<Pair<Integer, Size[]>> getSupportedResolutions() {
+        return retrieveOption(OPTION_SUPPORTED_RESOLUTIONS);
+    }
 
     /**
      * Builder for a {@link ImageOutputConfig}.
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/impl/PreviewConfig.java b/camera/camera-core/src/main/java/androidx/camera/core/impl/PreviewConfig.java
index a16b700..de4e98c1 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/impl/PreviewConfig.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/impl/PreviewConfig.java
@@ -16,23 +16,11 @@
 
 package androidx.camera.core.impl;
 
-import android.util.Pair;
-import android.util.Rational;
-import android.util.Size;
-import android.view.Surface;
-
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.camera.core.AspectRatio;
-import androidx.camera.core.CameraSelector;
 import androidx.camera.core.Preview;
-import androidx.camera.core.UseCase;
 import androidx.camera.core.internal.ThreadConfig;
 
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.Executor;
-
 /**
  * Configuration for a {@link Preview} use case.
  */
@@ -54,373 +42,10 @@
         mConfig = config;
     }
 
-    // Start of the default implementation of Config
-    // *********************************************************************************************
-
-    // Implementations of Config default methods
-
-    @Override
-    public boolean containsOption(@NonNull Option<?> id) {
-        return mConfig.containsOption(id);
-    }
-
-    @Override
-    @Nullable
-    public <ValueT> ValueT retrieveOption(@NonNull Option<ValueT> id) {
-        return mConfig.retrieveOption(id);
-    }
-
-    @Override
-    @Nullable
-    public <ValueT> ValueT retrieveOption(@NonNull Option<ValueT> id,
-            @Nullable ValueT valueIfMissing) {
-        return mConfig.retrieveOption(id, valueIfMissing);
-    }
-
-    @Override
-    public void findOptions(@NonNull String idStem, @NonNull OptionMatcher matcher) {
-        mConfig.findOptions(idStem, matcher);
-    }
-
-    @Override
-    @NonNull
-    public Set<Option<?>> listOptions() {
-        return mConfig.listOptions();
-    }
-
-    // Implementations of TargetConfig default methods
-
-    @Override
-    @Nullable
-    public Class<Preview> getTargetClass(
-            @Nullable Class<Preview> valueIfMissing) {
-        @SuppressWarnings("unchecked") // Value should only be added via Builder#setTargetClass()
-                Class<Preview> storedClass =
-                (Class<Preview>) retrieveOption(
-                        OPTION_TARGET_CLASS,
-                        valueIfMissing);
-        return storedClass;
-    }
-
-    @Override
-    @NonNull
-    public Class<Preview> getTargetClass() {
-        @SuppressWarnings("unchecked") // Value should only be added via Builder#setTargetClass()
-                Class<Preview> storedClass =
-                (Class<Preview>) retrieveOption(
-                        OPTION_TARGET_CLASS);
-        return storedClass;
-    }
-
-    /**
-     * Retrieves the name of the target object being configured.
-     *
-     * <p>The name should be a value that can uniquely identify an instance of the object being
-     * configured.
-     *
-     * @param valueIfMissing The value to return if this configuration option has not been set.
-     * @return The stored value or <code>valueIfMissing</code> if the value does not exist in this
-     * configuration.
-     */
-    @Override
-    @Nullable
-    public String getTargetName(@Nullable String valueIfMissing) {
-        return retrieveOption(OPTION_TARGET_NAME, valueIfMissing);
-    }
-
-    /**
-     * Retrieves the name of the target object being configured.
-     *
-     * <p>The name should be a value that can uniquely identify an instance of the object being
-     * configured.
-     *
-     * @return The stored value, if it exists in this configuration.
-     * @throws IllegalArgumentException if the option does not exist in this configuration.
-     */
-    @Override
-    @NonNull
-    public String getTargetName() {
-        return retrieveOption(OPTION_TARGET_NAME);
-    }
-
-    // Implementations of ImageOutputConfig default methods
-
-    /**
-     * Retrieves the aspect ratio of the target intending to use images from this configuration.
-     *
-     * <p>This is the ratio of the target's width to the image's height, where the numerator of the
-     * provided {@link Rational} corresponds to the width, and the denominator corresponds to the
-     * height.
-     *
-     * @param valueIfMissing The value to return if this configuration option has not been set.
-     * @return The stored value or <code>valueIfMissing</code> if the value does not exist in this
-     * configuration.
-     */
-    @Override
-    @Nullable
-    public Rational getTargetAspectRatioCustom(@Nullable Rational valueIfMissing) {
-        return retrieveOption(OPTION_TARGET_ASPECT_RATIO_CUSTOM, valueIfMissing);
-    }
-
-    /**
-     * Retrieves the aspect ratio of the target intending to use images from this configuration.
-     *
-     * <p>This is the ratio of the target's width to the image's height, where the numerator of the
-     * provided {@link Rational} corresponds to the width, and the denominator corresponds to the
-     * height.
-     *
-     * @return The stored value, if it exists in this configuration.
-     * @throws IllegalArgumentException if the option does not exist in this configuration.
-     */
     @NonNull
     @Override
-    public Rational getTargetAspectRatioCustom() {
-        return retrieveOption(OPTION_TARGET_ASPECT_RATIO_CUSTOM);
-    }
-
-    @Override
-    public boolean hasTargetAspectRatio() {
-        return containsOption(OPTION_TARGET_ASPECT_RATIO);
-    }
-
-    /**
-     * Retrieves the aspect ratio of the target intending to use images from this configuration.
-     *
-     * @return The stored value, if it exists in this configuration.
-     * @throws IllegalArgumentException if the option does not exist in this configuration.
-     */
-    @AspectRatio.Ratio
-    @Override
-    public int getTargetAspectRatio() {
-        return retrieveOption(OPTION_TARGET_ASPECT_RATIO);
-    }
-
-    /**
-     * Retrieves the rotation of the target intending to use images from this configuration.
-     *
-     * <p>This is one of four valid values: {@link Surface#ROTATION_0}, {@link Surface#ROTATION_90},
-     * {@link Surface#ROTATION_180}, {@link Surface#ROTATION_270}. Rotation values are relative to
-     * the device's "natural" rotation, {@link Surface#ROTATION_0}.
-     *
-     * <p>Preview always set the rotation to device's nature orientation.
-     *
-     * @param valueIfMissing The value to return if this configuration option has not been set.
-     * @return The stored value or <code>valueIfMissing</code> if the value does not exist in this
-     * configuration.
-     */
-    @Override
-    @RotationValue
-    public int getTargetRotation(int valueIfMissing) {
-        return retrieveOption(OPTION_TARGET_ROTATION, valueIfMissing);
-    }
-
-    /**
-     * Retrieves the rotation of the target intending to use images from this configuration.
-     *
-     * <p>This is one of four valid values: {@link Surface#ROTATION_0}, {@link Surface#ROTATION_90},
-     * {@link Surface#ROTATION_180}, {@link Surface#ROTATION_270}. Rotation values are relative to
-     * the device's "natural" rotation, {@link Surface#ROTATION_0}.
-     *
-     * <p>Preview always set the rotation to device's nature orientation.
-     *
-     * @return The stored value, if it exists in this configuration.
-     * @throws IllegalArgumentException if the option does not exist in this configuration.
-     */
-    @Override
-    @RotationValue
-    public int getTargetRotation() {
-        return retrieveOption(OPTION_TARGET_ROTATION);
-    }
-
-    /**
-     * Retrieves the resolution of the target intending to use from this configuration.
-     *
-     * @param valueIfMissing The value to return if this configuration option has not been set.
-     * @return The stored value or <code>valueIfMissing</code> if the value does not exist in this
-     * configuration.
-     */
-    @Override
-    @Nullable
-    public Size getTargetResolution(@Nullable Size valueIfMissing) {
-        return retrieveOption(ImageOutputConfig.OPTION_TARGET_RESOLUTION, valueIfMissing);
-    }
-
-    /**
-     * Retrieves the resolution of the target intending to use from this configuration.
-     *
-     * @return The stored value, if it exists in this configuration.
-     * @throws IllegalArgumentException if the option does not exist in this configuration.
-     */
-    @Override
-    @NonNull
-    public Size getTargetResolution() {
-        return retrieveOption(ImageOutputConfig.OPTION_TARGET_RESOLUTION);
-    }
-
-    /**
-     * Retrieves the default resolution of the target intending to use from this configuration.
-     *
-     * @param valueIfMissing The value to return if this configuration option has not been set.
-     * @return The stored value or <code>valueIfMissing</code> if the value does not exist in this
-     * configuration.
-     */
-    @Nullable
-    @Override
-    public Size getDefaultResolution(@Nullable Size valueIfMissing) {
-        return retrieveOption(ImageOutputConfig.OPTION_DEFAULT_RESOLUTION, valueIfMissing);
-    }
-
-    /**
-     * Retrieves the default resolution of the target intending to use from this configuration.
-     *
-     * @return The stored value, if it exists in this configuration.
-     * @throws IllegalArgumentException if the option does not exist in this configuration.
-     */
-    @NonNull
-    @Override
-    public Size getDefaultResolution() {
-        return retrieveOption(ImageOutputConfig.OPTION_DEFAULT_RESOLUTION);
-    }
-
-    @Override
-    @Nullable
-    public Size getMaxResolution(@Nullable Size valueIfMissing) {
-        return retrieveOption(OPTION_MAX_RESOLUTION, valueIfMissing);
-    }
-
-    @Override
-    @NonNull
-    public Size getMaxResolution() {
-        return retrieveOption(OPTION_MAX_RESOLUTION);
-    }
-
-    @Override
-    @Nullable
-    public List<Pair<Integer, Size[]>> getSupportedResolutions(
-            @Nullable List<Pair<Integer, Size[]>> valueIfMissing) {
-        return retrieveOption(OPTION_SUPPORTED_RESOLUTIONS, valueIfMissing);
-    }
-
-    @Override
-    @NonNull
-    public List<Pair<Integer, Size[]>> getSupportedResolutions() {
-        return retrieveOption(OPTION_SUPPORTED_RESOLUTIONS);
-    }
-
-    // Implementations of ThreadConfig default methods
-
-    /**
-     * Returns the executor that will be used for background tasks.
-     *
-     * <p>Background executor not used in {@link Preview}.
-     *
-     * @param valueIfMissing The value to return if this configuration option has not been set.
-     * @return The stored value or <code>valueIfMissing</code> if the value does not exist in this
-     * configuration.
-     */
-    @Override
-    @Nullable
-    public Executor getBackgroundExecutor(@Nullable Executor valueIfMissing) {
-        return retrieveOption(OPTION_BACKGROUND_EXECUTOR, valueIfMissing);
-    }
-
-    /**
-     * Returns the executor that will be used for background tasks.
-     *
-     * @return The stored value, if it exists in this configuration.
-     * @throws IllegalArgumentException if the option does not exist in this configuration.
-     */
-    @Override
-    @NonNull
-    public Executor getBackgroundExecutor() {
-        return retrieveOption(OPTION_BACKGROUND_EXECUTOR);
-    }
-
-    // Implementations of UseCaseConfig default methods
-
-    @Override
-    @Nullable
-    public SessionConfig getDefaultSessionConfig(@Nullable SessionConfig valueIfMissing) {
-        return retrieveOption(OPTION_DEFAULT_SESSION_CONFIG, valueIfMissing);
-    }
-
-    @Override
-    @NonNull
-    public SessionConfig getDefaultSessionConfig() {
-        return retrieveOption(OPTION_DEFAULT_SESSION_CONFIG);
-    }
-
-    @Override
-    @Nullable
-    public SessionConfig.OptionUnpacker getSessionOptionUnpacker(
-            @Nullable SessionConfig.OptionUnpacker valueIfMissing) {
-        return retrieveOption(OPTION_SESSION_CONFIG_UNPACKER, valueIfMissing);
-    }
-
-    @Override
-    @NonNull
-    public SessionConfig.OptionUnpacker getSessionOptionUnpacker() {
-        return retrieveOption(OPTION_SESSION_CONFIG_UNPACKER);
-    }
-
-    @Override
-    @Nullable
-    public CaptureConfig getDefaultCaptureConfig(@Nullable CaptureConfig valueIfMissing) {
-        return retrieveOption(OPTION_DEFAULT_CAPTURE_CONFIG, valueIfMissing);
-    }
-
-    @Override
-    @NonNull
-    public CaptureConfig getDefaultCaptureConfig() {
-        return retrieveOption(OPTION_DEFAULT_CAPTURE_CONFIG);
-    }
-
-    @Override
-    @Nullable
-    public CaptureConfig.OptionUnpacker getCaptureOptionUnpacker(
-            @Nullable CaptureConfig.OptionUnpacker valueIfMissing) {
-        return retrieveOption(OPTION_CAPTURE_CONFIG_UNPACKER, valueIfMissing);
-    }
-
-    @Override
-    @NonNull
-    public CaptureConfig.OptionUnpacker getCaptureOptionUnpacker() {
-        return retrieveOption(OPTION_CAPTURE_CONFIG_UNPACKER);
-    }
-
-    @Override
-    public int getSurfaceOccupancyPriority(int valueIfMissing) {
-        return retrieveOption(OPTION_SURFACE_OCCUPANCY_PRIORITY, valueIfMissing);
-    }
-
-    @Override
-    public int getSurfaceOccupancyPriority() {
-        return retrieveOption(OPTION_SURFACE_OCCUPANCY_PRIORITY);
-    }
-
-    @Override
-    @Nullable
-    public CameraSelector getCameraSelector(@Nullable CameraSelector valueIfMissing) {
-        return retrieveOption(OPTION_CAMERA_SELECTOR, valueIfMissing);
-    }
-
-    @Override
-    @NonNull
-    public CameraSelector getCameraSelector() {
-        return retrieveOption(OPTION_CAMERA_SELECTOR);
-    }
-
-    @Override
-    @Nullable
-    public UseCase.EventCallback getUseCaseEventCallback(
-            @Nullable UseCase.EventCallback valueIfMissing) {
-        return retrieveOption(OPTION_USE_CASE_EVENT_CALLBACK, valueIfMissing);
-    }
-
-    @Override
-    @NonNull
-    public UseCase.EventCallback getUseCaseEventCallback() {
-        return retrieveOption(OPTION_USE_CASE_EVENT_CALLBACK);
+    public Config getConfig() {
+        return mConfig;
     }
 
     /**
@@ -470,7 +95,4 @@
     public int getInputFormat() {
         return retrieveOption(OPTION_INPUT_FORMAT);
     }
-
-    // End of the default implementation of Config
-    // *********************************************************************************************
 }
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/impl/ReadableConfig.java b/camera/camera-core/src/main/java/androidx/camera/core/impl/ReadableConfig.java
new file mode 100644
index 0000000..75b01b1
--- /dev/null
+++ b/camera/camera-core/src/main/java/androidx/camera/core/impl/ReadableConfig.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.camera.core.impl;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.util.Set;
+
+/**
+ * Interface that can be extended to create APIs for reading specific options.
+ *
+ * <p>ReadableConfig objects are also {@link Config} objects, so can be passed to any method that
+ * expects a {@link Config}.
+ */
+public interface ReadableConfig extends Config {
+
+    /**
+     * Returns the underlying immutable {@link Config} object.
+     *
+     * @return The underlying {@link Config} object.
+     */
+    @NonNull
+    Config getConfig();
+
+    @Override
+    default boolean containsOption(@NonNull Option<?> id) {
+        return getConfig().containsOption(id);
+    }
+
+    @Override
+    @Nullable
+    default <ValueT> ValueT retrieveOption(@NonNull Option<ValueT> id) {
+        return getConfig().retrieveOption(id);
+    }
+
+    @Override
+    @Nullable
+    default <ValueT> ValueT retrieveOption(@NonNull Option<ValueT> id,
+            @Nullable ValueT valueIfMissing) {
+        return getConfig().retrieveOption(id, valueIfMissing);
+    }
+
+    @Override
+    default void findOptions(@NonNull String idSearchString, @NonNull OptionMatcher matcher) {
+        getConfig().findOptions(idSearchString, matcher);
+    }
+
+    @Override
+    @NonNull
+    default Set<Option<?>> listOptions() {
+        return getConfig().listOptions();
+    }
+}
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/impl/UseCaseConfig.java b/camera/camera-core/src/main/java/androidx/camera/core/impl/UseCaseConfig.java
index 859709f2..680d3f8 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/impl/UseCaseConfig.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/impl/UseCaseConfig.java
@@ -29,8 +29,8 @@
  *
  * @param <T> The use case being configured.
  */
-public interface UseCaseConfig<T extends UseCase> extends TargetConfig<T>, Config,
-        UseCaseEventConfig , ImageInputConfig {
+public interface UseCaseConfig<T extends UseCase> extends TargetConfig<T>, UseCaseEventConfig,
+        ImageInputConfig {
     // Option Declarations:
     // *********************************************************************************************
 
@@ -86,7 +86,9 @@
      * configuration.
      */
     @Nullable
-    SessionConfig getDefaultSessionConfig(@Nullable SessionConfig valueIfMissing);
+    default SessionConfig getDefaultSessionConfig(@Nullable SessionConfig valueIfMissing) {
+        return retrieveOption(OPTION_DEFAULT_SESSION_CONFIG, valueIfMissing);
+    }
 
     /**
      * Retrieves the default session configuration for this use case.
@@ -98,7 +100,9 @@
      * @throws IllegalArgumentException if the option does not exist in this configuration.
      */
     @NonNull
-    SessionConfig getDefaultSessionConfig();
+    default SessionConfig getDefaultSessionConfig() {
+        return retrieveOption(OPTION_DEFAULT_SESSION_CONFIG);
+    }
 
     /**
      * Retrieves the default capture configuration for this use case.
@@ -111,7 +115,9 @@
      * configuration.
      */
     @Nullable
-    CaptureConfig getDefaultCaptureConfig(@Nullable CaptureConfig valueIfMissing);
+    default CaptureConfig getDefaultCaptureConfig(@Nullable CaptureConfig valueIfMissing) {
+        return retrieveOption(OPTION_DEFAULT_CAPTURE_CONFIG, valueIfMissing);
+    }
 
     /**
      * Retrieves the default capture configuration for this use case.
@@ -123,7 +129,9 @@
      * @throws IllegalArgumentException if the option does not exist in this configuration.
      */
     @NonNull
-    CaptureConfig getDefaultCaptureConfig();
+    default CaptureConfig getDefaultCaptureConfig() {
+        return retrieveOption(OPTION_DEFAULT_CAPTURE_CONFIG);
+    }
 
     /**
      * Retrieves the {@link SessionConfig.OptionUnpacker} for this use case.
@@ -138,8 +146,10 @@
      * configuration.
      */
     @Nullable
-    SessionConfig.OptionUnpacker getSessionOptionUnpacker(
-            @Nullable SessionConfig.OptionUnpacker valueIfMissing);
+    default SessionConfig.OptionUnpacker getSessionOptionUnpacker(
+            @Nullable SessionConfig.OptionUnpacker valueIfMissing) {
+        return retrieveOption(OPTION_SESSION_CONFIG_UNPACKER, valueIfMissing);
+    }
 
     /**
      * Retrieves the {@link SessionConfig.OptionUnpacker} for this use case.
@@ -153,7 +163,9 @@
      * @throws IllegalArgumentException if the option does not exist in this configuration.
      */
     @NonNull
-    SessionConfig.OptionUnpacker getSessionOptionUnpacker();
+    default SessionConfig.OptionUnpacker getSessionOptionUnpacker() {
+        return retrieveOption(OPTION_SESSION_CONFIG_UNPACKER);
+    }
 
     /**
      * Retrieves the {@link CaptureConfig.OptionUnpacker} for this use case.
@@ -168,8 +180,10 @@
      * configuration.
      */
     @Nullable
-    CaptureConfig.OptionUnpacker getCaptureOptionUnpacker(
-            @Nullable CaptureConfig.OptionUnpacker valueIfMissing);
+    default CaptureConfig.OptionUnpacker getCaptureOptionUnpacker(
+            @Nullable CaptureConfig.OptionUnpacker valueIfMissing) {
+        return retrieveOption(OPTION_CAPTURE_CONFIG_UNPACKER, valueIfMissing);
+    }
 
     /**
      * Retrieves the {@link CaptureConfig.OptionUnpacker} for this use case.
@@ -183,7 +197,9 @@
      * @throws IllegalArgumentException if the option does not exist in this configuration.
      */
     @NonNull
-    CaptureConfig.OptionUnpacker getCaptureOptionUnpacker();
+    default CaptureConfig.OptionUnpacker getCaptureOptionUnpacker() {
+        return retrieveOption(OPTION_CAPTURE_CONFIG_UNPACKER);
+    }
 
     /**
      * Retrieves the surface occupancy priority of the target intending to use from this
@@ -193,7 +209,9 @@
      * @return The stored value or <code>valueIfMissing</code> if the value does not exist in this
      * configuration.
      */
-    int getSurfaceOccupancyPriority(int valueIfMissing);
+    default int getSurfaceOccupancyPriority(int valueIfMissing) {
+        return retrieveOption(OPTION_SURFACE_OCCUPANCY_PRIORITY, valueIfMissing);
+    }
 
     /**
      * Retrieves the surface occupancy priority of the target intending to use from this
@@ -202,7 +220,9 @@
      * @return The stored value, if it exists in this configuration.
      * @throws IllegalArgumentException if the option does not exist in this configuration.
      */
-    int getSurfaceOccupancyPriority();
+    default int getSurfaceOccupancyPriority() {
+        return retrieveOption(OPTION_SURFACE_OCCUPANCY_PRIORITY);
+    }
 
     /**
      * Retrieves the camera selector that this use case requires.
@@ -212,7 +232,9 @@
      * configuration.
      */
     @Nullable
-    CameraSelector getCameraSelector(@Nullable CameraSelector valueIfMissing);
+    default CameraSelector getCameraSelector(@Nullable CameraSelector valueIfMissing) {
+        return retrieveOption(OPTION_CAMERA_SELECTOR, valueIfMissing);
+    }
 
     /**
      * Retrieves the camera selector that this use case requires.
@@ -221,7 +243,9 @@
      * @throws IllegalArgumentException if the option does not exist in this configuration.
      */
     @NonNull
-    CameraSelector getCameraSelector();
+    default CameraSelector getCameraSelector() {
+        return retrieveOption(OPTION_CAMERA_SELECTOR);
+    }
 
     /**
      * Builder for a {@link UseCase}.
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/impl/VideoCaptureConfig.java b/camera/camera-core/src/main/java/androidx/camera/core/impl/VideoCaptureConfig.java
index 4dc69c0..732ffdf 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/impl/VideoCaptureConfig.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/impl/VideoCaptureConfig.java
@@ -23,7 +23,6 @@
 import android.view.Surface;
 
 import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
 import androidx.annotation.RestrictTo.Scope;
 import androidx.camera.core.AspectRatio;
@@ -34,7 +33,6 @@
 import androidx.camera.core.internal.ThreadConfig;
 
 import java.util.List;
-import java.util.Set;
 import java.util.UUID;
 import java.util.concurrent.Executor;
 
@@ -254,363 +252,12 @@
         return ImageFormatConstants.INTERNAL_DEFINED_IMAGE_FORMAT_PRIVATE;
     }
 
-    // Start of the default implementation of Config
-    // *********************************************************************************************
-
-    // Implementations of Config default methods
-
-    @Override
-    public boolean containsOption(@NonNull Option<?> id) {
-        return mConfig.containsOption(id);
-    }
-
-    @Override
-    @Nullable
-    public <ValueT> ValueT retrieveOption(@NonNull Option<ValueT> id) {
-        return mConfig.retrieveOption(id);
-    }
-
-    @Override
-    @Nullable
-    public <ValueT> ValueT retrieveOption(@NonNull Option<ValueT> id,
-            @Nullable ValueT valueIfMissing) {
-        return mConfig.retrieveOption(id, valueIfMissing);
-    }
-
-    @Override
-    public void findOptions(@NonNull String idStem, @NonNull OptionMatcher matcher) {
-        mConfig.findOptions(idStem, matcher);
-    }
-
-    @Override
-    @NonNull
-    public Set<Option<?>> listOptions() {
-        return mConfig.listOptions();
-    }
-
-    // Implementations of TargetConfig default methods
-
-    @Override
-    @Nullable
-    public Class<VideoCapture> getTargetClass(
-            @Nullable Class<VideoCapture> valueIfMissing) {
-        @SuppressWarnings("unchecked") // Value should only be added via Builder#setTargetClass()
-                Class<VideoCapture> storedClass =
-                (Class<VideoCapture>) retrieveOption(
-                        OPTION_TARGET_CLASS,
-                        valueIfMissing);
-        return storedClass;
-    }
-
-    @Override
-    @NonNull
-    public Class<VideoCapture> getTargetClass() {
-        @SuppressWarnings("unchecked") // Value should only be added via Builder#setTargetClass()
-                Class<VideoCapture> storedClass =
-                (Class<VideoCapture>) retrieveOption(
-                        OPTION_TARGET_CLASS);
-        return storedClass;
-    }
-
-    /**
-     * Retrieves the name of the target object being configured.
-     *
-     * <p>The name should be a value that can uniquely identify an instance of the object being
-     * configured.
-     *
-     * @param valueIfMissing The value to return if this configuration option has not been set.
-     * @return The stored value or <code>valueIfMissing</code> if the value does not exist in this
-     * configuration.
-     */
-    @Override
-    @Nullable
-    public String getTargetName(@Nullable String valueIfMissing) {
-        return retrieveOption(OPTION_TARGET_NAME, valueIfMissing);
-    }
-
-    /**
-     * Retrieves the name of the target object being configured.
-     *
-     * <p>The name should be a value that can uniquely identify an instance of the object being
-     * configured.
-     *
-     * @return The stored value, if it exists in this configuration.
-     * @throws IllegalArgumentException if the option does not exist in this configuration.
-     */
-    @Override
-    @NonNull
-    public String getTargetName() {
-        return retrieveOption(OPTION_TARGET_NAME);
-    }
-
-    // Implementations of ImageOutputConfig default methods
-
-    /**
-     * Retrieves the aspect ratio of the target intending to use images from this configuration.
-     *
-     * <p>This is the ratio of the target's width to the image's height, where the numerator of the
-     * provided {@link Rational} corresponds to the width, and the denominator corresponds to the
-     * height.
-     *
-     * @param valueIfMissing The value to return if this configuration option has not been set.
-     * @return The stored value or <code>valueIfMissing</code> if the value does not exist in this
-     * configuration.
-     */
-    @Override
-    @Nullable
-    public Rational getTargetAspectRatioCustom(@Nullable Rational valueIfMissing) {
-        return retrieveOption(OPTION_TARGET_ASPECT_RATIO_CUSTOM, valueIfMissing);
-    }
-
-    /**
-     * Retrieves the aspect ratio of the target intending to use images from this configuration.
-     *
-     * <p>This is the ratio of the target's width to the image's height, where the numerator of the
-     * provided {@link Rational} corresponds to the width, and the denominator corresponds to the
-     * height.
-     *
-     * @return The stored value, if it exists in this configuration.
-     * @throws IllegalArgumentException if the option does not exist in this configuration.
-     */
     @NonNull
     @Override
-    public Rational getTargetAspectRatioCustom() {
-        return retrieveOption(OPTION_TARGET_ASPECT_RATIO_CUSTOM);
+    public Config getConfig() {
+        return mConfig;
     }
 
-    @Override
-    public boolean hasTargetAspectRatio() {
-        return containsOption(OPTION_TARGET_ASPECT_RATIO);
-    }
-
-    /**
-     * Retrieves the aspect ratio of the target intending to use images from this configuration.
-     *
-     * @return The stored value, if it exists in this configuration.
-     * @throws IllegalArgumentException if the option does not exist in this configuration.
-     */
-    @AspectRatio.Ratio
-    @Override
-    public int getTargetAspectRatio() {
-        return retrieveOption(OPTION_TARGET_ASPECT_RATIO);
-    }
-
-    /**
-     * Retrieves the rotation of the target intending to use images from this configuration.
-     *
-     * <p>This is one of four valid values: {@link Surface#ROTATION_0}, {@link Surface#ROTATION_90},
-     * {@link Surface#ROTATION_180}, {@link Surface#ROTATION_270}. Rotation values are relative to
-     * the device's "natural" rotation, {@link Surface#ROTATION_0}.
-     *
-     * @param valueIfMissing The value to return if this configuration option has not been set.
-     * @return The stored value or <code>valueIfMissing</code> if the value does not exist in this
-     * configuration.
-     */
-    @Override
-    @RotationValue
-    public int getTargetRotation(int valueIfMissing) {
-        return retrieveOption(OPTION_TARGET_ROTATION, valueIfMissing);
-    }
-
-    /**
-     * Retrieves the rotation of the target intending to use images from this configuration.
-     *
-     * <p>This is one of four valid values: {@link Surface#ROTATION_0}, {@link Surface#ROTATION_90},
-     * {@link Surface#ROTATION_180}, {@link Surface#ROTATION_270}. Rotation values are relative to
-     * the device's "natural" rotation, {@link Surface#ROTATION_0}.
-     *
-     * @return The stored value, if it exists in this configuration.
-     * @throws IllegalArgumentException if the option does not exist in this configuration.
-     */
-    @Override
-    @RotationValue
-    public int getTargetRotation() {
-        return retrieveOption(OPTION_TARGET_ROTATION);
-    }
-
-    @Override
-    @Nullable
-    public Size getTargetResolution(@Nullable Size valueIfMissing) {
-        return retrieveOption(ImageOutputConfig.OPTION_TARGET_RESOLUTION, valueIfMissing);
-    }
-
-    @Override
-    @NonNull
-    public Size getTargetResolution() {
-        return retrieveOption(ImageOutputConfig.OPTION_TARGET_RESOLUTION);
-    }
-
-    /**
-     * Retrieves the default resolution of the target intending to use from this configuration.
-     *
-     * @param valueIfMissing The value to return if this configuration option has not been set.
-     * @return The stored value or <code>valueIfMissing</code> if the value does not exist in this
-     * configuration.
-     */
-    @Nullable
-    @Override
-    public Size getDefaultResolution(@Nullable Size valueIfMissing) {
-        return retrieveOption(ImageOutputConfig.OPTION_DEFAULT_RESOLUTION, valueIfMissing);
-    }
-
-    /**
-     * Retrieves the default resolution of the target intending to use from this configuration.
-     *
-     * @return The stored value, if it exists in this configuration.
-     * @throws IllegalArgumentException if the option does not exist in this configuration.
-     */
-    @NonNull
-    @Override
-    public Size getDefaultResolution() {
-        return retrieveOption(ImageOutputConfig.OPTION_DEFAULT_RESOLUTION);
-    }
-
-    @Override
-    @Nullable
-    public Size getMaxResolution(@Nullable Size valueIfMissing) {
-        return retrieveOption(OPTION_MAX_RESOLUTION, valueIfMissing);
-    }
-
-    @Override
-    @NonNull
-    public Size getMaxResolution() {
-        return retrieveOption(OPTION_MAX_RESOLUTION);
-    }
-
-    @Override
-    @Nullable
-    public List<Pair<Integer, Size[]>> getSupportedResolutions(
-            @Nullable List<Pair<Integer, Size[]>> valueIfMissing) {
-        return retrieveOption(OPTION_SUPPORTED_RESOLUTIONS, valueIfMissing);
-    }
-
-    @Override
-    @NonNull
-    public List<Pair<Integer, Size[]>> getSupportedResolutions() {
-        return retrieveOption(OPTION_SUPPORTED_RESOLUTIONS);
-    }
-
-    // Implementations of ThreadConfig default methods
-
-    /**
-     * Returns the executor that will be used for background tasks.
-     *
-     * @param valueIfMissing The value to return if this configuration option has not been set.
-     * @return The stored value or <code>valueIfMissing</code> if the value does not exist in this
-     * configuration.
-     */
-    @Override
-    @Nullable
-    public Executor getBackgroundExecutor(@Nullable Executor valueIfMissing) {
-        return retrieveOption(OPTION_BACKGROUND_EXECUTOR, valueIfMissing);
-    }
-
-    /**
-     * Returns the executor that will be used for background tasks.
-     *
-     * @return The stored value, if it exists in this configuration.
-     * @throws IllegalArgumentException if the option does not exist in this configuration.
-     */
-    @Override
-    @NonNull
-    public Executor getBackgroundExecutor() {
-        return retrieveOption(OPTION_BACKGROUND_EXECUTOR);
-    }
-
-    // Implementations of UseCaseConfig default methods
-
-    @Override
-    @Nullable
-    public SessionConfig getDefaultSessionConfig(@Nullable SessionConfig valueIfMissing) {
-        return retrieveOption(OPTION_DEFAULT_SESSION_CONFIG, valueIfMissing);
-    }
-
-    @Override
-    @NonNull
-    public SessionConfig getDefaultSessionConfig() {
-        return retrieveOption(OPTION_DEFAULT_SESSION_CONFIG);
-    }
-
-    @Override
-    @Nullable
-    public SessionConfig.OptionUnpacker getSessionOptionUnpacker(
-            @Nullable SessionConfig.OptionUnpacker valueIfMissing) {
-        return retrieveOption(OPTION_SESSION_CONFIG_UNPACKER, valueIfMissing);
-    }
-
-    @Override
-    @NonNull
-    public SessionConfig.OptionUnpacker getSessionOptionUnpacker() {
-        return retrieveOption(OPTION_SESSION_CONFIG_UNPACKER);
-    }
-
-    @Override
-    @Nullable
-    public CaptureConfig getDefaultCaptureConfig(@Nullable CaptureConfig valueIfMissing) {
-        return retrieveOption(OPTION_DEFAULT_CAPTURE_CONFIG, valueIfMissing);
-    }
-
-    @Override
-    @NonNull
-    public CaptureConfig getDefaultCaptureConfig() {
-        return retrieveOption(OPTION_DEFAULT_CAPTURE_CONFIG);
-    }
-
-    @Override
-    @Nullable
-    public CaptureConfig.OptionUnpacker getCaptureOptionUnpacker(
-            @Nullable CaptureConfig.OptionUnpacker valueIfMissing) {
-        return retrieveOption(OPTION_CAPTURE_CONFIG_UNPACKER, valueIfMissing);
-    }
-
-    @Override
-    @NonNull
-    public CaptureConfig.OptionUnpacker getCaptureOptionUnpacker() {
-        return retrieveOption(OPTION_CAPTURE_CONFIG_UNPACKER);
-    }
-
-    @Override
-    public int getSurfaceOccupancyPriority(int valueIfMissing) {
-        return retrieveOption(OPTION_SURFACE_OCCUPANCY_PRIORITY, valueIfMissing);
-    }
-
-    @Override
-    public int getSurfaceOccupancyPriority() {
-        return retrieveOption(OPTION_SURFACE_OCCUPANCY_PRIORITY);
-    }
-
-    /** @hide */
-    @RestrictTo(Scope.LIBRARY)
-    @Override
-    @Nullable
-    public CameraSelector getCameraSelector(@Nullable CameraSelector valueIfMissing) {
-        return retrieveOption(OPTION_CAMERA_SELECTOR, valueIfMissing);
-    }
-
-    /** @hide */
-    @RestrictTo(Scope.LIBRARY)
-    @Override
-    @NonNull
-    public CameraSelector getCameraSelector() {
-        return retrieveOption(OPTION_CAMERA_SELECTOR);
-    }
-
-    @Override
-    @Nullable
-    public UseCase.EventCallback getUseCaseEventCallback(
-            @Nullable UseCase.EventCallback valueIfMissing) {
-        return retrieveOption(OPTION_USE_CASE_EVENT_CALLBACK, valueIfMissing);
-    }
-
-    @Override
-    @NonNull
-    public UseCase.EventCallback getUseCaseEventCallback() {
-        return retrieveOption(OPTION_USE_CASE_EVENT_CALLBACK);
-    }
-
-    // End of the default implementation of Config
-    // *********************************************************************************************
-
     /** Builder for a {@link VideoCaptureConfig}. */
     public static final class Builder
             implements
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/internal/IoConfig.java b/camera/camera-core/src/main/java/androidx/camera/core/internal/IoConfig.java
index b8c4712..7f283be 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/internal/IoConfig.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/internal/IoConfig.java
@@ -18,14 +18,14 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.camera.core.impl.Config.Option;
+import androidx.camera.core.impl.ReadableConfig;
 
 import java.util.concurrent.Executor;
 
 /**
  * Configuration containing IO related options.
  */
-public interface IoConfig {
+public interface IoConfig extends ReadableConfig {
 
     // Option Declarations:
     // *********************************************************************************************
@@ -46,7 +46,9 @@
      * configuration.
      */
     @Nullable
-    Executor getIoExecutor(@Nullable Executor valueIfMissing);
+    default Executor getIoExecutor(@Nullable Executor valueIfMissing) {
+        return retrieveOption(OPTION_IO_EXECUTOR, valueIfMissing);
+    }
 
 
     /**
@@ -56,7 +58,9 @@
      * @throws IllegalArgumentException if the option does not exist in this configuration.
      */
     @NonNull
-    Executor getIoExecutor();
+    default Executor getIoExecutor() {
+        return retrieveOption(OPTION_IO_EXECUTOR);
+    }
 
     /**
      * Builder for a {@link IoConfig}.
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/internal/TargetConfig.java b/camera/camera-core/src/main/java/androidx/camera/core/internal/TargetConfig.java
index 2ddf24c..ad97e73 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/internal/TargetConfig.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/internal/TargetConfig.java
@@ -20,14 +20,14 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
 import androidx.annotation.RestrictTo.Scope;
-import androidx.camera.core.impl.Config.Option;
+import androidx.camera.core.impl.ReadableConfig;
 
 /**
  * Configuration containing options used to identify the target class and object being configured.
  *
  * @param <T> The type of the object being configured.
  */
-public interface TargetConfig<T> {
+public interface TargetConfig<T> extends ReadableConfig {
 
     // Option Declarations:
     // *********************************************************************************************
@@ -59,8 +59,11 @@
      * @return The stored value or <code>valueIfMissing</code> if the value does not exist in this
      * configuration.
      */
+    @SuppressWarnings("unchecked")
     @Nullable
-    Class<T> getTargetClass(@Nullable Class<T> valueIfMissing);
+    default Class<T> getTargetClass(@Nullable Class<T> valueIfMissing) {
+        return (Class<T>) retrieveOption(OPTION_TARGET_CLASS, valueIfMissing);
+    }
 
     /**
      * Retrieves the class of the object being configured.
@@ -68,8 +71,11 @@
      * @return The stored value, if it exists in this configuration.
      * @throws IllegalArgumentException if the option does not exist in this configuration.
      */
+    @SuppressWarnings("unchecked")
     @NonNull
-    Class<T> getTargetClass();
+    default Class<T> getTargetClass() {
+        return (Class<T>) retrieveOption(OPTION_TARGET_CLASS);
+    }
 
     /**
      * Retrieves the name of the target object being configured.
@@ -82,7 +88,9 @@
      * configuration.
      */
     @Nullable
-    String getTargetName(@Nullable String valueIfMissing);
+    default String getTargetName(@Nullable String valueIfMissing) {
+        return retrieveOption(OPTION_TARGET_NAME, valueIfMissing);
+    }
 
     /**
      * Retrieves the name of the target object being configured.
@@ -94,7 +102,9 @@
      * @throws IllegalArgumentException if the option does not exist in this configuration.
      */
     @NonNull
-    String getTargetName();
+    default String getTargetName() {
+        return retrieveOption(OPTION_TARGET_NAME);
+    }
 
     /**
      * Builder for a {@link TargetConfig}.
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/internal/ThreadConfig.java b/camera/camera-core/src/main/java/androidx/camera/core/internal/ThreadConfig.java
index 05aaa5f..e31c0f4 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/internal/ThreadConfig.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/internal/ThreadConfig.java
@@ -18,14 +18,14 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.camera.core.impl.Config.Option;
+import androidx.camera.core.impl.ReadableConfig;
 
 import java.util.concurrent.Executor;
 
 /**
  * Configuration containing options pertaining to threads used by the configured object.
  */
-public interface ThreadConfig {
+public interface ThreadConfig extends ReadableConfig {
 
     // Option Declarations:
     // *********************************************************************************************
@@ -46,7 +46,9 @@
      * configuration.
      */
     @Nullable
-    Executor getBackgroundExecutor(@Nullable Executor valueIfMissing);
+    default Executor getBackgroundExecutor(@Nullable Executor valueIfMissing) {
+        return retrieveOption(OPTION_BACKGROUND_EXECUTOR, valueIfMissing);
+    }
 
 
     /**
@@ -56,7 +58,9 @@
      * @throws IllegalArgumentException if the option does not exist in this configuration.
      */
     @NonNull
-    Executor getBackgroundExecutor();
+    default Executor getBackgroundExecutor() {
+        return retrieveOption(OPTION_BACKGROUND_EXECUTOR);
+    }
 
     /**
      * Builder for a {@link ThreadConfig}.
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/internal/UseCaseEventConfig.java b/camera/camera-core/src/main/java/androidx/camera/core/internal/UseCaseEventConfig.java
index 1183cc4..729683e 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/internal/UseCaseEventConfig.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/internal/UseCaseEventConfig.java
@@ -20,11 +20,12 @@
 import androidx.annotation.Nullable;
 import androidx.camera.core.UseCase;
 import androidx.camera.core.impl.Config;
+import androidx.camera.core.impl.ReadableConfig;
 
 /**
  * Configuration containing options pertaining to EventCallback object.
  */
-public interface UseCaseEventConfig {
+public interface UseCaseEventConfig extends ReadableConfig {
 
     /**
      * Option: camerax.core.useCaseEventCallback
@@ -40,7 +41,10 @@
      * configuration.
      */
     @Nullable
-    UseCase.EventCallback getUseCaseEventCallback(@Nullable UseCase.EventCallback valueIfMissing);
+    default UseCase.EventCallback getUseCaseEventCallback(
+            @Nullable UseCase.EventCallback valueIfMissing) {
+        return retrieveOption(OPTION_USE_CASE_EVENT_CALLBACK, valueIfMissing);
+    }
 
     /**
      * Returns the EventCallback.
@@ -48,7 +52,9 @@
      * @return The stored value, if it exists in this configuration.
      */
     @NonNull
-    UseCase.EventCallback getUseCaseEventCallback();
+    default UseCase.EventCallback getUseCaseEventCallback() {
+        return retrieveOption(OPTION_USE_CASE_EVENT_CALLBACK);
+    }
 
     // Option Declarations:
     // *********************************************************************************************
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 d213605..72fe289 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
@@ -1,5 +1,5 @@
 /*
- * Copyright 2019 The Android Open Source Project
+ * Copyright 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,9 +19,12 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import android.content.Context;
+import android.graphics.Rect;
 import android.os.Build;
 import android.os.Handler;
 import android.os.HandlerThread;
+import android.util.Rational;
+import android.view.Surface;
 
 import androidx.camera.core.impl.CameraFactory;
 import androidx.camera.core.impl.utils.executor.CameraXExecutors;
@@ -72,17 +75,18 @@
     private List<ImageProxy> mImageProxiesReceived;
     private ImageAnalysis mImageAnalysis;
     private FakeImageReaderProxy mFakeImageReaderProxy;
+    private HandlerThread mBackgroundThread;
+    private HandlerThread mCallbackThread;
 
     @Before
     public void setUp() throws ExecutionException, InterruptedException {
-        mFakeImageReaderProxy = new FakeImageReaderProxy(QUEUE_DEPTH);
-        HandlerThread callbackThread = new HandlerThread("Callback");
-        callbackThread.start();
-        mCallbackHandler = new Handler(callbackThread.getLooper());
+        mCallbackThread = new HandlerThread("Callback");
+        mCallbackThread.start();
+        mCallbackHandler = new Handler(mCallbackThread.getLooper());
 
-        HandlerThread backgroundThread = new HandlerThread("Background");
-        backgroundThread.start();
-        mBackgroundHandler = new Handler(backgroundThread.getLooper());
+        mBackgroundThread = new HandlerThread("Background");
+        mBackgroundThread.start();
+        mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
         mBackgroundExecutor = CameraXExecutors.newHandlerExecutor(mBackgroundHandler);
 
         mImageProxiesReceived = new ArrayList<>();
@@ -93,7 +97,6 @@
                     () -> new FakeCamera(ShadowCameraX.DEFAULT_CAMERA_ID));
             return cameraFactory;
         };
-
         CameraXConfig cameraXConfig = CameraXConfig.Builder.fromConfig(
                 FakeAppConfig.create()).setCameraFactoryProvider(cameraFactoryProvider).build();
 
@@ -106,6 +109,68 @@
         InstrumentationRegistry.getInstrumentation().runOnMainSync(CameraX::unbindAll);
         mImageProxiesReceived.clear();
         CameraX.shutdown().get();
+        if (mBackgroundThread != null) {
+            mBackgroundThread.quitSafely();
+        }
+        if (mCallbackThread != null) {
+            mCallbackThread.quitSafely();
+        }
+    }
+
+    @Test
+    public void largerThanBufferViewPortRect_cropRectIsBufferSize() throws InterruptedException {
+        // Arrange.
+        Rect largerThanBufferRect = new Rect(-1, -1, 10000, 10000);
+        setUpImageAnalysisWithStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST,
+                new ViewPort.Builder()
+                        .setAspectRatio(new Rational(1, 1))
+                        .setScaleType(ViewPort.FILL_CENTER)
+                        .setRotation(Surface.ROTATION_0).build());
+        // Sets viewPortRect directly because Shadow#invert() doesn't work in unit test.
+        mImageAnalysis.setViewPortCropRect(largerThanBufferRect);
+
+        // Act.
+        mFakeImageReaderProxy.triggerImageAvailable(IMAGE_TAG, TIMESTAMP_1);
+        flushHandler(mBackgroundHandler);
+        flushHandler(mCallbackHandler);
+
+        // Assert.
+        ImageProxy imageProxyReceived = Iterables.getOnlyElement(mImageProxiesReceived);
+        assertThat(imageProxyReceived.getCropRect())
+                .isEqualTo(new Rect(0, 0, mFakeImageReaderProxy.getWidth(),
+                        mFakeImageReaderProxy.getHeight()));
+        assertThat(imageProxyReceived.getViewPortRect()).isEqualTo(largerThanBufferRect);
+    }
+
+    @Test
+    public void bindViewPortWithFillStyle_returnsSameViewPortRectAndCropRect()
+            throws InterruptedException {
+        // Arrange.
+        setUpImageAnalysisWithStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST,
+                new ViewPort.Builder()
+                        .setAspectRatio(new Rational(1, 1))
+                        .setScaleType(ViewPort.FILL_CENTER)
+                        .setRotation(Surface.ROTATION_0).build());
+
+        // Act.
+        mFakeImageReaderProxy.triggerImageAvailable(IMAGE_TAG, TIMESTAMP_1);
+        flushHandler(mBackgroundHandler);
+        flushHandler(mCallbackHandler);
+
+        // Assert: both
+        ImageProxy imageProxyReceived = Iterables.getOnlyElement(mImageProxiesReceived);
+        // The expected value is based on fitting the 1:1 view port into a rect with the size of
+        // the ImageReader.
+        int expectedPadding =
+                (mFakeImageReaderProxy.getWidth() - mFakeImageReaderProxy.getHeight()) / 2;
+        assertThat(imageProxyReceived.getCropRect())
+                .isEqualTo(new Rect(expectedPadding, 0,
+                        mFakeImageReaderProxy.getWidth() - expectedPadding,
+                        mFakeImageReaderProxy.getHeight()));
+        assertThat(imageProxyReceived.getViewPortRect())
+                .isEqualTo(new Rect(expectedPadding, 0,
+                        mFakeImageReaderProxy.getWidth() - expectedPadding,
+                        mFakeImageReaderProxy.getHeight()));
     }
 
     @Test
@@ -233,12 +298,22 @@
 
     private void setUpImageAnalysisWithStrategy(
             @ImageAnalysis.BackpressureStrategy int backpressureStrategy) {
+        setUpImageAnalysisWithStrategy(backpressureStrategy, null);
+    }
+
+    private void setUpImageAnalysisWithStrategy(
+            @ImageAnalysis.BackpressureStrategy int backpressureStrategy, ViewPort viewPort) {
         mImageAnalysis = new ImageAnalysis.Builder()
                 .setBackgroundExecutor(mBackgroundExecutor)
+                .setTargetRotation(Surface.ROTATION_0)
                 .setImageQueueDepth(QUEUE_DEPTH)
                 .setBackpressureStrategy(backpressureStrategy)
                 .setImageReaderProxyProvider(
-                        (width, height, format, queueDepth, usage) -> mFakeImageReaderProxy)
+                        (width, height, format, queueDepth, usage) -> {
+                            mFakeImageReaderProxy = FakeImageReaderProxy.newInstance(width,
+                                    height, format, queueDepth, usage);
+                            return mFakeImageReaderProxy;
+                        })
                 .build();
 
         mImageAnalysis.setAnalyzer(CameraXExecutors.newHandlerExecutor(mCallbackHandler),
@@ -250,7 +325,10 @@
 
         FakeLifecycleOwner lifecycleOwner = new FakeLifecycleOwner();
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
-            CameraX.bindToLifecycle(lifecycleOwner, CameraSelector.DEFAULT_BACK_CAMERA,
+            CameraX.bindToLifecycle(
+                    lifecycleOwner,
+                    CameraSelector.DEFAULT_BACK_CAMERA,
+                    viewPort,
                     mImageAnalysis);
             lifecycleOwner.startAndResume();
         });
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/ImageCaptureTest.kt b/camera/camera-core/src/test/java/androidx/camera/core/ImageCaptureTest.kt
new file mode 100644
index 0000000..75bcbe6
--- /dev/null
+++ b/camera/camera-core/src/test/java/androidx/camera/core/ImageCaptureTest.kt
@@ -0,0 +1,228 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.camera.core
+
+import android.content.Context
+import android.graphics.ImageFormat
+import android.graphics.Rect
+import android.os.Build
+import android.os.Handler
+import android.os.HandlerThread
+import android.util.Rational
+import android.view.Surface
+import androidx.camera.core.impl.CameraFactory
+import androidx.camera.core.impl.CameraThreadConfig
+import androidx.camera.core.impl.CaptureConfig
+import androidx.camera.core.impl.UseCaseConfig
+import androidx.camera.core.impl.utils.executor.CameraXExecutors
+import androidx.camera.testing.fakes.FakeAppConfig
+import androidx.camera.testing.fakes.FakeCamera
+import androidx.camera.testing.fakes.FakeCameraFactory
+import androidx.camera.testing.fakes.FakeImageReaderProxy
+import androidx.camera.testing.fakes.FakeLifecycleOwner
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.filters.MediumTest
+import androidx.test.platform.app.InstrumentationRegistry
+import com.google.common.truth.Truth
+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.shadow.api.Shadow
+import org.robolectric.shadows.ShadowLooper
+import java.util.concurrent.ExecutionException
+import java.util.concurrent.Executor
+
+/**
+ * Unit tests for [ImageCapture].
+ */
+@MediumTest
+@RunWith(RobolectricTestRunner::class)
+@DoNotInstrument
+@Config(minSdk = Build.VERSION_CODES.LOLLIPOP, shadows = [ShadowCameraX::class])
+class ImageCaptureTest {
+
+    private var executor: Executor? = null
+    private var callbackHandler: Handler? = null
+    private var fakeImageReaderProxy: FakeImageReaderProxy? = null
+    private var capturedImage: ImageProxy? = null
+    private val  : ImageCapture.OnImageCapturedCallback() {
+        override fun onCaptureSuccess(image: ImageProxy) {
+            capturedImage = image
+        }
+
+        override fun onError(exception: ImageCaptureException) {
+        }
+    }
+
+    @Before
+    @Throws(ExecutionException::class, InterruptedException::class)
+    fun setUp() {
+        val cameraFactoryProvider =
+            CameraFactory.Provider { _: Context?, _: CameraThreadConfig? ->
+                val cameraFactory = FakeCameraFactory()
+                cameraFactory.insertDefaultBackCamera(ShadowCameraX.DEFAULT_CAMERA_ID) {
+                    FakeCamera(ShadowCameraX.DEFAULT_CAMERA_ID)
+                }
+                cameraFactory
+            }
+        val cameraXConfig = CameraXConfig.Builder.fromConfig(
+            FakeAppConfig.create()
+        ).setCameraFactoryProvider(cameraFactoryProvider).build()
+        val context =
+            ApplicationProvider.getApplicationContext<Context>()
+        CameraX.initialize(context, cameraXConfig).get()
+        val callbackThread = HandlerThread("Callback")
+        callbackThread.start()
+        callbackHandler = Handler(callbackThread.looper)
+        executor = CameraXExecutors.newHandlerExecutor(callbackHandler!!)
+    }
+
+    @After
+    @Throws(ExecutionException::class, InterruptedException::class)
+    fun tearDown() {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync { CameraX.unbindAll() }
+        CameraX.shutdown().get()
+        fakeImageReaderProxy = null
+    }
+
+    @Test
+    fun captureImageWithViewPortCropRectLargerThanBuffer_cropRectIsFullSize() {
+        // Arrange.
+        val imageCapture = bindImageCapture(
+            ViewPort.Builder()
+                .setAspectRatio(Rational(1, 1))
+                .setScaleType(ViewPort.FILL_CENTER)
+                .setRotation(Surface.ROTATION_0).build()
+        )
+        // Overwrites the view port crop rect to be larger than the surface. Cannot rely on the
+        // real code path to test this because ShadowMatrix#invert doesn't work.
+        val largerThanBufferRect = Rect(-1, -1, 10000, 10000)
+        imageCapture.viewPortCropRect = largerThanBufferRect
+
+        // Act
+        imageCapture.takePicture(executor!!, onImageCapturedCallback)
+        // Send fake image.
+        fakeImageReaderProxy?.triggerImageAvailable("tag", 0)
+        flushHandler(callbackHandler)
+
+        // Assert.
+        Truth.assertThat(capturedImage!!.viewPortRect).isEqualTo(largerThanBufferRect)
+        // When view port rect is larger, crop rect is full buffer size.
+        Truth.assertThat(capturedImage!!.cropRect).isEqualTo(
+            Rect(0, 0, fakeImageReaderProxy!!.width, fakeImageReaderProxy!!.height)
+        )
+    }
+
+    @Test
+    fun captureImageWithViewPort_isSet() {
+        // Arrange
+        val imageCapture = bindImageCapture(
+            ViewPort.Builder()
+                .setAspectRatio(Rational(1, 1))
+                .setScaleType(ViewPort.FILL_CENTER)
+                .setRotation(Surface.ROTATION_0).build()
+        )
+
+        // Act
+        imageCapture.takePicture(executor!!, onImageCapturedCallback)
+        // Send fake image.
+        fakeImageReaderProxy?.triggerImageAvailable("tag", 0)
+        flushHandler(callbackHandler)
+
+        // Assert.
+        // The expected value is based on fitting the 1:1 view port into a rect with the size of
+        // the ImageReader.
+        val expectedPadding = (fakeImageReaderProxy!!.width - fakeImageReaderProxy!!.height) / 2
+        Truth.assertThat(capturedImage!!.viewPortRect).isEqualTo(
+            Rect(
+                expectedPadding, 0, fakeImageReaderProxy!!.width - expectedPadding,
+                fakeImageReaderProxy!!.height
+            )
+        )
+        Truth.assertThat(capturedImage!!.cropRect).isEqualTo(
+            Rect(
+                expectedPadding, 0, fakeImageReaderProxy!!.width - expectedPadding,
+                fakeImageReaderProxy!!.height
+            )
+        )
+    }
+
+    @Test
+    fun capturedImageSize_isEqualToSurfaceSize() {
+        // Act/arrange.
+        val imageCapture = bindImageCapture()
+
+        // Act
+        imageCapture.takePicture(executor!!, onImageCapturedCallback)
+        // Send fake image.
+        fakeImageReaderProxy?.triggerImageAvailable("tag", 0)
+        flushHandler(callbackHandler)
+
+        // Assert.
+        Truth.assertThat(capturedImage!!.width).isEqualTo(fakeImageReaderProxy?.width)
+        Truth.assertThat(capturedImage!!.height).isEqualTo(fakeImageReaderProxy?.height)
+    }
+
+    private fun bindImageCapture(): ImageCapture {
+        return bindImageCapture(null)
+    }
+
+    private fun bindImageCapture(viewPort: ViewPort?): ImageCapture {
+        // Arrange.
+        val imageCapture = ImageCapture.Builder()
+            // Set non jpg format so it doesn't trigger the exif code path.
+            .setBufferFormat(ImageFormat.YUV_420_888)
+            .setTargetRotation(Surface.ROTATION_0)
+            .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
+            .setFlashMode(ImageCapture.FLASH_MODE_OFF)
+            .setCaptureOptionUnpacker { _: UseCaseConfig<*>?, _: CaptureConfig.Builder? -> }
+            .setImageReaderProxyProvider(getImageReaderProxyProvider())
+            .build()
+
+        // Act.
+        // Bind UseCase amd take picture.
+        val lifecycleOwner = FakeLifecycleOwner()
+        InstrumentationRegistry.getInstrumentation()
+            .runOnMainSync {
+                CameraX.bindToLifecycle(
+                    lifecycleOwner,
+                    CameraSelector.DEFAULT_BACK_CAMERA,
+                    viewPort,
+                    imageCapture
+                )
+                lifecycleOwner.startAndResume()
+            }
+        return imageCapture
+    }
+
+    private fun getImageReaderProxyProvider(): ImageReaderProxyProvider {
+        return ImageReaderProxyProvider { width, height, imageFormat, queueDepth, usage ->
+            fakeImageReaderProxy = FakeImageReaderProxy.newInstance(
+                width, height, imageFormat, queueDepth, usage
+            )
+            fakeImageReaderProxy!!
+        }
+    }
+
+    private fun flushHandler(handler: Handler?) {
+        (Shadow.extract<Any>(handler!!.looper) as ShadowLooper).idle()
+    }
+}
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/PreviewTest.kt b/camera/camera-core/src/test/java/androidx/camera/core/PreviewTest.kt
new file mode 100644
index 0000000..5a5e072
--- /dev/null
+++ b/camera/camera-core/src/test/java/androidx/camera/core/PreviewTest.kt
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.camera.core
+
+import android.content.Context
+import android.graphics.Rect
+import android.os.Build
+import android.util.Rational
+import android.util.Size
+import android.view.Surface
+import androidx.camera.core.impl.CameraFactory
+import androidx.camera.core.impl.CameraThreadConfig
+import androidx.camera.testing.fakes.FakeAppConfig
+import androidx.camera.testing.fakes.FakeCamera
+import androidx.camera.testing.fakes.FakeCameraDeviceSurfaceManager
+import androidx.camera.testing.fakes.FakeCameraFactory
+import androidx.camera.testing.fakes.FakeLifecycleOwner
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.filters.SmallTest
+import androidx.test.platform.app.InstrumentationRegistry
+import com.google.common.truth.Truth
+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 java.util.concurrent.ExecutionException
+
+/**
+ * Unit tests for [Preview].
+ */
+@SmallTest
+@RunWith(RobolectricTestRunner::class)
+@DoNotInstrument
+@Config(minSdk = Build.VERSION_CODES.LOLLIPOP, shadows = [ShadowCameraX::class])
+class PreviewTest {
+
+    @Before
+    @Throws(ExecutionException::class, InterruptedException::class)
+    fun setUp() {
+        val cameraFactoryProvider =
+            CameraFactory.Provider { _: Context?, _: CameraThreadConfig? ->
+                val cameraFactory = FakeCameraFactory()
+                cameraFactory.insertDefaultBackCamera(
+                    ShadowCameraX.DEFAULT_CAMERA_ID
+                ) { FakeCamera(ShadowCameraX.DEFAULT_CAMERA_ID) }
+                cameraFactory
+            }
+        val cameraXConfig = CameraXConfig.Builder.fromConfig(
+            FakeAppConfig.create()
+        ).setCameraFactoryProvider(cameraFactoryProvider).build()
+        val context = ApplicationProvider.getApplicationContext<Context>()
+        CameraX.initialize(context, cameraXConfig).get()
+    }
+
+    @After
+    @Throws(ExecutionException::class, InterruptedException::class)
+    fun tearDown() {
+        InstrumentationRegistry.getInstrumentation()
+            .runOnMainSync { CameraX.unbindAll() }
+        CameraX.shutdown().get()
+    }
+
+    @Test
+    fun viewPortCropSize() {
+        val expectedSurfaceRequest = bindToLifecycleAndGetSurfaceRequest(
+            ViewPort.Builder()
+                .setAspectRatio(Rational(1, 1))
+                .setScaleType(ViewPort.FILL_CENTER)
+                .setRotation(Surface.ROTATION_0).build()
+        )
+        // The expected value is based on fitting the 1:1 view port into a rect with the size of
+        // FakeCameraDeviceSurfaceManager.MAX_OUTPUT_SIZE.
+        val expectedPadding = (FakeCameraDeviceSurfaceManager.MAX_OUTPUT_SIZE.width -
+                FakeCameraDeviceSurfaceManager.MAX_OUTPUT_SIZE.height) / 2
+        Truth.assertThat(expectedSurfaceRequest.viewPortRect).isEqualTo(
+            Rect(
+                expectedPadding,
+                0,
+                FakeCameraDeviceSurfaceManager.MAX_OUTPUT_SIZE.width - expectedPadding,
+                FakeCameraDeviceSurfaceManager.MAX_OUTPUT_SIZE.height
+            )
+        )
+    }
+
+    @Test
+    fun surfaceRequestSize_isSurfaceSize() {
+        Truth.assertThat(bindToLifecycleAndGetSurfaceRequest().resolution).isEqualTo(
+            Size(
+                FakeCameraDeviceSurfaceManager.MAX_OUTPUT_SIZE.width,
+                FakeCameraDeviceSurfaceManager.MAX_OUTPUT_SIZE.height
+            )
+        )
+    }
+
+    private fun bindToLifecycleAndGetSurfaceRequest(): SurfaceRequest {
+        return bindToLifecycleAndGetSurfaceRequest(null)
+    }
+
+    private fun bindToLifecycleAndGetSurfaceRequest(viewPort: ViewPort?): SurfaceRequest {
+        // Arrange.
+        val preview = Preview.Builder().setTargetRotation(Surface.ROTATION_0).build()
+        var surfaceRequest: SurfaceRequest? = null
+        preview.setSurfaceProvider { surfaceRequest = it }
+
+        // Act.
+        val lifecycleOwner = FakeLifecycleOwner()
+        InstrumentationRegistry.getInstrumentation().runOnMainSync {
+            CameraX.bindToLifecycle(
+                lifecycleOwner,
+                CameraSelector.DEFAULT_BACK_CAMERA,
+                viewPort,
+                preview
+            )
+            lifecycleOwner.startAndResume()
+        }
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
+        return surfaceRequest!!
+    }
+}
\ No newline at end of file
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 be14a98..ae9118a 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
@@ -17,6 +17,7 @@
 package androidx.camera.testing.fakes;
 
 import static androidx.camera.core.ImageCapture.FLASH_MODE_OFF;
+import static androidx.camera.testing.fakes.FakeCameraDeviceSurfaceManager.MAX_OUTPUT_SIZE;
 
 import android.graphics.Rect;
 import android.util.Log;
@@ -146,6 +147,12 @@
         }
     }
 
+    @NonNull
+    @Override
+    public Rect getSensorRect() {
+        return new Rect(0, 0, MAX_OUTPUT_SIZE.getWidth(), MAX_OUTPUT_SIZE.getHeight());
+    }
+
     private void updateSessionConfig() {
         mControlUpdateCallback.onCameraControlUpdateSessionConfig(mSessionConfigBuilder.build());
     }
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeConfig.java b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeConfig.java
index 978a65c..3723736 100644
--- a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeConfig.java
+++ b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeConfig.java
@@ -17,7 +17,6 @@
 package androidx.camera.testing.fakes;
 
 import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
 import androidx.annotation.RestrictTo.Scope;
 import androidx.camera.core.ExtendableBuilder;
@@ -25,8 +24,7 @@
 import androidx.camera.core.impl.MutableConfig;
 import androidx.camera.core.impl.MutableOptionsBundle;
 import androidx.camera.core.impl.OptionsBundle;
-
-import java.util.Set;
+import androidx.camera.core.impl.ReadableConfig;
 
 /**
  * Wrapper for an empty Config
@@ -34,7 +32,7 @@
  * @hide
  */
 @RestrictTo(Scope.LIBRARY_GROUP)
-public final class FakeConfig implements Config {
+public final class FakeConfig implements ReadableConfig {
 
     private final Config mConfig;
 
@@ -42,53 +40,12 @@
         mConfig = config;
     }
 
-    // Start of the default implementation of Config
-    // *********************************************************************************************
-
-    // Implementations of Config default methods
-
-    /** @hide */
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Override
-    public boolean containsOption(@NonNull Option<?> id) {
-        return mConfig.containsOption(id);
-    }
-
-    /** @hide */
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Override
-    @Nullable
-    public <ValueT> ValueT retrieveOption(@NonNull Option<ValueT> id) {
-        return mConfig.retrieveOption(id);
-    }
-
-    /** @hide */
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Override
-    @Nullable
-    public <ValueT> ValueT retrieveOption(@NonNull Option<ValueT> id,
-            @Nullable ValueT valueIfMissing) {
-        return mConfig.retrieveOption(id, valueIfMissing);
-    }
-
-    /** @hide */
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Override
-    public void findOptions(@NonNull String idStem, @NonNull OptionMatcher matcher) {
-        mConfig.findOptions(idStem, matcher);
-    }
-
-    /** @hide */
     @NonNull
-    @RestrictTo(Scope.LIBRARY_GROUP)
     @Override
-    public Set<Option<?>> listOptions() {
-        return mConfig.listOptions();
+    public Config getConfig() {
+        return mConfig;
     }
 
-    // End of the default implementation of Config
-    // *********************************************************************************************
-
     /** Builder for an empty Config */
     public static final class Builder implements ExtendableBuilder<FakeConfig> {
 
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeImageReaderProxy.java b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeImageReaderProxy.java
index e57eede..7323432 100644
--- a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeImageReaderProxy.java
+++ b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeImageReaderProxy.java
@@ -66,6 +66,21 @@
         mImageProxyAcquisitionQueue = new LinkedBlockingQueue<>(maxImages);
     }
 
+    /**
+     * Create a new {@link FakeImageReaderProxy} instance.
+     *
+     * @param maxImages The maximum number of images that can be acquired at once
+     */
+    @NonNull
+    public static FakeImageReaderProxy newInstance(int width, int height, int format,
+            int maxImages, long usage) {
+        FakeImageReaderProxy fakeImageReaderProxy = new FakeImageReaderProxy(maxImages);
+        fakeImageReaderProxy.mWidth = width;
+        fakeImageReaderProxy.mHeight = height;
+        fakeImageReaderProxy.setImageFormat(format);
+        return fakeImageReaderProxy;
+    }
+
     @Override
     public ImageProxy acquireLatestImage() {
         ImageProxy imageProxy;
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeUseCaseConfig.java b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeUseCaseConfig.java
index 3e3694c..3d2c5f7 100644
--- a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeUseCaseConfig.java
+++ b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeUseCaseConfig.java
@@ -21,7 +21,6 @@
 import android.util.Size;
 
 import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
 import androidx.camera.core.CameraSelector;
 import androidx.camera.core.UseCase;
 import androidx.camera.core.impl.CaptureConfig;
@@ -35,13 +34,10 @@
 import androidx.camera.core.impl.UseCaseConfig;
 
 import java.util.List;
-import java.util.Set;
 import java.util.UUID;
 
 /** A fake configuration for {@link FakeUseCase}. */
-public class FakeUseCaseConfig
-        implements UseCaseConfig<FakeUseCase>,
-        ImageOutputConfig {
+public class FakeUseCaseConfig implements UseCaseConfig<FakeUseCase>, ImageOutputConfig {
 
     private final Config mConfig;
 
@@ -49,255 +45,17 @@
         mConfig = config;
     }
 
-    // Start of the default implementation of Config
-    // *********************************************************************************************
-
-    // Implementations of Config.Reader default methods
-
-    @Override
-    public boolean containsOption(@NonNull Option<?> id) {
-        return mConfig.containsOption(id);
-    }
-
-    @Override
-    @Nullable
-    public <ValueT> ValueT retrieveOption(@NonNull Option<ValueT> id) {
-        return mConfig.retrieveOption(id);
-    }
-
-    @Override
-    @Nullable
-    public <ValueT> ValueT retrieveOption(@NonNull Option<ValueT> id,
-            @Nullable ValueT valueIfMissing) {
-        return mConfig.retrieveOption(id, valueIfMissing);
-    }
-
-    @Override
-    public void findOptions(@NonNull String idStem, @NonNull OptionMatcher matcher) {
-        mConfig.findOptions(idStem, matcher);
-    }
-
-    @Override
-    @NonNull
-    public Set<Option<?>> listOptions() {
-        return mConfig.listOptions();
-    }
-
-    // Implementations of TargetConfig default methods
-
-    @Override
-    @Nullable
-    public Class<FakeUseCase> getTargetClass(
-            @Nullable Class<FakeUseCase> valueIfMissing) {
-        @SuppressWarnings("unchecked") // Value should only be added via Builder#setTargetClass()
-                Class<FakeUseCase> storedClass = (Class<FakeUseCase>) retrieveOption(
-                OPTION_TARGET_CLASS,
-                valueIfMissing);
-        return storedClass;
-    }
-
-    @Override
-    @NonNull
-    public Class<FakeUseCase> getTargetClass() {
-        @SuppressWarnings("unchecked") // Value should only be added via Builder#setTargetClass()
-                Class<FakeUseCase> storedClass = (Class<FakeUseCase>) retrieveOption(
-                OPTION_TARGET_CLASS);
-        return storedClass;
-    }
-
-    @Override
-    @Nullable
-    public String getTargetName(@Nullable String valueIfMissing) {
-        return retrieveOption(OPTION_TARGET_NAME, valueIfMissing);
-    }
-
-    @Override
-    @NonNull
-    public String getTargetName() {
-        return retrieveOption(OPTION_TARGET_NAME);
-    }
-
-    // Implementations of UseCaseConfig default methods
-
-    @Override
-    @Nullable
-    public SessionConfig getDefaultSessionConfig(@Nullable SessionConfig valueIfMissing) {
-        return retrieveOption(OPTION_DEFAULT_SESSION_CONFIG, valueIfMissing);
-    }
-
-    @Override
-    @NonNull
-    public SessionConfig getDefaultSessionConfig() {
-        return retrieveOption(OPTION_DEFAULT_SESSION_CONFIG);
-    }
-
-    @Override
-    @Nullable
-    public CaptureConfig getDefaultCaptureConfig(@Nullable CaptureConfig valueIfMissing) {
-        return retrieveOption(OPTION_DEFAULT_CAPTURE_CONFIG, valueIfMissing);
-    }
-
-    @Override
-    @NonNull
-    public CaptureConfig getDefaultCaptureConfig() {
-        return retrieveOption(OPTION_DEFAULT_CAPTURE_CONFIG);
-    }
-
-    @Override
-    @Nullable
-    public SessionConfig.OptionUnpacker getSessionOptionUnpacker(
-            @Nullable SessionConfig.OptionUnpacker valueIfMissing) {
-        return retrieveOption(OPTION_SESSION_CONFIG_UNPACKER, valueIfMissing);
-    }
-
-    @Override
-    @NonNull
-    public SessionConfig.OptionUnpacker getSessionOptionUnpacker() {
-        return retrieveOption(OPTION_SESSION_CONFIG_UNPACKER);
-    }
-
-    @Override
-    @Nullable
-    public CaptureConfig.OptionUnpacker getCaptureOptionUnpacker(
-            @Nullable CaptureConfig.OptionUnpacker valueIfMissing) {
-        return retrieveOption(OPTION_CAPTURE_CONFIG_UNPACKER, valueIfMissing);
-    }
-
-    @Override
-    @NonNull
-    public CaptureConfig.OptionUnpacker getCaptureOptionUnpacker() {
-        return retrieveOption(OPTION_CAPTURE_CONFIG_UNPACKER);
-    }
-
-    @Override
-    public int getSurfaceOccupancyPriority(int valueIfMissing) {
-        return retrieveOption(OPTION_SURFACE_OCCUPANCY_PRIORITY, valueIfMissing);
-    }
-
-    @Override
-    public int getSurfaceOccupancyPriority() {
-        return retrieveOption(OPTION_SURFACE_OCCUPANCY_PRIORITY);
-    }
-
-    @Override
-    @Nullable
-    public CameraSelector getCameraSelector(@Nullable CameraSelector valueIfMissing) {
-        return retrieveOption(OPTION_CAMERA_SELECTOR, valueIfMissing);
-    }
-
-    @Override
-    @NonNull
-    public CameraSelector getCameraSelector() {
-        return retrieveOption(OPTION_CAMERA_SELECTOR);
-    }
-
-    @Override
-    @Nullable
-    public UseCase.EventCallback getUseCaseEventCallback(
-            @Nullable UseCase.EventCallback valueIfMissing) {
-        return retrieveOption(OPTION_USE_CASE_EVENT_CALLBACK, valueIfMissing);
-    }
-
-    @Override
-    @NonNull
-    public UseCase.EventCallback getUseCaseEventCallback() {
-        return retrieveOption(OPTION_USE_CASE_EVENT_CALLBACK);
-    }
-
-    // Implementations of ImageOutputConfig default methods
-
-    @Nullable
-    @Override
-    public Rational getTargetAspectRatioCustom(@Nullable Rational valueIfMissing) {
-        return retrieveOption(OPTION_TARGET_ASPECT_RATIO_CUSTOM, valueIfMissing);
-    }
-
     @NonNull
     @Override
-    public Rational getTargetAspectRatioCustom() {
-        return retrieveOption(OPTION_TARGET_ASPECT_RATIO_CUSTOM);
+    public Config getConfig() {
+        return mConfig;
     }
 
     @Override
-    public boolean hasTargetAspectRatio() {
-        return containsOption(OPTION_TARGET_ASPECT_RATIO);
-    }
-
-    @Override
-    public int getTargetAspectRatio() {
-        return retrieveOption(OPTION_TARGET_ASPECT_RATIO);
-
-    }
-
-    @Override
-    public int getTargetRotation(int valueIfMissing) {
-        return retrieveOption(OPTION_TARGET_ROTATION, valueIfMissing);
-    }
-
-    @Override
-    public int getTargetRotation() {
-        return retrieveOption(OPTION_TARGET_ROTATION);
-    }
-
-    @Nullable
-    @Override
-    public Size getTargetResolution(@Nullable Size valueIfMissing) {
-        return retrieveOption(OPTION_TARGET_RESOLUTION, valueIfMissing);
-    }
-
-    @NonNull
-    @Override
-    public Size getTargetResolution() {
-        return retrieveOption(OPTION_TARGET_RESOLUTION);
-    }
-
-    @Nullable
-    @Override
-    public Size getDefaultResolution(@Nullable Size valueIfMissing) {
-        return retrieveOption(OPTION_DEFAULT_RESOLUTION, valueIfMissing);
-    }
-
-    @NonNull
-    @Override
-    public Size getDefaultResolution() {
-        return retrieveOption(OPTION_DEFAULT_RESOLUTION);
-    }
-
-    @Nullable
-    @Override
-    public Size getMaxResolution(@Nullable Size valueIfMissing) {
-        return retrieveOption(OPTION_MAX_RESOLUTION, valueIfMissing);
-    }
-
-    @NonNull
-    @Override
-    public Size getMaxResolution() {
-        return retrieveOption(OPTION_MAX_RESOLUTION);
-    }
-
-    @Nullable
-    @Override
-    public List<Pair<Integer, Size[]>> getSupportedResolutions(
-            @Nullable List<Pair<Integer, Size[]>> valueIfMissing) {
-        return retrieveOption(OPTION_SUPPORTED_RESOLUTIONS, valueIfMissing);
-    }
-
-    @NonNull
-    @Override
-    public List<Pair<Integer, Size[]>> getSupportedResolutions() {
-        return retrieveOption(OPTION_SUPPORTED_RESOLUTIONS);
-    }
-
-    // Implementations of ImageInputConfig default methods
-
-    @Override
     public int getInputFormat() {
         return ImageFormatConstants.INTERNAL_DEFINED_IMAGE_FORMAT_PRIVATE;
     }
 
-    // End of the default implementation of Config
-    // *********************************************************************************************
-
     /** Builder for an empty Config */
     public static final class Builder implements
             UseCaseConfig.Builder<FakeUseCase, FakeUseCaseConfig, FakeUseCaseConfig.Builder>,
diff --git a/camera/camera-view/src/androidTest/java/androidx/camera/view/PreviewViewTest.java b/camera/camera-view/src/androidTest/java/androidx/camera/view/PreviewViewTest.java
index 67f8abf..70e116c 100644
--- a/camera/camera-view/src/androidTest/java/androidx/camera/view/PreviewViewTest.java
+++ b/camera/camera-view/src/androidTest/java/androidx/camera/view/PreviewViewTest.java
@@ -21,6 +21,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assume.assumeTrue;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.timeout;
@@ -30,6 +31,7 @@
 
 import android.Manifest;
 import android.content.Context;
+import android.os.Build;
 import android.util.Size;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -106,7 +108,26 @@
 
     @Test
     @UiThreadTest
-    public void usesSurfaceView_whenNonLegacyDevice_andPreferredImplModeSurfaceView() {
+    public void usesTextureView_whenAPILevelNotNewerThanN() {
+        assumeTrue(Build.VERSION.SDK_INT <= 24);
+        final CameraInfo cameraInfo = mock(CameraInfo.class);
+        when(cameraInfo.getImplementationType()).thenReturn(
+                CameraInfo.IMPLEMENTATION_TYPE_CAMERA2);
+
+        final PreviewView previewView = new PreviewView(mContext);
+        setContentView(previewView);
+        previewView.setPreferredImplementationMode(SURFACE_VIEW);
+        Preview.SurfaceProvider surfaceProvider = previewView.createSurfaceProvider();
+        mSurfaceRequest = createSurfaceRequest(cameraInfo);
+        surfaceProvider.onSurfaceRequested(mSurfaceRequest);
+
+        assertThat(previewView.mImplementation).isInstanceOf(TextureViewImplementation.class);
+    }
+
+    @Test
+    @UiThreadTest
+    public void usesSurfaceView_whenNonLegacyDevice_andAPILevelNewerThanN() {
+        assumeTrue(Build.VERSION.SDK_INT > 24);
         final CameraInfo cameraInfo = mock(CameraInfo.class);
         when(cameraInfo.getImplementationType()).thenReturn(
                 CameraInfo.IMPLEMENTATION_TYPE_CAMERA2);
diff --git a/camera/camera-view/src/main/java/androidx/camera/view/PreviewView.java b/camera/camera-view/src/main/java/androidx/camera/view/PreviewView.java
index 96544c5..b4d0e76 100644
--- a/camera/camera-view/src/main/java/androidx/camera/view/PreviewView.java
+++ b/camera/camera-view/src/main/java/androidx/camera/view/PreviewView.java
@@ -123,7 +123,8 @@
      * Specifies the preferred {@link ImplementationMode} to use for preview.
      * <p>
      * When the preferred {@link ImplementationMode} is {@link ImplementationMode#SURFACE_VIEW}
-     * but the device doesn't support this mode (e.g. devices with a supported camera hardware level
+     * but the device doesn't support this mode (e.g. devices with API level not newer than
+     * Android 7.0 or a supported camera hardware level
      * {@link android.hardware.camera2.CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY}),
      * the actual implementation mode will be {@link ImplementationMode#TEXTURE_VIEW}.
      *
@@ -223,9 +224,9 @@
     }
 
     @NonNull
-    private ImplementationMode computeImplementationMode(@Nullable CameraInfo cameraInfo,
+    private ImplementationMode computeImplementationMode(@NonNull CameraInfo cameraInfo,
             @NonNull final ImplementationMode preferredMode) {
-        return cameraInfo == null || cameraInfo.getImplementationType().equals(
+        return Build.VERSION.SDK_INT <= 24 || cameraInfo.getImplementationType().equals(
                 CameraInfo.IMPLEMENTATION_TYPE_CAMERA2_LEGACY) ? ImplementationMode.TEXTURE_VIEW
                 : preferredMode;
     }
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 27cca3d..deb9ab6 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
@@ -134,7 +134,7 @@
 
                         @Override
                         public void onError(@NonNull ImageCaptureException exception) {
-                            report("Failure: " + exception.getMessage());
+                            report("Failure: " + exception.getMessage(), exception.getCause());
                         }
                     });
         }
@@ -158,7 +158,7 @@
                         @Override
                         public void onError(int videoCaptureError, @NonNull String message,
                                 @Nullable Throwable cause) {
-                            report("Failure: " + message);
+                            report("Failure: " + message, cause);
                         }
                     });
         }
@@ -225,16 +225,25 @@
     }
 
     private File createNewFile(String extension) {
+        File dirFile =
+                Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
+        if (dirFile != null && !dirFile.exists()) {
+            dirFile.mkdirs();
+        }
         // Use Locale.US to ensure we get ASCII digits
-        return new File(
-                Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
+        return new File(dirFile,
                 new SimpleDateFormat(FILENAME, Locale.US).format(System.currentTimeMillis())
                         + extension);
     }
 
     @SuppressWarnings("WeakerAccess")
-    void report(String msg) {
-        Log.d(TAG, msg);
+    void report(@NonNull String msg) {
+        report(msg, null);
+    }
+
+    @SuppressWarnings("WeakerAccess")
+    void report(@NonNull String msg, @Nullable Throwable cause) {
+        Log.d(TAG, msg, cause);
         Toast.makeText(mCameraView.getContext(), msg, Toast.LENGTH_SHORT).show();
     }
 
diff --git a/compose/compose-runtime/build.gradle b/compose/compose-runtime/build.gradle
index 0176276..cb04425 100644
--- a/compose/compose-runtime/build.gradle
+++ b/compose/compose-runtime/build.gradle
@@ -37,16 +37,10 @@
 
     sourceSets {
         commonMain.dependencies {
-            implementation(KOTLIN_STDLIB)
-        }
-        commonTest.dependencies {
-            implementation kotlin("test-junit")
-            implementation project(":ui:ui-core")
-        }
-
-        jvmMain {
+            implementation(KOTLIN_STDLIB_COMMON)
         }
         jvmMain.dependencies {
+            implementation(KOTLIN_STDLIB)
             api(KOTLIN_COROUTINES_CORE)
             implementation "org.jetbrains.kotlinx:kotlinx-collections-immutable-jvm:0.3"
         }
diff --git a/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/ComposeBenchmark.kt b/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/ComposeBenchmark.kt
index fde1b1e..983800a9 100644
--- a/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/ComposeBenchmark.kt
+++ b/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/ComposeBenchmark.kt
@@ -157,7 +157,11 @@
 private val redBackground = background(Color.Red)
 private val blackBackground = background(Color.Black)
 private val yellowBackground = background(Color.Yellow)
-private val defaultBackground = yellowBackground
+
+private val redModifier = Modifier.fillMaxSize() + redBackground
+private val blackModifier = Modifier.fillMaxSize() + blackBackground
+private val yellowModifier = Modifier.fillMaxSize() + yellowBackground
+private val defaultModifier = yellowModifier
 
 @Model
 class ColorModel(private var color: Color = Color.Black) {
@@ -165,31 +169,31 @@
         color = if (color == Color.Black) Color.Red else Color.Black
     }
 
-    val background
+    val modifier
         get() = when (color) {
-            Color.Red -> redBackground
-            Color.Black -> blackBackground
-            Color.Yellow -> yellowBackground
-            else -> Modifier.drawBackground(color)
+            Color.Red -> redModifier
+            Color.Black -> blackModifier
+            Color.Yellow -> yellowModifier
+            else -> Modifier.fillMaxSize().drawBackground(color)
         }
 }
 
 @Composable
 fun OneRect(model: ColorModel) {
-    Box(modifier = Modifier.fillMaxSize() + model.background)
+    Box(modifier = model.modifier)
 }
 
 @Composable
 fun TenRects(model: ColorModel, narrow: Boolean = false) {
     if (narrow) {
         Observe {
-            Box(modifier = Modifier.fillMaxSize() + model.background)
+            Box(modifier = model.modifier)
         }
     } else {
-        Box(modifier = Modifier.fillMaxSize() + model.background)
+        Box(modifier = model.modifier)
     }
     repeat(9) {
-        Box(modifier = Modifier.fillMaxSize() + defaultBackground)
+        Box(modifier = defaultModifier)
     }
 }
 
@@ -199,12 +203,12 @@
         if (it % 10 == 0)
             if (narrow) {
                 Observe {
-                    Box(modifier = Modifier.fillMaxSize() + model.background)
+                    Box(modifier = model.modifier)
                 }
             } else {
-                Box(modifier = Modifier.fillMaxSize() + model.background)
+                Box(modifier = model.modifier)
             }
         else
-            Box(modifier = Modifier.fillMaxSize() + defaultBackground)
+            Box(modifier = defaultModifier)
     }
 }
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 45422b0..21bf639 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
@@ -31,7 +31,7 @@
 import androidx.ui.layout.Column
 import androidx.ui.layout.padding
 import androidx.ui.foundation.Box
-import androidx.ui.foundation.DrawBackground
+import androidx.ui.foundation.drawBackground
 import androidx.ui.layout.Row
 import androidx.ui.layout.fillMaxSize
 import androidx.ui.layout.fillMaxWidth
@@ -54,7 +54,7 @@
     }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_001(
@@ -124,7 +124,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_002(
@@ -172,7 +172,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_003(
@@ -269,7 +269,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_004(
@@ -372,7 +372,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_005(
@@ -460,7 +460,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_133(
@@ -571,7 +571,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_070(
@@ -637,7 +637,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_071(
@@ -716,7 +716,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_012(
@@ -763,7 +763,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_123(
@@ -818,7 +818,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -856,7 +856,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -893,7 +893,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_091(
@@ -956,7 +956,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -995,7 +995,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -1040,7 +1040,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_119(
@@ -1099,7 +1099,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_057(
@@ -1169,7 +1169,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -1223,7 +1223,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_147(
@@ -1280,7 +1280,7 @@
     }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -1331,7 +1331,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -1364,7 +1364,7 @@
     }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -1416,7 +1416,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_015(
@@ -1499,7 +1499,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp5 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2 + tmp3 + tmp4
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp5.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp5.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_094(
@@ -1552,7 +1552,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_048(
@@ -1599,7 +1599,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_138(
@@ -1660,7 +1660,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -1699,7 +1699,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -1749,7 +1749,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -1792,7 +1792,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_016(
@@ -1839,7 +1839,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_121(
@@ -1887,7 +1887,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -1928,7 +1928,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp5 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2 + tmp3 + tmp4
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp5.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp5.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -1967,7 +1967,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_063(
@@ -2022,7 +2022,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -2067,7 +2067,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -2106,7 +2106,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -2158,7 +2158,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_076(
@@ -2258,7 +2258,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp5 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2 + tmp3 + tmp4
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp5.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp5.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_054(
@@ -2309,7 +2309,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_041(
@@ -2368,7 +2368,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_053(
@@ -2415,7 +2415,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_089(
@@ -2487,7 +2487,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -2545,7 +2545,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp5 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2 + tmp3 + tmp4
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp5.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp5.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_097(
@@ -2611,7 +2611,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp5 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2 + tmp3 + tmp4
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp5.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp5.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_124(
@@ -2697,7 +2697,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp5 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2 + tmp3 + tmp4
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp5.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp5.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_105(
@@ -2744,7 +2744,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_103(
@@ -2785,7 +2785,7 @@
     }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -2824,7 +2824,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -2863,7 +2863,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_107(
@@ -2924,7 +2924,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -2963,7 +2963,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -3002,7 +3002,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -3040,7 +3040,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -3070,7 +3070,7 @@
     }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_056(
@@ -3145,7 +3145,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_021(
@@ -3200,7 +3200,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_128(
@@ -3261,7 +3261,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp5 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2 + tmp3 + tmp4
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp5.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp5.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -3294,7 +3294,7 @@
     }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_067(
@@ -3351,7 +3351,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -3389,7 +3389,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -3425,7 +3425,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -3462,7 +3462,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_019(
@@ -3523,7 +3523,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -3562,7 +3562,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -3606,7 +3606,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -3649,7 +3649,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -3700,7 +3700,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -3750,7 +3750,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp5 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2 + tmp3 + tmp4
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp5.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp5.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_140(
@@ -3815,7 +3815,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_092(
@@ -3879,7 +3879,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_029(
@@ -3950,7 +3950,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp5 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2 + tmp3 + tmp4
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp5.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp5.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_073(
@@ -4019,7 +4019,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_118(
@@ -4066,7 +4066,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_074(
@@ -4112,7 +4112,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -4151,7 +4151,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_022(
@@ -4202,7 +4202,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_077(
@@ -4309,7 +4309,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_058(
@@ -4361,7 +4361,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_126(
@@ -4418,7 +4418,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -4458,7 +4458,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_112(
@@ -4538,7 +4538,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp5 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2 + tmp3 + tmp4
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp5.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp5.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_083(
@@ -4609,7 +4609,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_084(
@@ -4664,7 +4664,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_042(
@@ -4707,7 +4707,7 @@
     }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -4740,7 +4740,7 @@
     }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_088(
@@ -4798,7 +4798,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_111(
@@ -4854,7 +4854,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -4891,7 +4891,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_011(
@@ -4938,7 +4938,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -4982,7 +4982,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -5019,7 +5019,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -5059,7 +5059,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_044(
@@ -5117,7 +5117,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_096(
@@ -5190,7 +5190,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp5 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2 + tmp3 + tmp4
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp5.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp5.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_014(
@@ -5243,7 +5243,7 @@
     }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -5288,7 +5288,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_109(
@@ -5349,7 +5349,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_062(
@@ -5415,7 +5415,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_036(
@@ -5468,7 +5468,7 @@
     }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -5513,7 +5513,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_049(
@@ -5578,7 +5578,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_047(
@@ -5641,7 +5641,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -5679,7 +5679,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -5722,7 +5722,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -5761,7 +5761,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_026(
@@ -5817,7 +5817,7 @@
     }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -5862,7 +5862,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -5901,7 +5901,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -5934,7 +5934,7 @@
     }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -5985,7 +5985,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -6028,7 +6028,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp5 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2 + tmp3 + tmp4
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp5.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp5.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -6061,7 +6061,7 @@
     }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_116(
@@ -6120,7 +6120,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_114(
@@ -6191,7 +6191,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -6242,7 +6242,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -6281,7 +6281,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_117(
@@ -6328,7 +6328,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -6367,7 +6367,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -6406,7 +6406,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_130(
@@ -6449,7 +6449,7 @@
     }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -6494,7 +6494,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -6549,7 +6549,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp5 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2 + tmp3 + tmp4
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp5.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp5.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -6594,7 +6594,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -6639,7 +6639,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_125(
@@ -6686,7 +6686,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -6725,7 +6725,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -6758,7 +6758,7 @@
     }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -6803,7 +6803,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -6842,7 +6842,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -6875,7 +6875,7 @@
     }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -6922,7 +6922,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_132(
@@ -6998,7 +6998,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_006(
@@ -7133,7 +7133,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_134(
@@ -7191,7 +7191,7 @@
     }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_097(
@@ -7254,7 +7254,7 @@
     }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_136(
@@ -7301,7 +7301,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_051(
@@ -7368,7 +7368,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -7401,7 +7401,7 @@
     }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -7435,7 +7435,7 @@
     }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_141(
@@ -7496,7 +7496,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_076(
@@ -7573,7 +7573,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_092(
@@ -7636,7 +7636,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_071(
@@ -7728,7 +7728,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_144(
@@ -7825,7 +7825,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp5 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2 + tmp3 + tmp4
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp5.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp5.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_018(
@@ -7890,7 +7890,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_057(
@@ -7973,7 +7973,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_034(
@@ -8056,7 +8056,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp5 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2 + tmp3 + tmp4
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp5.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp5.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     Box(Modifier.fillMaxWidth().weight(1f), backgroundColor = model.toColor())
@@ -8094,7 +8094,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_041(
@@ -8161,7 +8161,7 @@
             }.map { it.toString().reversed() }.joinToString("-"))
     val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
     WithConstraints(modifier) {
-        Box(Modifier.padding(1.dp) + DrawBackground(color = tmp3.toColor())) {
+        Box(Modifier.padding(1.dp).drawBackground(color = tmp3.toColor())) {
             if (constraints.maxHeight > constraints.maxWidth) {
                 Column {
                     RealWorld4_FancyWidget_087(
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 0b9634b..9a4ed0d 100644
--- a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Composer.kt
+++ b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Composer.kt
@@ -2197,8 +2197,24 @@
 }
 
 // Invalidation helpers
-private fun MutableList<Invalidation>.findLocation(location: Int): Int =
-    binarySearch { it.location.compareTo(location) }
+private fun MutableList<Invalidation>.findLocation(location: Int): Int {
+    var low = 0
+    var high = size - 1
+
+    while (low <= high) {
+        val mid = (low + high).ushr(1) // safe from overflows
+        val midVal = get(mid)
+        val cmp = midVal.location.compareTo(location)
+
+        if (cmp < 0)
+            low = mid + 1
+        else if (cmp > 0)
+            high = mid - 1
+        else
+            return mid // key found
+    }
+    return -(low + 1) // key not found
+}
 
 private fun MutableList<Invalidation>.insertIfMissing(location: Int, scope: RecomposeScope) {
     val index = findLocation(location)
diff --git a/core/core-animation/api/api_lint.ignore b/core/core-animation/api/api_lint.ignore
index 3b4ea75..70743c5 100644
--- a/core/core-animation/api/api_lint.ignore
+++ b/core/core-animation/api/api_lint.ignore
@@ -1,3 +1,9 @@
 // Baseline format: 1.0
+BuilderSetStyle: androidx.core.animation.AnimatorSet.Builder#after(androidx.core.animation.Animator):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.core.animation.AnimatorSet.Builder.after(androidx.core.animation.Animator)
+BuilderSetStyle: androidx.core.animation.AnimatorSet.Builder#after(long):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.core.animation.AnimatorSet.Builder.after(long)
+BuilderSetStyle: androidx.core.animation.AnimatorSet.Builder#before(androidx.core.animation.Animator):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.core.animation.AnimatorSet.Builder.before(androidx.core.animation.Animator)
 BuilderSetStyle: androidx.core.animation.AnimatorSet.Builder#with(androidx.core.animation.Animator):
-    Builder methods names should use setFoo() style: method androidx.core.animation.AnimatorSet.Builder.with(androidx.core.animation.Animator)
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.core.animation.AnimatorSet.Builder.with(androidx.core.animation.Animator)
diff --git a/core/core/api/1.4.0-alpha01.txt b/core/core/api/1.4.0-alpha01.txt
index 31d0479..b8644ee 100644
--- a/core/core/api/1.4.0-alpha01.txt
+++ b/core/core/api/1.4.0-alpha01.txt
@@ -3069,6 +3069,15 @@
     method public static void showAsDropDown(android.widget.PopupWindow, android.view.View, int, int, int);
   }
 
+  public abstract class RichContentReceiverCompat<T extends android.view.View> {
+    ctor public RichContentReceiverCompat();
+    method public abstract java.util.Set<java.lang.String!> getSupportedMimeTypes();
+    method public abstract boolean onReceive(T, android.content.ClipData, int, int);
+    field public static final int FLAG_CONVERT_TO_PLAIN_TEXT = 1; // 0x1
+    field public static final int SOURCE_CLIPBOARD = 0; // 0x0
+    field public static final int SOURCE_INPUT_METHOD = 1; // 0x1
+  }
+
   @Deprecated public final class ScrollerCompat {
     method @Deprecated public void abortAnimation();
     method @Deprecated public boolean computeScrollOffset();
@@ -3123,6 +3132,12 @@
     field public static final int AUTO_SIZE_TEXT_TYPE_UNIFORM = 1; // 0x1
   }
 
+  public abstract class TextViewRichContentReceiverCompat extends androidx.core.widget.RichContentReceiverCompat<android.widget.TextView> {
+    ctor public TextViewRichContentReceiverCompat();
+    method public java.util.Set<java.lang.String!> getSupportedMimeTypes();
+    method public boolean onReceive(android.widget.TextView, android.content.ClipData, int, int);
+  }
+
   public interface TintableCompoundButton {
     method public android.content.res.ColorStateList? getSupportButtonTintList();
     method public android.graphics.PorterDuff.Mode? getSupportButtonTintMode();
diff --git a/core/core/api/api_lint.ignore b/core/core/api/api_lint.ignore
index 116fb6e..c20f29a 100644
--- a/core/core/api/api_lint.ignore
+++ b/core/core/api/api_lint.ignore
@@ -205,6 +205,30 @@
     Methods must not mention RuntimeException subclasses in throws clauses (was `java.lang.IllegalArgumentException`)
 
 
+BuilderSetStyle: androidx.core.app.NotificationCompat.Action.Builder#extend(androidx.core.app.NotificationCompat.Action.Extender):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.core.app.NotificationCompat.Action.Builder.extend(androidx.core.app.NotificationCompat.Action.Extender)
+BuilderSetStyle: androidx.core.app.NotificationCompat.Builder#extend(androidx.core.app.NotificationCompat.Extender):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.core.app.NotificationCompat.Builder.extend(androidx.core.app.NotificationCompat.Extender)
+BuilderSetStyle: androidx.core.app.NotificationCompat.Builder#limitCharSequenceLength(CharSequence):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.core.app.NotificationCompat.Builder.limitCharSequenceLength(CharSequence)
+BuilderSetStyle: androidx.core.app.ShareCompat.IntentBuilder#createChooserIntent():
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.core.app.ShareCompat.IntentBuilder.createChooserIntent()
+BuilderSetStyle: androidx.core.app.ShareCompat.IntentBuilder#from(android.app.Activity):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.core.app.ShareCompat.IntentBuilder.from(android.app.Activity)
+BuilderSetStyle: androidx.core.app.ShareCompat.IntentBuilder#startChooser():
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.core.app.ShareCompat.IntentBuilder.startChooser()
+BuilderSetStyle: androidx.core.app.TaskStackBuilder#create(android.content.Context):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.core.app.TaskStackBuilder.create(android.content.Context)
+BuilderSetStyle: androidx.core.app.TaskStackBuilder#editIntentAt(int):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.core.app.TaskStackBuilder.editIntentAt(int)
+BuilderSetStyle: androidx.core.app.TaskStackBuilder#startActivities():
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.core.app.TaskStackBuilder.startActivities()
+BuilderSetStyle: androidx.core.app.TaskStackBuilder#startActivities(android.os.Bundle):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.core.app.TaskStackBuilder.startActivities(android.os.Bundle)
+BuilderSetStyle: androidx.core.text.BidiFormatter.Builder#stereoReset(boolean):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.core.text.BidiFormatter.Builder.stereoReset(boolean)
+
+
 ContextFirst: androidx.core.view.LayoutInflaterFactory#onCreateView(android.view.View, String, android.content.Context, android.util.AttributeSet) parameter #2:
     Context is distinct, so it must be the first argument (method `onCreateView`)
 ContextFirst: androidx.core.view.ViewConfigurationCompat#getScaledHorizontalScrollFactor(android.view.ViewConfiguration, android.content.Context) parameter #1:
@@ -2091,6 +2115,14 @@
     Provide an explicit copy constructor instead of implementing `clone()`
 
 
+OptionalBuilderConstructorAgrument: androidx.core.app.NotificationCompat.Action.Builder#Builder(androidx.core.graphics.drawable.IconCompat, CharSequence, android.app.PendingIntent) parameter #0:
+    Builder constructor arguments must be mandatory (i.e. not @Nullable): parameter icon in androidx.core.app.NotificationCompat.Action.Builder(androidx.core.graphics.drawable.IconCompat icon, CharSequence title, android.app.PendingIntent intent)
+OptionalBuilderConstructorAgrument: androidx.core.app.NotificationCompat.Action.Builder#Builder(androidx.core.graphics.drawable.IconCompat, CharSequence, android.app.PendingIntent) parameter #1:
+    Builder constructor arguments must be mandatory (i.e. not @Nullable): parameter title in androidx.core.app.NotificationCompat.Action.Builder(androidx.core.graphics.drawable.IconCompat icon, CharSequence title, android.app.PendingIntent intent)
+OptionalBuilderConstructorAgrument: androidx.core.app.NotificationCompat.Action.Builder#Builder(androidx.core.graphics.drawable.IconCompat, CharSequence, android.app.PendingIntent) parameter #2:
+    Builder constructor arguments must be mandatory (i.e. not @Nullable): parameter intent in androidx.core.app.NotificationCompat.Action.Builder(androidx.core.graphics.drawable.IconCompat icon, CharSequence title, android.app.PendingIntent intent)
+
+
 PairedRegistration: androidx.core.view.OneShotPreDrawListener#removeListener():
     Found removeListener but not addListener in androidx.core.view.OneShotPreDrawListener
 
diff --git a/core/core/api/current.txt b/core/core/api/current.txt
index 31d0479..b8644ee 100644
--- a/core/core/api/current.txt
+++ b/core/core/api/current.txt
@@ -3069,6 +3069,15 @@
     method public static void showAsDropDown(android.widget.PopupWindow, android.view.View, int, int, int);
   }
 
+  public abstract class RichContentReceiverCompat<T extends android.view.View> {
+    ctor public RichContentReceiverCompat();
+    method public abstract java.util.Set<java.lang.String!> getSupportedMimeTypes();
+    method public abstract boolean onReceive(T, android.content.ClipData, int, int);
+    field public static final int FLAG_CONVERT_TO_PLAIN_TEXT = 1; // 0x1
+    field public static final int SOURCE_CLIPBOARD = 0; // 0x0
+    field public static final int SOURCE_INPUT_METHOD = 1; // 0x1
+  }
+
   @Deprecated public final class ScrollerCompat {
     method @Deprecated public void abortAnimation();
     method @Deprecated public boolean computeScrollOffset();
@@ -3123,6 +3132,12 @@
     field public static final int AUTO_SIZE_TEXT_TYPE_UNIFORM = 1; // 0x1
   }
 
+  public abstract class TextViewRichContentReceiverCompat extends androidx.core.widget.RichContentReceiverCompat<android.widget.TextView> {
+    ctor public TextViewRichContentReceiverCompat();
+    method public java.util.Set<java.lang.String!> getSupportedMimeTypes();
+    method public boolean onReceive(android.widget.TextView, android.content.ClipData, int, int);
+  }
+
   public interface TintableCompoundButton {
     method public android.content.res.ColorStateList? getSupportButtonTintList();
     method public android.graphics.PorterDuff.Mode? getSupportButtonTintMode();
diff --git a/core/core/api/public_plus_experimental_1.4.0-alpha01.txt b/core/core/api/public_plus_experimental_1.4.0-alpha01.txt
index b387d11..092bfc2 100644
--- a/core/core/api/public_plus_experimental_1.4.0-alpha01.txt
+++ b/core/core/api/public_plus_experimental_1.4.0-alpha01.txt
@@ -3067,6 +3067,15 @@
     method public static void showAsDropDown(android.widget.PopupWindow, android.view.View, int, int, int);
   }
 
+  public abstract class RichContentReceiverCompat<T extends android.view.View> {
+    ctor public RichContentReceiverCompat();
+    method public abstract java.util.Set<java.lang.String!> getSupportedMimeTypes();
+    method public abstract boolean onReceive(T, android.content.ClipData, int, int);
+    field public static final int FLAG_CONVERT_TO_PLAIN_TEXT = 1; // 0x1
+    field public static final int SOURCE_CLIPBOARD = 0; // 0x0
+    field public static final int SOURCE_INPUT_METHOD = 1; // 0x1
+  }
+
   @Deprecated public final class ScrollerCompat {
     method @Deprecated public void abortAnimation();
     method @Deprecated public boolean computeScrollOffset();
@@ -3121,6 +3130,12 @@
     field public static final int AUTO_SIZE_TEXT_TYPE_UNIFORM = 1; // 0x1
   }
 
+  public abstract class TextViewRichContentReceiverCompat extends androidx.core.widget.RichContentReceiverCompat<android.widget.TextView> {
+    ctor public TextViewRichContentReceiverCompat();
+    method public java.util.Set<java.lang.String!> getSupportedMimeTypes();
+    method public boolean onReceive(android.widget.TextView, android.content.ClipData, int, int);
+  }
+
   public interface TintableCompoundButton {
     method public android.content.res.ColorStateList? getSupportButtonTintList();
     method public android.graphics.PorterDuff.Mode? getSupportButtonTintMode();
diff --git a/core/core/api/public_plus_experimental_current.txt b/core/core/api/public_plus_experimental_current.txt
index b387d11..092bfc2 100644
--- a/core/core/api/public_plus_experimental_current.txt
+++ b/core/core/api/public_plus_experimental_current.txt
@@ -3067,6 +3067,15 @@
     method public static void showAsDropDown(android.widget.PopupWindow, android.view.View, int, int, int);
   }
 
+  public abstract class RichContentReceiverCompat<T extends android.view.View> {
+    ctor public RichContentReceiverCompat();
+    method public abstract java.util.Set<java.lang.String!> getSupportedMimeTypes();
+    method public abstract boolean onReceive(T, android.content.ClipData, int, int);
+    field public static final int FLAG_CONVERT_TO_PLAIN_TEXT = 1; // 0x1
+    field public static final int SOURCE_CLIPBOARD = 0; // 0x0
+    field public static final int SOURCE_INPUT_METHOD = 1; // 0x1
+  }
+
   @Deprecated public final class ScrollerCompat {
     method @Deprecated public void abortAnimation();
     method @Deprecated public boolean computeScrollOffset();
@@ -3121,6 +3130,12 @@
     field public static final int AUTO_SIZE_TEXT_TYPE_UNIFORM = 1; // 0x1
   }
 
+  public abstract class TextViewRichContentReceiverCompat extends androidx.core.widget.RichContentReceiverCompat<android.widget.TextView> {
+    ctor public TextViewRichContentReceiverCompat();
+    method public java.util.Set<java.lang.String!> getSupportedMimeTypes();
+    method public boolean onReceive(android.widget.TextView, android.content.ClipData, int, int);
+  }
+
   public interface TintableCompoundButton {
     method public android.content.res.ColorStateList? getSupportButtonTintList();
     method public android.graphics.PorterDuff.Mode? getSupportButtonTintMode();
diff --git a/core/core/api/restricted_1.4.0-alpha01.txt b/core/core/api/restricted_1.4.0-alpha01.txt
index 88d2713..7b3106b 100644
--- a/core/core/api/restricted_1.4.0-alpha01.txt
+++ b/core/core/api/restricted_1.4.0-alpha01.txt
@@ -3491,6 +3491,17 @@
     method public static void showAsDropDown(android.widget.PopupWindow, android.view.View, int, int, int);
   }
 
+  public abstract class RichContentReceiverCompat<T extends android.view.View> {
+    ctor public RichContentReceiverCompat();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final androidx.core.view.inputmethod.InputConnectionCompat.OnCommitContentListener buildOnCommitContentListener(T);
+    method public abstract java.util.Set<java.lang.String!> getSupportedMimeTypes();
+    method public abstract boolean onReceive(T, android.content.ClipData, int, int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final void populateEditorInfoContentMimeTypes(android.view.inputmethod.InputConnection?, android.view.inputmethod.EditorInfo?);
+    field public static final int FLAG_CONVERT_TO_PLAIN_TEXT = 1; // 0x1
+    field public static final int SOURCE_CLIPBOARD = 0; // 0x0
+    field public static final int SOURCE_INPUT_METHOD = 1; // 0x1
+  }
+
   @Deprecated public final class ScrollerCompat {
     method @Deprecated public void abortAnimation();
     method @Deprecated public boolean computeScrollOffset();
@@ -3549,6 +3560,12 @@
   @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 abstract class TextViewRichContentReceiverCompat extends androidx.core.widget.RichContentReceiverCompat<android.widget.TextView> {
+    ctor public TextViewRichContentReceiverCompat();
+    method public java.util.Set<java.lang.String!> getSupportedMimeTypes();
+    method public boolean onReceive(android.widget.TextView, android.content.ClipData, int, int);
+  }
+
   public interface TintableCompoundButton {
     method public android.content.res.ColorStateList? getSupportButtonTintList();
     method public android.graphics.PorterDuff.Mode? getSupportButtonTintMode();
diff --git a/core/core/api/restricted_current.txt b/core/core/api/restricted_current.txt
index 88d2713..7b3106b 100644
--- a/core/core/api/restricted_current.txt
+++ b/core/core/api/restricted_current.txt
@@ -3491,6 +3491,17 @@
     method public static void showAsDropDown(android.widget.PopupWindow, android.view.View, int, int, int);
   }
 
+  public abstract class RichContentReceiverCompat<T extends android.view.View> {
+    ctor public RichContentReceiverCompat();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final androidx.core.view.inputmethod.InputConnectionCompat.OnCommitContentListener buildOnCommitContentListener(T);
+    method public abstract java.util.Set<java.lang.String!> getSupportedMimeTypes();
+    method public abstract boolean onReceive(T, android.content.ClipData, int, int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final void populateEditorInfoContentMimeTypes(android.view.inputmethod.InputConnection?, android.view.inputmethod.EditorInfo?);
+    field public static final int FLAG_CONVERT_TO_PLAIN_TEXT = 1; // 0x1
+    field public static final int SOURCE_CLIPBOARD = 0; // 0x0
+    field public static final int SOURCE_INPUT_METHOD = 1; // 0x1
+  }
+
   @Deprecated public final class ScrollerCompat {
     method @Deprecated public void abortAnimation();
     method @Deprecated public boolean computeScrollOffset();
@@ -3549,6 +3560,12 @@
   @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 abstract class TextViewRichContentReceiverCompat extends androidx.core.widget.RichContentReceiverCompat<android.widget.TextView> {
+    ctor public TextViewRichContentReceiverCompat();
+    method public java.util.Set<java.lang.String!> getSupportedMimeTypes();
+    method public boolean onReceive(android.widget.TextView, android.content.ClipData, int, int);
+  }
+
   public interface TintableCompoundButton {
     method public android.content.res.ColorStateList? getSupportButtonTintList();
     method public android.graphics.PorterDuff.Mode? getSupportButtonTintMode();
diff --git a/core/core/src/androidTest/AndroidManifest.xml b/core/core/src/androidTest/AndroidManifest.xml
index b71482b..eebdc4d 100644
--- a/core/core/src/androidTest/AndroidManifest.xml
+++ b/core/core/src/androidTest/AndroidManifest.xml
@@ -34,6 +34,8 @@
 
         <activity android:name="androidx.core.widget.TextViewTestActivity"/>
 
+        <activity android:name="androidx.core.widget.RichContentReceiverTestActivity"/>
+
         <activity android:name="androidx.core.widget.TestContentViewActivity"/>
 
         <activity android:name="androidx.core.view.VpaActivity"/>
diff --git a/core/core/src/androidTest/java/androidx/core/app/ActivityCompatTest.java b/core/core/src/androidTest/java/androidx/core/app/ActivityCompatTest.java
index 61e47ef..46f071a 100644
--- a/core/core/src/androidTest/java/androidx/core/app/ActivityCompatTest.java
+++ b/core/core/src/androidTest/java/androidx/core/app/ActivityCompatTest.java
@@ -16,6 +16,8 @@
 
 package androidx.core.app;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.junit.Assert.assertSame;
 import static org.mockito.AdditionalMatchers.aryEq;
 import static org.mockito.ArgumentMatchers.eq;
@@ -37,6 +39,8 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.Arrays;
+
 @RunWith(AndroidJUnit4.class)
 @LargeTest
 public class ActivityCompatTest extends BaseInstrumentationTestCase<TestActivity> {
@@ -71,6 +75,32 @@
     }
 
     @Test
+    public void testPermissionNull() {
+        Activity activity = mActivityTestRule.getActivity();
+        String[] permissions = new String[]{null};
+
+        try {
+            ActivityCompat.requestPermissions(activity, permissions, 42);
+        } catch (IllegalArgumentException e) {
+            assertThat(e).hasMessageThat().contains("Permission request for permissions "
+                    + Arrays.toString(permissions) + " must not contain null or empty values");
+        }
+    }
+
+    @Test
+    public void testPermissionEmpty() {
+        Activity activity = mActivityTestRule.getActivity();
+        String[] permissions = new String[]{Manifest.permission.ACCESS_FINE_LOCATION, ""};
+
+        try {
+            ActivityCompat.requestPermissions(activity, permissions, 42);
+        } catch (IllegalArgumentException e) {
+            assertThat(e).hasMessageThat().contains("Permission request for permissions "
+                    + Arrays.toString(permissions) + " must not contain null or empty values");
+        }
+    }
+
+    @Test
     public void testRequireViewByIdFound() {
         View view = getActivity().findViewById(R.id.view);
         assertSame(view, ActivityCompat.requireViewById(getActivity(), R.id.view));
diff --git a/core/core/src/androidTest/java/androidx/core/widget/RichContentReceiverCompatTest.java b/core/core/src/androidTest/java/androidx/core/widget/RichContentReceiverCompatTest.java
new file mode 100644
index 0000000..6310271
--- /dev/null
+++ b/core/core/src/androidTest/java/androidx/core/widget/RichContentReceiverCompatTest.java
@@ -0,0 +1,308 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.core.widget;
+
+import static androidx.core.widget.RichContentReceiverCompat.FLAG_CONVERT_TO_PLAIN_TEXT;
+import static androidx.core.widget.RichContentReceiverCompat.SOURCE_CLIPBOARD;
+import static androidx.core.widget.RichContentReceiverCompat.SOURCE_INPUT_METHOD;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static java.util.Collections.singleton;
+
+import android.content.ClipData;
+import android.net.Uri;
+import android.text.Selection;
+import android.text.SpannableStringBuilder;
+import android.text.Spanned;
+import android.text.style.UnderlineSpan;
+import android.view.inputmethod.BaseInputConnection;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputConnection;
+import android.widget.EditText;
+import android.widget.TextView;
+
+import androidx.core.test.R;
+import androidx.core.view.inputmethod.EditorInfoCompat;
+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.rule.ActivityTestRule;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@MediumTest
+@RunWith(AndroidJUnit4.class)
+public class RichContentReceiverCompatTest {
+
+    @Rule
+    public final ActivityTestRule<RichContentReceiverTestActivity> mActivityTestRule =
+            new ActivityTestRule<>(RichContentReceiverTestActivity.class);
+
+    private EditText mEditText;
+    private RichContentReceiverCompat<TextView> mReceiver;
+
+    @Before
+    public void before() {
+        RichContentReceiverTestActivity activity = mActivityTestRule.getActivity();
+        mEditText = activity.findViewById(R.id.edit_text_for_rich_content_receiver);
+        mReceiver = new TextViewRichContentReceiverCompat() {};
+    }
+
+    @UiThreadTest
+    @Test
+    public void testGetSupportedMimeTypes() throws Exception {
+        assertThat(mReceiver.getSupportedMimeTypes()).isEqualTo(singleton("text/*"));
+    }
+
+    @UiThreadTest
+    @Test
+    public void testOnReceive_text() throws Exception {
+        setTextAndCursor("xz", 1);
+
+        ClipData clip = ClipData.newPlainText("test", "y");
+        boolean result = onReceive(mReceiver, clip, SOURCE_CLIPBOARD, 0);
+
+        assertThat(result).isTrue();
+        assertTextAndCursorPosition("xyz", 2);
+    }
+
+    @UiThreadTest
+    @Test
+    public void testOnReceive_styledText() throws Exception {
+        setTextAndCursor("xz", 1);
+
+        UnderlineSpan underlineSpan = new UnderlineSpan();
+        SpannableStringBuilder ssb = new SpannableStringBuilder("hi world");
+        ssb.setSpan(underlineSpan, 3, 7, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+        ClipData clip = ClipData.newPlainText("test", ssb);
+
+        boolean result = onReceive(mReceiver, clip, SOURCE_CLIPBOARD, 0);
+
+        assertThat(result).isTrue();
+        assertTextAndCursorPosition("xhi worldz", 9);
+        int spanStart = mEditText.getText().getSpanStart(underlineSpan);
+        assertThat(spanStart).isEqualTo(4);
+    }
+
+    @UiThreadTest
+    @Test
+    public void testOnReceive_text_convertToPlainText() throws Exception {
+        setTextAndCursor("xz", 1);
+
+        ClipData clip = ClipData.newPlainText("test", "y");
+        boolean result = onReceive(mReceiver, clip, SOURCE_CLIPBOARD, FLAG_CONVERT_TO_PLAIN_TEXT);
+
+        assertThat(result).isTrue();
+        assertTextAndCursorPosition("xyz", 2);
+    }
+
+    @UiThreadTest
+    @Test
+    public void testOnReceive_styledText_convertToPlainText() throws Exception {
+        setTextAndCursor("xz", 1);
+
+        UnderlineSpan underlineSpan = new UnderlineSpan();
+        SpannableStringBuilder ssb = new SpannableStringBuilder("hi world");
+        ssb.setSpan(underlineSpan, 3, 7, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+        ClipData clip = ClipData.newPlainText("test", ssb);
+
+        boolean result = onReceive(mReceiver, clip, SOURCE_CLIPBOARD, FLAG_CONVERT_TO_PLAIN_TEXT);
+
+        assertThat(result).isTrue();
+        assertTextAndCursorPosition("xhi worldz", 9);
+        int spanStart = mEditText.getText().getSpanStart(underlineSpan);
+        assertThat(spanStart).isEqualTo(-1);
+    }
+
+    @SdkSuppress(minSdkVersion = 16) // Passing HTML into a ClipData.Item was added in SDK 16.
+    @UiThreadTest
+    @Test
+    public void testOnReceive_html() throws Exception {
+        setTextAndCursor("xz", 1);
+
+        ClipData clip = ClipData.newHtmlText("test", "*y*", "<b>y</b>");
+        boolean result = onReceive(mReceiver, clip, SOURCE_CLIPBOARD, 0);
+
+        assertThat(result).isTrue();
+        assertTextAndCursorPosition("xyz", 2);
+    }
+
+    @SdkSuppress(minSdkVersion = 16) // Passing HTML into a ClipData.Item was added in SDK 16.
+    @UiThreadTest
+    @Test
+    public void testOnReceive_html_convertToPlainText() throws Exception {
+        setTextAndCursor("xz", 1);
+
+        ClipData clip = ClipData.newHtmlText("test", "*y*", "<b>y</b>");
+        boolean result = onReceive(mReceiver, clip, SOURCE_CLIPBOARD, FLAG_CONVERT_TO_PLAIN_TEXT);
+
+        assertThat(result).isTrue();
+        assertTextAndCursorPosition("x*y*z", 4);
+    }
+
+    @UiThreadTest
+    @Test
+    public void testOnReceive_multipleItemsInClipData() throws Exception {
+        setTextAndCursor("xz", 1);
+
+        ClipData clip = ClipData.newPlainText("test", "ONE");
+        clip.addItem(new ClipData.Item("TWO"));
+        clip.addItem(new ClipData.Item("THREE"));
+        boolean result = onReceive(mReceiver, clip, SOURCE_CLIPBOARD, 0);
+
+        assertThat(result).isTrue();
+        assertTextAndCursorPosition("xONE\nTWO\nTHREEz", 14);
+    }
+
+    @UiThreadTest
+    @Test
+    public void testOnReceive_noSelectionPriorToPaste() throws Exception {
+        // Set the text and then clear the selection (ie, ensure that nothing is selected and
+        // that the cursor is not present).
+        setTextAndCursor("xz", 0);
+        Selection.removeSelection(mEditText.getText());
+        assertTextAndCursorPosition("xz", -1);
+
+        // Pasting should still work (should just insert the text at the beginning).
+        ClipData clip = ClipData.newPlainText("test", "y");
+        boolean result = onReceive(mReceiver, clip, SOURCE_CLIPBOARD, 0);
+
+        assertThat(result).isTrue();
+        assertTextAndCursorPosition("yxz", 1);
+    }
+
+    @UiThreadTest
+    @Test
+    public void testOnReceive_selectionStartAndEndSwapped() throws Exception {
+        // Set the text and then set the selection such that "end" is before "start".
+        setTextAndCursor("hey", 0);
+        Selection.setSelection(mEditText.getText(), 3, 1);
+        assertTextAndSelection("hey", 3, 1);
+
+        // Pasting should still work (should still successfully overwrite the selection).
+        ClipData clip = ClipData.newPlainText("test", "i");
+        boolean result = onReceive(mReceiver, clip, SOURCE_CLIPBOARD, 0);
+
+        assertThat(result).isTrue();
+        assertTextAndCursorPosition("hi", 2);
+    }
+
+    @SdkSuppress(minSdkVersion = 16) // Passing HTML into a ClipData.Item was added in SDK 16.
+    @UiThreadTest
+    @Test
+    public void testOnReceive_unsupportedMimeType_viaMenu() throws Exception {
+        setTextAndCursor("xz", 1);
+
+        ClipData clip = new ClipData("test", new String[]{"video/mp4"},
+                new ClipData.Item("text", "html", null, Uri.parse("content://com.example/path")));
+        boolean result = onReceive(mReceiver, clip, SOURCE_CLIPBOARD, 0);
+
+        assertThat(result).isTrue();
+        assertTextAndCursorPosition("xhtmlz", 5);
+    }
+
+    @SdkSuppress(minSdkVersion = 16) // Passing HTML into a ClipData.Item was added in SDK 16.
+    @UiThreadTest
+    @Test
+    public void testOnReceive_unsupportedMimeType_viaMenu_convertToPlainText() throws Exception {
+        setTextAndCursor("xz", 1);
+
+        ClipData clip = new ClipData("test", new String[]{"video/mp4"},
+                new ClipData.Item("text", "html", null, Uri.parse("content://com.example/path")));
+        boolean result = onReceive(mReceiver, clip, SOURCE_CLIPBOARD, FLAG_CONVERT_TO_PLAIN_TEXT);
+
+        assertThat(result).isTrue();
+        assertTextAndCursorPosition("xtextz", 5);
+    }
+
+    @UiThreadTest
+    @Test
+    public void testOnReceive_unsupportedMimeType_viaInputMethod() throws Exception {
+        setTextAndCursor("xz", 1);
+
+        ClipData clip = new ClipData("test", new String[]{"video/mp4"},
+                new ClipData.Item("text", null, Uri.parse("content://com.example/path")));
+        boolean result = onReceive(mReceiver, clip, SOURCE_INPUT_METHOD, 0);
+
+        assertThat(result).isFalse();
+        assertTextAndCursorPosition("xz", 1);
+    }
+
+    @UiThreadTest
+    @Test
+    public void testPopulateEditorInfoContentMimeTypes() throws Exception {
+        InputConnection ic = new BaseInputConnection(mEditText, true);
+        EditorInfo outAttrs = new EditorInfo();
+
+        // The field contentMimeTypes in outAttrs should be set to the MIME types of the receiver.
+        mReceiver.populateEditorInfoContentMimeTypes(ic, outAttrs);
+        assertThat(EditorInfoCompat.getContentMimeTypes(outAttrs)).isEqualTo(
+                new String[] {"text/*"});
+
+        // If the field contentMimeTypes in outAttrs already has a value assigned, it should be
+        // overwritten with the MIME types of the receiver.
+        EditorInfoCompat.setContentMimeTypes(outAttrs, new String[] {"video/mp4"});
+        mReceiver.populateEditorInfoContentMimeTypes(ic, outAttrs);
+        assertThat(EditorInfoCompat.getContentMimeTypes(outAttrs)).isEqualTo(
+                new String[] {"text/*"});
+    }
+
+    @UiThreadTest
+    @Test
+    public void testPopulateEditorInfoContentMimeTypes_nulls() throws Exception {
+        InputConnection ic = new BaseInputConnection(mEditText, true);
+        EditorInfo outAttrs = new EditorInfo();
+
+        // If the ic arg is null, outAttrs should not be populated.
+        mReceiver.populateEditorInfoContentMimeTypes(null, outAttrs);
+        assertThat(EditorInfoCompat.getContentMimeTypes(outAttrs)).isEqualTo(new String[0]);
+
+        // If the outAttrs arg is null, it should not be populated.
+        mReceiver.populateEditorInfoContentMimeTypes(ic, null);
+        assertThat(EditorInfoCompat.getContentMimeTypes(outAttrs)).isEqualTo(new String[0]);
+    }
+
+    private boolean onReceive(final RichContentReceiverCompat<TextView> receiver,
+            final ClipData clip, @RichContentReceiverCompat.Source final int source,
+            final int flags) {
+        return receiver.onReceive(mEditText, clip, source, flags);
+    }
+
+    private void setTextAndCursor(final String text, final int cursorPosition) {
+        mEditText.requestFocus();
+        SpannableStringBuilder ssb = new SpannableStringBuilder(text);
+        mEditText.setText(ssb);
+        mEditText.setSelection(cursorPosition);
+        assertThat(mEditText.hasFocus()).isTrue();
+        assertTextAndCursorPosition(text, cursorPosition);
+    }
+
+    private void assertTextAndCursorPosition(String expectedText, int cursorPosition) {
+        assertTextAndSelection(expectedText, cursorPosition, cursorPosition);
+    }
+
+    private void assertTextAndSelection(String expectedText, int start, int end) {
+        assertThat(mEditText.getText().toString()).isEqualTo(expectedText);
+        assertThat(mEditText.getSelectionStart()).isEqualTo(start);
+        assertThat(mEditText.getSelectionEnd()).isEqualTo(end);
+    }
+}
diff --git a/core/core/src/androidTest/java/androidx/core/widget/RichContentReceiverTestActivity.java b/core/core/src/androidTest/java/androidx/core/widget/RichContentReceiverTestActivity.java
new file mode 100644
index 0000000..83a6ba0
--- /dev/null
+++ b/core/core/src/androidTest/java/androidx/core/widget/RichContentReceiverTestActivity.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.core.widget;
+
+import android.support.v4.BaseTestActivity;
+
+import androidx.core.test.R;
+
+public class RichContentReceiverTestActivity extends BaseTestActivity {
+    @Override
+    protected int getContentViewLayoutResId() {
+        return R.layout.rich_content_receiver_activity;
+    }
+}
diff --git a/core/core/src/androidTest/res/layout/rich_content_receiver_activity.xml b/core/core/src/androidTest/res/layout/rich_content_receiver_activity.xml
new file mode 100644
index 0000000..81b6479
--- /dev/null
+++ b/core/core/src/androidTest/res/layout/rich_content_receiver_activity.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2020 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/content"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <EditText
+        android:id="@+id/edit_text_for_rich_content_receiver"
+        android:layout_width="200dip"
+        android:layout_height="60dip" />
+</FrameLayout>
diff --git a/core/core/src/main/java/androidx/core/app/ActivityCompat.java b/core/core/src/main/java/androidx/core/app/ActivityCompat.java
index 523f70d..ae5d7ee 100644
--- a/core/core/src/main/java/androidx/core/app/ActivityCompat.java
+++ b/core/core/src/main/java/androidx/core/app/ActivityCompat.java
@@ -29,6 +29,7 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Parcelable;
+import android.text.TextUtils;
 import android.view.DragEvent;
 import android.view.View;
 
@@ -41,6 +42,7 @@
 import androidx.core.content.ContextCompat;
 import androidx.core.view.DragAndDropPermissionsCompat;
 
+import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 
@@ -494,6 +496,13 @@
             return;
         }
 
+        for (String permission : permissions) {
+            if (TextUtils.isEmpty(permission)) {
+                throw new IllegalArgumentException("Permission request for permissions "
+                        + Arrays.toString(permissions) + " must not contain null or empty values");
+            }
+        }
+
         if (Build.VERSION.SDK_INT >= 23) {
             if (activity instanceof RequestPermissionsRequestCodeValidator) {
                 ((RequestPermissionsRequestCodeValidator) activity)
diff --git a/core/core/src/main/java/androidx/core/widget/RichContentReceiverCompat.java b/core/core/src/main/java/androidx/core/widget/RichContentReceiverCompat.java
new file mode 100644
index 0000000..2a66954
--- /dev/null
+++ b/core/core/src/main/java/androidx/core/widget/RichContentReceiverCompat.java
@@ -0,0 +1,223 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.core.widget;
+
+import android.content.ClipData;
+import android.content.ClipDescription;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputConnection;
+
+import androidx.annotation.IntDef;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RestrictTo;
+import androidx.core.view.inputmethod.EditorInfoCompat;
+import androidx.core.view.inputmethod.InputConnectionCompat;
+import androidx.core.view.inputmethod.InputContentInfoCompat;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Set;
+
+/**
+ * Callback for apps to implement handling for insertion of rich content. "Rich content" here refers
+ * to both text and non-text content: plain text, styled text, HTML, images, videos, audio files,
+ * etc.
+ *
+ * <p>This callback can be attached to different types of UI components. For editable
+ * {@link android.widget.TextView} components, implementations should typically extend from
+ * {@link TextViewRichContentReceiverCompat}.
+ *
+ * <p>Example implementation:<br>
+ * <pre class="prettyprint">
+ *   public class MyRichContentReceiver extends TextViewRichContentReceiverCompat {
+ *
+ *       private static final Set&lt;String&gt; SUPPORTED_MIME_TYPES = Collections.unmodifiableSet(
+ *           Set.of("text/*", "image/gif", "image/png", "image/jpg"));
+ *
+ *       &#64;NonNull
+ *       &#64;Override
+ *       public Set&lt;String&gt; getSupportedMimeTypes() {
+ *           return SUPPORTED_MIME_TYPES;
+ *       }
+ *
+ *       &#64;Override
+ *       public boolean onReceive(@NonNull TextView textView, @NonNull ClipData clip,
+ *               int source, int flags) {
+ *         if (clip.getDescription().hasMimeType("image/*")) {
+ *             return receiveImage(textView, clip);
+ *         }
+ *         return super.onReceive(textView, clip, source);
+ *       }
+ *
+ *       private boolean receiveImage(@NonNull TextView textView, @NonNull ClipData clip) {
+ *           // ... app-specific logic to handle the content URI in the clip ...
+ *       }
+ *   }
+ * </pre>
+ *
+ * @param <T> The type of {@link View} with which this receiver can be associated.
+ */
+public abstract class RichContentReceiverCompat<T extends View> {
+    private static final String TAG = "RichContentReceiver";
+
+    /**
+     * Specifies the UI through which content is being inserted.
+     */
+    @IntDef(value = {SOURCE_CLIPBOARD, SOURCE_INPUT_METHOD})
+    @Retention(RetentionPolicy.SOURCE)
+    @interface Source {}
+
+    /**
+     * Specifies that the operation was triggered by a paste from the clipboard (e.g. "Paste" or
+     * "Paste as plain text" action in the insertion/selection menu).
+     */
+    public static final int SOURCE_CLIPBOARD = 0;
+
+    /**
+     * Specifies that the operation was triggered from the soft keyboard (also known as input method
+     * editor or IME). See https://developer.android.com/guide/topics/text/image-keyboard for more
+     * info.
+     */
+    public static final int SOURCE_INPUT_METHOD = 1;
+
+    /**
+     * Flags to configure the insertion behavior.
+     */
+    @IntDef(flag = true, value = {FLAG_CONVERT_TO_PLAIN_TEXT})
+    @Retention(RetentionPolicy.SOURCE)
+    @interface Flags {}
+
+    /**
+     * Flag for {@link #onReceive} requesting that the content should be converted to plain text
+     * prior to inserting.
+     */
+    public static final int FLAG_CONVERT_TO_PLAIN_TEXT = 1 << 0;
+
+    /**
+     * Insert the given clip.
+     *
+     * <p>For a UI component where this callback is set, this function will be invoked in the
+     * following scenarios:
+     * <ol>
+     *     <li>Paste from the clipboard (e.g. "Paste" or "Paste as plain text" action in the
+     *     insertion/selection menu)
+     *     <li>Content insertion from the keyboard ({@link InputConnection#commitContent})
+     * </ol>
+     *
+     * <p>For text, if the view has a selection, the selection should be overwritten by the
+     * clip; if there's no selection, this method should insert the content at the current
+     * cursor position.
+     *
+     * <p>For rich content (e.g. an image), this function may insert the content inline, or it may
+     * add the content as an attachment (could potentially go into a completely separate view).
+     *
+     * <p>This function may be invoked with a clip whose MIME type is not in the list of supported
+     * types returned by {@link #getSupportedMimeTypes()}. This provides the opportunity to
+     * implement custom fallback logic if desired.
+     *
+     * @param view   The view where the content insertion was requested.
+     * @param clip   The clip to insert.
+     * @param source The trigger of the operation.
+     * @param flags  Optional flags to configure the insertion behavior. Use 0 for default
+     *               behavior. See {@code FLAG_} constants on this class for other options.
+     * @return Returns true if the clip was inserted.
+     */
+    public abstract boolean onReceive(@NonNull T view, @NonNull ClipData clip, @Source int source,
+            @Flags int flags);
+
+    /**
+     * Returns the MIME types that can be handled by this callback.
+     *
+     * <p>Different platform features (e.g. pasting from the clipboard, inserting stickers from the
+     * keyboard, etc) may use this function to conditionally alter their behavior. For example, the
+     * keyboard may choose to hide its UI for inserting GIFs if the input field that has focus has
+     * a {@link RichContentReceiverCompat} set and the MIME types returned from this function
+     * don't include "image/gif".
+     *
+     * @return An immutable set with the MIME types supported by this callback. The returned
+     * MIME types may contain wildcards such as "text/*", "image/*", etc.
+     */
+    @NonNull
+    public abstract Set<String> getSupportedMimeTypes();
+
+    /**
+     * Returns true if the MIME type of the given clip is {@link #getSupportedMimeTypes() supported}
+     * by this receiver.
+     *
+     * @hide
+     */
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
+    public final boolean supports(@NonNull ClipDescription description) {
+        for (String supportedMimeType : getSupportedMimeTypes()) {
+            if (description.hasMimeType(supportedMimeType)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Populates {@code outAttrs.contentMimeTypes} with the supported MIME types of this receiver.
+     *
+     * @hide
+     */
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
+    public final void populateEditorInfoContentMimeTypes(@Nullable InputConnection ic,
+            @Nullable EditorInfo outAttrs) {
+        if (ic == null || outAttrs == null) {
+            return;
+        }
+        String[] mimeTypes = getSupportedMimeTypes().toArray(new String[0]);
+        EditorInfoCompat.setContentMimeTypes(outAttrs, mimeTypes);
+    }
+
+    /**
+     * Creates an {@link InputConnectionCompat.OnCommitContentListener} that uses this receiver
+     * to insert content. The object returned by this function should be passed to
+     * {@link InputConnectionCompat#createWrapper} when creating the {@link InputConnection} in
+     * {@link View#onCreateInputConnection}.
+     *
+     * @hide
+     */
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
+    @NonNull
+    public final InputConnectionCompat.OnCommitContentListener buildOnCommitContentListener(
+            @NonNull final T view) {
+        return new InputConnectionCompat.OnCommitContentListener() {
+            @Override
+            public boolean onCommitContent(InputContentInfoCompat content, int flags,
+                    Bundle opts) {
+                ClipDescription description = content.getDescription();
+                if ((flags & InputConnectionCompat.INPUT_CONTENT_GRANT_READ_URI_PERMISSION) != 0) {
+                    try {
+                        content.requestPermission();
+                    } catch (Exception e) {
+                        Log.w(TAG, "Can't insert from IME; requestPermission() failed: " + e);
+                        return false; // Can't insert the content if we don't have permission
+                    }
+                }
+                ClipData clip = new ClipData(description,
+                        new ClipData.Item(content.getContentUri()));
+                return onReceive(view, clip, SOURCE_INPUT_METHOD, 0);
+            }
+        };
+    }
+}
diff --git a/core/core/src/main/java/androidx/core/widget/TextViewRichContentReceiverCompat.java b/core/core/src/main/java/androidx/core/widget/TextViewRichContentReceiverCompat.java
new file mode 100644
index 0000000..31c51b1
--- /dev/null
+++ b/core/core/src/main/java/androidx/core/widget/TextViewRichContentReceiverCompat.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.core.widget;
+
+import android.content.ClipData;
+import android.content.Context;
+import android.os.Build;
+import android.text.Editable;
+import android.text.Selection;
+import android.text.Spanned;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * Base implementation of {@link RichContentReceiverCompat} for editable {@link TextView}
+ * components.
+ *
+ * <p>This class handles insertion of text (plain text, styled text, HTML, etc) but not images or
+ * other rich content. It should be used as a base class when implementing a custom
+ * {@link RichContentReceiverCompat}, to provide consistent behavior for insertion of text while
+ * implementing custom behavior for insertion of other content (images, etc).
+ *
+ * <p>See {@link RichContentReceiverCompat} for an example of how to implement a custom receiver.
+ */
+public abstract class TextViewRichContentReceiverCompat extends
+        RichContentReceiverCompat<TextView> {
+
+    private static final Set<String> MIME_TYPES_ALL_TEXT = Collections.singleton("text/*");
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    @NonNull
+    public Set<String> getSupportedMimeTypes() {
+        return MIME_TYPES_ALL_TEXT;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean onReceive(@NonNull TextView textView, @NonNull ClipData clip,
+            @Source int source, @Flags int flags) {
+        if (source == SOURCE_INPUT_METHOD && !supports(clip.getDescription())) {
+            return false;
+        }
+
+        // The code here follows the platform logic in TextView:
+        // https://cs.android.com/android/_/android/platform/frameworks/base/+/9fefb65aa9e7beae9ca8306b925b9fbfaeffecc9:core/java/android/widget/TextView.java;l=12644
+        // In particular, multiple items within the given ClipData will trigger separate calls to
+        // replace/insert. This is to preserve the platform behavior with respect to TextWatcher
+        // notifications fired from SpannableStringBuilder when replace/insert is called.
+        final Editable editable = (Editable) textView.getText();
+        final Context context = textView.getContext();
+        boolean didFirst = false;
+        for (int i = 0; i < clip.getItemCount(); i++) {
+            CharSequence paste;
+            if ((flags & FLAG_CONVERT_TO_PLAIN_TEXT) != 0) {
+                paste = clip.getItemAt(i).coerceToText(context);
+                paste = (paste instanceof Spanned) ? paste.toString() : paste;
+            } else {
+                if (Build.VERSION.SDK_INT >= 16) {
+                    paste = clip.getItemAt(i).coerceToStyledText(context);
+                } else {
+                    paste = clip.getItemAt(i).coerceToText(context);
+                }
+            }
+            if (paste != null) {
+                if (!didFirst) {
+                    final int selStart = Selection.getSelectionStart(editable);
+                    final int selEnd = Selection.getSelectionEnd(editable);
+                    final int start = Math.max(0, Math.min(selStart, selEnd));
+                    final int end = Math.max(0, Math.max(selStart, selEnd));
+                    Selection.setSelection(editable, end);
+                    editable.replace(start, end, paste);
+                    didFirst = true;
+                } else {
+                    editable.insert(Selection.getSelectionEnd(editable), "\n");
+                    editable.insert(Selection.getSelectionEnd(editable), paste);
+                }
+            }
+        }
+        return didFirst;
+    }
+}
diff --git a/customview/customview/api/api_lint.ignore b/customview/customview/api/api_lint.ignore
index e3d334f..ba85783 100644
--- a/customview/customview/api/api_lint.ignore
+++ b/customview/customview/api/api_lint.ignore
@@ -1,8 +1,4 @@
 // Baseline format: 1.0
-CallbackMethodName: androidx.customview.widget.ViewDragHelper.Callback:
-    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:
diff --git a/datastore/datastore-preferences/api/api_lint.ignore b/datastore/datastore-preferences/api/api_lint.ignore
new file mode 100644
index 0000000..2890439
--- /dev/null
+++ b/datastore/datastore-preferences/api/api_lint.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+BuilderSetStyle: androidx.datastore.preferences.Preferences.Builder#remove(String):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.datastore.preferences.Preferences.Builder.remove(String)
diff --git a/fragment/fragment-ktx/api/1.3.0-alpha06.ignore b/fragment/fragment-ktx/api/1.3.0-alpha06.ignore
new file mode 100644
index 0000000..4da20b8
--- /dev/null
+++ b/fragment/fragment-ktx/api/1.3.0-alpha06.ignore
@@ -0,0 +1,21 @@
+// Baseline format: 1.0
+ChangedType: androidx.fragment.app.FragmentViewModelLazyKt#activityViewModels(androidx.fragment.app.Fragment, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>):
+    Method androidx.fragment.app.FragmentViewModelLazyKt.activityViewModels has changed return type from kotlin.Lazy<VM> to kotlin.Lazy<? extends VM>
+ChangedType: androidx.fragment.app.FragmentViewModelLazyKt#viewModels(androidx.fragment.app.Fragment, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelStoreOwner>, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>):
+    Method androidx.fragment.app.FragmentViewModelLazyKt.viewModels has changed return type from kotlin.Lazy<VM> to kotlin.Lazy<? extends VM>
+
+
+InvalidNullConversion: androidx.fragment.app.FragmentTransactionKt#add(androidx.fragment.app.FragmentTransaction, String, android.os.Bundle):
+    Attempted to remove @NonNull annotation from method androidx.fragment.app.FragmentTransactionKt.add(androidx.fragment.app.FragmentTransaction,String,android.os.Bundle)
+InvalidNullConversion: androidx.fragment.app.FragmentTransactionKt#add(androidx.fragment.app.FragmentTransaction, int, String, android.os.Bundle):
+    Attempted to remove @NonNull annotation from method androidx.fragment.app.FragmentTransactionKt.add(androidx.fragment.app.FragmentTransaction,int,String,android.os.Bundle)
+InvalidNullConversion: androidx.fragment.app.FragmentTransactionKt#add(androidx.fragment.app.FragmentTransaction, int, String, android.os.Bundle) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter tag in androidx.fragment.app.FragmentTransactionKt.add(androidx.fragment.app.FragmentTransaction arg1, int containerViewId, String tag, android.os.Bundle args)
+InvalidNullConversion: androidx.fragment.app.FragmentTransactionKt#replace(androidx.fragment.app.FragmentTransaction, int, String, android.os.Bundle):
+    Attempted to remove @NonNull annotation from method androidx.fragment.app.FragmentTransactionKt.replace(androidx.fragment.app.FragmentTransaction,int,String,android.os.Bundle)
+InvalidNullConversion: androidx.fragment.app.FragmentTransactionKt#replace(androidx.fragment.app.FragmentTransaction, int, String, android.os.Bundle) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter tag in androidx.fragment.app.FragmentTransactionKt.replace(androidx.fragment.app.FragmentTransaction arg1, int containerViewId, String tag, android.os.Bundle args)
+InvalidNullConversion: androidx.fragment.app.FragmentViewModelLazyKt#activityViewModels(androidx.fragment.app.Fragment, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>):
+    Attempted to remove @NonNull annotation from method androidx.fragment.app.FragmentViewModelLazyKt.activityViewModels(androidx.fragment.app.Fragment,kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>)
+InvalidNullConversion: androidx.fragment.app.FragmentViewModelLazyKt#viewModels(androidx.fragment.app.Fragment, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelStoreOwner>, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>):
+    Attempted to remove @NonNull annotation from method androidx.fragment.app.FragmentViewModelLazyKt.viewModels(androidx.fragment.app.Fragment,kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelStoreOwner>,kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>)
diff --git a/fragment/fragment-ktx/api/1.3.0-alpha06.txt b/fragment/fragment-ktx/api/1.3.0-alpha06.txt
new file mode 100644
index 0000000..7fc1d63
--- /dev/null
+++ b/fragment/fragment-ktx/api/1.3.0-alpha06.txt
@@ -0,0 +1,38 @@
+// Signature format: 3.0
+package androidx.fragment.app {
+
+  public final class FragmentKt {
+    method public static void clearFragmentResult(androidx.fragment.app.Fragment, String requestKey);
+    method public static void clearFragmentResultListener(androidx.fragment.app.Fragment, String requestKey);
+    method public static void setFragmentResult(androidx.fragment.app.Fragment, String requestKey, android.os.Bundle result);
+    method public static inline void setFragmentResultListener(androidx.fragment.app.Fragment, String requestKey, kotlin.jvm.functions.Function2<? super java.lang.String,? super android.os.Bundle,kotlin.Unit> listener);
+  }
+
+  public final class FragmentManagerKt {
+    method public static inline void commit(androidx.fragment.app.FragmentManager, 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 FragmentResultOwnerKt {
+    method public static inline void setFragmentResultListener(androidx.fragment.app.FragmentResultOwner, String requestKey, androidx.lifecycle.LifecycleOwner lifecycleOwner, kotlin.jvm.functions.Function2<? super java.lang.String,? super android.os.Bundle,kotlin.Unit> listener);
+  }
+
+  public final class FragmentTransactionKt {
+    method public static inline <reified F> 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> androidx.fragment.app.FragmentTransaction! add(androidx.fragment.app.FragmentTransaction, String tag, android.os.Bundle? args = null);
+    method public static inline <reified F> androidx.fragment.app.FragmentTransaction! replace(androidx.fragment.app.FragmentTransaction, @IdRes int containerViewId, String tag = null, android.os.Bundle? args = null);
+  }
+
+  public final class FragmentViewModelLazyKt {
+    method @MainThread public static inline <reified VM> kotlin.Lazy<? extends 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> kotlin.Lazy<? extends VM>! viewModels(androidx.fragment.app.Fragment, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelStoreOwner> ownerProducer = { return this }, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer = null);
+  }
+
+  public final class ViewKt {
+    method public static <F extends androidx.fragment.app.Fragment> F findFragment(android.view.View);
+  }
+
+}
+
diff --git a/fragment/fragment-ktx/api/public_plus_experimental_1.3.0-alpha06.txt b/fragment/fragment-ktx/api/public_plus_experimental_1.3.0-alpha06.txt
new file mode 100644
index 0000000..7fc1d63
--- /dev/null
+++ b/fragment/fragment-ktx/api/public_plus_experimental_1.3.0-alpha06.txt
@@ -0,0 +1,38 @@
+// Signature format: 3.0
+package androidx.fragment.app {
+
+  public final class FragmentKt {
+    method public static void clearFragmentResult(androidx.fragment.app.Fragment, String requestKey);
+    method public static void clearFragmentResultListener(androidx.fragment.app.Fragment, String requestKey);
+    method public static void setFragmentResult(androidx.fragment.app.Fragment, String requestKey, android.os.Bundle result);
+    method public static inline void setFragmentResultListener(androidx.fragment.app.Fragment, String requestKey, kotlin.jvm.functions.Function2<? super java.lang.String,? super android.os.Bundle,kotlin.Unit> listener);
+  }
+
+  public final class FragmentManagerKt {
+    method public static inline void commit(androidx.fragment.app.FragmentManager, 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 FragmentResultOwnerKt {
+    method public static inline void setFragmentResultListener(androidx.fragment.app.FragmentResultOwner, String requestKey, androidx.lifecycle.LifecycleOwner lifecycleOwner, kotlin.jvm.functions.Function2<? super java.lang.String,? super android.os.Bundle,kotlin.Unit> listener);
+  }
+
+  public final class FragmentTransactionKt {
+    method public static inline <reified F> 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> androidx.fragment.app.FragmentTransaction! add(androidx.fragment.app.FragmentTransaction, String tag, android.os.Bundle? args = null);
+    method public static inline <reified F> androidx.fragment.app.FragmentTransaction! replace(androidx.fragment.app.FragmentTransaction, @IdRes int containerViewId, String tag = null, android.os.Bundle? args = null);
+  }
+
+  public final class FragmentViewModelLazyKt {
+    method @MainThread public static inline <reified VM> kotlin.Lazy<? extends 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> kotlin.Lazy<? extends VM>! viewModels(androidx.fragment.app.Fragment, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelStoreOwner> ownerProducer = { return this }, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer = null);
+  }
+
+  public final class ViewKt {
+    method public static <F extends androidx.fragment.app.Fragment> F findFragment(android.view.View);
+  }
+
+}
+
diff --git a/fragment/fragment-ktx/api/res-1.3.0-alpha06.txt b/fragment/fragment-ktx/api/res-1.3.0-alpha06.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/fragment/fragment-ktx/api/res-1.3.0-alpha06.txt
diff --git a/fragment/fragment-ktx/api/restricted_1.3.0-alpha06.ignore b/fragment/fragment-ktx/api/restricted_1.3.0-alpha06.ignore
new file mode 100644
index 0000000..4da20b8
--- /dev/null
+++ b/fragment/fragment-ktx/api/restricted_1.3.0-alpha06.ignore
@@ -0,0 +1,21 @@
+// Baseline format: 1.0
+ChangedType: androidx.fragment.app.FragmentViewModelLazyKt#activityViewModels(androidx.fragment.app.Fragment, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>):
+    Method androidx.fragment.app.FragmentViewModelLazyKt.activityViewModels has changed return type from kotlin.Lazy<VM> to kotlin.Lazy<? extends VM>
+ChangedType: androidx.fragment.app.FragmentViewModelLazyKt#viewModels(androidx.fragment.app.Fragment, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelStoreOwner>, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>):
+    Method androidx.fragment.app.FragmentViewModelLazyKt.viewModels has changed return type from kotlin.Lazy<VM> to kotlin.Lazy<? extends VM>
+
+
+InvalidNullConversion: androidx.fragment.app.FragmentTransactionKt#add(androidx.fragment.app.FragmentTransaction, String, android.os.Bundle):
+    Attempted to remove @NonNull annotation from method androidx.fragment.app.FragmentTransactionKt.add(androidx.fragment.app.FragmentTransaction,String,android.os.Bundle)
+InvalidNullConversion: androidx.fragment.app.FragmentTransactionKt#add(androidx.fragment.app.FragmentTransaction, int, String, android.os.Bundle):
+    Attempted to remove @NonNull annotation from method androidx.fragment.app.FragmentTransactionKt.add(androidx.fragment.app.FragmentTransaction,int,String,android.os.Bundle)
+InvalidNullConversion: androidx.fragment.app.FragmentTransactionKt#add(androidx.fragment.app.FragmentTransaction, int, String, android.os.Bundle) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter tag in androidx.fragment.app.FragmentTransactionKt.add(androidx.fragment.app.FragmentTransaction arg1, int containerViewId, String tag, android.os.Bundle args)
+InvalidNullConversion: androidx.fragment.app.FragmentTransactionKt#replace(androidx.fragment.app.FragmentTransaction, int, String, android.os.Bundle):
+    Attempted to remove @NonNull annotation from method androidx.fragment.app.FragmentTransactionKt.replace(androidx.fragment.app.FragmentTransaction,int,String,android.os.Bundle)
+InvalidNullConversion: androidx.fragment.app.FragmentTransactionKt#replace(androidx.fragment.app.FragmentTransaction, int, String, android.os.Bundle) parameter #2:
+    Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter tag in androidx.fragment.app.FragmentTransactionKt.replace(androidx.fragment.app.FragmentTransaction arg1, int containerViewId, String tag, android.os.Bundle args)
+InvalidNullConversion: androidx.fragment.app.FragmentViewModelLazyKt#activityViewModels(androidx.fragment.app.Fragment, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>):
+    Attempted to remove @NonNull annotation from method androidx.fragment.app.FragmentViewModelLazyKt.activityViewModels(androidx.fragment.app.Fragment,kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>)
+InvalidNullConversion: androidx.fragment.app.FragmentViewModelLazyKt#viewModels(androidx.fragment.app.Fragment, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelStoreOwner>, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>):
+    Attempted to remove @NonNull annotation from method androidx.fragment.app.FragmentViewModelLazyKt.viewModels(androidx.fragment.app.Fragment,kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelStoreOwner>,kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>)
diff --git a/fragment/fragment-ktx/api/restricted_1.3.0-alpha06.txt b/fragment/fragment-ktx/api/restricted_1.3.0-alpha06.txt
new file mode 100644
index 0000000..7fc1d63
--- /dev/null
+++ b/fragment/fragment-ktx/api/restricted_1.3.0-alpha06.txt
@@ -0,0 +1,38 @@
+// Signature format: 3.0
+package androidx.fragment.app {
+
+  public final class FragmentKt {
+    method public static void clearFragmentResult(androidx.fragment.app.Fragment, String requestKey);
+    method public static void clearFragmentResultListener(androidx.fragment.app.Fragment, String requestKey);
+    method public static void setFragmentResult(androidx.fragment.app.Fragment, String requestKey, android.os.Bundle result);
+    method public static inline void setFragmentResultListener(androidx.fragment.app.Fragment, String requestKey, kotlin.jvm.functions.Function2<? super java.lang.String,? super android.os.Bundle,kotlin.Unit> listener);
+  }
+
+  public final class FragmentManagerKt {
+    method public static inline void commit(androidx.fragment.app.FragmentManager, 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 FragmentResultOwnerKt {
+    method public static inline void setFragmentResultListener(androidx.fragment.app.FragmentResultOwner, String requestKey, androidx.lifecycle.LifecycleOwner lifecycleOwner, kotlin.jvm.functions.Function2<? super java.lang.String,? super android.os.Bundle,kotlin.Unit> listener);
+  }
+
+  public final class FragmentTransactionKt {
+    method public static inline <reified F> 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> androidx.fragment.app.FragmentTransaction! add(androidx.fragment.app.FragmentTransaction, String tag, android.os.Bundle? args = null);
+    method public static inline <reified F> androidx.fragment.app.FragmentTransaction! replace(androidx.fragment.app.FragmentTransaction, @IdRes int containerViewId, String tag = null, android.os.Bundle? args = null);
+  }
+
+  public final class FragmentViewModelLazyKt {
+    method @MainThread public static inline <reified VM> kotlin.Lazy<? extends 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> kotlin.Lazy<? extends VM>! viewModels(androidx.fragment.app.Fragment, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelStoreOwner> ownerProducer = { return this }, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer = null);
+  }
+
+  public final class ViewKt {
+    method public static <F extends androidx.fragment.app.Fragment> F findFragment(android.view.View);
+  }
+
+}
+
diff --git a/fragment/fragment-testing/api/1.3.0-alpha06.ignore b/fragment/fragment-testing/api/1.3.0-alpha06.ignore
new file mode 100644
index 0000000..0c3c8e4
--- /dev/null
+++ b/fragment/fragment-testing/api/1.3.0-alpha06.ignore
@@ -0,0 +1,9 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.fragment.app.testing.FragmentScenarioKt#launchFragment(android.os.Bundle, int, androidx.fragment.app.FragmentFactory):
+    Attempted to remove @NonNull annotation from method androidx.fragment.app.testing.FragmentScenarioKt.launchFragment(android.os.Bundle,int,androidx.fragment.app.FragmentFactory)
+InvalidNullConversion: androidx.fragment.app.testing.FragmentScenarioKt#launchFragment(android.os.Bundle, int, kotlin.jvm.functions.Function0<? extends F>):
+    Attempted to remove @NonNull annotation from method androidx.fragment.app.testing.FragmentScenarioKt.launchFragment(android.os.Bundle,int,kotlin.jvm.functions.Function0<? extends F>)
+InvalidNullConversion: androidx.fragment.app.testing.FragmentScenarioKt#launchFragmentInContainer(android.os.Bundle, int, androidx.fragment.app.FragmentFactory):
+    Attempted to remove @NonNull annotation from method androidx.fragment.app.testing.FragmentScenarioKt.launchFragmentInContainer(android.os.Bundle,int,androidx.fragment.app.FragmentFactory)
+InvalidNullConversion: androidx.fragment.app.testing.FragmentScenarioKt#launchFragmentInContainer(android.os.Bundle, int, kotlin.jvm.functions.Function0<? extends F>):
+    Attempted to remove @NonNull annotation from method androidx.fragment.app.testing.FragmentScenarioKt.launchFragmentInContainer(android.os.Bundle,int,kotlin.jvm.functions.Function0<? extends F>)
diff --git a/fragment/fragment-testing/api/1.3.0-alpha06.txt b/fragment/fragment-testing/api/1.3.0-alpha06.txt
new file mode 100644
index 0000000..7b33baa
--- /dev/null
+++ b/fragment/fragment-testing/api/1.3.0-alpha06.txt
@@ -0,0 +1,30 @@
+// 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 {
+    method public static inline <reified F> androidx.fragment.app.testing.FragmentScenario<F>! launchFragment(android.os.Bundle? fragmentArgs = null, @StyleRes int themeResId = androidx.fragment.testing.R.style.FragmentScenarioEmptyFragmentActivityTheme, androidx.fragment.app.FragmentFactory? factory = null);
+    method public static inline <reified F> androidx.fragment.app.testing.FragmentScenario<F>! launchFragment(android.os.Bundle? fragmentArgs = null, @StyleRes int themeResId = androidx.fragment.testing.R.style.FragmentScenarioEmptyFragmentActivityTheme, kotlin.jvm.functions.Function0<? extends F> instantiate);
+    method public static inline <reified F> androidx.fragment.app.testing.FragmentScenario<F>! launchFragmentInContainer(android.os.Bundle? fragmentArgs = null, @StyleRes int themeResId = androidx.fragment.testing.R.style.FragmentScenarioEmptyFragmentActivityTheme, androidx.fragment.app.FragmentFactory? factory = null);
+    method public static inline <reified F> androidx.fragment.app.testing.FragmentScenario<F>! launchFragmentInContainer(android.os.Bundle? fragmentArgs = null, @StyleRes int themeResId = androidx.fragment.testing.R.style.FragmentScenarioEmptyFragmentActivityTheme, kotlin.jvm.functions.Function0<? extends F> instantiate);
+  }
+
+}
+
diff --git a/fragment/fragment-testing/api/public_plus_experimental_1.3.0-alpha06.txt b/fragment/fragment-testing/api/public_plus_experimental_1.3.0-alpha06.txt
new file mode 100644
index 0000000..7b33baa
--- /dev/null
+++ b/fragment/fragment-testing/api/public_plus_experimental_1.3.0-alpha06.txt
@@ -0,0 +1,30 @@
+// 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 {
+    method public static inline <reified F> androidx.fragment.app.testing.FragmentScenario<F>! launchFragment(android.os.Bundle? fragmentArgs = null, @StyleRes int themeResId = androidx.fragment.testing.R.style.FragmentScenarioEmptyFragmentActivityTheme, androidx.fragment.app.FragmentFactory? factory = null);
+    method public static inline <reified F> androidx.fragment.app.testing.FragmentScenario<F>! launchFragment(android.os.Bundle? fragmentArgs = null, @StyleRes int themeResId = androidx.fragment.testing.R.style.FragmentScenarioEmptyFragmentActivityTheme, kotlin.jvm.functions.Function0<? extends F> instantiate);
+    method public static inline <reified F> androidx.fragment.app.testing.FragmentScenario<F>! launchFragmentInContainer(android.os.Bundle? fragmentArgs = null, @StyleRes int themeResId = androidx.fragment.testing.R.style.FragmentScenarioEmptyFragmentActivityTheme, androidx.fragment.app.FragmentFactory? factory = null);
+    method public static inline <reified F> androidx.fragment.app.testing.FragmentScenario<F>! launchFragmentInContainer(android.os.Bundle? fragmentArgs = null, @StyleRes int themeResId = androidx.fragment.testing.R.style.FragmentScenarioEmptyFragmentActivityTheme, kotlin.jvm.functions.Function0<? extends F> instantiate);
+  }
+
+}
+
diff --git a/fragment/fragment-testing/api/res-1.3.0-alpha06.txt b/fragment/fragment-testing/api/res-1.3.0-alpha06.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/fragment/fragment-testing/api/res-1.3.0-alpha06.txt
diff --git a/fragment/fragment-testing/api/restricted_1.3.0-alpha06.ignore b/fragment/fragment-testing/api/restricted_1.3.0-alpha06.ignore
new file mode 100644
index 0000000..0c3c8e4
--- /dev/null
+++ b/fragment/fragment-testing/api/restricted_1.3.0-alpha06.ignore
@@ -0,0 +1,9 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.fragment.app.testing.FragmentScenarioKt#launchFragment(android.os.Bundle, int, androidx.fragment.app.FragmentFactory):
+    Attempted to remove @NonNull annotation from method androidx.fragment.app.testing.FragmentScenarioKt.launchFragment(android.os.Bundle,int,androidx.fragment.app.FragmentFactory)
+InvalidNullConversion: androidx.fragment.app.testing.FragmentScenarioKt#launchFragment(android.os.Bundle, int, kotlin.jvm.functions.Function0<? extends F>):
+    Attempted to remove @NonNull annotation from method androidx.fragment.app.testing.FragmentScenarioKt.launchFragment(android.os.Bundle,int,kotlin.jvm.functions.Function0<? extends F>)
+InvalidNullConversion: androidx.fragment.app.testing.FragmentScenarioKt#launchFragmentInContainer(android.os.Bundle, int, androidx.fragment.app.FragmentFactory):
+    Attempted to remove @NonNull annotation from method androidx.fragment.app.testing.FragmentScenarioKt.launchFragmentInContainer(android.os.Bundle,int,androidx.fragment.app.FragmentFactory)
+InvalidNullConversion: androidx.fragment.app.testing.FragmentScenarioKt#launchFragmentInContainer(android.os.Bundle, int, kotlin.jvm.functions.Function0<? extends F>):
+    Attempted to remove @NonNull annotation from method androidx.fragment.app.testing.FragmentScenarioKt.launchFragmentInContainer(android.os.Bundle,int,kotlin.jvm.functions.Function0<? extends F>)
diff --git a/fragment/fragment-testing/api/restricted_1.3.0-alpha06.txt b/fragment/fragment-testing/api/restricted_1.3.0-alpha06.txt
new file mode 100644
index 0000000..7b33baa
--- /dev/null
+++ b/fragment/fragment-testing/api/restricted_1.3.0-alpha06.txt
@@ -0,0 +1,30 @@
+// 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 {
+    method public static inline <reified F> androidx.fragment.app.testing.FragmentScenario<F>! launchFragment(android.os.Bundle? fragmentArgs = null, @StyleRes int themeResId = androidx.fragment.testing.R.style.FragmentScenarioEmptyFragmentActivityTheme, androidx.fragment.app.FragmentFactory? factory = null);
+    method public static inline <reified F> androidx.fragment.app.testing.FragmentScenario<F>! launchFragment(android.os.Bundle? fragmentArgs = null, @StyleRes int themeResId = androidx.fragment.testing.R.style.FragmentScenarioEmptyFragmentActivityTheme, kotlin.jvm.functions.Function0<? extends F> instantiate);
+    method public static inline <reified F> androidx.fragment.app.testing.FragmentScenario<F>! launchFragmentInContainer(android.os.Bundle? fragmentArgs = null, @StyleRes int themeResId = androidx.fragment.testing.R.style.FragmentScenarioEmptyFragmentActivityTheme, androidx.fragment.app.FragmentFactory? factory = null);
+    method public static inline <reified F> androidx.fragment.app.testing.FragmentScenario<F>! launchFragmentInContainer(android.os.Bundle? fragmentArgs = null, @StyleRes int themeResId = androidx.fragment.testing.R.style.FragmentScenarioEmptyFragmentActivityTheme, kotlin.jvm.functions.Function0<? extends F> instantiate);
+  }
+
+}
+
diff --git a/fragment/fragment/api/1.3.0-alpha06.txt b/fragment/fragment/api/1.3.0-alpha06.txt
new file mode 100644
index 0000000..d5b26f6
--- /dev/null
+++ b/fragment/fragment/api/1.3.0-alpha06.txt
@@ -0,0 +1,444 @@
+// 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();
+    ctor public DialogFragment(@LayoutRes int);
+    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 androidx.activity.result.ActivityResultCaller android.content.ComponentCallbacks androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.savedstate.SavedStateRegistryOwner android.view.View.OnCreateContextMenuListener androidx.lifecycle.ViewModelStoreOwner {
+    ctor public Fragment();
+    ctor @ContentView public Fragment(@LayoutRes int);
+    method public void dump(String, java.io.FileDescriptor?, java.io.PrintWriter, String![]?);
+    method public final boolean equals(Object?);
+    method public final androidx.fragment.app.FragmentActivity? getActivity();
+    method public boolean getAllowEnterTransitionOverlap();
+    method public boolean getAllowReturnTransitionOverlap();
+    method public final android.os.Bundle? getArguments();
+    method public final androidx.fragment.app.FragmentManager getChildFragmentManager();
+    method public android.content.Context? getContext();
+    method public androidx.lifecycle.ViewModelProvider.Factory getDefaultViewModelProviderFactory();
+    method public Object? getEnterTransition();
+    method public Object? getExitTransition();
+    method @Deprecated public final androidx.fragment.app.FragmentManager? getFragmentManager();
+    method public final Object? getHost();
+    method public final int getId();
+    method public final android.view.LayoutInflater getLayoutInflater();
+    method public androidx.lifecycle.Lifecycle getLifecycle();
+    method @Deprecated public androidx.loader.app.LoaderManager getLoaderManager();
+    method public final androidx.fragment.app.Fragment? getParentFragment();
+    method public final androidx.fragment.app.FragmentManager getParentFragmentManager();
+    method public Object? getReenterTransition();
+    method public final android.content.res.Resources getResources();
+    method @Deprecated public final boolean getRetainInstance();
+    method public Object? getReturnTransition();
+    method public final androidx.savedstate.SavedStateRegistry getSavedStateRegistry();
+    method public Object? getSharedElementEnterTransition();
+    method public Object? getSharedElementReturnTransition();
+    method public final String getString(@StringRes int);
+    method public final String getString(@StringRes int, java.lang.Object!...);
+    method public final String? getTag();
+    method @Deprecated public final androidx.fragment.app.Fragment? getTargetFragment();
+    method @Deprecated public final int getTargetRequestCode();
+    method public final CharSequence getText(@StringRes int);
+    method @Deprecated public boolean getUserVisibleHint();
+    method public android.view.View? getView();
+    method @MainThread public androidx.lifecycle.LifecycleOwner getViewLifecycleOwner();
+    method public androidx.lifecycle.LiveData<androidx.lifecycle.LifecycleOwner!> getViewLifecycleOwnerLiveData();
+    method public androidx.lifecycle.ViewModelStore getViewModelStore();
+    method public final int hashCode();
+    method @Deprecated public static androidx.fragment.app.Fragment instantiate(android.content.Context, String);
+    method @Deprecated public static androidx.fragment.app.Fragment instantiate(android.content.Context, String, android.os.Bundle?);
+    method public final boolean isAdded();
+    method public final boolean isDetached();
+    method public final boolean isHidden();
+    method public final boolean isInLayout();
+    method public final boolean isRemoving();
+    method public final boolean isResumed();
+    method public final boolean isStateSaved();
+    method public final boolean isVisible();
+    method @Deprecated @CallSuper @MainThread public void onActivityCreated(android.os.Bundle?);
+    method @Deprecated public void onActivityResult(int, int, android.content.Intent?);
+    method @CallSuper @MainThread public void onAttach(android.content.Context);
+    method @Deprecated @CallSuper @MainThread public void onAttach(android.app.Activity);
+    method @MainThread public void onAttachFragment(androidx.fragment.app.Fragment);
+    method @CallSuper public void onConfigurationChanged(android.content.res.Configuration);
+    method @MainThread public boolean onContextItemSelected(android.view.MenuItem);
+    method @CallSuper @MainThread public void onCreate(android.os.Bundle?);
+    method @MainThread public android.view.animation.Animation? onCreateAnimation(int, boolean, int);
+    method @MainThread public android.animation.Animator? onCreateAnimator(int, boolean, int);
+    method @MainThread public void onCreateContextMenu(android.view.ContextMenu, android.view.View, android.view.ContextMenu.ContextMenuInfo?);
+    method @MainThread public void onCreateOptionsMenu(android.view.Menu, android.view.MenuInflater);
+    method @MainThread public android.view.View? onCreateView(android.view.LayoutInflater, android.view.ViewGroup?, android.os.Bundle?);
+    method @CallSuper @MainThread public void onDestroy();
+    method @MainThread public void onDestroyOptionsMenu();
+    method @CallSuper @MainThread public void onDestroyView();
+    method @CallSuper @MainThread public void onDetach();
+    method public android.view.LayoutInflater onGetLayoutInflater(android.os.Bundle?);
+    method @MainThread public void onHiddenChanged(boolean);
+    method @CallSuper @UiThread public void onInflate(android.content.Context, android.util.AttributeSet, android.os.Bundle?);
+    method @Deprecated @CallSuper @UiThread public void onInflate(android.app.Activity, android.util.AttributeSet, android.os.Bundle?);
+    method @CallSuper @MainThread public void onLowMemory();
+    method public void onMultiWindowModeChanged(boolean);
+    method @MainThread public boolean onOptionsItemSelected(android.view.MenuItem);
+    method @MainThread public void onOptionsMenuClosed(android.view.Menu);
+    method @CallSuper @MainThread public void onPause();
+    method public void onPictureInPictureModeChanged(boolean);
+    method @MainThread public void onPrepareOptionsMenu(android.view.Menu);
+    method @MainThread public void onPrimaryNavigationFragmentChanged(boolean);
+    method @Deprecated public void onRequestPermissionsResult(int, String![], int[]);
+    method @CallSuper @MainThread public void onResume();
+    method @MainThread public void onSaveInstanceState(android.os.Bundle);
+    method @CallSuper @MainThread public void onStart();
+    method @CallSuper @MainThread public void onStop();
+    method @MainThread public void onViewCreated(android.view.View, android.os.Bundle?);
+    method @CallSuper @MainThread public void onViewStateRestored(android.os.Bundle?);
+    method public void postponeEnterTransition();
+    method public final void postponeEnterTransition(long, java.util.concurrent.TimeUnit);
+    method public final <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerForActivityResult(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+    method public final <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerForActivityResult(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultRegistry, androidx.activity.result.ActivityResultCallback<O!>);
+    method public void registerForContextMenu(android.view.View);
+    method @Deprecated public final void requestPermissions(String![], int);
+    method public final androidx.fragment.app.FragmentActivity requireActivity();
+    method public final android.os.Bundle requireArguments();
+    method public final android.content.Context requireContext();
+    method @Deprecated public final androidx.fragment.app.FragmentManager requireFragmentManager();
+    method public final Object requireHost();
+    method public final androidx.fragment.app.Fragment requireParentFragment();
+    method public final android.view.View requireView();
+    method public void setAllowEnterTransitionOverlap(boolean);
+    method public void setAllowReturnTransitionOverlap(boolean);
+    method public void setArguments(android.os.Bundle?);
+    method public void setEnterSharedElementCallback(androidx.core.app.SharedElementCallback?);
+    method public void setEnterTransition(Object?);
+    method public void setExitSharedElementCallback(androidx.core.app.SharedElementCallback?);
+    method public void setExitTransition(Object?);
+    method public void setHasOptionsMenu(boolean);
+    method public void setInitialSavedState(androidx.fragment.app.Fragment.SavedState?);
+    method public void setMenuVisibility(boolean);
+    method public void setReenterTransition(Object?);
+    method @Deprecated public void setRetainInstance(boolean);
+    method public void setReturnTransition(Object?);
+    method public void setSharedElementEnterTransition(Object?);
+    method public void setSharedElementReturnTransition(Object?);
+    method @Deprecated public void setTargetFragment(androidx.fragment.app.Fragment?, int);
+    method @Deprecated public void setUserVisibleHint(boolean);
+    method public boolean shouldShowRequestPermissionRationale(String);
+    method public void startActivity(android.content.Intent!);
+    method public void startActivity(android.content.Intent!, android.os.Bundle?);
+    method @Deprecated public void startActivityForResult(android.content.Intent!, int);
+    method @Deprecated public void startActivityForResult(android.content.Intent!, int, android.os.Bundle?);
+    method @Deprecated public void startIntentSenderForResult(android.content.IntentSender!, int, android.content.Intent?, int, int, int, android.os.Bundle?) throws android.content.IntentSender.SendIntentException;
+    method public void startPostponedEnterTransition();
+    method public void unregisterForContextMenu(android.view.View);
+  }
+
+  public static class Fragment.InstantiationException extends java.lang.RuntimeException {
+    ctor public Fragment.InstantiationException(String, Exception?);
+  }
+
+  public static class Fragment.SavedState implements android.os.Parcelable {
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<androidx.fragment.app.Fragment.SavedState!> CREATOR;
+  }
+
+  public class FragmentActivity extends androidx.activity.ComponentActivity implements androidx.core.app.ActivityCompat.OnRequestPermissionsResultCallback androidx.lifecycle.LifecycleOwner {
+    ctor public FragmentActivity();
+    ctor @ContentView public FragmentActivity(@LayoutRes int);
+    method public androidx.fragment.app.FragmentManager getSupportFragmentManager();
+    method @Deprecated public androidx.loader.app.LoaderManager getSupportLoaderManager();
+    method 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 @Deprecated public void startIntentSenderFromFragment(androidx.fragment.app.Fragment, android.content.IntentSender!, int, android.content.Intent?, int, int, int, android.os.Bundle?) throws android.content.IntentSender.SendIntentException;
+    method public void supportFinishAfterTransition();
+    method @Deprecated public void supportInvalidateOptionsMenu();
+    method public void supportPostponeEnterTransition();
+    method public void supportStartPostponedEnterTransition();
+    method @Deprecated public final void validateRequestPermissionsRequestCode(int);
+  }
+
+  public abstract class FragmentContainer {
+    ctor public FragmentContainer();
+    method @Deprecated public androidx.fragment.app.Fragment instantiate(android.content.Context, String, android.os.Bundle?);
+    method public abstract android.view.View? onFindViewById(@IdRes int);
+    method public abstract boolean onHasView();
+  }
+
+  public final class FragmentContainerView extends android.widget.FrameLayout {
+    ctor public FragmentContainerView(android.content.Context);
+    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 @Deprecated public void onRequestPermissionsFromFragment(androidx.fragment.app.Fragment, String![], int);
+    method public boolean onShouldSaveFragmentState(androidx.fragment.app.Fragment);
+    method public boolean onShouldShowRequestPermissionRationale(String);
+    method public void onStartActivityFromFragment(androidx.fragment.app.Fragment, android.content.Intent!, int);
+    method public void onStartActivityFromFragment(androidx.fragment.app.Fragment, android.content.Intent!, int, android.os.Bundle?);
+    method @Deprecated public void onStartIntentSenderFromFragment(androidx.fragment.app.Fragment, android.content.IntentSender!, int, android.content.Intent?, int, int, int, android.os.Bundle?) throws android.content.IntentSender.SendIntentException;
+    method public void onSupportInvalidateOptionsMenu();
+  }
+
+  public abstract class FragmentManager implements androidx.fragment.app.FragmentResultOwner {
+    ctor public FragmentManager();
+    method public void addOnBackStackChangedListener(androidx.fragment.app.FragmentManager.OnBackStackChangedListener);
+    method public androidx.fragment.app.FragmentTransaction beginTransaction();
+    method public final void clearFragmentResult(String);
+    method public final void clearFragmentResultListener(String);
+    method public void dump(String, java.io.FileDescriptor?, java.io.PrintWriter, String![]?);
+    method @Deprecated public static void enableDebugLogging(boolean);
+    method public boolean executePendingTransactions();
+    method public static <F extends androidx.fragment.app.Fragment> F findFragment(android.view.View);
+    method public androidx.fragment.app.Fragment? findFragmentById(@IdRes int);
+    method public androidx.fragment.app.Fragment? findFragmentByTag(String?);
+    method public androidx.fragment.app.FragmentManager.BackStackEntry getBackStackEntryAt(int);
+    method public int getBackStackEntryCount();
+    method public androidx.fragment.app.Fragment? getFragment(android.os.Bundle, String);
+    method public androidx.fragment.app.FragmentFactory getFragmentFactory();
+    method public java.util.List<androidx.fragment.app.Fragment!> getFragments();
+    method public androidx.fragment.app.Fragment? getPrimaryNavigationFragment();
+    method public 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 final void setFragmentResult(String, android.os.Bundle);
+    method public final void setFragmentResultListener(String, androidx.lifecycle.LifecycleOwner, androidx.fragment.app.FragmentResultListener);
+    method public void unregisterFragmentLifecycleCallbacks(androidx.fragment.app.FragmentManager.FragmentLifecycleCallbacks);
+    field public static final int POP_BACK_STACK_INCLUSIVE = 1; // 0x1
+  }
+
+  public static interface FragmentManager.BackStackEntry {
+    method @Deprecated public CharSequence? getBreadCrumbShortTitle();
+    method @Deprecated @StringRes public int getBreadCrumbShortTitleRes();
+    method @Deprecated public CharSequence? getBreadCrumbTitle();
+    method @Deprecated @StringRes public int getBreadCrumbTitleRes();
+    method public int getId();
+    method public String? getName();
+  }
+
+  public abstract static class FragmentManager.FragmentLifecycleCallbacks {
+    ctor public FragmentManager.FragmentLifecycleCallbacks();
+    method @Deprecated public void onFragmentActivityCreated(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.os.Bundle?);
+    method public void onFragmentAttached(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.content.Context);
+    method public void onFragmentCreated(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.os.Bundle?);
+    method public void onFragmentDestroyed(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
+    method public void onFragmentDetached(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
+    method public void onFragmentPaused(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
+    method public void onFragmentPreAttached(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.content.Context);
+    method public void onFragmentPreCreated(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.os.Bundle?);
+    method public void onFragmentResumed(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
+    method public void onFragmentSaveInstanceState(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.os.Bundle);
+    method public void onFragmentStarted(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
+    method public void onFragmentStopped(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
+    method public void onFragmentViewCreated(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.view.View, android.os.Bundle?);
+    method public void onFragmentViewDestroyed(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
+  }
+
+  public static interface FragmentManager.OnBackStackChangedListener {
+    method @MainThread public void onBackStackChanged();
+  }
+
+  @Deprecated public class FragmentManagerNonConfig {
+  }
+
+  @Deprecated public abstract class FragmentPagerAdapter extends androidx.viewpager.widget.PagerAdapter {
+    ctor @Deprecated public FragmentPagerAdapter(androidx.fragment.app.FragmentManager);
+    ctor @Deprecated public FragmentPagerAdapter(androidx.fragment.app.FragmentManager, int);
+    method @Deprecated public abstract androidx.fragment.app.Fragment getItem(int);
+    method @Deprecated public long getItemId(int);
+    method @Deprecated public boolean isViewFromObject(android.view.View, Object);
+    field @Deprecated public static final int BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT = 1; // 0x1
+    field @Deprecated public static final int BEHAVIOR_SET_USER_VISIBLE_HINT = 0; // 0x0
+  }
+
+  public interface FragmentResultListener {
+    method public void onFragmentResult(String, android.os.Bundle);
+  }
+
+  public interface FragmentResultOwner {
+    method public void clearFragmentResult(String);
+    method public void clearFragmentResultListener(String);
+    method public void setFragmentResult(String, android.os.Bundle);
+    method public void setFragmentResultListener(String, androidx.lifecycle.LifecycleOwner, androidx.fragment.app.FragmentResultListener);
+  }
+
+  @Deprecated public abstract class FragmentStatePagerAdapter extends androidx.viewpager.widget.PagerAdapter {
+    ctor @Deprecated public FragmentStatePagerAdapter(androidx.fragment.app.FragmentManager);
+    ctor @Deprecated public FragmentStatePagerAdapter(androidx.fragment.app.FragmentManager, int);
+    method @Deprecated public abstract androidx.fragment.app.Fragment getItem(int);
+    method @Deprecated public boolean isViewFromObject(android.view.View, Object);
+    field @Deprecated public static final int BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT = 1; // 0x1
+    field @Deprecated public static final int BEHAVIOR_SET_USER_VISIBLE_HINT = 0; // 0x0
+  }
+
+  @Deprecated public class FragmentTabHost extends android.widget.TabHost implements android.widget.TabHost.OnTabChangeListener {
+    ctor @Deprecated public FragmentTabHost(android.content.Context);
+    ctor @Deprecated public FragmentTabHost(android.content.Context, android.util.AttributeSet?);
+    method @Deprecated public void addTab(android.widget.TabHost.TabSpec, Class<?>, android.os.Bundle?);
+    method @Deprecated public void onTabChanged(String?);
+    method @Deprecated public void setup(android.content.Context, androidx.fragment.app.FragmentManager);
+    method @Deprecated public void setup(android.content.Context, androidx.fragment.app.FragmentManager, int);
+  }
+
+  public abstract class FragmentTransaction {
+    ctor @Deprecated public FragmentTransaction();
+    method public final androidx.fragment.app.FragmentTransaction add(Class<? extends androidx.fragment.app.Fragment>, android.os.Bundle?, String?);
+    method public androidx.fragment.app.FragmentTransaction add(androidx.fragment.app.Fragment, String?);
+    method public final androidx.fragment.app.FragmentTransaction add(@IdRes int, Class<? extends androidx.fragment.app.Fragment>, android.os.Bundle?);
+    method public androidx.fragment.app.FragmentTransaction add(@IdRes int, androidx.fragment.app.Fragment);
+    method public final androidx.fragment.app.FragmentTransaction add(@IdRes int, Class<? extends androidx.fragment.app.Fragment>, android.os.Bundle?, String?);
+    method public androidx.fragment.app.FragmentTransaction add(@IdRes int, androidx.fragment.app.Fragment, String?);
+    method public androidx.fragment.app.FragmentTransaction addSharedElement(android.view.View, String);
+    method public androidx.fragment.app.FragmentTransaction addToBackStack(String?);
+    method public androidx.fragment.app.FragmentTransaction attach(androidx.fragment.app.Fragment);
+    method public abstract int commit();
+    method public abstract int commitAllowingStateLoss();
+    method public abstract void commitNow();
+    method public abstract void commitNowAllowingStateLoss();
+    method public androidx.fragment.app.FragmentTransaction detach(androidx.fragment.app.Fragment);
+    method public androidx.fragment.app.FragmentTransaction disallowAddToBackStack();
+    method public androidx.fragment.app.FragmentTransaction hide(androidx.fragment.app.Fragment);
+    method public boolean isAddToBackStackAllowed();
+    method public boolean isEmpty();
+    method public androidx.fragment.app.FragmentTransaction remove(androidx.fragment.app.Fragment);
+    method public final androidx.fragment.app.FragmentTransaction replace(@IdRes int, Class<? extends androidx.fragment.app.Fragment>, android.os.Bundle?);
+    method public androidx.fragment.app.FragmentTransaction replace(@IdRes int, androidx.fragment.app.Fragment);
+    method public final androidx.fragment.app.FragmentTransaction replace(@IdRes int, Class<? extends androidx.fragment.app.Fragment>, android.os.Bundle?, String?);
+    method public androidx.fragment.app.FragmentTransaction replace(@IdRes int, androidx.fragment.app.Fragment, String?);
+    method public androidx.fragment.app.FragmentTransaction runOnCommit(Runnable);
+    method @Deprecated public androidx.fragment.app.FragmentTransaction setAllowOptimization(boolean);
+    method @Deprecated public androidx.fragment.app.FragmentTransaction setBreadCrumbShortTitle(@StringRes int);
+    method @Deprecated public androidx.fragment.app.FragmentTransaction setBreadCrumbShortTitle(CharSequence?);
+    method @Deprecated public androidx.fragment.app.FragmentTransaction setBreadCrumbTitle(@StringRes int);
+    method @Deprecated public androidx.fragment.app.FragmentTransaction setBreadCrumbTitle(CharSequence?);
+    method public androidx.fragment.app.FragmentTransaction setCustomAnimations(@AnimRes @AnimatorRes int, @AnimRes @AnimatorRes int);
+    method public androidx.fragment.app.FragmentTransaction setCustomAnimations(@AnimRes @AnimatorRes int, @AnimRes @AnimatorRes int, @AnimRes @AnimatorRes int, @AnimRes @AnimatorRes int);
+    method public androidx.fragment.app.FragmentTransaction setMaxLifecycle(androidx.fragment.app.Fragment, androidx.lifecycle.Lifecycle.State);
+    method public androidx.fragment.app.FragmentTransaction setPrimaryNavigationFragment(androidx.fragment.app.Fragment?);
+    method public androidx.fragment.app.FragmentTransaction setReorderingAllowed(boolean);
+    method public androidx.fragment.app.FragmentTransaction setTransition(int);
+    method @Deprecated public androidx.fragment.app.FragmentTransaction setTransitionStyle(@StyleRes int);
+    method public androidx.fragment.app.FragmentTransaction show(androidx.fragment.app.Fragment);
+    field public static final int TRANSIT_ENTER_MASK = 4096; // 0x1000
+    field public static final int TRANSIT_EXIT_MASK = 8192; // 0x2000
+    field public static final int TRANSIT_FRAGMENT_CLOSE = 8194; // 0x2002
+    field public static final int TRANSIT_FRAGMENT_FADE = 4099; // 0x1003
+    field public static final int TRANSIT_FRAGMENT_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 3f1f664..0268087 100644
--- a/fragment/fragment/api/api_lint.ignore
+++ b/fragment/fragment/api/api_lint.ignore
@@ -27,18 +27,10 @@
     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:
diff --git a/fragment/fragment/api/public_plus_experimental_1.3.0-alpha06.txt b/fragment/fragment/api/public_plus_experimental_1.3.0-alpha06.txt
new file mode 100644
index 0000000..cce8158
--- /dev/null
+++ b/fragment/fragment/api/public_plus_experimental_1.3.0-alpha06.txt
@@ -0,0 +1,444 @@
+// 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();
+    ctor public DialogFragment(@LayoutRes int);
+    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 androidx.activity.result.ActivityResultCaller android.content.ComponentCallbacks androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.savedstate.SavedStateRegistryOwner android.view.View.OnCreateContextMenuListener androidx.lifecycle.ViewModelStoreOwner {
+    ctor public Fragment();
+    ctor @ContentView public Fragment(@LayoutRes int);
+    method public void dump(String, java.io.FileDescriptor?, java.io.PrintWriter, String![]?);
+    method public final boolean equals(Object?);
+    method public final androidx.fragment.app.FragmentActivity? getActivity();
+    method public boolean getAllowEnterTransitionOverlap();
+    method public boolean getAllowReturnTransitionOverlap();
+    method public final android.os.Bundle? getArguments();
+    method public final androidx.fragment.app.FragmentManager getChildFragmentManager();
+    method public android.content.Context? getContext();
+    method public androidx.lifecycle.ViewModelProvider.Factory getDefaultViewModelProviderFactory();
+    method public Object? getEnterTransition();
+    method public Object? getExitTransition();
+    method @Deprecated public final androidx.fragment.app.FragmentManager? getFragmentManager();
+    method public final Object? getHost();
+    method public final int getId();
+    method public final android.view.LayoutInflater getLayoutInflater();
+    method public androidx.lifecycle.Lifecycle getLifecycle();
+    method @Deprecated public androidx.loader.app.LoaderManager getLoaderManager();
+    method public final androidx.fragment.app.Fragment? getParentFragment();
+    method public final androidx.fragment.app.FragmentManager getParentFragmentManager();
+    method public Object? getReenterTransition();
+    method public final android.content.res.Resources getResources();
+    method @Deprecated public final boolean getRetainInstance();
+    method public Object? getReturnTransition();
+    method public final androidx.savedstate.SavedStateRegistry getSavedStateRegistry();
+    method public Object? getSharedElementEnterTransition();
+    method public Object? getSharedElementReturnTransition();
+    method public final String getString(@StringRes int);
+    method public final String getString(@StringRes int, java.lang.Object!...);
+    method public final String? getTag();
+    method @Deprecated public final androidx.fragment.app.Fragment? getTargetFragment();
+    method @Deprecated public final int getTargetRequestCode();
+    method public final CharSequence getText(@StringRes int);
+    method @Deprecated public boolean getUserVisibleHint();
+    method public android.view.View? getView();
+    method @MainThread public androidx.lifecycle.LifecycleOwner getViewLifecycleOwner();
+    method public androidx.lifecycle.LiveData<androidx.lifecycle.LifecycleOwner!> getViewLifecycleOwnerLiveData();
+    method public androidx.lifecycle.ViewModelStore getViewModelStore();
+    method public final int hashCode();
+    method @Deprecated public static androidx.fragment.app.Fragment instantiate(android.content.Context, String);
+    method @Deprecated public static androidx.fragment.app.Fragment instantiate(android.content.Context, String, android.os.Bundle?);
+    method public final boolean isAdded();
+    method public final boolean isDetached();
+    method public final boolean isHidden();
+    method public final boolean isInLayout();
+    method public final boolean isRemoving();
+    method public final boolean isResumed();
+    method public final boolean isStateSaved();
+    method public final boolean isVisible();
+    method @Deprecated @CallSuper @MainThread public void onActivityCreated(android.os.Bundle?);
+    method @Deprecated public void onActivityResult(int, int, android.content.Intent?);
+    method @CallSuper @MainThread public void onAttach(android.content.Context);
+    method @Deprecated @CallSuper @MainThread public void onAttach(android.app.Activity);
+    method @MainThread public void onAttachFragment(androidx.fragment.app.Fragment);
+    method @CallSuper public void onConfigurationChanged(android.content.res.Configuration);
+    method @MainThread public boolean onContextItemSelected(android.view.MenuItem);
+    method @CallSuper @MainThread public void onCreate(android.os.Bundle?);
+    method @MainThread public android.view.animation.Animation? onCreateAnimation(int, boolean, int);
+    method @MainThread public android.animation.Animator? onCreateAnimator(int, boolean, int);
+    method @MainThread public void onCreateContextMenu(android.view.ContextMenu, android.view.View, android.view.ContextMenu.ContextMenuInfo?);
+    method @MainThread public void onCreateOptionsMenu(android.view.Menu, android.view.MenuInflater);
+    method @MainThread public android.view.View? onCreateView(android.view.LayoutInflater, android.view.ViewGroup?, android.os.Bundle?);
+    method @CallSuper @MainThread public void onDestroy();
+    method @MainThread public void onDestroyOptionsMenu();
+    method @CallSuper @MainThread public void onDestroyView();
+    method @CallSuper @MainThread public void onDetach();
+    method public android.view.LayoutInflater onGetLayoutInflater(android.os.Bundle?);
+    method @MainThread public void onHiddenChanged(boolean);
+    method @CallSuper @UiThread public void onInflate(android.content.Context, android.util.AttributeSet, android.os.Bundle?);
+    method @Deprecated @CallSuper @UiThread public void onInflate(android.app.Activity, android.util.AttributeSet, android.os.Bundle?);
+    method @CallSuper @MainThread public void onLowMemory();
+    method public void onMultiWindowModeChanged(boolean);
+    method @MainThread public boolean onOptionsItemSelected(android.view.MenuItem);
+    method @MainThread public void onOptionsMenuClosed(android.view.Menu);
+    method @CallSuper @MainThread public void onPause();
+    method public void onPictureInPictureModeChanged(boolean);
+    method @MainThread public void onPrepareOptionsMenu(android.view.Menu);
+    method @MainThread public void onPrimaryNavigationFragmentChanged(boolean);
+    method @Deprecated public void onRequestPermissionsResult(int, String![], int[]);
+    method @CallSuper @MainThread public void onResume();
+    method @MainThread public void onSaveInstanceState(android.os.Bundle);
+    method @CallSuper @MainThread public void onStart();
+    method @CallSuper @MainThread public void onStop();
+    method @MainThread public void onViewCreated(android.view.View, android.os.Bundle?);
+    method @CallSuper @MainThread public void onViewStateRestored(android.os.Bundle?);
+    method public void postponeEnterTransition();
+    method public final void postponeEnterTransition(long, java.util.concurrent.TimeUnit);
+    method public final <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerForActivityResult(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+    method public final <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerForActivityResult(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultRegistry, androidx.activity.result.ActivityResultCallback<O!>);
+    method public void registerForContextMenu(android.view.View);
+    method @Deprecated public final void requestPermissions(String![], int);
+    method public final androidx.fragment.app.FragmentActivity requireActivity();
+    method public final android.os.Bundle requireArguments();
+    method public final android.content.Context requireContext();
+    method @Deprecated public final androidx.fragment.app.FragmentManager requireFragmentManager();
+    method public final Object requireHost();
+    method public final androidx.fragment.app.Fragment requireParentFragment();
+    method public final android.view.View requireView();
+    method public void setAllowEnterTransitionOverlap(boolean);
+    method public void setAllowReturnTransitionOverlap(boolean);
+    method public void setArguments(android.os.Bundle?);
+    method public void setEnterSharedElementCallback(androidx.core.app.SharedElementCallback?);
+    method public void setEnterTransition(Object?);
+    method public void setExitSharedElementCallback(androidx.core.app.SharedElementCallback?);
+    method public void setExitTransition(Object?);
+    method public void setHasOptionsMenu(boolean);
+    method public void setInitialSavedState(androidx.fragment.app.Fragment.SavedState?);
+    method public void setMenuVisibility(boolean);
+    method public void setReenterTransition(Object?);
+    method @Deprecated public void setRetainInstance(boolean);
+    method public void setReturnTransition(Object?);
+    method public void setSharedElementEnterTransition(Object?);
+    method public void setSharedElementReturnTransition(Object?);
+    method @Deprecated public void setTargetFragment(androidx.fragment.app.Fragment?, int);
+    method @Deprecated public void setUserVisibleHint(boolean);
+    method public boolean shouldShowRequestPermissionRationale(String);
+    method public void startActivity(android.content.Intent!);
+    method public void startActivity(android.content.Intent!, android.os.Bundle?);
+    method @Deprecated public void startActivityForResult(android.content.Intent!, int);
+    method @Deprecated public void startActivityForResult(android.content.Intent!, int, android.os.Bundle?);
+    method @Deprecated public void startIntentSenderForResult(android.content.IntentSender!, int, android.content.Intent?, int, int, int, android.os.Bundle?) throws android.content.IntentSender.SendIntentException;
+    method public void startPostponedEnterTransition();
+    method public void unregisterForContextMenu(android.view.View);
+  }
+
+  public static class Fragment.InstantiationException extends java.lang.RuntimeException {
+    ctor public Fragment.InstantiationException(String, Exception?);
+  }
+
+  public static class Fragment.SavedState implements android.os.Parcelable {
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<androidx.fragment.app.Fragment.SavedState!> CREATOR;
+  }
+
+  public class FragmentActivity extends androidx.activity.ComponentActivity implements androidx.core.app.ActivityCompat.OnRequestPermissionsResultCallback androidx.core.app.ActivityCompat.RequestPermissionsRequestCodeValidator {
+    ctor public FragmentActivity();
+    ctor @ContentView public FragmentActivity(@LayoutRes int);
+    method public androidx.fragment.app.FragmentManager getSupportFragmentManager();
+    method @Deprecated public androidx.loader.app.LoaderManager getSupportLoaderManager();
+    method 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 @Deprecated public void startIntentSenderFromFragment(androidx.fragment.app.Fragment, android.content.IntentSender!, int, android.content.Intent?, int, int, int, android.os.Bundle?) throws android.content.IntentSender.SendIntentException;
+    method public void supportFinishAfterTransition();
+    method @Deprecated public void supportInvalidateOptionsMenu();
+    method public void supportPostponeEnterTransition();
+    method public void supportStartPostponedEnterTransition();
+    method @Deprecated public final void validateRequestPermissionsRequestCode(int);
+  }
+
+  public abstract class FragmentContainer {
+    ctor public FragmentContainer();
+    method @Deprecated public androidx.fragment.app.Fragment instantiate(android.content.Context, String, android.os.Bundle?);
+    method public abstract android.view.View? onFindViewById(@IdRes int);
+    method public abstract boolean onHasView();
+  }
+
+  public final class FragmentContainerView extends android.widget.FrameLayout {
+    ctor public FragmentContainerView(android.content.Context);
+    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 @Deprecated public void onRequestPermissionsFromFragment(androidx.fragment.app.Fragment, String![], int);
+    method public boolean onShouldSaveFragmentState(androidx.fragment.app.Fragment);
+    method public boolean onShouldShowRequestPermissionRationale(String);
+    method public void onStartActivityFromFragment(androidx.fragment.app.Fragment, android.content.Intent!, int);
+    method public void onStartActivityFromFragment(androidx.fragment.app.Fragment, android.content.Intent!, int, android.os.Bundle?);
+    method @Deprecated public void onStartIntentSenderFromFragment(androidx.fragment.app.Fragment, android.content.IntentSender!, int, android.content.Intent?, int, int, int, android.os.Bundle?) throws android.content.IntentSender.SendIntentException;
+    method public void onSupportInvalidateOptionsMenu();
+  }
+
+  public abstract class FragmentManager implements androidx.fragment.app.FragmentResultOwner {
+    ctor public FragmentManager();
+    method public void addOnBackStackChangedListener(androidx.fragment.app.FragmentManager.OnBackStackChangedListener);
+    method public androidx.fragment.app.FragmentTransaction beginTransaction();
+    method public final void clearFragmentResult(String);
+    method public final void clearFragmentResultListener(String);
+    method public void dump(String, java.io.FileDescriptor?, java.io.PrintWriter, String![]?);
+    method @Deprecated public static void enableDebugLogging(boolean);
+    method public boolean executePendingTransactions();
+    method public static <F extends androidx.fragment.app.Fragment> F findFragment(android.view.View);
+    method public androidx.fragment.app.Fragment? findFragmentById(@IdRes int);
+    method public androidx.fragment.app.Fragment? findFragmentByTag(String?);
+    method public androidx.fragment.app.FragmentManager.BackStackEntry getBackStackEntryAt(int);
+    method public int getBackStackEntryCount();
+    method public androidx.fragment.app.Fragment? getFragment(android.os.Bundle, String);
+    method public androidx.fragment.app.FragmentFactory getFragmentFactory();
+    method public java.util.List<androidx.fragment.app.Fragment!> getFragments();
+    method public androidx.fragment.app.Fragment? getPrimaryNavigationFragment();
+    method public 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 final void setFragmentResult(String, android.os.Bundle);
+    method public final void setFragmentResultListener(String, androidx.lifecycle.LifecycleOwner, androidx.fragment.app.FragmentResultListener);
+    method public void unregisterFragmentLifecycleCallbacks(androidx.fragment.app.FragmentManager.FragmentLifecycleCallbacks);
+    field public static final int POP_BACK_STACK_INCLUSIVE = 1; // 0x1
+  }
+
+  public static interface FragmentManager.BackStackEntry {
+    method @Deprecated public CharSequence? getBreadCrumbShortTitle();
+    method @Deprecated @StringRes public int getBreadCrumbShortTitleRes();
+    method @Deprecated public CharSequence? getBreadCrumbTitle();
+    method @Deprecated @StringRes public int getBreadCrumbTitleRes();
+    method public int getId();
+    method public String? getName();
+  }
+
+  public abstract static class FragmentManager.FragmentLifecycleCallbacks {
+    ctor public FragmentManager.FragmentLifecycleCallbacks();
+    method @Deprecated public void onFragmentActivityCreated(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.os.Bundle?);
+    method public void onFragmentAttached(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.content.Context);
+    method public void onFragmentCreated(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.os.Bundle?);
+    method public void onFragmentDestroyed(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
+    method public void onFragmentDetached(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
+    method public void onFragmentPaused(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
+    method public void onFragmentPreAttached(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.content.Context);
+    method public void onFragmentPreCreated(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.os.Bundle?);
+    method public void onFragmentResumed(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
+    method public void onFragmentSaveInstanceState(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.os.Bundle);
+    method public void onFragmentStarted(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
+    method public void onFragmentStopped(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
+    method public void onFragmentViewCreated(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.view.View, android.os.Bundle?);
+    method public void onFragmentViewDestroyed(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
+  }
+
+  public static interface FragmentManager.OnBackStackChangedListener {
+    method @MainThread public void onBackStackChanged();
+  }
+
+  @Deprecated public class FragmentManagerNonConfig {
+  }
+
+  @Deprecated public abstract class FragmentPagerAdapter extends androidx.viewpager.widget.PagerAdapter {
+    ctor @Deprecated public FragmentPagerAdapter(androidx.fragment.app.FragmentManager);
+    ctor @Deprecated public FragmentPagerAdapter(androidx.fragment.app.FragmentManager, int);
+    method @Deprecated public abstract androidx.fragment.app.Fragment getItem(int);
+    method @Deprecated public long getItemId(int);
+    method @Deprecated public boolean isViewFromObject(android.view.View, Object);
+    field @Deprecated public static final int BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT = 1; // 0x1
+    field @Deprecated public static final int BEHAVIOR_SET_USER_VISIBLE_HINT = 0; // 0x0
+  }
+
+  public interface FragmentResultListener {
+    method public void onFragmentResult(String, android.os.Bundle);
+  }
+
+  public interface FragmentResultOwner {
+    method public void clearFragmentResult(String);
+    method public void clearFragmentResultListener(String);
+    method public void setFragmentResult(String, android.os.Bundle);
+    method public void setFragmentResultListener(String, androidx.lifecycle.LifecycleOwner, androidx.fragment.app.FragmentResultListener);
+  }
+
+  @Deprecated public abstract class FragmentStatePagerAdapter extends androidx.viewpager.widget.PagerAdapter {
+    ctor @Deprecated public FragmentStatePagerAdapter(androidx.fragment.app.FragmentManager);
+    ctor @Deprecated public FragmentStatePagerAdapter(androidx.fragment.app.FragmentManager, int);
+    method @Deprecated public abstract androidx.fragment.app.Fragment getItem(int);
+    method @Deprecated public boolean isViewFromObject(android.view.View, Object);
+    field @Deprecated public static final int BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT = 1; // 0x1
+    field @Deprecated public static final int BEHAVIOR_SET_USER_VISIBLE_HINT = 0; // 0x0
+  }
+
+  @Deprecated public class FragmentTabHost extends android.widget.TabHost implements android.widget.TabHost.OnTabChangeListener {
+    ctor @Deprecated public FragmentTabHost(android.content.Context);
+    ctor @Deprecated public FragmentTabHost(android.content.Context, android.util.AttributeSet?);
+    method @Deprecated public void addTab(android.widget.TabHost.TabSpec, Class<?>, android.os.Bundle?);
+    method @Deprecated public void onTabChanged(String?);
+    method @Deprecated public void setup(android.content.Context, androidx.fragment.app.FragmentManager);
+    method @Deprecated public void setup(android.content.Context, androidx.fragment.app.FragmentManager, int);
+  }
+
+  public abstract class FragmentTransaction {
+    ctor @Deprecated public FragmentTransaction();
+    method public final androidx.fragment.app.FragmentTransaction add(Class<? extends androidx.fragment.app.Fragment>, android.os.Bundle?, String?);
+    method public androidx.fragment.app.FragmentTransaction add(androidx.fragment.app.Fragment, String?);
+    method public final androidx.fragment.app.FragmentTransaction add(@IdRes int, Class<? extends androidx.fragment.app.Fragment>, android.os.Bundle?);
+    method public androidx.fragment.app.FragmentTransaction add(@IdRes int, androidx.fragment.app.Fragment);
+    method public final androidx.fragment.app.FragmentTransaction add(@IdRes int, Class<? extends androidx.fragment.app.Fragment>, android.os.Bundle?, String?);
+    method public androidx.fragment.app.FragmentTransaction add(@IdRes int, androidx.fragment.app.Fragment, String?);
+    method public androidx.fragment.app.FragmentTransaction addSharedElement(android.view.View, String);
+    method public androidx.fragment.app.FragmentTransaction addToBackStack(String?);
+    method public androidx.fragment.app.FragmentTransaction attach(androidx.fragment.app.Fragment);
+    method public abstract int commit();
+    method public abstract int commitAllowingStateLoss();
+    method public abstract void commitNow();
+    method public abstract void commitNowAllowingStateLoss();
+    method public androidx.fragment.app.FragmentTransaction detach(androidx.fragment.app.Fragment);
+    method public androidx.fragment.app.FragmentTransaction disallowAddToBackStack();
+    method public androidx.fragment.app.FragmentTransaction hide(androidx.fragment.app.Fragment);
+    method public boolean isAddToBackStackAllowed();
+    method public boolean isEmpty();
+    method public androidx.fragment.app.FragmentTransaction remove(androidx.fragment.app.Fragment);
+    method public final androidx.fragment.app.FragmentTransaction replace(@IdRes int, Class<? extends androidx.fragment.app.Fragment>, android.os.Bundle?);
+    method public androidx.fragment.app.FragmentTransaction replace(@IdRes int, androidx.fragment.app.Fragment);
+    method public final androidx.fragment.app.FragmentTransaction replace(@IdRes int, Class<? extends androidx.fragment.app.Fragment>, android.os.Bundle?, String?);
+    method public androidx.fragment.app.FragmentTransaction replace(@IdRes int, androidx.fragment.app.Fragment, String?);
+    method public androidx.fragment.app.FragmentTransaction runOnCommit(Runnable);
+    method @Deprecated public androidx.fragment.app.FragmentTransaction setAllowOptimization(boolean);
+    method @Deprecated public androidx.fragment.app.FragmentTransaction setBreadCrumbShortTitle(@StringRes int);
+    method @Deprecated public androidx.fragment.app.FragmentTransaction setBreadCrumbShortTitle(CharSequence?);
+    method @Deprecated public androidx.fragment.app.FragmentTransaction setBreadCrumbTitle(@StringRes int);
+    method @Deprecated public androidx.fragment.app.FragmentTransaction setBreadCrumbTitle(CharSequence?);
+    method public androidx.fragment.app.FragmentTransaction setCustomAnimations(@AnimRes @AnimatorRes int, @AnimRes @AnimatorRes int);
+    method public androidx.fragment.app.FragmentTransaction setCustomAnimations(@AnimRes @AnimatorRes int, @AnimRes @AnimatorRes int, @AnimRes @AnimatorRes int, @AnimRes @AnimatorRes int);
+    method public androidx.fragment.app.FragmentTransaction setMaxLifecycle(androidx.fragment.app.Fragment, androidx.lifecycle.Lifecycle.State);
+    method public androidx.fragment.app.FragmentTransaction setPrimaryNavigationFragment(androidx.fragment.app.Fragment?);
+    method public androidx.fragment.app.FragmentTransaction setReorderingAllowed(boolean);
+    method public androidx.fragment.app.FragmentTransaction setTransition(int);
+    method @Deprecated public androidx.fragment.app.FragmentTransaction setTransitionStyle(@StyleRes int);
+    method public androidx.fragment.app.FragmentTransaction show(androidx.fragment.app.Fragment);
+    field public static final int TRANSIT_ENTER_MASK = 4096; // 0x1000
+    field public static final int TRANSIT_EXIT_MASK = 8192; // 0x2000
+    field public static final int TRANSIT_FRAGMENT_CLOSE = 8194; // 0x2002
+    field public static final int TRANSIT_FRAGMENT_FADE = 4099; // 0x1003
+    field public static final int TRANSIT_FRAGMENT_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/res-1.3.0-alpha06.txt b/fragment/fragment/api/res-1.3.0-alpha06.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/fragment/fragment/api/res-1.3.0-alpha06.txt
diff --git a/fragment/fragment/api/restricted_1.3.0-alpha06.txt b/fragment/fragment/api/restricted_1.3.0-alpha06.txt
new file mode 100644
index 0000000..76caf91
--- /dev/null
+++ b/fragment/fragment/api/restricted_1.3.0-alpha06.txt
@@ -0,0 +1,474 @@
+// 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();
+    ctor public DialogFragment(@LayoutRes int);
+    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 androidx.activity.result.ActivityResultCaller android.content.ComponentCallbacks androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.savedstate.SavedStateRegistryOwner android.view.View.OnCreateContextMenuListener androidx.lifecycle.ViewModelStoreOwner {
+    ctor public Fragment();
+    ctor @ContentView public Fragment(@LayoutRes int);
+    method public void dump(String, java.io.FileDescriptor?, java.io.PrintWriter, String![]?);
+    method public final boolean equals(Object?);
+    method public final androidx.fragment.app.FragmentActivity? getActivity();
+    method public boolean getAllowEnterTransitionOverlap();
+    method public boolean getAllowReturnTransitionOverlap();
+    method public final android.os.Bundle? getArguments();
+    method public final androidx.fragment.app.FragmentManager getChildFragmentManager();
+    method public android.content.Context? getContext();
+    method public androidx.lifecycle.ViewModelProvider.Factory getDefaultViewModelProviderFactory();
+    method public Object? getEnterTransition();
+    method public Object? getExitTransition();
+    method @Deprecated public final androidx.fragment.app.FragmentManager? getFragmentManager();
+    method public final Object? getHost();
+    method public final int getId();
+    method public final android.view.LayoutInflater getLayoutInflater();
+    method @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.view.LayoutInflater getLayoutInflater(android.os.Bundle?);
+    method public androidx.lifecycle.Lifecycle getLifecycle();
+    method @Deprecated public androidx.loader.app.LoaderManager getLoaderManager();
+    method public final androidx.fragment.app.Fragment? getParentFragment();
+    method public final androidx.fragment.app.FragmentManager getParentFragmentManager();
+    method public Object? getReenterTransition();
+    method public final android.content.res.Resources getResources();
+    method @Deprecated public final boolean getRetainInstance();
+    method public Object? getReturnTransition();
+    method public final androidx.savedstate.SavedStateRegistry getSavedStateRegistry();
+    method public Object? getSharedElementEnterTransition();
+    method public Object? getSharedElementReturnTransition();
+    method public final String getString(@StringRes int);
+    method public final String getString(@StringRes int, java.lang.Object!...);
+    method public final String? getTag();
+    method @Deprecated public final androidx.fragment.app.Fragment? getTargetFragment();
+    method @Deprecated public final int getTargetRequestCode();
+    method public final CharSequence getText(@StringRes int);
+    method @Deprecated public boolean getUserVisibleHint();
+    method public android.view.View? getView();
+    method @MainThread public androidx.lifecycle.LifecycleOwner getViewLifecycleOwner();
+    method public androidx.lifecycle.LiveData<androidx.lifecycle.LifecycleOwner!> getViewLifecycleOwnerLiveData();
+    method public androidx.lifecycle.ViewModelStore getViewModelStore();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final boolean hasOptionsMenu();
+    method public final int hashCode();
+    method @Deprecated public static androidx.fragment.app.Fragment instantiate(android.content.Context, String);
+    method @Deprecated public static androidx.fragment.app.Fragment instantiate(android.content.Context, String, android.os.Bundle?);
+    method public final boolean isAdded();
+    method public final boolean isDetached();
+    method public final boolean isHidden();
+    method public final boolean isInLayout();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final boolean isMenuVisible();
+    method public final boolean isRemoving();
+    method public final boolean isResumed();
+    method public final boolean isStateSaved();
+    method public final boolean isVisible();
+    method @Deprecated @CallSuper @MainThread public void onActivityCreated(android.os.Bundle?);
+    method @Deprecated public void onActivityResult(int, int, android.content.Intent?);
+    method @CallSuper @MainThread public void onAttach(android.content.Context);
+    method @Deprecated @CallSuper @MainThread public void onAttach(android.app.Activity);
+    method @MainThread public void onAttachFragment(androidx.fragment.app.Fragment);
+    method @CallSuper public void onConfigurationChanged(android.content.res.Configuration);
+    method @MainThread public boolean onContextItemSelected(android.view.MenuItem);
+    method @CallSuper @MainThread public void onCreate(android.os.Bundle?);
+    method @MainThread public android.view.animation.Animation? onCreateAnimation(int, boolean, int);
+    method @MainThread public android.animation.Animator? onCreateAnimator(int, boolean, int);
+    method @MainThread public void onCreateContextMenu(android.view.ContextMenu, android.view.View, android.view.ContextMenu.ContextMenuInfo?);
+    method @MainThread public void onCreateOptionsMenu(android.view.Menu, android.view.MenuInflater);
+    method @MainThread public android.view.View? onCreateView(android.view.LayoutInflater, android.view.ViewGroup?, android.os.Bundle?);
+    method @CallSuper @MainThread public void onDestroy();
+    method @MainThread public void onDestroyOptionsMenu();
+    method @CallSuper @MainThread public void onDestroyView();
+    method @CallSuper @MainThread public void onDetach();
+    method public android.view.LayoutInflater onGetLayoutInflater(android.os.Bundle?);
+    method @MainThread public void onHiddenChanged(boolean);
+    method @CallSuper @UiThread public void onInflate(android.content.Context, android.util.AttributeSet, android.os.Bundle?);
+    method @Deprecated @CallSuper @UiThread public void onInflate(android.app.Activity, android.util.AttributeSet, android.os.Bundle?);
+    method @CallSuper @MainThread public void onLowMemory();
+    method public void onMultiWindowModeChanged(boolean);
+    method @MainThread public boolean onOptionsItemSelected(android.view.MenuItem);
+    method @MainThread public void onOptionsMenuClosed(android.view.Menu);
+    method @CallSuper @MainThread public void onPause();
+    method public void onPictureInPictureModeChanged(boolean);
+    method @MainThread public void onPrepareOptionsMenu(android.view.Menu);
+    method @MainThread public void onPrimaryNavigationFragmentChanged(boolean);
+    method @Deprecated public void onRequestPermissionsResult(int, String![], int[]);
+    method @CallSuper @MainThread public void onResume();
+    method @MainThread public void onSaveInstanceState(android.os.Bundle);
+    method @CallSuper @MainThread public void onStart();
+    method @CallSuper @MainThread public void onStop();
+    method @MainThread public void onViewCreated(android.view.View, android.os.Bundle?);
+    method @CallSuper @MainThread public void onViewStateRestored(android.os.Bundle?);
+    method public void postponeEnterTransition();
+    method public final void postponeEnterTransition(long, java.util.concurrent.TimeUnit);
+    method public final <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerForActivityResult(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+    method public final <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerForActivityResult(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultRegistry, androidx.activity.result.ActivityResultCallback<O!>);
+    method public void registerForContextMenu(android.view.View);
+    method @Deprecated public final void requestPermissions(String![], int);
+    method public final androidx.fragment.app.FragmentActivity requireActivity();
+    method public final android.os.Bundle requireArguments();
+    method public final android.content.Context requireContext();
+    method @Deprecated public final androidx.fragment.app.FragmentManager requireFragmentManager();
+    method public final Object requireHost();
+    method public final androidx.fragment.app.Fragment requireParentFragment();
+    method public final android.view.View requireView();
+    method public void setAllowEnterTransitionOverlap(boolean);
+    method public void setAllowReturnTransitionOverlap(boolean);
+    method public void setArguments(android.os.Bundle?);
+    method public void setEnterSharedElementCallback(androidx.core.app.SharedElementCallback?);
+    method public void setEnterTransition(Object?);
+    method public void setExitSharedElementCallback(androidx.core.app.SharedElementCallback?);
+    method public void setExitTransition(Object?);
+    method public void setHasOptionsMenu(boolean);
+    method public void setInitialSavedState(androidx.fragment.app.Fragment.SavedState?);
+    method public void setMenuVisibility(boolean);
+    method public void setReenterTransition(Object?);
+    method @Deprecated public void setRetainInstance(boolean);
+    method public void setReturnTransition(Object?);
+    method public void setSharedElementEnterTransition(Object?);
+    method public void setSharedElementReturnTransition(Object?);
+    method @Deprecated public void setTargetFragment(androidx.fragment.app.Fragment?, int);
+    method @Deprecated public void setUserVisibleHint(boolean);
+    method public boolean shouldShowRequestPermissionRationale(String);
+    method public void startActivity(android.content.Intent!);
+    method public void startActivity(android.content.Intent!, android.os.Bundle?);
+    method @Deprecated public void startActivityForResult(android.content.Intent!, int);
+    method @Deprecated public void startActivityForResult(android.content.Intent!, int, android.os.Bundle?);
+    method @Deprecated public void startIntentSenderForResult(android.content.IntentSender!, int, android.content.Intent?, int, int, int, android.os.Bundle?) throws android.content.IntentSender.SendIntentException;
+    method public void startPostponedEnterTransition();
+    method public void unregisterForContextMenu(android.view.View);
+  }
+
+  public static class Fragment.InstantiationException extends java.lang.RuntimeException {
+    ctor public Fragment.InstantiationException(String, Exception?);
+  }
+
+  public static class Fragment.SavedState implements android.os.Parcelable {
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<androidx.fragment.app.Fragment.SavedState!> CREATOR;
+  }
+
+  public class FragmentActivity extends androidx.activity.ComponentActivity implements androidx.core.app.ActivityCompat.OnRequestPermissionsResultCallback androidx.core.app.ActivityCompat.RequestPermissionsRequestCodeValidator {
+    ctor public FragmentActivity();
+    ctor @ContentView public FragmentActivity(@LayoutRes int);
+    method public androidx.fragment.app.FragmentManager getSupportFragmentManager();
+    method @Deprecated public androidx.loader.app.LoaderManager getSupportLoaderManager();
+    method 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 @Deprecated public void startIntentSenderFromFragment(androidx.fragment.app.Fragment, android.content.IntentSender!, int, android.content.Intent?, int, int, int, android.os.Bundle?) throws android.content.IntentSender.SendIntentException;
+    method public void supportFinishAfterTransition();
+    method @Deprecated public void supportInvalidateOptionsMenu();
+    method public void supportPostponeEnterTransition();
+    method public void supportStartPostponedEnterTransition();
+    method @Deprecated public final void validateRequestPermissionsRequestCode(int);
+  }
+
+  public abstract class FragmentContainer {
+    ctor public FragmentContainer();
+    method @Deprecated public androidx.fragment.app.Fragment instantiate(android.content.Context, String, android.os.Bundle?);
+    method public abstract android.view.View? onFindViewById(@IdRes int);
+    method public abstract boolean onHasView();
+  }
+
+  public final class FragmentContainerView extends android.widget.FrameLayout {
+    ctor public FragmentContainerView(android.content.Context);
+    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 @Deprecated public void onRequestPermissionsFromFragment(androidx.fragment.app.Fragment, String![], int);
+    method public boolean onShouldSaveFragmentState(androidx.fragment.app.Fragment);
+    method public boolean onShouldShowRequestPermissionRationale(String);
+    method public void onStartActivityFromFragment(androidx.fragment.app.Fragment, android.content.Intent!, int);
+    method public void onStartActivityFromFragment(androidx.fragment.app.Fragment, android.content.Intent!, int, android.os.Bundle?);
+    method @Deprecated public void onStartIntentSenderFromFragment(androidx.fragment.app.Fragment, android.content.IntentSender!, int, android.content.Intent?, int, int, int, android.os.Bundle?) throws android.content.IntentSender.SendIntentException;
+    method public void onSupportInvalidateOptionsMenu();
+  }
+
+  public abstract class FragmentManager implements androidx.fragment.app.FragmentResultOwner {
+    ctor public FragmentManager();
+    method public void addOnBackStackChangedListener(androidx.fragment.app.FragmentManager.OnBackStackChangedListener);
+    method public androidx.fragment.app.FragmentTransaction beginTransaction();
+    method public final void clearFragmentResult(String);
+    method public final void clearFragmentResultListener(String);
+    method public void dump(String, java.io.FileDescriptor?, java.io.PrintWriter, String![]?);
+    method @Deprecated public static void enableDebugLogging(boolean);
+    method public boolean executePendingTransactions();
+    method public static <F extends androidx.fragment.app.Fragment> F findFragment(android.view.View);
+    method public androidx.fragment.app.Fragment? findFragmentById(@IdRes int);
+    method public androidx.fragment.app.Fragment? findFragmentByTag(String?);
+    method public androidx.fragment.app.FragmentManager.BackStackEntry getBackStackEntryAt(int);
+    method public int getBackStackEntryCount();
+    method public androidx.fragment.app.Fragment? getFragment(android.os.Bundle, String);
+    method public androidx.fragment.app.FragmentFactory getFragmentFactory();
+    method public java.util.List<androidx.fragment.app.Fragment!> getFragments();
+    method public androidx.fragment.app.Fragment? getPrimaryNavigationFragment();
+    method public 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 final void setFragmentResult(String, android.os.Bundle);
+    method public final void setFragmentResultListener(String, androidx.lifecycle.LifecycleOwner, androidx.fragment.app.FragmentResultListener);
+    method public void unregisterFragmentLifecycleCallbacks(androidx.fragment.app.FragmentManager.FragmentLifecycleCallbacks);
+    field public static final int POP_BACK_STACK_INCLUSIVE = 1; // 0x1
+  }
+
+  public static interface FragmentManager.BackStackEntry {
+    method @Deprecated public CharSequence? getBreadCrumbShortTitle();
+    method @Deprecated @StringRes public int getBreadCrumbShortTitleRes();
+    method @Deprecated public CharSequence? getBreadCrumbTitle();
+    method @Deprecated @StringRes public int getBreadCrumbTitleRes();
+    method public int getId();
+    method public String? getName();
+  }
+
+  public abstract static class FragmentManager.FragmentLifecycleCallbacks {
+    ctor public FragmentManager.FragmentLifecycleCallbacks();
+    method @Deprecated public void onFragmentActivityCreated(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.os.Bundle?);
+    method public void onFragmentAttached(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.content.Context);
+    method public void onFragmentCreated(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.os.Bundle?);
+    method public void onFragmentDestroyed(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
+    method public void onFragmentDetached(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
+    method public void onFragmentPaused(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
+    method public void onFragmentPreAttached(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.content.Context);
+    method public void onFragmentPreCreated(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.os.Bundle?);
+    method public void onFragmentResumed(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
+    method public void onFragmentSaveInstanceState(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.os.Bundle);
+    method public void onFragmentStarted(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
+    method public void onFragmentStopped(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
+    method public void onFragmentViewCreated(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.view.View, android.os.Bundle?);
+    method public void onFragmentViewDestroyed(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
+  }
+
+  public static interface FragmentManager.OnBackStackChangedListener {
+    method @MainThread public void onBackStackChanged();
+  }
+
+  @Deprecated public class FragmentManagerNonConfig {
+  }
+
+  @Deprecated public abstract class FragmentPagerAdapter extends androidx.viewpager.widget.PagerAdapter {
+    ctor @Deprecated public FragmentPagerAdapter(androidx.fragment.app.FragmentManager);
+    ctor @Deprecated public FragmentPagerAdapter(androidx.fragment.app.FragmentManager, int);
+    method @Deprecated public abstract androidx.fragment.app.Fragment getItem(int);
+    method @Deprecated public long getItemId(int);
+    method @Deprecated public boolean isViewFromObject(android.view.View, Object);
+    field @Deprecated public static final int BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT = 1; // 0x1
+    field @Deprecated public static final int BEHAVIOR_SET_USER_VISIBLE_HINT = 0; // 0x0
+  }
+
+  public interface FragmentResultListener {
+    method public void onFragmentResult(String, android.os.Bundle);
+  }
+
+  public interface FragmentResultOwner {
+    method public void clearFragmentResult(String);
+    method public void clearFragmentResultListener(String);
+    method public void setFragmentResult(String, android.os.Bundle);
+    method public void setFragmentResultListener(String, androidx.lifecycle.LifecycleOwner, androidx.fragment.app.FragmentResultListener);
+  }
+
+  @Deprecated public abstract class FragmentStatePagerAdapter extends androidx.viewpager.widget.PagerAdapter {
+    ctor @Deprecated public FragmentStatePagerAdapter(androidx.fragment.app.FragmentManager);
+    ctor @Deprecated public FragmentStatePagerAdapter(androidx.fragment.app.FragmentManager, int);
+    method @Deprecated public abstract androidx.fragment.app.Fragment getItem(int);
+    method @Deprecated public boolean isViewFromObject(android.view.View, Object);
+    field @Deprecated public static final int BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT = 1; // 0x1
+    field @Deprecated public static final int BEHAVIOR_SET_USER_VISIBLE_HINT = 0; // 0x0
+  }
+
+  @Deprecated public class FragmentTabHost extends android.widget.TabHost implements android.widget.TabHost.OnTabChangeListener {
+    ctor @Deprecated public FragmentTabHost(android.content.Context);
+    ctor @Deprecated public FragmentTabHost(android.content.Context, android.util.AttributeSet?);
+    method @Deprecated public void addTab(android.widget.TabHost.TabSpec, Class<?>, android.os.Bundle?);
+    method @Deprecated public void onTabChanged(String?);
+    method @Deprecated public void setup(android.content.Context, androidx.fragment.app.FragmentManager);
+    method @Deprecated public void setup(android.content.Context, androidx.fragment.app.FragmentManager, int);
+  }
+
+  public abstract class FragmentTransaction {
+    ctor @Deprecated public FragmentTransaction();
+    method public final androidx.fragment.app.FragmentTransaction add(Class<? extends androidx.fragment.app.Fragment>, android.os.Bundle?, String?);
+    method public androidx.fragment.app.FragmentTransaction add(androidx.fragment.app.Fragment, String?);
+    method public final androidx.fragment.app.FragmentTransaction add(@IdRes int, Class<? extends androidx.fragment.app.Fragment>, android.os.Bundle?);
+    method public androidx.fragment.app.FragmentTransaction add(@IdRes int, androidx.fragment.app.Fragment);
+    method public final androidx.fragment.app.FragmentTransaction add(@IdRes int, Class<? extends androidx.fragment.app.Fragment>, android.os.Bundle?, String?);
+    method public androidx.fragment.app.FragmentTransaction add(@IdRes int, androidx.fragment.app.Fragment, String?);
+    method public androidx.fragment.app.FragmentTransaction addSharedElement(android.view.View, String);
+    method public androidx.fragment.app.FragmentTransaction addToBackStack(String?);
+    method public androidx.fragment.app.FragmentTransaction attach(androidx.fragment.app.Fragment);
+    method public abstract int commit();
+    method public abstract int commitAllowingStateLoss();
+    method public abstract void commitNow();
+    method public abstract void commitNowAllowingStateLoss();
+    method public androidx.fragment.app.FragmentTransaction detach(androidx.fragment.app.Fragment);
+    method public androidx.fragment.app.FragmentTransaction disallowAddToBackStack();
+    method public androidx.fragment.app.FragmentTransaction hide(androidx.fragment.app.Fragment);
+    method public boolean isAddToBackStackAllowed();
+    method public boolean isEmpty();
+    method public androidx.fragment.app.FragmentTransaction remove(androidx.fragment.app.Fragment);
+    method public final androidx.fragment.app.FragmentTransaction replace(@IdRes int, Class<? extends androidx.fragment.app.Fragment>, android.os.Bundle?);
+    method public androidx.fragment.app.FragmentTransaction replace(@IdRes int, androidx.fragment.app.Fragment);
+    method public final androidx.fragment.app.FragmentTransaction replace(@IdRes int, Class<? extends androidx.fragment.app.Fragment>, android.os.Bundle?, String?);
+    method public androidx.fragment.app.FragmentTransaction replace(@IdRes int, androidx.fragment.app.Fragment, String?);
+    method public androidx.fragment.app.FragmentTransaction runOnCommit(Runnable);
+    method @Deprecated public androidx.fragment.app.FragmentTransaction setAllowOptimization(boolean);
+    method @Deprecated public androidx.fragment.app.FragmentTransaction setBreadCrumbShortTitle(@StringRes int);
+    method @Deprecated public androidx.fragment.app.FragmentTransaction setBreadCrumbShortTitle(CharSequence?);
+    method @Deprecated public androidx.fragment.app.FragmentTransaction setBreadCrumbTitle(@StringRes int);
+    method @Deprecated public androidx.fragment.app.FragmentTransaction setBreadCrumbTitle(CharSequence?);
+    method public androidx.fragment.app.FragmentTransaction setCustomAnimations(@AnimRes @AnimatorRes int, @AnimRes @AnimatorRes int);
+    method public androidx.fragment.app.FragmentTransaction setCustomAnimations(@AnimRes @AnimatorRes int, @AnimRes @AnimatorRes int, @AnimRes @AnimatorRes int, @AnimRes @AnimatorRes int);
+    method public androidx.fragment.app.FragmentTransaction setMaxLifecycle(androidx.fragment.app.Fragment, androidx.lifecycle.Lifecycle.State);
+    method public androidx.fragment.app.FragmentTransaction setPrimaryNavigationFragment(androidx.fragment.app.Fragment?);
+    method public androidx.fragment.app.FragmentTransaction setReorderingAllowed(boolean);
+    method public androidx.fragment.app.FragmentTransaction setTransition(int);
+    method @Deprecated public androidx.fragment.app.FragmentTransaction setTransitionStyle(@StyleRes int);
+    method public androidx.fragment.app.FragmentTransaction show(androidx.fragment.app.Fragment);
+    field public static final int TRANSIT_ENTER_MASK = 4096; // 0x1000
+    field public static final int TRANSIT_EXIT_MASK = 8192; // 0x2000
+    field public static final int TRANSIT_FRAGMENT_CLOSE = 8194; // 0x2002
+    field public static final int TRANSIT_FRAGMENT_FADE = 4099; // 0x1003
+    field public static final int TRANSIT_FRAGMENT_OPEN = 4097; // 0x1001
+    field public static final int TRANSIT_NONE = 0; // 0x0
+    field public static final int TRANSIT_UNSET = -1; // 0xffffffff
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public abstract class FragmentTransitionImpl {
+    ctor public FragmentTransitionImpl();
+    method public abstract void addTarget(Object!, android.view.View!);
+    method public abstract void addTargets(Object!, java.util.ArrayList<android.view.View!>!);
+    method public abstract void beginDelayedTransition(android.view.ViewGroup!, Object!);
+    method protected static void bfsAddViewChildren(java.util.List<android.view.View!>!, android.view.View!);
+    method public abstract boolean canHandle(Object!);
+    method public abstract Object! cloneTransition(Object!);
+    method protected void getBoundsOnScreen(android.view.View!, android.graphics.Rect!);
+    method protected static boolean isNullOrEmpty(java.util.List!);
+    method public abstract Object! mergeTransitionsInSequence(Object!, Object!, Object!);
+    method public abstract Object! mergeTransitionsTogether(Object!, Object!, Object!);
+    method public abstract void removeTarget(Object!, android.view.View!);
+    method public abstract void replaceTargets(Object!, java.util.ArrayList<android.view.View!>!, java.util.ArrayList<android.view.View!>!);
+    method public abstract void scheduleHideFragmentView(Object!, android.view.View!, java.util.ArrayList<android.view.View!>!);
+    method public abstract void scheduleRemoveTargets(Object!, Object!, java.util.ArrayList<android.view.View!>!, Object!, java.util.ArrayList<android.view.View!>!, Object!, java.util.ArrayList<android.view.View!>!);
+    method public abstract void setEpicenter(Object!, android.view.View!);
+    method public abstract void setEpicenter(Object!, android.graphics.Rect!);
+    method public void setListenerForTransitionEnd(androidx.fragment.app.Fragment, Object, androidx.core.os.CancellationSignal, Runnable);
+    method public abstract void setSharedElementTargets(Object!, android.view.View!, java.util.ArrayList<android.view.View!>!);
+    method public abstract void swapSharedElementTargets(Object!, java.util.ArrayList<android.view.View!>!, java.util.ArrayList<android.view.View!>!);
+    method public abstract Object! wrapTransitionInSet(Object!);
+  }
+
+  public class ListFragment extends androidx.fragment.app.Fragment {
+    ctor public ListFragment();
+    method public android.widget.ListAdapter? getListAdapter();
+    method public android.widget.ListView getListView();
+    method public long getSelectedItemId();
+    method public int getSelectedItemPosition();
+    method public void onListItemClick(android.widget.ListView, android.view.View, int, long);
+    method public final android.widget.ListAdapter requireListAdapter();
+    method public void setEmptyText(CharSequence?);
+    method public void setListAdapter(android.widget.ListAdapter?);
+    method public void setListShown(boolean);
+    method public void setListShownNoAnimation(boolean);
+    method public void setSelection(int);
+  }
+
+}
+
diff --git a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentReceiveResultTest.kt b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentReceiveResultTest.kt
index fd65a6f..5dfdb3d 100644
--- a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentReceiveResultTest.kt
+++ b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentReceiveResultTest.kt
@@ -22,6 +22,7 @@
 import androidx.fragment.app.test.FragmentResultActivity
 import androidx.fragment.app.test.FragmentTestActivity
 import androidx.fragment.test.R
+import androidx.test.annotation.UiThreadTest
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
 import androidx.test.platform.app.InstrumentationRegistry
@@ -56,7 +57,10 @@
 
     @Suppress("DEPRECATION")
     @Test
+    @UiThreadTest
     fun testNoFragmentOnActivityResult() {
+        activity.supportFragmentManager.saveAllState()
+
         // 0xffff is the request code for the startActivityResult launcher in FragmentManager
         activity.onActivityResult(0xffff, Activity.RESULT_OK, Intent())
     }
diff --git a/fragment/fragment/src/androidTest/java/androidx/fragment/app/test/FragmentTestActivity.kt b/fragment/fragment/src/androidTest/java/androidx/fragment/app/test/FragmentTestActivity.kt
index 83c45c1..597ee6a 100644
--- a/fragment/fragment/src/androidTest/java/androidx/fragment/app/test/FragmentTestActivity.kt
+++ b/fragment/fragment/src/androidTest/java/androidx/fragment/app/test/FragmentTestActivity.kt
@@ -38,6 +38,8 @@
     @Suppress("DEPRECATION")
     public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
         super.onActivityResult(requestCode, resultCode, data)
+        supportFragmentManager.beginTransaction()
+            .commitNow()
     }
 
     class ParentFragment : Fragment() {
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentActivity.java b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentActivity.java
index 6d8ff8c..194c9eb 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentActivity.java
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentActivity.java
@@ -119,6 +119,15 @@
     // HOOKS INTO ACTIVITY
     // ------------------------------------------------------------------------
 
+    @SuppressWarnings("deprecation")
+    @Override
+    @CallSuper
+    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
+        mFragments.noteStateNotSaved();
+        super.onActivityResult(requestCode, resultCode, data);
+    }
+
+
     /**
      * Reverses the Activity Scene entry Transition and triggers the calling Activity
      * to reverse its exit Transition. When the exit Transition completes,
@@ -561,6 +570,15 @@
     @Deprecated
     public final void validateRequestPermissionsRequestCode(int requestCode) { }
 
+    @SuppressWarnings("deprecation")
+    @CallSuper
+    @Override
+    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
+            @NonNull int[] grantResults) {
+        mFragments.noteStateNotSaved();
+        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+    }
+
     /**
      * Called by Fragment.startActivityForResult() to implement its behavior.
      *
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 c06c661..da3933b 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentManager.java
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentManager.java
@@ -2768,7 +2768,6 @@
                                                 + fragmentWho);
                                 return;
                             }
-                            noteStateNotSaved();
                             fragment.onActivityResult(requestCode, result.getResultCode(),
                                     result.getData());
                         }
@@ -2797,7 +2796,6 @@
                                                 + fragmentWho);
                                 return;
                             }
-                            noteStateNotSaved();
                             fragment.onActivityResult(requestCode, result.getResultCode(),
                                     result.getData());
                         }
@@ -2833,7 +2831,6 @@
                                         + "Fragment " + fragmentWho);
                                 return;
                             }
-                            noteStateNotSaved();
                             fragment.onRequestPermissionsResult(requestCode, permissions,
                                     grantResults);
                         }
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 3a0fdf2..820c319 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -5,4 +5,4 @@
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=../../../../tools/external/gradle/gradle-6.3-bin.zip
+distributionUrl=../../../../tools/external/gradle/gradle-6.4-bin.zip
diff --git a/leanback/leanback/api/api_lint.ignore b/leanback/leanback/api/api_lint.ignore
index 32f2b54..1eea158 100644
--- a/leanback/leanback/api/api_lint.ignore
+++ b/leanback/leanback/api/api_lint.ignore
@@ -53,12 +53,18 @@
     Must avoid boxed primitives (`java.lang.Number`)
 
 
-CallbackMethodName: androidx.leanback.widget.DiffCallback:
-    Callback method names must follow the on<Something> style: areItemsTheSame
-CallbackMethodName: androidx.leanback.widget.GuidedActionDiffCallback:
-    Callback method names must follow the on<Something> style: getInstance
-CallbackMethodName: androidx.leanback.widget.SearchBar.SearchBarPermissionListener:
-    Listener method names must follow the on<Something> style: requestAudioPermission
+BuilderSetStyle: androidx.leanback.widget.ShadowOverlayHelper.Builder#keepForegroundDrawable(boolean):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.leanback.widget.ShadowOverlayHelper.Builder.keepForegroundDrawable(boolean)
+BuilderSetStyle: androidx.leanback.widget.ShadowOverlayHelper.Builder#needsOverlay(boolean):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.leanback.widget.ShadowOverlayHelper.Builder.needsOverlay(boolean)
+BuilderSetStyle: androidx.leanback.widget.ShadowOverlayHelper.Builder#needsRoundedCorner(boolean):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.leanback.widget.ShadowOverlayHelper.Builder.needsRoundedCorner(boolean)
+BuilderSetStyle: androidx.leanback.widget.ShadowOverlayHelper.Builder#needsShadow(boolean):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.leanback.widget.ShadowOverlayHelper.Builder.needsShadow(boolean)
+BuilderSetStyle: androidx.leanback.widget.ShadowOverlayHelper.Builder#options(androidx.leanback.widget.ShadowOverlayHelper.Options):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.leanback.widget.ShadowOverlayHelper.Builder.options(androidx.leanback.widget.ShadowOverlayHelper.Options)
+BuilderSetStyle: androidx.leanback.widget.ShadowOverlayHelper.Builder#preferZOrder(boolean):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.leanback.widget.ShadowOverlayHelper.Builder.preferZOrder(boolean)
 
 
 CallbackName: androidx.leanback.widget.ObjectAdapter.DataObserver:
diff --git a/media/media/api/api_lint.ignore b/media/media/api/api_lint.ignore
index 6e997641..fe4b00a 100644
--- a/media/media/api/api_lint.ignore
+++ b/media/media/api/api_lint.ignore
@@ -21,8 +21,16 @@
     Inconsistent extra value; expected `androidx.media.extra.SUGGESTED`, was `android.service.media.extra.SUGGESTED`
 
 
-CallbackMethodName: android.support.v4.media.session.MediaControllerCompat.Callback:
-    Callback method names must follow the on<Something> style: binderDied
+BuilderSetStyle: android.support.v4.media.MediaMetadataCompat.Builder#putBitmap(String, android.graphics.Bitmap):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method android.support.v4.media.MediaMetadataCompat.Builder.putBitmap(String,android.graphics.Bitmap)
+BuilderSetStyle: android.support.v4.media.MediaMetadataCompat.Builder#putLong(String, long):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method android.support.v4.media.MediaMetadataCompat.Builder.putLong(String,long)
+BuilderSetStyle: android.support.v4.media.MediaMetadataCompat.Builder#putRating(String, android.support.v4.media.RatingCompat):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method android.support.v4.media.MediaMetadataCompat.Builder.putRating(String,android.support.v4.media.RatingCompat)
+BuilderSetStyle: android.support.v4.media.MediaMetadataCompat.Builder#putString(String, String):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method android.support.v4.media.MediaMetadataCompat.Builder.putString(String,String)
+BuilderSetStyle: android.support.v4.media.MediaMetadataCompat.Builder#putText(String, CharSequence):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method android.support.v4.media.MediaMetadataCompat.Builder.putText(String,CharSequence)
 
 
 ContextNameSuffix: androidx.media.MediaBrowserServiceCompat:
diff --git a/media2/common/api/api_lint.ignore b/media2/common/api/api_lint.ignore
index 35e4147..d2bb9aa 100644
--- a/media2/common/api/api_lint.ignore
+++ b/media2/common/api/api_lint.ignore
@@ -1,6 +1,16 @@
 // Baseline format: 1.0
-CallbackMethodName: androidx.media2.common.DataSourceCallback:
-    Callback method names must follow the on<Something> style: readAt
+BuilderSetStyle: androidx.media2.common.MediaMetadata.Builder#putBitmap(String, android.graphics.Bitmap):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.media2.common.MediaMetadata.Builder.putBitmap(String,android.graphics.Bitmap)
+BuilderSetStyle: androidx.media2.common.MediaMetadata.Builder#putFloat(String, float):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.media2.common.MediaMetadata.Builder.putFloat(String,float)
+BuilderSetStyle: androidx.media2.common.MediaMetadata.Builder#putLong(String, long):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.media2.common.MediaMetadata.Builder.putLong(String,long)
+BuilderSetStyle: androidx.media2.common.MediaMetadata.Builder#putRating(String, androidx.media2.common.Rating):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.media2.common.MediaMetadata.Builder.putRating(String,androidx.media2.common.Rating)
+BuilderSetStyle: androidx.media2.common.MediaMetadata.Builder#putString(String, String):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.media2.common.MediaMetadata.Builder.putString(String,String)
+BuilderSetStyle: androidx.media2.common.MediaMetadata.Builder#putText(String, CharSequence):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.media2.common.MediaMetadata.Builder.putText(String,CharSequence)
 
 
 GenericException: androidx.media2.common.SessionPlayer#close():
diff --git a/media2/session/api/api_lint.ignore b/media2/session/api/api_lint.ignore
index ac1c632..9ae568a 100644
--- a/media2/session/api/api_lint.ignore
+++ b/media2/session/api/api_lint.ignore
@@ -5,6 +5,10 @@
     Use ListenableFuture (library), or a combination of Consumer<T>, Executor, and CancellationSignal (platform) instead of java.util.concurrent.Future (method androidx.media2.session.RemoteSessionPlayer.setVolume(int))
 
 
+BuilderSetStyle: androidx.media2.session.SessionCommandGroup.Builder#removeCommand(androidx.media2.session.SessionCommand):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.media2.session.SessionCommandGroup.Builder.removeCommand(androidx.media2.session.SessionCommand)
+
+
 MissingNullability: androidx.media2.session.MediaLibraryService#onBind(android.content.Intent):
     Missing nullability on method `onBind` return
 MissingNullability: androidx.media2.session.MediaSessionService#onStartCommand(android.content.Intent, int, int) parameter #0:
diff --git a/navigation/navigation-common-ktx/api/api_lint.ignore b/navigation/navigation-common-ktx/api/api_lint.ignore
index 6ba701d..82360c9 100644
--- a/navigation/navigation-common-ktx/api/api_lint.ignore
+++ b/navigation/navigation-common-ktx/api/api_lint.ignore
@@ -1,4 +1,20 @@
 // Baseline format: 1.0
+BuilderSetStyle: androidx.navigation.NavActionBuilder#navOptions(kotlin.jvm.functions.Function1<? super androidx.navigation.NavOptionsBuilder,kotlin.Unit>):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.navigation.NavActionBuilder.navOptions(kotlin.jvm.functions.Function1<? super androidx.navigation.NavOptionsBuilder,kotlin.Unit>)
+BuilderSetStyle: androidx.navigation.NavDestinationBuilder#action(int, kotlin.jvm.functions.Function1<? super androidx.navigation.NavActionBuilder,kotlin.Unit>):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.navigation.NavDestinationBuilder.action(int,kotlin.jvm.functions.Function1<? super androidx.navigation.NavActionBuilder,kotlin.Unit>)
+BuilderSetStyle: androidx.navigation.NavDestinationBuilder#argument(String, kotlin.jvm.functions.Function1<? super androidx.navigation.NavArgumentBuilder,kotlin.Unit>):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.navigation.NavDestinationBuilder.argument(String,kotlin.jvm.functions.Function1<? super androidx.navigation.NavArgumentBuilder,kotlin.Unit>)
+BuilderSetStyle: androidx.navigation.NavDestinationBuilder#deepLink(String):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.navigation.NavDestinationBuilder.deepLink(String)
+BuilderSetStyle: androidx.navigation.NavDestinationBuilder#deepLink(kotlin.jvm.functions.Function1<? super androidx.navigation.NavDeepLinkDslBuilder,kotlin.Unit>):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.navigation.NavDestinationBuilder.deepLink(kotlin.jvm.functions.Function1<? super androidx.navigation.NavDeepLinkDslBuilder,kotlin.Unit>)
+BuilderSetStyle: androidx.navigation.NavOptionsBuilder#anim(kotlin.jvm.functions.Function1<? super androidx.navigation.AnimBuilder,kotlin.Unit>):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.navigation.NavOptionsBuilder.anim(kotlin.jvm.functions.Function1<? super androidx.navigation.AnimBuilder,kotlin.Unit>)
+BuilderSetStyle: androidx.navigation.NavOptionsBuilder#popUpTo(int, kotlin.jvm.functions.Function1<? super androidx.navigation.PopUpToBuilder,kotlin.Unit>):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.navigation.NavOptionsBuilder.popUpTo(int,kotlin.jvm.functions.Function1<? super androidx.navigation.PopUpToBuilder,kotlin.Unit>)
+
+
 DocumentExceptions: androidx.navigation.NavArgumentBuilder#getType():
     Method NavArgumentBuilder.getType 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.navigation.NavGraphBuilder#build():
diff --git a/navigation/navigation-common/api/api_lint.ignore b/navigation/navigation-common/api/api_lint.ignore
index 9c1799e7..50d8eb6 100644
--- a/navigation/navigation-common/api/api_lint.ignore
+++ b/navigation/navigation-common/api/api_lint.ignore
@@ -13,5 +13,19 @@
     Method parameter should be Collection<D> (or subclass) instead of raw array; was `D[]`
 
 
+BuilderSetStyle: androidx.navigation.NavDeepLink.Builder#fromAction(String):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.navigation.NavDeepLink.Builder.fromAction(String)
+BuilderSetStyle: androidx.navigation.NavDeepLink.Builder#fromMimeType(String):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.navigation.NavDeepLink.Builder.fromMimeType(String)
+BuilderSetStyle: androidx.navigation.NavDeepLink.Builder#fromUriPattern(String):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.navigation.NavDeepLink.Builder.fromUriPattern(String)
+BuilderSetStyle: androidx.navigation.NavDeepLinkRequest.Builder#fromAction(String):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.navigation.NavDeepLinkRequest.Builder.fromAction(String)
+BuilderSetStyle: androidx.navigation.NavDeepLinkRequest.Builder#fromMimeType(String):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.navigation.NavDeepLinkRequest.Builder.fromMimeType(String)
+BuilderSetStyle: androidx.navigation.NavDeepLinkRequest.Builder#fromUri(android.net.Uri):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.navigation.NavDeepLinkRequest.Builder.fromUri(android.net.Uri)
+
+
 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)
diff --git a/navigation/navigation-fragment/src/androidTest/AndroidManifest.xml b/navigation/navigation-fragment/src/androidTest/AndroidManifest.xml
index d40a782..c51701b 100644
--- a/navigation/navigation-fragment/src/androidTest/AndroidManifest.xml
+++ b/navigation/navigation-fragment/src/androidTest/AndroidManifest.xml
@@ -21,6 +21,7 @@
         <activity android:name="androidx.navigation.fragment.test.NavigationActivity"/>
         <activity
             android:name="androidx.navigation.fragment.test.NavigationActivityWithFragmentTag"/>
+        <activity android:name="androidx.navigation.fragment.test.NavigationActivityMultiNavHost"/>
         <activity android:name="androidx.navigation.fragment.XmlNavigationActivity" />
         <activity android:name="androidx.navigation.fragment.DynamicNavigationActivity" />
         <activity android:name="androidx.navigation.fragment.EmbeddedXmlActivity" />
diff --git a/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/MultiNavHostFragmentTest.kt b/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/MultiNavHostFragmentTest.kt
new file mode 100644
index 0000000..c895377
--- /dev/null
+++ b/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/MultiNavHostFragmentTest.kt
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.navigation.fragment
+
+import android.os.Bundle
+import androidx.navigation.findNavController
+import androidx.navigation.fragment.test.NavigationActivityMultiNavHost
+import androidx.navigation.fragment.test.R
+import androidx.test.core.app.ActivityScenario
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
+import androidx.testutils.withActivity
+import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.Truth.assertWithMessage
+import org.junit.Test
+import org.junit.runner.RunWith
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+
+@MediumTest
+@RunWith(AndroidJUnit4::class)
+class MultiNavHostFragmentTest {
+
+    @Test
+    fun testFragmentToNavHost() {
+        with(ActivityScenario.launch(NavigationActivityMultiNavHost::class.java)) {
+            val navController = withActivity {
+                findNavController(R.id.nav_host_fragment)
+            }
+
+            navController.setGraph(R.navigation.nav_nav_host)
+            navController.navigate(R.id.nav_host_1)
+
+            val rootNavController = withActivity {
+                val navHostFragment = supportFragmentManager
+                    .findFragmentById(R.id.nav_host_fragment)!!
+                navHostFragment.requireView().findNavController()
+            }
+            assertWithMessage("Child should have changed the NavController")
+                .that(rootNavController)
+                .isNotEqualTo(navController)
+        }
+    }
+
+    @Test
+    fun testNavHostToFragment() {
+        with(ActivityScenario.launch(NavigationActivityMultiNavHost::class.java)) {
+            val navController = withActivity {
+                findNavController(R.id.nav_host_fragment)
+            }
+
+            navController.setGraph(R.navigation.nav_nav_host)
+            navController.navigate(R.id.nav_host_1)
+
+            val childFragment = withActivity {
+                supportFragmentManager.findFragmentById(R.id.nav_host_fragment)
+                    ?.childFragmentManager?.findFragmentById(R.id.nav_host_fragment) as
+                        BasicNavHostFragment
+            }
+
+            navController.popBackStack()
+
+            val returnNavController = withActivity {
+                val navHostFragment =
+                    supportFragmentManager.findFragmentById(R.id.nav_host_fragment)!!
+                navHostFragment.requireView().findNavController()
+            }
+
+            assertThat(childFragment.destroyViewCountDownLatch.await(1000, TimeUnit.MILLISECONDS))
+                .isTrue()
+
+            assertWithMessage("NavController should not have changed")
+                .that(returnNavController)
+                .isSameInstanceAs(navController)
+        }
+    }
+
+    @Test
+    fun testNavHostToNavHost() {
+        with(ActivityScenario.launch(NavigationActivityMultiNavHost::class.java)) {
+            val navController = withActivity {
+                findNavController(R.id.nav_host_fragment)
+            }
+
+            navController.setGraph(R.navigation.nav_nav_host)
+            navController.navigate(R.id.nav_host_1)
+
+            val firstChildNavController = withActivity {
+                val navHostFragment =
+                    supportFragmentManager.findFragmentById(R.id.nav_host_fragment)!!
+                navHostFragment.requireView().findNavController()
+            }
+            assertWithMessage("child should have changed the NavController")
+                .that(firstChildNavController)
+                .isNotEqualTo(navController)
+
+            navController.navigate(R.id.nav_host_2)
+
+            val secondChildNavController = withActivity {
+                val navHostFragment =
+                    supportFragmentManager.findFragmentById(R.id.nav_host_fragment)!!
+                navHostFragment.requireView().findNavController()
+            }
+
+            assertWithMessage("Second child should have changed the NavController")
+                .that(secondChildNavController)
+                .isNotEqualTo(firstChildNavController)
+
+            assertWithMessage("the second child navHost should be different from the parent")
+                .that(secondChildNavController)
+                .isNotEqualTo(navController)
+        }
+    }
+}
+
+class BasicNavHostFragment : NavHostFragment() {
+    val destroyViewCountDownLatch = CountDownLatch(1)
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        navController.setGraph(R.navigation.nav_nav_host)
+    }
+
+    override fun onDestroyView() {
+        super.onDestroyView()
+        destroyViewCountDownLatch.countDown()
+    }
+}
\ No newline at end of file
diff --git a/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/test/NavigationActivity.kt b/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/test/NavigationActivity.kt
index 460f906..a4de7e6 100644
--- a/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/test/NavigationActivity.kt
+++ b/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/test/NavigationActivity.kt
@@ -26,6 +26,8 @@
     R.layout.navigation_activity_fragment_tag
 )
 
+class NavigationActivityMultiNavHost : NavigationBaseActivity(R.layout.navigation_activity_nav_host)
+
 open class NavigationBaseActivity(contentLayoutId: Int) : FragmentActivity(contentLayoutId) {
     val navController get() = findNavController(R.id.nav_host)
 
diff --git a/navigation/navigation-fragment/src/androidTest/res/layout/navigation_activity_nav_host.xml b/navigation/navigation-fragment/src/androidTest/res/layout/navigation_activity_nav_host.xml
new file mode 100644
index 0000000..ef4772d
--- /dev/null
+++ b/navigation/navigation-fragment/src/androidTest/res/layout/navigation_activity_nav_host.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2020 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<androidx.fragment.app.FragmentContainerView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:id="@+id/nav_host_fragment"
+    android:name="androidx.navigation.fragment.NavHostFragment"
+    app:navGraph="@navigation/nav_nav_host"
+    app:defaultNavHost="true"
+/>
\ No newline at end of file
diff --git a/navigation/navigation-fragment/src/androidTest/res/navigation/nav_nav_host.xml b/navigation/navigation-fragment/src/androidTest/res/navigation/nav_nav_host.xml
new file mode 100644
index 0000000..d9c1a03
--- /dev/null
+++ b/navigation/navigation-fragment/src/androidTest/res/navigation/nav_nav_host.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2020 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<navigation xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/nav_nav_host"
+    app:startDestination="@+id/start_fragment">
+    <fragment
+        android:id="@+id/start_fragment"
+        android:name="androidx.navigation.fragment.test.EmptyFragment"/>
+    <fragment
+        android:id="@+id/nav_host_1"
+        android:name="androidx.navigation.fragment.BasicNavHostFragment"/>
+    <fragment
+        android:id="@+id/nav_host_2"
+        android:name="androidx.navigation.fragment.BasicNavHostFragment"/>
+</navigation>
\ No newline at end of file
diff --git a/navigation/navigation-fragment/src/main/java/androidx/navigation/fragment/NavHostFragment.java b/navigation/navigation-fragment/src/main/java/androidx/navigation/fragment/NavHostFragment.java
index aab2ef5..ba0c6a2 100644
--- a/navigation/navigation-fragment/src/main/java/androidx/navigation/fragment/NavHostFragment.java
+++ b/navigation/navigation-fragment/src/main/java/androidx/navigation/fragment/NavHostFragment.java
@@ -123,6 +123,7 @@
 
     private NavHostController mNavController;
     private Boolean mIsPrimaryBeforeOnCreate = null;
+    private View mViewParent;
 
     // State that will be saved and restored
     private int mGraphId;
@@ -335,9 +336,9 @@
         // When added programmatically, we need to set the NavController on the parent - i.e.,
         // the View that has the ID matching this NavHostFragment.
         if (view.getParent() != null) {
-            View rootView = (View) view.getParent();
-            if (rootView.getId() == getId()) {
-                Navigation.setViewNavController(rootView, mNavController);
+            mViewParent = (View) view.getParent();
+            if (mViewParent.getId() == getId()) {
+                Navigation.setViewNavController(mViewParent, mNavController);
             }
         }
     }
@@ -380,4 +381,13 @@
             outState.putInt(KEY_GRAPH_ID, mGraphId);
         }
     }
+
+    @Override
+    public void onDestroyView() {
+        super.onDestroyView();
+        if (mViewParent != null && Navigation.findNavController(mViewParent) == mNavController) {
+            Navigation.setViewNavController(mViewParent, null);
+        }
+        mViewParent = null;
+    }
 }
diff --git a/navigation/navigation-runtime/api/api_lint.ignore b/navigation/navigation-runtime/api/api_lint.ignore
index 12f82c6..8005e78 100644
--- a/navigation/navigation-runtime/api/api_lint.ignore
+++ b/navigation/navigation-runtime/api/api_lint.ignore
@@ -1,4 +1,10 @@
 // Baseline format: 1.0
+BuilderSetStyle: androidx.navigation.NavDeepLinkBuilder#createPendingIntent():
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.navigation.NavDeepLinkBuilder.createPendingIntent()
+BuilderSetStyle: androidx.navigation.NavDeepLinkBuilder#createTaskStackBuilder():
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.navigation.NavDeepLinkBuilder.createTaskStackBuilder()
+
+
 MissingBuildMethod: androidx.navigation.NavDeepLinkBuilder:
     androidx.navigation.NavDeepLinkBuilder does not declare a `build()` method, but builder classes are expected to
 
diff --git a/paging/rxjava2/api/api_lint.ignore b/paging/rxjava2/api/api_lint.ignore
index 20c6bba..153d977 100644
--- a/paging/rxjava2/api/api_lint.ignore
+++ b/paging/rxjava2/api/api_lint.ignore
@@ -1,4 +1,10 @@
 // Baseline format: 1.0
+BuilderSetStyle: androidx.paging.RxPagedListBuilder#buildFlowable(io.reactivex.BackpressureStrategy):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.paging.RxPagedListBuilder.buildFlowable(io.reactivex.BackpressureStrategy)
+BuilderSetStyle: androidx.paging.RxPagedListBuilder#buildObservable():
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.paging.RxPagedListBuilder.buildObservable()
+
+
 MissingBuildMethod: androidx.paging.RxPagedListBuilder:
     androidx.paging.RxPagedListBuilder does not declare a `build()` method, but builder classes are expected to
 
diff --git a/palette/palette/api/api_lint.ignore b/palette/palette/api/api_lint.ignore
index b8c8876..162d7eb 100644
--- a/palette/palette/api/api_lint.ignore
+++ b/palette/palette/api/api_lint.ignore
@@ -1,3 +1,13 @@
 // Baseline format: 1.0
+BuilderSetStyle: androidx.palette.graphics.Palette.Builder#generate():
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.palette.graphics.Palette.Builder.generate()
+BuilderSetStyle: androidx.palette.graphics.Palette.Builder#generate(androidx.palette.graphics.Palette.PaletteAsyncListener):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.palette.graphics.Palette.Builder.generate(androidx.palette.graphics.Palette.PaletteAsyncListener)
+BuilderSetStyle: androidx.palette.graphics.Palette.Builder#maximumColorCount(int):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.palette.graphics.Palette.Builder.maximumColorCount(int)
+BuilderSetStyle: androidx.palette.graphics.Palette.Builder#resizeBitmapArea(int):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.palette.graphics.Palette.Builder.resizeBitmapArea(int)
+
+
 MissingBuildMethod: androidx.palette.graphics.Palette.Builder:
     androidx.palette.graphics.Palette.Builder does not declare a `build()` method, but builder classes are expected to
diff --git a/preference/preference/api/api_lint.ignore b/preference/preference/api/api_lint.ignore
index de479d5..8cd2bf7 100644
--- a/preference/preference/api/api_lint.ignore
+++ b/preference/preference/api/api_lint.ignore
@@ -19,12 +19,6 @@
     Method parameter should be Collection<CharSequence> (or subclass) instead of raw array; was `java.lang.CharSequence[]`
 
 
-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
-
-
 InternalField: androidx.preference.TwoStatePreference#mChecked:
     Internal field mChecked must not be exposed
 
diff --git a/recyclerview/recyclerview-selection/api/api_lint.ignore b/recyclerview/recyclerview-selection/api/api_lint.ignore
index a607d9e..82e97e9 100644
--- a/recyclerview/recyclerview-selection/api/api_lint.ignore
+++ b/recyclerview/recyclerview-selection/api/api_lint.ignore
@@ -6,21 +6,21 @@
 
 
 BuilderSetStyle: androidx.recyclerview.selection.SelectionTracker.Builder#withBandOverlay(int):
-    Builder methods names should use setFoo() style: method androidx.recyclerview.selection.SelectionTracker.Builder.withBandOverlay(int)
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.recyclerview.selection.SelectionTracker.Builder.withBandOverlay(int)
 BuilderSetStyle: androidx.recyclerview.selection.SelectionTracker.Builder#withBandPredicate(androidx.recyclerview.selection.BandPredicate):
-    Builder methods names should use setFoo() style: method androidx.recyclerview.selection.SelectionTracker.Builder.withBandPredicate(androidx.recyclerview.selection.BandPredicate)
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.recyclerview.selection.SelectionTracker.Builder.withBandPredicate(androidx.recyclerview.selection.BandPredicate)
 BuilderSetStyle: androidx.recyclerview.selection.SelectionTracker.Builder#withFocusDelegate(androidx.recyclerview.selection.FocusDelegate<K>):
-    Builder methods names should use setFoo() style: method androidx.recyclerview.selection.SelectionTracker.Builder.withFocusDelegate(androidx.recyclerview.selection.FocusDelegate<K>)
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.recyclerview.selection.SelectionTracker.Builder.withFocusDelegate(androidx.recyclerview.selection.FocusDelegate<K>)
 BuilderSetStyle: androidx.recyclerview.selection.SelectionTracker.Builder#withOnContextClickListener(androidx.recyclerview.selection.OnContextClickListener):
-    Builder methods names should use setFoo() style: method androidx.recyclerview.selection.SelectionTracker.Builder.withOnContextClickListener(androidx.recyclerview.selection.OnContextClickListener)
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.recyclerview.selection.SelectionTracker.Builder.withOnContextClickListener(androidx.recyclerview.selection.OnContextClickListener)
 BuilderSetStyle: androidx.recyclerview.selection.SelectionTracker.Builder#withOnDragInitiatedListener(androidx.recyclerview.selection.OnDragInitiatedListener):
-    Builder methods names should use setFoo() style: method androidx.recyclerview.selection.SelectionTracker.Builder.withOnDragInitiatedListener(androidx.recyclerview.selection.OnDragInitiatedListener)
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.recyclerview.selection.SelectionTracker.Builder.withOnDragInitiatedListener(androidx.recyclerview.selection.OnDragInitiatedListener)
 BuilderSetStyle: androidx.recyclerview.selection.SelectionTracker.Builder#withOnItemActivatedListener(androidx.recyclerview.selection.OnItemActivatedListener<K>):
-    Builder methods names should use setFoo() style: method androidx.recyclerview.selection.SelectionTracker.Builder.withOnItemActivatedListener(androidx.recyclerview.selection.OnItemActivatedListener<K>)
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.recyclerview.selection.SelectionTracker.Builder.withOnItemActivatedListener(androidx.recyclerview.selection.OnItemActivatedListener<K>)
 BuilderSetStyle: androidx.recyclerview.selection.SelectionTracker.Builder#withOperationMonitor(androidx.recyclerview.selection.OperationMonitor):
-    Builder methods names should use setFoo() style: method androidx.recyclerview.selection.SelectionTracker.Builder.withOperationMonitor(androidx.recyclerview.selection.OperationMonitor)
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.recyclerview.selection.SelectionTracker.Builder.withOperationMonitor(androidx.recyclerview.selection.OperationMonitor)
 BuilderSetStyle: androidx.recyclerview.selection.SelectionTracker.Builder#withSelectionPredicate(androidx.recyclerview.selection.SelectionTracker.SelectionPredicate<K>):
-    Builder methods names should use setFoo() style: method androidx.recyclerview.selection.SelectionTracker.Builder.withSelectionPredicate(androidx.recyclerview.selection.SelectionTracker.SelectionPredicate<K>)
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.recyclerview.selection.SelectionTracker.Builder.withSelectionPredicate(androidx.recyclerview.selection.SelectionTracker.SelectionPredicate<K>)
 
 
 CallbackName: androidx.recyclerview.selection.SelectionTracker.SelectionObserver:
diff --git a/recyclerview/recyclerview/api/api_lint.ignore b/recyclerview/recyclerview/api/api_lint.ignore
index 2510713..bd0ba08 100644
--- a/recyclerview/recyclerview/api/api_lint.ignore
+++ b/recyclerview/recyclerview/api/api_lint.ignore
@@ -23,26 +23,6 @@
     Methods must not mention RuntimeException subclasses in throws clauses (was `java.lang.IndexOutOfBoundsException`)
 
 
-CallbackMethodName: androidx.recyclerview.widget.AsyncListUtil.DataCallback:
-    Callback method names must follow the on<Something> style: refreshData
-CallbackMethodName: androidx.recyclerview.widget.AsyncListUtil.ViewCallback:
-    Callback method names must follow the on<Something> style: getItemRangeInto
-CallbackMethodName: androidx.recyclerview.widget.BatchingListUpdateCallback:
-    Callback method names must follow the on<Something> style: dispatchLastEvent
-CallbackMethodName: androidx.recyclerview.widget.DiffUtil.Callback:
-    Callback method names must follow the on<Something> style: getOldListSize
-CallbackMethodName: androidx.recyclerview.widget.DiffUtil.ItemCallback:
-    Callback method names must follow the on<Something> style: areItemsTheSame
-CallbackMethodName: androidx.recyclerview.widget.ItemTouchHelper.Callback:
-    Callback method names must follow the on<Something> style: getDefaultUIUtil
-CallbackMethodName: androidx.recyclerview.widget.ItemTouchHelper.SimpleCallback:
-    Callback method names must follow the on<Something> style: setDefaultSwipeDirs
-CallbackMethodName: androidx.recyclerview.widget.SortedList.BatchedCallback:
-    Callback method names must follow the on<Something> style: compare
-CallbackMethodName: androidx.recyclerview.widget.SortedList.Callback:
-    Callback method names must follow the on<Something> style: compare
-
-
 CallbackName: androidx.recyclerview.widget.RecyclerView.AdapterDataObserver:
     Class should be named AdapterDataCallback
 
diff --git a/remotecallback/remotecallback/api/api_lint.ignore b/remotecallback/remotecallback/api/api_lint.ignore
index 732332e..277ff92 100644
--- a/remotecallback/remotecallback/api/api_lint.ignore
+++ b/remotecallback/remotecallback/api/api_lint.ignore
@@ -1,8 +1,4 @@
 // Baseline format: 1.0
-CallbackMethodName: androidx.remotecallback.RemoteCallback:
-    Callback method names must follow the on<Something> style: getType
-
-
 ContextFirst: androidx.remotecallback.RemoteCallback#create(Class<T>, android.content.Context) parameter #1:
     Context is distinct, so it must be the first argument (method `create`)
 
diff --git a/room/runtime/api/api_lint.ignore b/room/runtime/api/api_lint.ignore
index 49e0dbf..8c2f59a 100644
--- a/room/runtime/api/api_lint.ignore
+++ b/room/runtime/api/api_lint.ignore
@@ -3,6 +3,24 @@
     Method parameter should be Collection<Object> (or subclass) instead of raw array; was `java.lang.Object[]`
 
 
+BuilderSetStyle: androidx.room.RoomDatabase.Builder#allowMainThreadQueries():
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.room.RoomDatabase.Builder.allowMainThreadQueries()
+BuilderSetStyle: androidx.room.RoomDatabase.Builder#createFromAsset(String):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.room.RoomDatabase.Builder.createFromAsset(String)
+BuilderSetStyle: androidx.room.RoomDatabase.Builder#createFromFile(java.io.File):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.room.RoomDatabase.Builder.createFromFile(java.io.File)
+BuilderSetStyle: androidx.room.RoomDatabase.Builder#enableMultiInstanceInvalidation():
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.room.RoomDatabase.Builder.enableMultiInstanceInvalidation()
+BuilderSetStyle: androidx.room.RoomDatabase.Builder#fallbackToDestructiveMigration():
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.room.RoomDatabase.Builder.fallbackToDestructiveMigration()
+BuilderSetStyle: androidx.room.RoomDatabase.Builder#fallbackToDestructiveMigrationFrom(int...):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.room.RoomDatabase.Builder.fallbackToDestructiveMigrationFrom(int...)
+BuilderSetStyle: androidx.room.RoomDatabase.Builder#fallbackToDestructiveMigrationOnDowngrade():
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.room.RoomDatabase.Builder.fallbackToDestructiveMigrationOnDowngrade()
+BuilderSetStyle: androidx.room.RoomDatabase.Builder#openHelperFactory(androidx.sqlite.db.SupportSQLiteOpenHelper.Factory):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.room.RoomDatabase.Builder.openHelperFactory(androidx.sqlite.db.SupportSQLiteOpenHelper.Factory)
+
+
 CallbackName: androidx.room.InvalidationTracker.Observer:
     Class should be named Callback
 
diff --git a/samples/Support7Demos/src/main/AndroidManifest.xml b/samples/Support7Demos/src/main/AndroidManifest.xml
index fd36e80..0433f43 100644
--- a/samples/Support7Demos/src/main/AndroidManifest.xml
+++ b/samples/Support7Demos/src/main/AndroidManifest.xml
@@ -731,6 +731,16 @@
                 <category android:name="com.example.android.supportv7.SAMPLE_CODE"/>
             </intent-filter>
         </activity>
+
+        <!-- Custom drawable activity -->
+        <activity android:name=".drawable.CustomDrawableActivity"
+            android:label="@string/custom_drawable"
+            android:theme="@style/Theme.AppCompat.Light">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="com.example.android.supportv7.SAMPLE_CODE"/>
+            </intent-filter>
+        </activity>
     </application>
 
 </manifest>
diff --git a/samples/Support7Demos/src/main/java/com/example/android/supportv7/drawable/CustomDrawableActivity.java b/samples/Support7Demos/src/main/java/com/example/android/supportv7/drawable/CustomDrawableActivity.java
new file mode 100644
index 0000000..196a768
--- /dev/null
+++ b/samples/Support7Demos/src/main/java/com/example/android/supportv7/drawable/CustomDrawableActivity.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.supportv7.drawable;
+
+import android.os.Bundle;
+
+import androidx.appcompat.app.AppCompatActivity;
+
+import com.example.android.supportv7.R;
+
+/**
+ * This demonstrates usage of a custom <drawable>
+ */
+public class CustomDrawableActivity extends AppCompatActivity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.custom_drawable_image);
+    }
+}
diff --git a/samples/Support7Demos/src/main/java/com/example/android/supportv7/drawable/MyDrawable.java b/samples/Support7Demos/src/main/java/com/example/android/supportv7/drawable/MyDrawable.java
new file mode 100644
index 0000000..ecab1b2
--- /dev/null
+++ b/samples/Support7Demos/src/main/java/com/example/android/supportv7/drawable/MyDrawable.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.supportv7.drawable;
+
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.drawable.Drawable;
+
+/**
+ * Simple custom drawable.
+ */
+public class MyDrawable extends Drawable {
+    private final Paint mPaint;
+
+    public MyDrawable() {
+        mPaint = new Paint();
+        mPaint.setARGB(255, 255, 0, 0);
+        mPaint.setAntiAlias(true);
+    }
+
+    @Override
+    public void draw(Canvas canvas) {
+        // Get the drawable's bounds
+        int width = getBounds().width();
+        int height = getBounds().height();
+        float radius = Math.min(width, height) / 2;
+
+        // Draw a red circle in the center
+        canvas.drawCircle(width / 2, height / 2, radius, mPaint);
+    }
+
+    @Override
+    public void setAlpha(int alpha) {
+        // This method is required
+    }
+
+    @Override
+    public void setColorFilter(ColorFilter colorFilter) {
+        // This method is required
+    }
+
+    @Override
+    public int getOpacity() {
+        return PixelFormat.OPAQUE;
+    }
+}
diff --git a/samples/Support7Demos/src/main/res/drawable/my_drawable.xml b/samples/Support7Demos/src/main/res/drawable/my_drawable.xml
new file mode 100644
index 0000000..8eb5c46
--- /dev/null
+++ b/samples/Support7Demos/src/main/res/drawable/my_drawable.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2020 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<drawable xmlns:android="http://schemas.android.com/apk/res/android"
+    class="com.example.android.supportv7.drawable.MyDrawable"
+    android:color="#ffff0000" />
diff --git a/samples/Support7Demos/src/main/res/layout/custom_drawable_image.xml b/samples/Support7Demos/src/main/res/layout/custom_drawable_image.xml
new file mode 100644
index 0000000..4baca82
--- /dev/null
+++ b/samples/Support7Demos/src/main/res/layout/custom_drawable_image.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  Copyright 2020 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    android:padding="8dp">
+
+    <ImageView
+        android:layout_width="32dp"
+        android:layout_height="32dp"
+        app:srcCompat="@drawable/my_drawable" />
+
+    <ImageView
+        android:layout_width="64dp"
+        android:layout_height="64dp"
+        android:layout_marginTop="8dp"
+        app:srcCompat="@drawable/my_drawable" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/samples/Support7Demos/src/main/res/values/strings.xml b/samples/Support7Demos/src/main/res/values/strings.xml
index 86faac1..a6922ae 100644
--- a/samples/Support7Demos/src/main/res/values/strings.xml
+++ b/samples/Support7Demos/src/main/res/values/strings.xml
@@ -280,4 +280,6 @@
 
     <string name="webview">WebView</string>
     <string name="launch_activity">Launch Activity</string>
+
+    <string name="custom_drawable">Drawable/Custom drawable</string>
 </resources>
diff --git a/sqlite/sqlite/api/api_lint.ignore b/sqlite/sqlite/api/api_lint.ignore
index fa0a8dd..a9d0891 100644
--- a/sqlite/sqlite/api/api_lint.ignore
+++ b/sqlite/sqlite/api/api_lint.ignore
@@ -35,6 +35,32 @@
     Method parameter should be Collection<Object> (or subclass) instead of raw array; was `java.lang.Object[]`
 
 
+BuilderSetStyle: androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder#callback(androidx.sqlite.db.SupportSQLiteOpenHelper.Callback):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder.callback(androidx.sqlite.db.SupportSQLiteOpenHelper.Callback)
+BuilderSetStyle: androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder#name(String):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder.name(String)
+BuilderSetStyle: androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder#noBackupDirectory(boolean):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder.noBackupDirectory(boolean)
+BuilderSetStyle: androidx.sqlite.db.SupportSQLiteQueryBuilder#builder(String):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.sqlite.db.SupportSQLiteQueryBuilder.builder(String)
+BuilderSetStyle: androidx.sqlite.db.SupportSQLiteQueryBuilder#columns(String[]):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.sqlite.db.SupportSQLiteQueryBuilder.columns(String[])
+BuilderSetStyle: androidx.sqlite.db.SupportSQLiteQueryBuilder#create():
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.sqlite.db.SupportSQLiteQueryBuilder.create()
+BuilderSetStyle: androidx.sqlite.db.SupportSQLiteQueryBuilder#distinct():
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.sqlite.db.SupportSQLiteQueryBuilder.distinct()
+BuilderSetStyle: androidx.sqlite.db.SupportSQLiteQueryBuilder#groupBy(String):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.sqlite.db.SupportSQLiteQueryBuilder.groupBy(String)
+BuilderSetStyle: androidx.sqlite.db.SupportSQLiteQueryBuilder#having(String):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.sqlite.db.SupportSQLiteQueryBuilder.having(String)
+BuilderSetStyle: androidx.sqlite.db.SupportSQLiteQueryBuilder#limit(String):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.sqlite.db.SupportSQLiteQueryBuilder.limit(String)
+BuilderSetStyle: androidx.sqlite.db.SupportSQLiteQueryBuilder#orderBy(String):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.sqlite.db.SupportSQLiteQueryBuilder.orderBy(String)
+BuilderSetStyle: androidx.sqlite.db.SupportSQLiteQueryBuilder#selection(String, Object[]):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.sqlite.db.SupportSQLiteQueryBuilder.selection(String,Object[])
+
+
 MissingBuildMethod: androidx.sqlite.db.SupportSQLiteQueryBuilder:
     androidx.sqlite.db.SupportSQLiteQueryBuilder does not declare a `build()` method, but builder classes are expected to
 
diff --git a/textclassifier/textclassifier/api/api_lint.ignore b/textclassifier/textclassifier/api/api_lint.ignore
index fe3256c..b4fcb1d 100644
--- a/textclassifier/textclassifier/api/api_lint.ignore
+++ b/textclassifier/textclassifier/api/api_lint.ignore
@@ -15,6 +15,10 @@
     Must avoid boxed primitives (`java.lang.Long`)
 
 
+BuilderSetStyle: androidx.textclassifier.TextClassifier.EntityConfig.Builder#includeTypesFromTextClassifier(boolean):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.textclassifier.TextClassifier.EntityConfig.Builder.includeTypesFromTextClassifier(boolean)
+
+
 MissingNullability: androidx.textclassifier.TextClassification#getConfidenceScore(String) parameter #0:
     Missing nullability on parameter `entity` in method `getConfidenceScore`
 MissingNullability: androidx.textclassifier.TextClassification.Builder#setEntityType(String, float):
diff --git a/tv-provider/tv-provider/api/api_lint.ignore b/tv-provider/tv-provider/api/api_lint.ignore
index c2050f2..7c43e2f 100644
--- a/tv-provider/tv-provider/api/api_lint.ignore
+++ b/tv-provider/tv-provider/api/api_lint.ignore
@@ -273,10 +273,6 @@
     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:
diff --git a/ui/gradle/wrapper/gradle-wrapper.properties b/ui/gradle/wrapper/gradle-wrapper.properties
index a0c65fe..2bec472 100644
--- a/ui/gradle/wrapper/gradle-wrapper.properties
+++ b/ui/gradle/wrapper/gradle-wrapper.properties
@@ -5,4 +5,4 @@
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=../../../../../tools/external/gradle/gradle-6.3-bin.zip
+distributionUrl=../../../../../tools/external/gradle/gradle-6.4-bin.zip
diff --git a/ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/benchmark/test/RectsInColumnBenchmark.kt b/ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/benchmark/test/RectsInColumnBenchmark.kt
index 1c742d3..fc82db8 100644
--- a/ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/benchmark/test/RectsInColumnBenchmark.kt
+++ b/ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/benchmark/test/RectsInColumnBenchmark.kt
@@ -44,7 +44,7 @@
     companion object {
         @JvmStatic
         @Parameterized.Parameters(name = "{0}")
-        fun initParameters(): Array<Any> = arrayOf(1, 10)
+        fun initParameters(): Array<Any> = arrayOf(10, 100)
     }
 
     @get:Rule
diff --git a/ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/benchmark/test/TextInColumnBenchmark.kt b/ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/benchmark/test/TextInColumnBenchmark.kt
new file mode 100644
index 0000000..25ce2fd
--- /dev/null
+++ b/ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/benchmark/test/TextInColumnBenchmark.kt
@@ -0,0 +1,105 @@
+/*
+ * 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 androidx.test.filters.LargeTest
+import androidx.ui.benchmark.ComposeBenchmarkRule
+import androidx.ui.benchmark.benchmarkDrawPerf
+import androidx.ui.benchmark.benchmarkFirstCompose
+import androidx.ui.benchmark.benchmarkFirstDraw
+import androidx.ui.benchmark.benchmarkFirstLayout
+import androidx.ui.benchmark.benchmarkFirstMeasure
+import androidx.ui.benchmark.benchmarkLayoutPerf
+import androidx.ui.benchmark.toggleStateBenchmarkDraw
+import androidx.ui.benchmark.toggleStateBenchmarkLayout
+import androidx.ui.benchmark.toggleStateBenchmarkMeasure
+import androidx.ui.benchmark.toggleStateBenchmarkRecompose
+import androidx.ui.integration.test.foundation.RectsInColumnTestCase
+import androidx.ui.integration.test.foundation.TextInColumnTestCase
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+/**
+ * Benchmark that runs [RectsInColumnTestCase].
+ */
+@LargeTest
+@RunWith(Parameterized::class)
+class TextInColumnBenchmark(private val numberOfTexts: Int) {
+
+    companion object {
+        @JvmStatic
+        @Parameterized.Parameters(name = "{0}")
+        fun initParameters(): Array<Any> = arrayOf(10, 100)
+    }
+
+    @get:Rule
+    val benchmarkRule = ComposeBenchmarkRule()
+
+    private val textInColumnCaseFactory = { TextInColumnTestCase(numberOfTexts) }
+
+    @Test
+    fun first_compose() {
+        benchmarkRule.benchmarkFirstCompose(textInColumnCaseFactory)
+    }
+
+    @Test
+    fun first_measure() {
+        benchmarkRule.benchmarkFirstMeasure(textInColumnCaseFactory)
+    }
+
+    @Test
+    fun first_layout() {
+        benchmarkRule.benchmarkFirstLayout(textInColumnCaseFactory)
+    }
+
+    @Test
+    fun first_draw() {
+        benchmarkRule.benchmarkFirstDraw(textInColumnCaseFactory)
+    }
+
+    @Test
+    fun toggleRectangleColor_recompose() {
+        benchmarkRule.toggleStateBenchmarkRecompose(textInColumnCaseFactory)
+    }
+
+    @Test
+    fun toggleRectangleColor_measure() {
+        benchmarkRule.toggleStateBenchmarkMeasure(textInColumnCaseFactory)
+    }
+
+    @Test
+    fun toggleRectangleColor_layout() {
+        benchmarkRule.toggleStateBenchmarkLayout(textInColumnCaseFactory)
+    }
+
+    @Test
+    fun toggleRectangleColor_draw() {
+        benchmarkRule.toggleStateBenchmarkDraw(textInColumnCaseFactory)
+    }
+
+    @Test
+    fun layout() {
+        benchmarkRule.benchmarkLayoutPerf(textInColumnCaseFactory)
+    }
+
+    @Test
+    fun draw() {
+        benchmarkRule.benchmarkDrawPerf(textInColumnCaseFactory)
+    }
+}
diff --git a/ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/benchmark/test/view/AndroidRectsInLinearLayoutBenchmark.kt b/ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/benchmark/test/view/AndroidRectsInLinearLayoutBenchmark.kt
new file mode 100644
index 0000000..de8bcff
--- /dev/null
+++ b/ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/benchmark/test/view/AndroidRectsInLinearLayoutBenchmark.kt
@@ -0,0 +1,83 @@
+/*
+ * 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 androidx.test.filters.LargeTest
+import androidx.ui.benchmark.AndroidBenchmarkRule
+import androidx.ui.benchmark.benchmarkDrawPerf
+import androidx.ui.benchmark.benchmarkFirstDraw
+import androidx.ui.benchmark.benchmarkFirstLayout
+import androidx.ui.benchmark.benchmarkFirstMeasure
+import androidx.ui.benchmark.benchmarkFirstSetContent
+import androidx.ui.benchmark.benchmarkLayoutPerf
+import androidx.ui.integration.test.view.AndroidCheckboxesInLinearLayoutTestCase
+import androidx.ui.integration.test.view.AndroidRectsInLinearLayoutTestCase
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+/**
+ * Benchmark that runs [AndroidCheckboxesInLinearLayoutTestCase].
+ */
+@LargeTest
+@RunWith(Parameterized::class)
+class AndroidRectsInLinearLayoutBenchmark(private val numberOfRectangles: Int) {
+
+    companion object {
+        @JvmStatic
+        @Parameterized.Parameters(name = "{0}")
+        fun initParameters(): Array<Any> = arrayOf(10, 100)
+    }
+
+    @get:Rule
+    val benchmarkRule = AndroidBenchmarkRule()
+
+    private val rectanglesCaseFactory = {
+        AndroidRectsInLinearLayoutTestCase(numberOfRectangles)
+    }
+
+    @Test
+    fun first_setContent() {
+        benchmarkRule.benchmarkFirstSetContent(rectanglesCaseFactory)
+    }
+
+    @Test
+    fun first_measure() {
+        benchmarkRule.benchmarkFirstMeasure(rectanglesCaseFactory)
+    }
+
+    @Test
+    fun first_layout() {
+        benchmarkRule.benchmarkFirstLayout(rectanglesCaseFactory)
+    }
+
+    @Test
+    fun first_draw() {
+        benchmarkRule.benchmarkFirstDraw(rectanglesCaseFactory)
+    }
+
+    @Test
+    fun layout() {
+        benchmarkRule.benchmarkLayoutPerf(rectanglesCaseFactory)
+    }
+
+    @Test
+    fun draw() {
+        benchmarkRule.benchmarkDrawPerf(rectanglesCaseFactory)
+    }
+}
\ No newline at end of file
diff --git a/ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/benchmark/test/view/AndroidTextViewsInLinearLayoutBenchmark.kt b/ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/benchmark/test/view/AndroidTextViewsInLinearLayoutBenchmark.kt
new file mode 100644
index 0000000..c85a7fa
--- /dev/null
+++ b/ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/benchmark/test/view/AndroidTextViewsInLinearLayoutBenchmark.kt
@@ -0,0 +1,83 @@
+/*
+ * 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 androidx.test.filters.LargeTest
+import androidx.ui.benchmark.AndroidBenchmarkRule
+import androidx.ui.benchmark.benchmarkDrawPerf
+import androidx.ui.benchmark.benchmarkFirstDraw
+import androidx.ui.benchmark.benchmarkFirstLayout
+import androidx.ui.benchmark.benchmarkFirstMeasure
+import androidx.ui.benchmark.benchmarkFirstSetContent
+import androidx.ui.benchmark.benchmarkLayoutPerf
+import androidx.ui.integration.test.view.AndroidCheckboxesInLinearLayoutTestCase
+import androidx.ui.integration.test.view.AndroidTextViewsInLinearLayoutTestCase
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+/**
+ * Benchmark that runs [AndroidCheckboxesInLinearLayoutTestCase].
+ */
+@LargeTest
+@RunWith(Parameterized::class)
+class AndroidTextViewsInLinearLayoutBenchmark(private val numberOfTexts: Int) {
+
+    companion object {
+        @JvmStatic
+        @Parameterized.Parameters(name = "{0}")
+        fun initParameters(): Array<Any> = arrayOf(10, 100)
+    }
+
+    @get:Rule
+    val benchmarkRule = AndroidBenchmarkRule()
+
+    private val rectanglesCaseFactory = {
+        AndroidTextViewsInLinearLayoutTestCase(numberOfTexts)
+    }
+
+    @Test
+    fun first_setContent() {
+        benchmarkRule.benchmarkFirstSetContent(rectanglesCaseFactory)
+    }
+
+    @Test
+    fun first_measure() {
+        benchmarkRule.benchmarkFirstMeasure(rectanglesCaseFactory)
+    }
+
+    @Test
+    fun first_layout() {
+        benchmarkRule.benchmarkFirstLayout(rectanglesCaseFactory)
+    }
+
+    @Test
+    fun first_draw() {
+        benchmarkRule.benchmarkFirstDraw(rectanglesCaseFactory)
+    }
+
+    @Test
+    fun layout() {
+        benchmarkRule.benchmarkLayoutPerf(rectanglesCaseFactory)
+    }
+
+    @Test
+    fun draw() {
+        benchmarkRule.benchmarkDrawPerf(rectanglesCaseFactory)
+    }
+}
\ No newline at end of file
diff --git a/ui/integration-tests/demos/src/main/java/androidx/ui/demos/DemoFilter.kt b/ui/integration-tests/demos/src/main/java/androidx/ui/demos/DemoFilter.kt
index 3398a9c..7d10c55 100644
--- a/ui/integration-tests/demos/src/main/java/androidx/ui/demos/DemoFilter.kt
+++ b/ui/integration-tests/demos/src/main/java/androidx/ui/demos/DemoFilter.kt
@@ -22,7 +22,7 @@
 import androidx.ui.core.Alignment
 import androidx.ui.core.Modifier
 import androidx.ui.demos.common.Demo
-import androidx.ui.focus.FocusModifier
+import androidx.ui.core.focus.FocusModifier
 import androidx.ui.foundation.Icon
 import androidx.ui.foundation.Text
 import androidx.ui.foundation.TextField
diff --git a/ui/integration-tests/src/main/java/androidx/ui/integration/test/foundation/TextInColumnTestCase.kt b/ui/integration-tests/src/main/java/androidx/ui/integration/test/foundation/TextInColumnTestCase.kt
new file mode 100644
index 0000000..ddd6c47
--- /dev/null
+++ b/ui/integration-tests/src/main/java/androidx/ui/integration/test/foundation/TextInColumnTestCase.kt
@@ -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.ui.integration.test.foundation
+
+import androidx.compose.Composable
+import androidx.compose.mutableStateOf
+import androidx.ui.foundation.Text
+import androidx.ui.integration.test.ToggleableTestCase
+import androidx.ui.layout.Column
+import androidx.ui.material.MaterialTheme
+import androidx.ui.material.Surface
+import androidx.ui.test.ComposeTestCase
+import androidx.ui.text.TextStyle
+import androidx.ui.unit.sp
+
+/**
+ * Test case that puts the given amount of rectangles into a column layout and makes changes by
+ * modifying the color used in the model.
+ *
+ * Note: Each rectangle has its own model so changes should always affect only the first one.
+ */
+class TextInColumnTestCase(
+    private val numberOfTexts: Int
+) : ComposeTestCase, ToggleableTestCase {
+
+    private val fontSize = mutableStateOf(20.sp)
+
+    @Composable
+    override fun emitContent() {
+        MaterialTheme {
+            Surface {
+                Column {
+                    repeat(numberOfTexts) {
+                        // 32-character text to match dashboards
+                        Text(
+                            "Hello World Hello World Hello W",
+                            style = TextStyle(fontSize = fontSize.value)
+                        )
+                    }
+                }
+            }
+        }
+    }
+
+    override fun toggleState() {
+        fontSize.value = if (fontSize.value == 20.sp) {
+            15.sp
+        } else {
+            20.sp
+        }
+    }
+}
\ No newline at end of file
diff --git a/ui/integration-tests/src/main/java/androidx/ui/integration/test/view/AndroidRectsInLinearLayoutTestCase.kt b/ui/integration-tests/src/main/java/androidx/ui/integration/test/view/AndroidRectsInLinearLayoutTestCase.kt
new file mode 100644
index 0000000..b816715
--- /dev/null
+++ b/ui/integration-tests/src/main/java/androidx/ui/integration/test/view/AndroidRectsInLinearLayoutTestCase.kt
@@ -0,0 +1,65 @@
+/*
+ * 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.integration.test.view
+
+import android.app.Activity
+import android.graphics.Color
+import android.view.View
+import android.view.ViewGroup
+import android.widget.LinearLayout
+import androidx.ui.benchmark.android.AndroidTestCase
+import androidx.ui.integration.test.material.CheckboxesInRowsTestCase
+
+/**
+ * Version of [CheckboxesInRowsTestCase] using Android views.
+ */
+class AndroidRectsInLinearLayoutTestCase(
+    private val numberOfRectangles: Int
+) : AndroidTestCase {
+
+    private val rectangles = mutableListOf<View>()
+    var isBlue = true
+
+    override fun getContent(activity: Activity): ViewGroup {
+        val column = LinearLayout(activity)
+        column.orientation = LinearLayout.VERTICAL
+        column.layoutParams = ViewGroup.LayoutParams(
+            ViewGroup.LayoutParams.MATCH_PARENT,
+            ViewGroup.LayoutParams.WRAP_CONTENT
+        )
+        repeat(numberOfRectangles) {
+            val rectangle = View(activity)
+            rectangle.setBackgroundColor(Color.BLUE)
+            rectangle.layoutParams = LinearLayout.LayoutParams(
+                ViewGroup.LayoutParams.WRAP_CONTENT,
+                ViewGroup.LayoutParams.WRAP_CONTENT
+            )
+
+            column.addView(rectangle)
+            rectangles += rectangle
+        }
+        return column
+    }
+
+    fun toggleState() {
+        rectangles.forEach {
+            isBlue = !isBlue
+            val color = if (isBlue) Color.BLUE else Color.RED
+            it.setBackgroundColor(color)
+        }
+    }
+}
diff --git a/ui/integration-tests/src/main/java/androidx/ui/integration/test/view/AndroidTextViewsInLinearLayoutTestCase.kt b/ui/integration-tests/src/main/java/androidx/ui/integration/test/view/AndroidTextViewsInLinearLayoutTestCase.kt
new file mode 100644
index 0000000..8d4769d
--- /dev/null
+++ b/ui/integration-tests/src/main/java/androidx/ui/integration/test/view/AndroidTextViewsInLinearLayoutTestCase.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.
+ */
+
+package androidx.ui.integration.test.view
+
+import android.app.Activity
+import android.view.ViewGroup
+import android.widget.LinearLayout
+import android.widget.TextView
+import androidx.ui.benchmark.android.AndroidTestCase
+import androidx.ui.integration.test.material.CheckboxesInRowsTestCase
+
+/**
+ * Version of [CheckboxesInRowsTestCase] using Android views.
+ */
+class AndroidTextViewsInLinearLayoutTestCase(
+    private val amountOfCheckboxes: Int
+) : AndroidTestCase {
+
+    private val textViews = mutableListOf<TextView>()
+    private var fontSize = 20f
+
+    override fun getContent(activity: Activity): ViewGroup {
+        val column = LinearLayout(activity)
+        column.orientation = LinearLayout.VERTICAL
+        column.layoutParams = ViewGroup.LayoutParams(
+            ViewGroup.LayoutParams.MATCH_PARENT,
+            ViewGroup.LayoutParams.WRAP_CONTENT
+        )
+        repeat(amountOfCheckboxes) {
+            val text = TextView(activity)
+            text.text = "Hello World Hello World Hello W"
+            text.layoutParams = LinearLayout.LayoutParams(
+                ViewGroup.LayoutParams.WRAP_CONTENT,
+                ViewGroup.LayoutParams.WRAP_CONTENT
+            )
+            text.setTextSize(fontSize)
+            column.addView(text)
+            textViews += text
+        }
+        return column
+    }
+
+    fun toggleState() {
+        fontSize = if (fontSize == 20f) 15f else 20f
+        textViews.forEach {
+            it.textSize = fontSize
+        }
+    }
+}
diff --git a/ui/ui-animation-core/src/main/java/androidx/animation/TransitionDefinition.kt b/ui/ui-animation-core/src/main/java/androidx/animation/TransitionDefinition.kt
index b9a83b6..ce0c1e3a 100644
--- a/ui/ui-animation-core/src/main/java/androidx/animation/TransitionDefinition.kt
+++ b/ui/ui-animation-core/src/main/java/androidx/animation/TransitionDefinition.kt
@@ -16,6 +16,7 @@
 
 package androidx.animation
 
+import androidx.ui.util.fastFirstOrNull
 import kotlin.experimental.ExperimentalTypeInference
 
 /**
@@ -269,10 +270,10 @@
         }
 
     internal fun getSpec(fromState: T, toState: T): TransitionSpec<T> {
-        return transitionSpecs.firstOrNull { it.defines(fromState, toState) }
-            ?: transitionSpecs.firstOrNull { it.defines(fromState, null) }
-            ?: transitionSpecs.firstOrNull { it.defines(null, toState) }
-            ?: transitionSpecs.firstOrNull { it.defines(null, null) }
+        return transitionSpecs.fastFirstOrNull { it.defines(fromState, toState) }
+            ?: transitionSpecs.fastFirstOrNull { it.defines(fromState, null) }
+            ?: transitionSpecs.fastFirstOrNull { it.defines(null, toState) }
+            ?: transitionSpecs.fastFirstOrNull { it.defines(null, null) }
             ?: defaultTransitionSpec
     }
 
diff --git a/ui/ui-core/OWNERS b/ui/ui-core/OWNERS
index 4ccb43c..8abcc5f 100644
--- a/ui/ui-core/OWNERS
+++ b/ui/ui-core/OWNERS
@@ -4,6 +4,7 @@
 ryanmentley@google.com
 njawad@google.com
 popam@google.com
+soboleva@google.com
 
 # For text related files
 qqd@google.com
diff --git a/ui/ui-core/api/0.1.0-dev12.txt b/ui/ui-core/api/0.1.0-dev12.txt
index 65cd94e..1996b5b 100644
--- a/ui/ui-core/api/0.1.0-dev12.txt
+++ b/ui/ui-core/api/0.1.0-dev12.txt
@@ -716,10 +716,6 @@
     method public static androidx.ui.core.Modifier paint(androidx.ui.core.Modifier, androidx.ui.graphics.painter.Painter painter, boolean sizeToIntrinsics = true, androidx.ui.core.Alignment alignment = Alignment.Center, androidx.ui.core.ContentScale contentScale = ContentScale.Inside, float alpha = 1.0f, androidx.ui.graphics.ColorFilter? colorFilter = null, boolean rtl = false);
   }
 
-  public final class ParentDataKt {
-    method @Deprecated public static inline void ParentData(Object data, kotlin.jvm.functions.Function0<kotlin.Unit> children);
-  }
-
   public interface ParentDataModifier extends androidx.ui.core.Modifier.Element {
     method public default Object? modifyParentData(androidx.ui.unit.Density, Object? parentData);
   }
@@ -935,7 +931,6 @@
     method public static androidx.compose.ProvidableAmbient<androidx.ui.core.texttoolbar.TextToolbar> getTextToolbarAmbient();
     method public static androidx.compose.ProvidableAmbient<androidx.ui.platform.UriHandler> getUriHandlerAmbient();
     method public static androidx.compose.Composition setContent(androidx.activity.ComponentActivity, androidx.compose.Recomposer recomposer = Recomposer.current(), kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @Deprecated public static androidx.compose.Composition setContent(android.app.Activity, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method public static androidx.compose.Composition setContent(android.view.ViewGroup, androidx.compose.Recomposer recomposer, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method @Deprecated public static androidx.compose.Composition setContent(android.view.ViewGroup, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method public static androidx.compose.Composition setViewContent(android.view.ViewGroup, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
@@ -969,13 +964,48 @@
 
 package androidx.ui.core.focus {
 
-  public final class FocusModifierImplKt {
-    method public static androidx.ui.focus.FocusModifier createFocusModifier(androidx.ui.focus.FocusDetailedState focusDetailedState);
+  public enum FocusDetailedState {
+    enum_constant public static final androidx.ui.core.focus.FocusDetailedState Active;
+    enum_constant public static final androidx.ui.core.focus.FocusDetailedState ActiveParent;
+    enum_constant public static final androidx.ui.core.focus.FocusDetailedState Captured;
+    enum_constant public static final androidx.ui.core.focus.FocusDetailedState Disabled;
+    enum_constant public static final androidx.ui.core.focus.FocusDetailedState Inactive;
+  }
+
+  public interface FocusModifier extends androidx.ui.core.Modifier.Element {
+    method public boolean captureFocus();
+    method public boolean freeFocus();
+    method public androidx.ui.core.focus.FocusDetailedState getFocusDetailedState();
+    method public void requestFocus();
+    property public abstract androidx.ui.core.focus.FocusDetailedState focusDetailedState;
+  }
+
+  public final class FocusModifierKt {
+    method public static androidx.ui.core.focus.FocusModifier FocusModifier();
+    method public static androidx.ui.core.focus.FocusState getFocusState(androidx.ui.core.focus.FocusModifier);
   }
 
   public final class FocusNodeUtilsKt {
   }
 
+  @Deprecated public final class FocusOperator {
+    ctor @Deprecated public FocusOperator();
+  }
+
+  public enum FocusState {
+    enum_constant public static final androidx.ui.core.focus.FocusState Focused;
+    enum_constant public static final androidx.ui.core.focus.FocusState NotFocusable;
+    enum_constant public static final androidx.ui.core.focus.FocusState NotFocused;
+  }
+
+  public final class FocusStateKt {
+    method public static androidx.ui.core.focus.FocusState focusState(androidx.ui.core.focus.FocusDetailedState);
+  }
+
+  public final class FocusableKt {
+    method @Deprecated public static void Focusable(Object focusOperator, kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit> children);
+  }
+
 }
 
 package androidx.ui.core.gesture {
@@ -1933,49 +1963,6 @@
 
 }
 
-package androidx.ui.focus {
-
-  public enum FocusDetailedState {
-    enum_constant public static final androidx.ui.focus.FocusDetailedState Active;
-    enum_constant public static final androidx.ui.focus.FocusDetailedState ActiveParent;
-    enum_constant public static final androidx.ui.focus.FocusDetailedState Captured;
-    enum_constant public static final androidx.ui.focus.FocusDetailedState Disabled;
-    enum_constant public static final androidx.ui.focus.FocusDetailedState Inactive;
-  }
-
-  public interface FocusModifier extends androidx.ui.core.Modifier.Element {
-    method public boolean captureFocus();
-    method public boolean freeFocus();
-    method public androidx.ui.focus.FocusDetailedState getFocusDetailedState();
-    method public void requestFocus();
-    property public abstract androidx.ui.focus.FocusDetailedState focusDetailedState;
-  }
-
-  public final class FocusModifierProviderKt {
-    method public static androidx.ui.focus.FocusModifier FocusModifier();
-    method public static androidx.ui.focus.FocusState getFocusState(androidx.ui.focus.FocusModifier);
-  }
-
-  @Deprecated public final class FocusOperator {
-    ctor @Deprecated public FocusOperator();
-  }
-
-  public enum FocusState {
-    enum_constant public static final androidx.ui.focus.FocusState Focused;
-    enum_constant public static final androidx.ui.focus.FocusState NotFocusable;
-    enum_constant public static final androidx.ui.focus.FocusState NotFocused;
-  }
-
-  public final class FocusStateKt {
-    method public static androidx.ui.focus.FocusState focusState(androidx.ui.focus.FocusDetailedState);
-  }
-
-  public final class FocusableKt {
-    method @Deprecated public static void Focusable(Object focusOperator, kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit> children);
-  }
-
-}
-
 package androidx.ui.graphics.vector {
 
   public final class VectorAsset {
diff --git a/ui/ui-core/api/api_lint.ignore b/ui/ui-core/api/api_lint.ignore
index f6b8aeb..5bf293e 100644
--- a/ui/ui-core/api/api_lint.ignore
+++ b/ui/ui-core/api/api_lint.ignore
@@ -1,6 +1,8 @@
 // Baseline format: 1.0
 AcronymName: androidx.ui.core.AlignmentLineKt#merge-CBRbNzc(androidx.ui.core.AlignmentLine, int, int):
     Acronyms should not be capitalized in method names: was `merge-CBRbNzc`, should this be `merge-CbRbNzc`?
+AcronymName: androidx.ui.core.ContentScaleKt#scale-iWWM28M(androidx.ui.core.ContentScale, long, long):
+    Acronyms should not be capitalized in method names: was `scale-iWWM28M`, should this be `scale-iWwM28M`?
 AcronymName: androidx.ui.core.DrawShadowKt#drawShadow-xWKVMPI(androidx.ui.core.Modifier, float, androidx.ui.graphics.Shape, boolean, float):
     Acronyms should not be capitalized in method names: was `drawShadow-xWKVMPI`, should this be `drawShadow-xWkvmpi`?
 AcronymName: androidx.ui.core.IntrinsicMeasureScope#maxIntrinsicHeight-e0m06WU(androidx.ui.core.IntrinsicMeasurable, int):
@@ -31,17 +33,33 @@
     Method parameter should be Collection<PointerInputChange> (or subclass) instead of raw array; was `androidx.ui.core.PointerInputChange[]`
 
 
+BuilderSetStyle: androidx.ui.graphics.vector.VectorAssetBuilder#popGroup():
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.ui.graphics.vector.VectorAssetBuilder.popGroup()
+BuilderSetStyle: androidx.ui.graphics.vector.VectorAssetBuilder#pushGroup(String, float, float, float, float, float, float, float, java.util.List<? extends androidx.ui.graphics.vector.PathNode>):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.ui.graphics.vector.VectorAssetBuilder.pushGroup(String,float,float,float,float,float,float,float,java.util.List<? extends androidx.ui.graphics.vector.PathNode>)
+
+
+CallbackName: androidx.ui.core.ModelObserver:
+    Class should be named ModelCallback
+CallbackName: androidx.ui.core.gesture.DragObserver:
+    Class should be named DragCallback
+CallbackName: androidx.ui.core.gesture.LongPressDragObserver:
+    Class should be named LongPressDragCallback
+CallbackName: androidx.ui.core.gesture.RawScaleObserver:
+    Class should be named RawScaleCallback
+CallbackName: androidx.ui.core.gesture.ScaleObserver:
+    Class should be named ScaleCallback
+
+
 ContextFirst: androidx.ui.core.WrapperKt#subcomposeInto(androidx.ui.core.ComponentNode, android.content.Context, androidx.compose.CompositionReference, kotlin.jvm.functions.Function0<kotlin.Unit>) parameter #1:
     Context is distinct, so it must be the first argument (method `subcomposeInto`)
 
 
-TopLevelBuilder: androidx.ui.graphics.vector.VectorAssetBuilder:
-    Builder should be defined as inner class: androidx.ui.graphics.vector.VectorAssetBuilder
-
-
-MissingNullability: androidx.ui.core.Constraints2#toString-impl(long):
-    Missing nullability on method `toString-impl` return
 MissingNullability: androidx.ui.core.PointerId#toString-impl(long):
     Missing nullability on method `toString-impl` return
 MissingNullability: androidx.ui.core.TransformOrigin#toString-impl(long):
     Missing nullability on method `toString-impl` return
+
+
+TopLevelBuilder: androidx.ui.graphics.vector.VectorAssetBuilder:
+    Builder should be defined as inner class: androidx.ui.graphics.vector.VectorAssetBuilder
diff --git a/ui/ui-core/api/current.txt b/ui/ui-core/api/current.txt
index 65cd94e..1996b5b 100644
--- a/ui/ui-core/api/current.txt
+++ b/ui/ui-core/api/current.txt
@@ -716,10 +716,6 @@
     method public static androidx.ui.core.Modifier paint(androidx.ui.core.Modifier, androidx.ui.graphics.painter.Painter painter, boolean sizeToIntrinsics = true, androidx.ui.core.Alignment alignment = Alignment.Center, androidx.ui.core.ContentScale contentScale = ContentScale.Inside, float alpha = 1.0f, androidx.ui.graphics.ColorFilter? colorFilter = null, boolean rtl = false);
   }
 
-  public final class ParentDataKt {
-    method @Deprecated public static inline void ParentData(Object data, kotlin.jvm.functions.Function0<kotlin.Unit> children);
-  }
-
   public interface ParentDataModifier extends androidx.ui.core.Modifier.Element {
     method public default Object? modifyParentData(androidx.ui.unit.Density, Object? parentData);
   }
@@ -935,7 +931,6 @@
     method public static androidx.compose.ProvidableAmbient<androidx.ui.core.texttoolbar.TextToolbar> getTextToolbarAmbient();
     method public static androidx.compose.ProvidableAmbient<androidx.ui.platform.UriHandler> getUriHandlerAmbient();
     method public static androidx.compose.Composition setContent(androidx.activity.ComponentActivity, androidx.compose.Recomposer recomposer = Recomposer.current(), kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @Deprecated public static androidx.compose.Composition setContent(android.app.Activity, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method public static androidx.compose.Composition setContent(android.view.ViewGroup, androidx.compose.Recomposer recomposer, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method @Deprecated public static androidx.compose.Composition setContent(android.view.ViewGroup, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method public static androidx.compose.Composition setViewContent(android.view.ViewGroup, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
@@ -969,13 +964,48 @@
 
 package androidx.ui.core.focus {
 
-  public final class FocusModifierImplKt {
-    method public static androidx.ui.focus.FocusModifier createFocusModifier(androidx.ui.focus.FocusDetailedState focusDetailedState);
+  public enum FocusDetailedState {
+    enum_constant public static final androidx.ui.core.focus.FocusDetailedState Active;
+    enum_constant public static final androidx.ui.core.focus.FocusDetailedState ActiveParent;
+    enum_constant public static final androidx.ui.core.focus.FocusDetailedState Captured;
+    enum_constant public static final androidx.ui.core.focus.FocusDetailedState Disabled;
+    enum_constant public static final androidx.ui.core.focus.FocusDetailedState Inactive;
+  }
+
+  public interface FocusModifier extends androidx.ui.core.Modifier.Element {
+    method public boolean captureFocus();
+    method public boolean freeFocus();
+    method public androidx.ui.core.focus.FocusDetailedState getFocusDetailedState();
+    method public void requestFocus();
+    property public abstract androidx.ui.core.focus.FocusDetailedState focusDetailedState;
+  }
+
+  public final class FocusModifierKt {
+    method public static androidx.ui.core.focus.FocusModifier FocusModifier();
+    method public static androidx.ui.core.focus.FocusState getFocusState(androidx.ui.core.focus.FocusModifier);
   }
 
   public final class FocusNodeUtilsKt {
   }
 
+  @Deprecated public final class FocusOperator {
+    ctor @Deprecated public FocusOperator();
+  }
+
+  public enum FocusState {
+    enum_constant public static final androidx.ui.core.focus.FocusState Focused;
+    enum_constant public static final androidx.ui.core.focus.FocusState NotFocusable;
+    enum_constant public static final androidx.ui.core.focus.FocusState NotFocused;
+  }
+
+  public final class FocusStateKt {
+    method public static androidx.ui.core.focus.FocusState focusState(androidx.ui.core.focus.FocusDetailedState);
+  }
+
+  public final class FocusableKt {
+    method @Deprecated public static void Focusable(Object focusOperator, kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit> children);
+  }
+
 }
 
 package androidx.ui.core.gesture {
@@ -1933,49 +1963,6 @@
 
 }
 
-package androidx.ui.focus {
-
-  public enum FocusDetailedState {
-    enum_constant public static final androidx.ui.focus.FocusDetailedState Active;
-    enum_constant public static final androidx.ui.focus.FocusDetailedState ActiveParent;
-    enum_constant public static final androidx.ui.focus.FocusDetailedState Captured;
-    enum_constant public static final androidx.ui.focus.FocusDetailedState Disabled;
-    enum_constant public static final androidx.ui.focus.FocusDetailedState Inactive;
-  }
-
-  public interface FocusModifier extends androidx.ui.core.Modifier.Element {
-    method public boolean captureFocus();
-    method public boolean freeFocus();
-    method public androidx.ui.focus.FocusDetailedState getFocusDetailedState();
-    method public void requestFocus();
-    property public abstract androidx.ui.focus.FocusDetailedState focusDetailedState;
-  }
-
-  public final class FocusModifierProviderKt {
-    method public static androidx.ui.focus.FocusModifier FocusModifier();
-    method public static androidx.ui.focus.FocusState getFocusState(androidx.ui.focus.FocusModifier);
-  }
-
-  @Deprecated public final class FocusOperator {
-    ctor @Deprecated public FocusOperator();
-  }
-
-  public enum FocusState {
-    enum_constant public static final androidx.ui.focus.FocusState Focused;
-    enum_constant public static final androidx.ui.focus.FocusState NotFocusable;
-    enum_constant public static final androidx.ui.focus.FocusState NotFocused;
-  }
-
-  public final class FocusStateKt {
-    method public static androidx.ui.focus.FocusState focusState(androidx.ui.focus.FocusDetailedState);
-  }
-
-  public final class FocusableKt {
-    method @Deprecated public static void Focusable(Object focusOperator, kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit> children);
-  }
-
-}
-
 package androidx.ui.graphics.vector {
 
   public final class VectorAsset {
diff --git a/ui/ui-core/api/public_plus_experimental_0.1.0-dev12.txt b/ui/ui-core/api/public_plus_experimental_0.1.0-dev12.txt
index 312c643..e4965f4 100644
--- a/ui/ui-core/api/public_plus_experimental_0.1.0-dev12.txt
+++ b/ui/ui-core/api/public_plus_experimental_0.1.0-dev12.txt
@@ -718,10 +718,6 @@
     method public static androidx.ui.core.Modifier paint(androidx.ui.core.Modifier, androidx.ui.graphics.painter.Painter painter, boolean sizeToIntrinsics = true, androidx.ui.core.Alignment alignment = Alignment.Center, androidx.ui.core.ContentScale contentScale = ContentScale.Inside, float alpha = 1.0f, androidx.ui.graphics.ColorFilter? colorFilter = null, boolean rtl = false);
   }
 
-  public final class ParentDataKt {
-    method @Deprecated public static inline void ParentData(Object data, kotlin.jvm.functions.Function0<kotlin.Unit> children);
-  }
-
   public interface ParentDataModifier extends androidx.ui.core.Modifier.Element {
     method public default Object? modifyParentData(androidx.ui.unit.Density, Object? parentData);
   }
@@ -937,7 +933,6 @@
     method public static androidx.compose.ProvidableAmbient<androidx.ui.core.texttoolbar.TextToolbar> getTextToolbarAmbient();
     method public static androidx.compose.ProvidableAmbient<androidx.ui.platform.UriHandler> getUriHandlerAmbient();
     method public static androidx.compose.Composition setContent(androidx.activity.ComponentActivity, androidx.compose.Recomposer recomposer = Recomposer.current(), kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @Deprecated public static androidx.compose.Composition setContent(android.app.Activity, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method public static androidx.compose.Composition setContent(android.view.ViewGroup, androidx.compose.Recomposer recomposer, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method @Deprecated public static androidx.compose.Composition setContent(android.view.ViewGroup, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method public static androidx.compose.Composition setViewContent(android.view.ViewGroup, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
@@ -971,13 +966,48 @@
 
 package androidx.ui.core.focus {
 
-  public final class FocusModifierImplKt {
-    method public static androidx.ui.focus.FocusModifier createFocusModifier(androidx.ui.focus.FocusDetailedState focusDetailedState);
+  public enum FocusDetailedState {
+    enum_constant public static final androidx.ui.core.focus.FocusDetailedState Active;
+    enum_constant public static final androidx.ui.core.focus.FocusDetailedState ActiveParent;
+    enum_constant public static final androidx.ui.core.focus.FocusDetailedState Captured;
+    enum_constant public static final androidx.ui.core.focus.FocusDetailedState Disabled;
+    enum_constant public static final androidx.ui.core.focus.FocusDetailedState Inactive;
+  }
+
+  public interface FocusModifier extends androidx.ui.core.Modifier.Element {
+    method public boolean captureFocus();
+    method public boolean freeFocus();
+    method public androidx.ui.core.focus.FocusDetailedState getFocusDetailedState();
+    method public void requestFocus();
+    property public abstract androidx.ui.core.focus.FocusDetailedState focusDetailedState;
+  }
+
+  public final class FocusModifierKt {
+    method public static androidx.ui.core.focus.FocusModifier FocusModifier();
+    method public static androidx.ui.core.focus.FocusState getFocusState(androidx.ui.core.focus.FocusModifier);
   }
 
   public final class FocusNodeUtilsKt {
   }
 
+  @Deprecated public final class FocusOperator {
+    ctor @Deprecated public FocusOperator();
+  }
+
+  public enum FocusState {
+    enum_constant public static final androidx.ui.core.focus.FocusState Focused;
+    enum_constant public static final androidx.ui.core.focus.FocusState NotFocusable;
+    enum_constant public static final androidx.ui.core.focus.FocusState NotFocused;
+  }
+
+  public final class FocusStateKt {
+    method public static androidx.ui.core.focus.FocusState focusState(androidx.ui.core.focus.FocusDetailedState);
+  }
+
+  public final class FocusableKt {
+    method @Deprecated public static void Focusable(Object focusOperator, kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit> children);
+  }
+
 }
 
 package androidx.ui.core.gesture {
@@ -1935,49 +1965,6 @@
 
 }
 
-package androidx.ui.focus {
-
-  public enum FocusDetailedState {
-    enum_constant public static final androidx.ui.focus.FocusDetailedState Active;
-    enum_constant public static final androidx.ui.focus.FocusDetailedState ActiveParent;
-    enum_constant public static final androidx.ui.focus.FocusDetailedState Captured;
-    enum_constant public static final androidx.ui.focus.FocusDetailedState Disabled;
-    enum_constant public static final androidx.ui.focus.FocusDetailedState Inactive;
-  }
-
-  public interface FocusModifier extends androidx.ui.core.Modifier.Element {
-    method public boolean captureFocus();
-    method public boolean freeFocus();
-    method public androidx.ui.focus.FocusDetailedState getFocusDetailedState();
-    method public void requestFocus();
-    property public abstract androidx.ui.focus.FocusDetailedState focusDetailedState;
-  }
-
-  public final class FocusModifierProviderKt {
-    method public static androidx.ui.focus.FocusModifier FocusModifier();
-    method public static androidx.ui.focus.FocusState getFocusState(androidx.ui.focus.FocusModifier);
-  }
-
-  @Deprecated public final class FocusOperator {
-    ctor @Deprecated public FocusOperator();
-  }
-
-  public enum FocusState {
-    enum_constant public static final androidx.ui.focus.FocusState Focused;
-    enum_constant public static final androidx.ui.focus.FocusState NotFocusable;
-    enum_constant public static final androidx.ui.focus.FocusState NotFocused;
-  }
-
-  public final class FocusStateKt {
-    method public static androidx.ui.focus.FocusState focusState(androidx.ui.focus.FocusDetailedState);
-  }
-
-  public final class FocusableKt {
-    method @Deprecated public static void Focusable(Object focusOperator, kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit> children);
-  }
-
-}
-
 package androidx.ui.graphics.vector {
 
   public final class VectorAsset {
diff --git a/ui/ui-core/api/public_plus_experimental_current.txt b/ui/ui-core/api/public_plus_experimental_current.txt
index 312c643..e4965f4 100644
--- a/ui/ui-core/api/public_plus_experimental_current.txt
+++ b/ui/ui-core/api/public_plus_experimental_current.txt
@@ -718,10 +718,6 @@
     method public static androidx.ui.core.Modifier paint(androidx.ui.core.Modifier, androidx.ui.graphics.painter.Painter painter, boolean sizeToIntrinsics = true, androidx.ui.core.Alignment alignment = Alignment.Center, androidx.ui.core.ContentScale contentScale = ContentScale.Inside, float alpha = 1.0f, androidx.ui.graphics.ColorFilter? colorFilter = null, boolean rtl = false);
   }
 
-  public final class ParentDataKt {
-    method @Deprecated public static inline void ParentData(Object data, kotlin.jvm.functions.Function0<kotlin.Unit> children);
-  }
-
   public interface ParentDataModifier extends androidx.ui.core.Modifier.Element {
     method public default Object? modifyParentData(androidx.ui.unit.Density, Object? parentData);
   }
@@ -937,7 +933,6 @@
     method public static androidx.compose.ProvidableAmbient<androidx.ui.core.texttoolbar.TextToolbar> getTextToolbarAmbient();
     method public static androidx.compose.ProvidableAmbient<androidx.ui.platform.UriHandler> getUriHandlerAmbient();
     method public static androidx.compose.Composition setContent(androidx.activity.ComponentActivity, androidx.compose.Recomposer recomposer = Recomposer.current(), kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @Deprecated public static androidx.compose.Composition setContent(android.app.Activity, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method public static androidx.compose.Composition setContent(android.view.ViewGroup, androidx.compose.Recomposer recomposer, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method @Deprecated public static androidx.compose.Composition setContent(android.view.ViewGroup, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method public static androidx.compose.Composition setViewContent(android.view.ViewGroup, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
@@ -971,13 +966,48 @@
 
 package androidx.ui.core.focus {
 
-  public final class FocusModifierImplKt {
-    method public static androidx.ui.focus.FocusModifier createFocusModifier(androidx.ui.focus.FocusDetailedState focusDetailedState);
+  public enum FocusDetailedState {
+    enum_constant public static final androidx.ui.core.focus.FocusDetailedState Active;
+    enum_constant public static final androidx.ui.core.focus.FocusDetailedState ActiveParent;
+    enum_constant public static final androidx.ui.core.focus.FocusDetailedState Captured;
+    enum_constant public static final androidx.ui.core.focus.FocusDetailedState Disabled;
+    enum_constant public static final androidx.ui.core.focus.FocusDetailedState Inactive;
+  }
+
+  public interface FocusModifier extends androidx.ui.core.Modifier.Element {
+    method public boolean captureFocus();
+    method public boolean freeFocus();
+    method public androidx.ui.core.focus.FocusDetailedState getFocusDetailedState();
+    method public void requestFocus();
+    property public abstract androidx.ui.core.focus.FocusDetailedState focusDetailedState;
+  }
+
+  public final class FocusModifierKt {
+    method public static androidx.ui.core.focus.FocusModifier FocusModifier();
+    method public static androidx.ui.core.focus.FocusState getFocusState(androidx.ui.core.focus.FocusModifier);
   }
 
   public final class FocusNodeUtilsKt {
   }
 
+  @Deprecated public final class FocusOperator {
+    ctor @Deprecated public FocusOperator();
+  }
+
+  public enum FocusState {
+    enum_constant public static final androidx.ui.core.focus.FocusState Focused;
+    enum_constant public static final androidx.ui.core.focus.FocusState NotFocusable;
+    enum_constant public static final androidx.ui.core.focus.FocusState NotFocused;
+  }
+
+  public final class FocusStateKt {
+    method public static androidx.ui.core.focus.FocusState focusState(androidx.ui.core.focus.FocusDetailedState);
+  }
+
+  public final class FocusableKt {
+    method @Deprecated public static void Focusable(Object focusOperator, kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit> children);
+  }
+
 }
 
 package androidx.ui.core.gesture {
@@ -1935,49 +1965,6 @@
 
 }
 
-package androidx.ui.focus {
-
-  public enum FocusDetailedState {
-    enum_constant public static final androidx.ui.focus.FocusDetailedState Active;
-    enum_constant public static final androidx.ui.focus.FocusDetailedState ActiveParent;
-    enum_constant public static final androidx.ui.focus.FocusDetailedState Captured;
-    enum_constant public static final androidx.ui.focus.FocusDetailedState Disabled;
-    enum_constant public static final androidx.ui.focus.FocusDetailedState Inactive;
-  }
-
-  public interface FocusModifier extends androidx.ui.core.Modifier.Element {
-    method public boolean captureFocus();
-    method public boolean freeFocus();
-    method public androidx.ui.focus.FocusDetailedState getFocusDetailedState();
-    method public void requestFocus();
-    property public abstract androidx.ui.focus.FocusDetailedState focusDetailedState;
-  }
-
-  public final class FocusModifierProviderKt {
-    method public static androidx.ui.focus.FocusModifier FocusModifier();
-    method public static androidx.ui.focus.FocusState getFocusState(androidx.ui.focus.FocusModifier);
-  }
-
-  @Deprecated public final class FocusOperator {
-    ctor @Deprecated public FocusOperator();
-  }
-
-  public enum FocusState {
-    enum_constant public static final androidx.ui.focus.FocusState Focused;
-    enum_constant public static final androidx.ui.focus.FocusState NotFocusable;
-    enum_constant public static final androidx.ui.focus.FocusState NotFocused;
-  }
-
-  public final class FocusStateKt {
-    method public static androidx.ui.focus.FocusState focusState(androidx.ui.focus.FocusDetailedState);
-  }
-
-  public final class FocusableKt {
-    method @Deprecated public static void Focusable(Object focusOperator, kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit> children);
-  }
-
-}
-
 package androidx.ui.graphics.vector {
 
   public final class VectorAsset {
diff --git a/ui/ui-core/api/restricted_0.1.0-dev12.txt b/ui/ui-core/api/restricted_0.1.0-dev12.txt
index bded631..f09213b 100644
--- a/ui/ui-core/api/restricted_0.1.0-dev12.txt
+++ b/ui/ui-core/api/restricted_0.1.0-dev12.txt
@@ -726,10 +726,6 @@
     method public static androidx.ui.core.Modifier paint(androidx.ui.core.Modifier, androidx.ui.graphics.painter.Painter painter, boolean sizeToIntrinsics = true, androidx.ui.core.Alignment alignment = Alignment.Center, androidx.ui.core.ContentScale contentScale = ContentScale.Inside, float alpha = 1.0f, androidx.ui.graphics.ColorFilter? colorFilter = null, boolean rtl = false);
   }
 
-  public final class ParentDataKt {
-    method @Deprecated public static inline void ParentData(Object data, kotlin.jvm.functions.Function0<kotlin.Unit> children);
-  }
-
   public interface ParentDataModifier extends androidx.ui.core.Modifier.Element {
     method public default Object? modifyParentData(androidx.ui.unit.Density, Object? parentData);
   }
@@ -945,7 +941,6 @@
     method public static androidx.compose.ProvidableAmbient<androidx.ui.core.texttoolbar.TextToolbar> getTextToolbarAmbient();
     method public static androidx.compose.ProvidableAmbient<androidx.ui.platform.UriHandler> getUriHandlerAmbient();
     method public static androidx.compose.Composition setContent(androidx.activity.ComponentActivity, androidx.compose.Recomposer recomposer = Recomposer.current(), kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @Deprecated public static androidx.compose.Composition setContent(android.app.Activity, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method public static androidx.compose.Composition setContent(android.view.ViewGroup, androidx.compose.Recomposer recomposer, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method @Deprecated public static androidx.compose.Composition setContent(android.view.ViewGroup, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method public static androidx.compose.Composition setViewContent(android.view.ViewGroup, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
@@ -979,13 +974,48 @@
 
 package androidx.ui.core.focus {
 
-  public final class FocusModifierImplKt {
-    method public static androidx.ui.focus.FocusModifier createFocusModifier(androidx.ui.focus.FocusDetailedState focusDetailedState);
+  public enum FocusDetailedState {
+    enum_constant public static final androidx.ui.core.focus.FocusDetailedState Active;
+    enum_constant public static final androidx.ui.core.focus.FocusDetailedState ActiveParent;
+    enum_constant public static final androidx.ui.core.focus.FocusDetailedState Captured;
+    enum_constant public static final androidx.ui.core.focus.FocusDetailedState Disabled;
+    enum_constant public static final androidx.ui.core.focus.FocusDetailedState Inactive;
+  }
+
+  public interface FocusModifier extends androidx.ui.core.Modifier.Element {
+    method public boolean captureFocus();
+    method public boolean freeFocus();
+    method public androidx.ui.core.focus.FocusDetailedState getFocusDetailedState();
+    method public void requestFocus();
+    property public abstract androidx.ui.core.focus.FocusDetailedState focusDetailedState;
+  }
+
+  public final class FocusModifierKt {
+    method public static androidx.ui.core.focus.FocusModifier FocusModifier();
+    method public static androidx.ui.core.focus.FocusState getFocusState(androidx.ui.core.focus.FocusModifier);
   }
 
   public final class FocusNodeUtilsKt {
   }
 
+  @Deprecated public final class FocusOperator {
+    ctor @Deprecated public FocusOperator();
+  }
+
+  public enum FocusState {
+    enum_constant public static final androidx.ui.core.focus.FocusState Focused;
+    enum_constant public static final androidx.ui.core.focus.FocusState NotFocusable;
+    enum_constant public static final androidx.ui.core.focus.FocusState NotFocused;
+  }
+
+  public final class FocusStateKt {
+    method public static androidx.ui.core.focus.FocusState focusState(androidx.ui.core.focus.FocusDetailedState);
+  }
+
+  public final class FocusableKt {
+    method @Deprecated public static void Focusable(Object focusOperator, kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit> children);
+  }
+
 }
 
 package androidx.ui.core.gesture {
@@ -1943,49 +1973,6 @@
 
 }
 
-package androidx.ui.focus {
-
-  public enum FocusDetailedState {
-    enum_constant public static final androidx.ui.focus.FocusDetailedState Active;
-    enum_constant public static final androidx.ui.focus.FocusDetailedState ActiveParent;
-    enum_constant public static final androidx.ui.focus.FocusDetailedState Captured;
-    enum_constant public static final androidx.ui.focus.FocusDetailedState Disabled;
-    enum_constant public static final androidx.ui.focus.FocusDetailedState Inactive;
-  }
-
-  public interface FocusModifier extends androidx.ui.core.Modifier.Element {
-    method public boolean captureFocus();
-    method public boolean freeFocus();
-    method public androidx.ui.focus.FocusDetailedState getFocusDetailedState();
-    method public void requestFocus();
-    property public abstract androidx.ui.focus.FocusDetailedState focusDetailedState;
-  }
-
-  public final class FocusModifierProviderKt {
-    method public static androidx.ui.focus.FocusModifier FocusModifier();
-    method public static androidx.ui.focus.FocusState getFocusState(androidx.ui.focus.FocusModifier);
-  }
-
-  @Deprecated public final class FocusOperator {
-    ctor @Deprecated public FocusOperator();
-  }
-
-  public enum FocusState {
-    enum_constant public static final androidx.ui.focus.FocusState Focused;
-    enum_constant public static final androidx.ui.focus.FocusState NotFocusable;
-    enum_constant public static final androidx.ui.focus.FocusState NotFocused;
-  }
-
-  public final class FocusStateKt {
-    method public static androidx.ui.focus.FocusState focusState(androidx.ui.focus.FocusDetailedState);
-  }
-
-  public final class FocusableKt {
-    method @Deprecated public static void Focusable(Object focusOperator, kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit> children);
-  }
-
-}
-
 package androidx.ui.graphics.vector {
 
   public final class VectorAsset {
diff --git a/ui/ui-core/api/restricted_current.txt b/ui/ui-core/api/restricted_current.txt
index bded631..f09213b 100644
--- a/ui/ui-core/api/restricted_current.txt
+++ b/ui/ui-core/api/restricted_current.txt
@@ -726,10 +726,6 @@
     method public static androidx.ui.core.Modifier paint(androidx.ui.core.Modifier, androidx.ui.graphics.painter.Painter painter, boolean sizeToIntrinsics = true, androidx.ui.core.Alignment alignment = Alignment.Center, androidx.ui.core.ContentScale contentScale = ContentScale.Inside, float alpha = 1.0f, androidx.ui.graphics.ColorFilter? colorFilter = null, boolean rtl = false);
   }
 
-  public final class ParentDataKt {
-    method @Deprecated public static inline void ParentData(Object data, kotlin.jvm.functions.Function0<kotlin.Unit> children);
-  }
-
   public interface ParentDataModifier extends androidx.ui.core.Modifier.Element {
     method public default Object? modifyParentData(androidx.ui.unit.Density, Object? parentData);
   }
@@ -945,7 +941,6 @@
     method public static androidx.compose.ProvidableAmbient<androidx.ui.core.texttoolbar.TextToolbar> getTextToolbarAmbient();
     method public static androidx.compose.ProvidableAmbient<androidx.ui.platform.UriHandler> getUriHandlerAmbient();
     method public static androidx.compose.Composition setContent(androidx.activity.ComponentActivity, androidx.compose.Recomposer recomposer = Recomposer.current(), kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @Deprecated public static androidx.compose.Composition setContent(android.app.Activity, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method public static androidx.compose.Composition setContent(android.view.ViewGroup, androidx.compose.Recomposer recomposer, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method @Deprecated public static androidx.compose.Composition setContent(android.view.ViewGroup, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method public static androidx.compose.Composition setViewContent(android.view.ViewGroup, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
@@ -979,13 +974,48 @@
 
 package androidx.ui.core.focus {
 
-  public final class FocusModifierImplKt {
-    method public static androidx.ui.focus.FocusModifier createFocusModifier(androidx.ui.focus.FocusDetailedState focusDetailedState);
+  public enum FocusDetailedState {
+    enum_constant public static final androidx.ui.core.focus.FocusDetailedState Active;
+    enum_constant public static final androidx.ui.core.focus.FocusDetailedState ActiveParent;
+    enum_constant public static final androidx.ui.core.focus.FocusDetailedState Captured;
+    enum_constant public static final androidx.ui.core.focus.FocusDetailedState Disabled;
+    enum_constant public static final androidx.ui.core.focus.FocusDetailedState Inactive;
+  }
+
+  public interface FocusModifier extends androidx.ui.core.Modifier.Element {
+    method public boolean captureFocus();
+    method public boolean freeFocus();
+    method public androidx.ui.core.focus.FocusDetailedState getFocusDetailedState();
+    method public void requestFocus();
+    property public abstract androidx.ui.core.focus.FocusDetailedState focusDetailedState;
+  }
+
+  public final class FocusModifierKt {
+    method public static androidx.ui.core.focus.FocusModifier FocusModifier();
+    method public static androidx.ui.core.focus.FocusState getFocusState(androidx.ui.core.focus.FocusModifier);
   }
 
   public final class FocusNodeUtilsKt {
   }
 
+  @Deprecated public final class FocusOperator {
+    ctor @Deprecated public FocusOperator();
+  }
+
+  public enum FocusState {
+    enum_constant public static final androidx.ui.core.focus.FocusState Focused;
+    enum_constant public static final androidx.ui.core.focus.FocusState NotFocusable;
+    enum_constant public static final androidx.ui.core.focus.FocusState NotFocused;
+  }
+
+  public final class FocusStateKt {
+    method public static androidx.ui.core.focus.FocusState focusState(androidx.ui.core.focus.FocusDetailedState);
+  }
+
+  public final class FocusableKt {
+    method @Deprecated public static void Focusable(Object focusOperator, kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit> children);
+  }
+
 }
 
 package androidx.ui.core.gesture {
@@ -1943,49 +1973,6 @@
 
 }
 
-package androidx.ui.focus {
-
-  public enum FocusDetailedState {
-    enum_constant public static final androidx.ui.focus.FocusDetailedState Active;
-    enum_constant public static final androidx.ui.focus.FocusDetailedState ActiveParent;
-    enum_constant public static final androidx.ui.focus.FocusDetailedState Captured;
-    enum_constant public static final androidx.ui.focus.FocusDetailedState Disabled;
-    enum_constant public static final androidx.ui.focus.FocusDetailedState Inactive;
-  }
-
-  public interface FocusModifier extends androidx.ui.core.Modifier.Element {
-    method public boolean captureFocus();
-    method public boolean freeFocus();
-    method public androidx.ui.focus.FocusDetailedState getFocusDetailedState();
-    method public void requestFocus();
-    property public abstract androidx.ui.focus.FocusDetailedState focusDetailedState;
-  }
-
-  public final class FocusModifierProviderKt {
-    method public static androidx.ui.focus.FocusModifier FocusModifier();
-    method public static androidx.ui.focus.FocusState getFocusState(androidx.ui.focus.FocusModifier);
-  }
-
-  @Deprecated public final class FocusOperator {
-    ctor @Deprecated public FocusOperator();
-  }
-
-  public enum FocusState {
-    enum_constant public static final androidx.ui.focus.FocusState Focused;
-    enum_constant public static final androidx.ui.focus.FocusState NotFocusable;
-    enum_constant public static final androidx.ui.focus.FocusState NotFocused;
-  }
-
-  public final class FocusStateKt {
-    method public static androidx.ui.focus.FocusState focusState(androidx.ui.focus.FocusDetailedState);
-  }
-
-  public final class FocusableKt {
-    method @Deprecated public static void Focusable(Object focusOperator, kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit> children);
-  }
-
-}
-
 package androidx.ui.graphics.vector {
 
   public final class VectorAsset {
diff --git a/ui/ui-core/integration-tests/ui-core-demos/src/main/java/androidx/ui/core/demos/focus/FocusableDemo.kt b/ui/ui-core/integration-tests/ui-core-demos/src/main/java/androidx/ui/core/demos/focus/FocusableDemo.kt
index d7b5433..386580e 100644
--- a/ui/ui-core/integration-tests/ui-core-demos/src/main/java/androidx/ui/core/demos/focus/FocusableDemo.kt
+++ b/ui/ui-core/integration-tests/ui-core-demos/src/main/java/androidx/ui/core/demos/focus/FocusableDemo.kt
@@ -19,11 +19,11 @@
 import androidx.compose.Composable
 import androidx.ui.core.Modifier
 import androidx.ui.core.gesture.tapGestureFilter
-import androidx.ui.focus.FocusModifier
-import androidx.ui.focus.FocusState.Focused
-import androidx.ui.focus.FocusState.NotFocusable
-import androidx.ui.focus.FocusState.NotFocused
-import androidx.ui.focus.focusState
+import androidx.ui.core.focus.FocusModifier
+import androidx.ui.core.focus.FocusState.Focused
+import androidx.ui.core.focus.FocusState.NotFocusable
+import androidx.ui.core.focus.FocusState.NotFocused
+import androidx.ui.core.focus.focusState
 import androidx.ui.foundation.Text
 import androidx.ui.graphics.Color
 import androidx.ui.layout.Arrangement
diff --git a/ui/ui-core/integration-tests/ui-core-demos/src/main/java/androidx/ui/core/demos/keyinput/KeyInputDemo.kt b/ui/ui-core/integration-tests/ui-core-demos/src/main/java/androidx/ui/core/demos/keyinput/KeyInputDemo.kt
index 482ca25..642005a 100644
--- a/ui/ui-core/integration-tests/ui-core-demos/src/main/java/androidx/ui/core/demos/keyinput/KeyInputDemo.kt
+++ b/ui/ui-core/integration-tests/ui-core-demos/src/main/java/androidx/ui/core/demos/keyinput/KeyInputDemo.kt
@@ -21,11 +21,11 @@
 import androidx.compose.state
 import androidx.ui.core.Modifier
 import androidx.ui.core.gesture.tapGestureFilter
-import androidx.ui.focus.FocusModifier
-import androidx.ui.focus.FocusState.Focused
-import androidx.ui.focus.FocusState.NotFocusable
-import androidx.ui.focus.FocusState.NotFocused
-import androidx.ui.focus.focusState
+import androidx.ui.core.focus.FocusModifier
+import androidx.ui.core.focus.FocusState.Focused
+import androidx.ui.core.focus.FocusState.NotFocusable
+import androidx.ui.core.focus.FocusState.NotFocused
+import androidx.ui.core.focus.focusState
 import androidx.ui.foundation.Text
 import androidx.ui.graphics.Color
 import androidx.ui.layout.Arrangement
diff --git a/ui/ui-core/src/androidTest/java/androidx/ui/core/focus/CaptureFocusTest.kt b/ui/ui-core/src/androidTest/java/androidx/ui/core/focus/CaptureFocusTest.kt
index 63ac2d2..792fd1c 100644
--- a/ui/ui-core/src/androidTest/java/androidx/ui/core/focus/CaptureFocusTest.kt
+++ b/ui/ui-core/src/androidTest/java/androidx/ui/core/focus/CaptureFocusTest.kt
@@ -17,15 +17,15 @@
 package androidx.ui.core.focus
 
 import androidx.test.filters.SmallTest
-import androidx.ui.focus.FocusDetailedState.Active
-import androidx.ui.focus.FocusDetailedState.ActiveParent
-import androidx.ui.focus.FocusDetailedState.Captured
-import androidx.ui.focus.FocusDetailedState.Disabled
-import androidx.ui.focus.FocusDetailedState.Inactive
+import androidx.ui.core.focus.FocusDetailedState.Active
+import androidx.ui.core.focus.FocusDetailedState.ActiveParent
+import androidx.ui.core.focus.FocusDetailedState.Captured
+import androidx.ui.core.focus.FocusDetailedState.Disabled
+import androidx.ui.core.focus.FocusDetailedState.Inactive
 import androidx.ui.foundation.Box
 import androidx.ui.test.createComposeRule
-import androidx.ui.test.runOnUiThread
-import com.google.common.truth.Truth
+import androidx.ui.test.runOnIdleCompose
+import com.google.common.truth.Truth.assertThat
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -39,86 +39,106 @@
 
     @Test
     fun active_captureFocus_changesStateToCaptured() {
-        runOnUiThread {
-            // Arrange.
-            val focusModifier = createFocusModifier(Active).also {
-                composeTestRule.setContent { Box(modifier = it) }
-            }
+        // Arrange.
+        lateinit var focusModifier: FocusModifier
+        composeTestRule.setFocusableContent {
+            focusModifier = FocusModifierImpl(Active)
+            Box(modifier = focusModifier)
+        }
 
-            // Act.
-            val success = focusModifier.captureFocus()
+        // Act.
+        val success = runOnIdleCompose {
+            focusModifier.captureFocus()
+        }
 
-            // Assert.
-            Truth.assertThat(success).isTrue()
-            Truth.assertThat(focusModifier.focusDetailedState).isEqualTo(Captured)
+        // Assert.
+        runOnIdleCompose {
+            assertThat(success).isTrue()
+            assertThat(focusModifier.focusDetailedState).isEqualTo(Captured)
         }
     }
 
     @Test
     fun activeParent_captureFocus_retainsStateAsActiveParent() {
-        runOnUiThread {
-            // Arrange.
-            val focusModifier = createFocusModifier(ActiveParent).also {
-                composeTestRule.setContent { Box(modifier = it) }
-            }
+        // Arrange.
+        lateinit var focusModifier: FocusModifier
+        composeTestRule.setFocusableContent {
+            focusModifier = FocusModifierImpl(ActiveParent)
+            Box(modifier = focusModifier)
+        }
 
-            // Act.
-            val success = focusModifier.captureFocus()
+        // Act.
+        val success = runOnIdleCompose {
+            focusModifier.captureFocus()
+        }
 
-            // Assert.
-            Truth.assertThat(success).isFalse()
-            Truth.assertThat(focusModifier.focusDetailedState).isEqualTo(ActiveParent)
+        // Assert.
+        runOnIdleCompose {
+            assertThat(success).isFalse()
+            assertThat(focusModifier.focusDetailedState).isEqualTo(ActiveParent)
         }
     }
 
     @Test
     fun captured_captureFocus_retainsStateAsCaptured() {
-        runOnUiThread {
-            // Arrange.
-            val focusModifier = createFocusModifier(Captured).also {
-                composeTestRule.setContent { Box(modifier = it) }
-            }
+        // Arrange.
+        lateinit var focusModifier: FocusModifier
+        composeTestRule.setFocusableContent {
+            focusModifier = FocusModifierImpl(Captured)
+            Box(modifier = focusModifier)
+        }
 
-            // Act.
-            val success = focusModifier.captureFocus()
+        // Act.
+        val success = runOnIdleCompose {
+            focusModifier.captureFocus()
+        }
 
-            // Assert.
-            Truth.assertThat(success).isTrue()
-            Truth.assertThat(focusModifier.focusDetailedState).isEqualTo(Captured)
+        // Assert.
+        runOnIdleCompose {
+            assertThat(success).isTrue()
+            assertThat(focusModifier.focusDetailedState).isEqualTo(Captured)
         }
     }
 
     @Test
     fun disabled_captureFocus_retainsStateAsDisabled() {
-        runOnUiThread {
-            // Arrange.
-            val focusModifier = createFocusModifier(Disabled).also {
-                composeTestRule.setContent { Box(modifier = it) }
-            }
+        // Arrange.
+        lateinit var focusModifier: FocusModifier
+        composeTestRule.setFocusableContent {
+            focusModifier = FocusModifierImpl(Disabled)
+            Box(modifier = focusModifier)
+        }
 
-            // Act.
-            val success = focusModifier.captureFocus()
+        // Act.
+        val success = runOnIdleCompose {
+            focusModifier.captureFocus()
+        }
 
-            // Assert.
-            Truth.assertThat(success).isFalse()
-            Truth.assertThat(focusModifier.focusDetailedState).isEqualTo(Disabled)
+        // Assert.
+        runOnIdleCompose {
+            assertThat(success).isFalse()
+            assertThat(focusModifier.focusDetailedState).isEqualTo(Disabled)
         }
     }
 
     @Test
     fun inactive_captureFocus_retainsStateAsInactive() {
-        runOnUiThread {
-            // Arrange.
-            val focusModifier = createFocusModifier(Inactive).also {
-                composeTestRule.setContent { Box(modifier = it) }
-            }
+        // Arrange.
+        lateinit var focusModifier: FocusModifier
+        composeTestRule.setFocusableContent {
+            focusModifier = FocusModifierImpl(Inactive)
+            Box(modifier = focusModifier)
+        }
 
-            // Act.
-            val success = focusModifier.captureFocus()
+        // Act.
+        val success = runOnIdleCompose {
+            focusModifier.captureFocus()
+        }
 
-            // Assert.
-            Truth.assertThat(success).isFalse()
-            Truth.assertThat(focusModifier.focusDetailedState).isEqualTo(Inactive)
+        // Assert.
+        runOnIdleCompose {
+            assertThat(success).isFalse()
+            assertThat(focusModifier.focusDetailedState).isEqualTo(Inactive)
         }
     }
-}
\ No newline at end of file
+}
diff --git a/ui/ui-core/src/androidTest/java/androidx/ui/core/focus/FindFocusableChildrenTest.kt b/ui/ui-core/src/androidTest/java/androidx/ui/core/focus/FindFocusableChildrenTest.kt
index f630a48..4774df6 100644
--- a/ui/ui-core/src/androidTest/java/androidx/ui/core/focus/FindFocusableChildrenTest.kt
+++ b/ui/ui-core/src/androidTest/java/androidx/ui/core/focus/FindFocusableChildrenTest.kt
@@ -18,13 +18,12 @@
 
 import androidx.test.filters.SmallTest
 import androidx.ui.core.Modifier
-import androidx.ui.focus.FocusDetailedState
 import androidx.ui.foundation.Box
 import androidx.ui.foundation.drawBackground
 import androidx.ui.graphics.Color.Companion.Red
 import androidx.ui.test.createComposeRule
-import androidx.ui.test.runOnUiThread
-import com.google.common.truth.Truth
+import androidx.ui.test.runOnIdleCompose
+import com.google.common.truth.Truth.assertThat
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -38,68 +37,84 @@
 
     @Test
     fun returnsFirstFocusNodeInModifierChain() {
-        runOnUiThread {
-            // Arrange.
-            // layoutNode--focusNode1--focusNode2--focusNode3
-            val focusModifier1 = createFocusModifier(FocusDetailedState.Inactive)
-            val focusModifier2 = createFocusModifier(FocusDetailedState.Inactive)
-            val focusModifier3 = createFocusModifier(FocusDetailedState.Inactive)
-            composeTestRule.setContent {
-                Box(modifier = focusModifier1 + focusModifier2 + focusModifier3)
-            }
+        lateinit var focusModifier1: FocusModifier
+        lateinit var focusModifier2: FocusModifier
+        lateinit var focusModifier3: FocusModifier
+        // Arrange.
+        // layoutNode--focusNode1--focusNode2--focusNode3
+        composeTestRule.setContent {
+            focusModifier1 = FocusModifier()
+            focusModifier2 = FocusModifier()
+            focusModifier3 = FocusModifier()
+            Box(modifier = focusModifier1 + focusModifier2 + focusModifier3)
+        }
 
-            // Act.
-            val focusableChildren = focusModifier1.focusNode.focusableChildren()
+        // Act.
+        val focusableChildren = runOnIdleCompose {
+            focusModifier1.focusNode.focusableChildren()
+        }
 
-            // Assert.
-            Truth.assertThat(focusableChildren).containsExactly(focusModifier2.focusNode)
+        // Assert.
+        runOnIdleCompose {
+            assertThat(focusableChildren).containsExactly(focusModifier2.focusNode)
         }
     }
 
     @Test
     fun skipsNonFocusNodesAndReturnsFirstFocusNodeInModifierChain() {
-        runOnUiThread {
-            // Arrange.
-            // layoutNode--focusNode1--nonFocusNode--focusNode2
-            val focusModifier1 = createFocusModifier(FocusDetailedState.Inactive)
-            val focusModifier2 = createFocusModifier(FocusDetailedState.Inactive)
-            composeTestRule.setContent {
-                Box(modifier = focusModifier1 + Modifier.drawBackground(Red) + focusModifier2)
-            }
+        lateinit var focusModifier1: FocusModifier
+        lateinit var focusModifier2: FocusModifier
+        // Arrange.
+        // layoutNode--focusNode1--nonFocusNode--focusNode2
+        composeTestRule.setContent {
+            focusModifier1 = FocusModifier()
+            focusModifier2 = FocusModifier()
+            Box(modifier = focusModifier1 + Modifier.drawBackground(Red) + focusModifier2)
+        }
 
-            // Act.
-            val focusableChildren = focusModifier1.focusNode.focusableChildren()
+        // Act.
+        val focusableChildren = runOnIdleCompose {
+            focusModifier1.focusNode.focusableChildren()
+        }
 
-            // Assert.
-            Truth.assertThat(focusableChildren).containsExactly(focusModifier2.focusNode)
+        // Assert.
+        runOnIdleCompose {
+            assertThat(focusableChildren).containsExactly(focusModifier2.focusNode)
         }
     }
 
     @Test
     fun returnsFirstFocusChildOfEachChildLayoutNode() {
-        runOnUiThread {
-            // Arrange.
-            // parentLayoutNode--parentFocusNode
-            //       |___________________________________
-            //       |                                   |
-            // childLayoutNode1--focusNode1          childLayoutNode2--focusNode2--focusNode3
-            val parentFocusModifier = createFocusModifier(FocusDetailedState.Inactive)
-            val focusModifier1 = createFocusModifier(FocusDetailedState.Inactive)
-            val focusModifier2 = createFocusModifier(FocusDetailedState.Inactive)
-            val focusModifier3 = createFocusModifier(FocusDetailedState.Inactive)
-            composeTestRule.setContent {
-                Box(modifier = parentFocusModifier) {
-                    Box(modifier = focusModifier1)
-                    Box(modifier = focusModifier2 + focusModifier3)
-                }
+        // Arrange.
+        // parentLayoutNode--parentFocusNode
+        //       |___________________________________
+        //       |                                   |
+        // childLayoutNode1--focusNode1          childLayoutNode2--focusNode2--focusNode3
+        lateinit var parentFocusModifier: FocusModifier
+        lateinit var focusModifier1: FocusModifier
+        lateinit var focusModifier2: FocusModifier
+        lateinit var focusModifier3: FocusModifier
+        composeTestRule.setContent {
+            parentFocusModifier = FocusModifier()
+            focusModifier1 = FocusModifier()
+            focusModifier2 = FocusModifier()
+            focusModifier3 = FocusModifier()
+            Box(modifier = parentFocusModifier) {
+                Box(modifier = focusModifier1)
+                Box(modifier = focusModifier2 + focusModifier3)
             }
+        }
 
-            // Act.
-            val focusableChildren = parentFocusModifier.focusNode.focusableChildren()
+        // Act.
+        val focusableChildren = runOnIdleCompose {
+            parentFocusModifier.focusNode.focusableChildren()
+        }
 
-            // Assert.
-            Truth.assertThat(focusableChildren)
-                .containsExactly(focusModifier1.focusNode, focusModifier2.focusNode)
+        // Assert.
+        runOnIdleCompose {
+            assertThat(focusableChildren).containsExactly(
+                focusModifier1.focusNode, focusModifier2.focusNode
+            )
         }
     }
 }
diff --git a/ui/ui-core/src/androidTest/java/androidx/ui/core/focus/FindParentFocusNodeTest.kt b/ui/ui-core/src/androidTest/java/androidx/ui/core/focus/FindParentFocusNodeTest.kt
index 5bb81b2..2548c47 100644
--- a/ui/ui-core/src/androidTest/java/androidx/ui/core/focus/FindParentFocusNodeTest.kt
+++ b/ui/ui-core/src/androidTest/java/androidx/ui/core/focus/FindParentFocusNodeTest.kt
@@ -18,13 +18,11 @@
 
 import androidx.test.filters.SmallTest
 import androidx.ui.core.Modifier
-import androidx.ui.focus.FocusDetailedState
-import androidx.ui.focus.FocusDetailedState.Inactive
 import androidx.ui.foundation.Box
 import androidx.ui.foundation.drawBackground
 import androidx.ui.graphics.Color.Companion.Red
 import androidx.ui.test.createComposeRule
-import androidx.ui.test.runOnUiThread
+import androidx.ui.test.runOnIdleCompose
 import com.google.common.truth.Truth.assertThat
 import org.junit.Rule
 import org.junit.Test
@@ -39,138 +37,167 @@
 
     @Test
     fun noParentReturnsNull() {
-        runOnUiThread {
-            // Arrange.
-            val focusModifier = createFocusModifier(FocusDetailedState.Inactive).also {
-                composeTestRule.setContent { Box(modifier = it) }
-            }
+        // Arrange.
+        lateinit var focusModifier: FocusModifier
+        composeTestRule.setFocusableContent {
+            focusModifier = FocusModifier()
+            Box(modifier = focusModifier)
+        }
 
-            // Act.
-            val rootFocusNode = focusModifier.focusNode.findParentFocusNode()!!
-                .findParentFocusNode()
+        // Act.
+        val rootFocusNode = runOnIdleCompose {
+            focusModifier.focusNode.findParentFocusNode()!!.findParentFocusNode()
+        }
 
-            // Assert.
+        // Assert.
+        runOnIdleCompose {
             assertThat(rootFocusNode).isNull()
         }
     }
 
     @Test
     fun returnsImmediateParentFromModifierChain() {
-        runOnUiThread {
-            // Arrange.
-            // focusNode1--focusNode2--focusNode3--focusNode4--focusNode5
-            val modifier1 = createFocusModifier(Inactive)
-            val modifier2 = createFocusModifier(Inactive)
-            val modifier3 = createFocusModifier(Inactive)
-            val modifier4 = createFocusModifier(Inactive)
-            val modifier5 = createFocusModifier(Inactive)
-            composeTestRule.setContent {
-                Box(modifier = modifier1 + modifier2 + modifier3 + modifier4 + modifier5) {}
-            }
+        // Arrange.
+        // focusNode1--focusNode2--focusNode3--focusNode4--focusNode5
+        lateinit var modifier1: FocusModifier
+        lateinit var modifier2: FocusModifier
+        lateinit var modifier3: FocusModifier
+        lateinit var modifier4: FocusModifier
+        lateinit var modifier5: FocusModifier
+        composeTestRule.setFocusableContent {
+            modifier1 = FocusModifier()
+            modifier2 = FocusModifier()
+            modifier3 = FocusModifier()
+            modifier4 = FocusModifier()
+            modifier5 = FocusModifier()
+            Box(modifier = modifier1 + modifier2 + modifier3 + modifier4 + modifier5) {}
+        }
 
-            // Act.
-            val parent = modifier3.focusNode.findParentFocusNode()
+        // Act.
+        val parent = runOnIdleCompose {
+            modifier3.focusNode.findParentFocusNode()
+        }
 
-            // Assert.
+        // Assert.
+        runOnIdleCompose {
             assertThat(parent).isEqualTo(modifier2.focusNode)
         }
     }
 
     @Test
     fun returnsImmediateParentFromModifierChain_ignoresNonFocusModifiers() {
-        runOnUiThread {
-            // Arrange.
-            // focusNode1--focusNode2--nonFocusNode--focusNode3
-            val modifier1 = createFocusModifier(Inactive)
-            val modifier2 = createFocusModifier(Inactive)
-            val modifier3 = createFocusModifier(Inactive)
-            composeTestRule.setContent {
-                Box(modifier = modifier1 + modifier2 + Modifier.drawBackground(Red) + modifier3)
-            }
+        // Arrange.
+        // focusNode1--focusNode2--nonFocusNode--focusNode3
+        lateinit var modifier1: FocusModifier
+        lateinit var modifier2: FocusModifier
+        lateinit var modifier3: FocusModifier
+        composeTestRule.setFocusableContent {
+            modifier1 = FocusModifier()
+            modifier2 = FocusModifier()
+            modifier3 = FocusModifier()
+            Box(modifier = modifier1 + modifier2 + Modifier.drawBackground(Red) + modifier3)
+        }
 
-            // Act.
-            val parent = modifier3.focusNode.findParentFocusNode()
+        // Act.
+        val parent = runOnIdleCompose {
+            modifier3.focusNode.findParentFocusNode()
+        }
 
-            // Assert.
+        // Assert.
+        runOnIdleCompose {
             assertThat(parent).isEqualTo(modifier2.focusNode)
         }
     }
 
     @Test
     fun returnsLastFocusParentFromParentLayoutNode() {
-        runOnUiThread {
-            // Arrange.
-            // parentLayoutNode--parentFocusNode1--parentFocusNode2
-            //       |
-            // layoutNode--focusNode
-            val parentFocusModifier1 = createFocusModifier(Inactive)
-            val parentFocusModifier2 = createFocusModifier(Inactive)
-            val focusModifier = createFocusModifier(Inactive)
-            composeTestRule.setContent {
-                Box(modifier = parentFocusModifier1 + parentFocusModifier2) {
-                    Box(modifier = focusModifier)
-                }
+        // Arrange.
+        // parentLayoutNode--parentFocusNode1--parentFocusNode2
+        //       |
+        // layoutNode--focusNode
+        lateinit var parentFocusModifier1: FocusModifier
+        lateinit var parentFocusModifier2: FocusModifier
+        lateinit var focusModifier: FocusModifier
+        composeTestRule.setFocusableContent {
+            parentFocusModifier1 = FocusModifier()
+            parentFocusModifier2 = FocusModifier()
+            focusModifier = FocusModifier()
+            Box(modifier = parentFocusModifier1 + parentFocusModifier2) {
+                Box(modifier = focusModifier)
             }
+        }
 
-            // Act.
-            val parent = focusModifier.focusNode.findParentFocusNode()
+        // Act.
+        val parent = runOnIdleCompose {
+            focusModifier.focusNode.findParentFocusNode()
+        }
 
-            // Assert.
+        // Assert.
+        runOnIdleCompose {
             assertThat(parent).isEqualTo(parentFocusModifier2.focusNode)
         }
     }
 
     @Test
     fun returnsImmediateParent() {
-        runOnUiThread {
-            // Arrange.
-            // grandparentLayoutNode--grandparentFocusNode
-            //       |
-            // parentLayoutNode--parentFocusNode
-            //       |
-            // layoutNode--focusNode
-            val grandparentFocusModifier = createFocusModifier(Inactive)
-            val parentFocusModifier = createFocusModifier(Inactive)
-            val focusModifier = createFocusModifier(Inactive)
-            composeTestRule.setContent {
-                Box(modifier = grandparentFocusModifier) {
-                    Box(modifier = parentFocusModifier) {
-                        Box(modifier = focusModifier)
-                    }
+        // Arrange.
+        // grandparentLayoutNode--grandparentFocusNode
+        //       |
+        // parentLayoutNode--parentFocusNode
+        //       |
+        // layoutNode--focusNode
+        lateinit var grandparentFocusModifier: FocusModifier
+        lateinit var parentFocusModifier: FocusModifier
+        lateinit var focusModifier: FocusModifier
+        composeTestRule.setFocusableContent {
+            grandparentFocusModifier = FocusModifier()
+            parentFocusModifier = FocusModifier()
+            focusModifier = FocusModifier()
+            Box(modifier = grandparentFocusModifier) {
+                Box(modifier = parentFocusModifier) {
+                    Box(modifier = focusModifier)
                 }
             }
+        }
 
-            // Act.
-            val parent = focusModifier.focusNode.findParentFocusNode()
+        // Act.
+        val parent = runOnIdleCompose {
+            focusModifier.focusNode.findParentFocusNode()
+        }
 
-            // Assert.
+        // Assert.
+        runOnIdleCompose {
             assertThat(parent).isEqualTo(parentFocusModifier.focusNode)
         }
     }
 
     @Test
     fun ignoresIntermediateLayoutNodesThatDontHaveFocusNodes() {
-        runOnUiThread {
-            // Arrange.
-            // grandparentLayoutNode--grandparentFocusNode
-            //       |
-            // parentLayoutNode
-            //       |
-            // layoutNode--focusNode
-            val grandparentFocusModifier = createFocusModifier(Inactive)
-            val focusModifier = createFocusModifier(Inactive)
-            composeTestRule.setContent {
-                Box(modifier = grandparentFocusModifier) {
-                    Box {
-                        Box(modifier = focusModifier)
-                    }
+        // Arrange.
+        // grandparentLayoutNode--grandparentFocusNode
+        //       |
+        // parentLayoutNode
+        //       |
+        // layoutNode--focusNode
+        lateinit var grandparentFocusModifier: FocusModifier
+        lateinit var focusModifier: FocusModifier
+        composeTestRule.setFocusableContent {
+            grandparentFocusModifier = FocusModifier()
+            focusModifier = FocusModifier()
+            Box(modifier = grandparentFocusModifier) {
+                Box {
+                    Box(modifier = focusModifier)
                 }
             }
+        }
 
-            // Act.
-            val parent = focusModifier.focusNode.findParentFocusNode()
+        // Act.
+        val parent = runOnIdleCompose {
+            focusModifier.focusNode.findParentFocusNode()
+        }
 
-            // Assert.
+        // Assert.
+        runOnIdleCompose {
             assertThat(parent).isEqualTo(grandparentFocusModifier.focusNode)
         }
     }
diff --git a/ui/ui-core/src/androidTest/java/androidx/ui/core/focus/FocusTestUtils.kt b/ui/ui-core/src/androidTest/java/androidx/ui/core/focus/FocusTestUtils.kt
index f470758..db6d410 100644
--- a/ui/ui-core/src/androidTest/java/androidx/ui/core/focus/FocusTestUtils.kt
+++ b/ui/ui-core/src/androidTest/java/androidx/ui/core/focus/FocusTestUtils.kt
@@ -16,7 +16,12 @@
 
 package androidx.ui.core.focus
 
-import androidx.ui.focus.FocusModifier
+import androidx.compose.Composable
+import androidx.ui.core.Modifier
+import androidx.ui.foundation.Box
+import androidx.ui.layout.size
+import androidx.ui.test.ComposeTestRule
+import androidx.ui.unit.dp
 
 internal val FocusModifier.focusNode get() = (this as FocusModifierImpl).focusNode!!
 
@@ -24,4 +29,14 @@
     get() = (this as FocusModifierImpl).focusedChild
     set(value) {
         (this as FocusModifierImpl).focusedChild = value
-    }
\ No newline at end of file
+    }
+
+/**
+ * This function adds a parent composable which has size. [View.requestFocus()][android.view.View
+ * .requestFocus] will not take focus if the view has no size.
+ */
+internal fun ComposeTestRule.setFocusableContent(children: @Composable () -> Unit) {
+    setContent {
+        Box(modifier = Modifier.size(10.dp, 10.dp), children = children)
+    }
+}
diff --git a/ui/ui-core/src/androidTest/java/androidx/ui/core/focus/FreeFocusTest.kt b/ui/ui-core/src/androidTest/java/androidx/ui/core/focus/FreeFocusTest.kt
index 2913959..77e4e76 100644
--- a/ui/ui-core/src/androidTest/java/androidx/ui/core/focus/FreeFocusTest.kt
+++ b/ui/ui-core/src/androidTest/java/androidx/ui/core/focus/FreeFocusTest.kt
@@ -17,11 +17,11 @@
 package androidx.ui.core.focus
 
 import androidx.test.filters.SmallTest
-import androidx.ui.focus.FocusDetailedState.Active
-import androidx.ui.focus.FocusDetailedState.ActiveParent
-import androidx.ui.focus.FocusDetailedState.Captured
-import androidx.ui.focus.FocusDetailedState.Disabled
-import androidx.ui.focus.FocusDetailedState.Inactive
+import androidx.ui.core.focus.FocusDetailedState.Active
+import androidx.ui.core.focus.FocusDetailedState.ActiveParent
+import androidx.ui.core.focus.FocusDetailedState.Captured
+import androidx.ui.core.focus.FocusDetailedState.Disabled
+import androidx.ui.core.focus.FocusDetailedState.Inactive
 import androidx.ui.foundation.Box
 import androidx.ui.test.createComposeRule
 import androidx.ui.test.runOnUiThread
@@ -41,8 +41,8 @@
     fun active_freeFocus_retainFocusAsActive() {
         runOnUiThread {
             // Arrange.
-            val focusModifier = createFocusModifier(Active).also {
-                composeTestRule.setContent { Box(modifier = it) }
+            val focusModifier = FocusModifierImpl(Active).also {
+                composeTestRule.setFocusableContent { Box(modifier = it) }
             }
 
             // Act.
@@ -58,8 +58,8 @@
     fun activeParent_freeFocus_retainFocusAsActiveParent() {
         runOnUiThread {
             // Arrange.
-            val focusModifier = createFocusModifier(ActiveParent).also {
-                composeTestRule.setContent { Box(modifier = it) }
+            val focusModifier = FocusModifierImpl(ActiveParent).also {
+                composeTestRule.setFocusableContent { Box(modifier = it) }
             }
 
             // Act.
@@ -75,8 +75,8 @@
     fun captured_freeFocus_changesStateToActive() {
         runOnUiThread {
             // Arrange.
-            val focusModifier = createFocusModifier(Captured).also {
-                composeTestRule.setContent { Box(modifier = it) }
+            val focusModifier = FocusModifierImpl(Captured).also {
+                composeTestRule.setFocusableContent { Box(modifier = it) }
             }
 
             // Act.
@@ -92,8 +92,8 @@
     fun disabled_freeFocus_retainFocusAsDisabled() {
         runOnUiThread {
             // Arrange.
-            val focusModifier = createFocusModifier(Disabled).also {
-                composeTestRule.setContent { Box(modifier = it) }
+            val focusModifier = FocusModifierImpl(Disabled).also {
+                composeTestRule.setFocusableContent { Box(modifier = it) }
             }
 
             // Act.
@@ -109,8 +109,8 @@
     fun inactive_freeFocus_retainFocusAsInactive() {
         runOnUiThread {
             // Arrange.
-            val focusModifier = createFocusModifier(Inactive).also {
-                composeTestRule.setContent { Box(modifier = it) }
+            val focusModifier = FocusModifierImpl(Inactive).also {
+                composeTestRule.setFocusableContent { Box(modifier = it) }
             }
 
             // Act.
diff --git a/ui/ui-core/src/androidTest/java/androidx/ui/core/focus/RequestFocusTest.kt b/ui/ui-core/src/androidTest/java/androidx/ui/core/focus/RequestFocusTest.kt
index 8f72d8fb..19ff7db 100644
--- a/ui/ui-core/src/androidTest/java/androidx/ui/core/focus/RequestFocusTest.kt
+++ b/ui/ui-core/src/androidTest/java/androidx/ui/core/focus/RequestFocusTest.kt
@@ -17,14 +17,14 @@
 package androidx.ui.core.focus
 
 import androidx.test.filters.SmallTest
-import androidx.ui.focus.FocusDetailedState.Active
-import androidx.ui.focus.FocusDetailedState.ActiveParent
-import androidx.ui.focus.FocusDetailedState.Captured
-import androidx.ui.focus.FocusDetailedState.Disabled
-import androidx.ui.focus.FocusDetailedState.Inactive
+import androidx.ui.core.focus.FocusDetailedState.Active
+import androidx.ui.core.focus.FocusDetailedState.ActiveParent
+import androidx.ui.core.focus.FocusDetailedState.Captured
+import androidx.ui.core.focus.FocusDetailedState.Disabled
+import androidx.ui.core.focus.FocusDetailedState.Inactive
 import androidx.ui.foundation.Box
 import androidx.ui.test.createComposeRule
-import androidx.ui.test.runOnUiThread
+import androidx.ui.test.runOnIdleCompose
 
 import com.google.common.truth.Truth.assertThat
 import org.junit.Rule
@@ -46,82 +46,104 @@
 
     @Test
     fun active_isUnchanged() {
-        runOnUiThread {
-            // Arrange.
-            val focusModifier = createFocusModifier(Active).also {
-                composeTestRule.setContent { Box(modifier = it) }
-            }
+        // Arrange.
+        lateinit var focusModifier: FocusModifier
+        composeTestRule.setFocusableContent {
+            focusModifier = FocusModifierImpl(Active)
+            Box(modifier = focusModifier)
+        }
 
-            // Act.
+        // Act.
+        runOnIdleCompose {
             focusModifier.focusNode.requestFocus(propagateFocus)
+        }
 
-            // Assert.
+        // Assert.
+        runOnIdleCompose {
             assertThat(focusModifier.focusDetailedState).isEqualTo(Active)
         }
     }
 
     @Test
     fun captured_isUnchanged() {
-        runOnUiThread {
-            // Arrange.
-            val focusModifier = createFocusModifier(Captured).also {
-                composeTestRule.setContent { Box(modifier = it) }
-            }
 
-            // Act.
+        // Arrange.
+        lateinit var focusModifier: FocusModifier
+        composeTestRule.setFocusableContent {
+            focusModifier = FocusModifierImpl(Captured)
+            Box(modifier = focusModifier)
+        }
+
+        // Act.
+        runOnIdleCompose {
             focusModifier.focusNode.requestFocus(propagateFocus)
+        }
 
-            // Assert.
+        // Assert.
+        runOnIdleCompose {
             assertThat(focusModifier.focusDetailedState).isEqualTo(Captured)
         }
     }
 
     @Test
     fun disabled_isUnchanged() {
-        runOnUiThread {
-            // Arrange.
-            val focusModifier = createFocusModifier(Disabled).also {
-                composeTestRule.setContent { Box(modifier = it) }
-            }
+        // Arrange.
+        lateinit var focusModifier: FocusModifier
+        composeTestRule.setFocusableContent {
+            focusModifier = FocusModifierImpl(Disabled)
+            Box(modifier = focusModifier)
+        }
 
-            // Act.
+        // Act.
+        runOnIdleCompose {
             focusModifier.focusNode.requestFocus(propagateFocus)
+        }
 
-            // Assert.
+        // Assert.
+        runOnIdleCompose {
             assertThat(focusModifier.focusDetailedState).isEqualTo(Disabled)
         }
     }
 
     @Test(expected = IllegalArgumentException::class)
     fun activeParent_withNoFocusedChild_throwsException() {
-        runOnUiThread {
-            // Arrange.
-            val focusModifier = createFocusModifier(ActiveParent).also {
-                composeTestRule.setContent { Box(modifier = it) }
-            }
+        // Arrange.
+        lateinit var focusModifier: FocusModifier
+        composeTestRule.setFocusableContent {
+            focusModifier = FocusModifierImpl(ActiveParent)
+            Box(modifier = focusModifier)
+        }
 
-            // Act.
+        // Act.
+        runOnIdleCompose {
             focusModifier.focusNode.requestFocus(propagateFocus)
         }
     }
 
     @Test
     fun activeParent_propagateFocus() {
-        runOnUiThread {
-            // Arrange.
-            val focusModifier = createFocusModifier(ActiveParent)
-            val childFocusModifier = createFocusModifier(Active)
-            composeTestRule.setContent {
-                Box(modifier = focusModifier) {
-                    Box(modifier = childFocusModifier)
-                }
+        // Arrange.
+        lateinit var focusModifier: FocusModifier
+        lateinit var childFocusModifier: FocusModifier
+
+        composeTestRule.setFocusableContent {
+            focusModifier = FocusModifierImpl(ActiveParent)
+            childFocusModifier = FocusModifierImpl(Active)
+            Box(modifier = focusModifier) {
+                Box(modifier = childFocusModifier)
             }
+        }
+        runOnIdleCompose {
             focusModifier.focusedChild = childFocusModifier.focusNode
+        }
 
-            // Act.
+        // Act.
+        runOnIdleCompose {
             focusModifier.focusNode.requestFocus(propagateFocus)
+        }
 
-            // Assert.
+        // Assert.
+        runOnIdleCompose {
             when (propagateFocus) {
                 true -> {
                     // Unchanged.
@@ -139,36 +161,44 @@
 
     @Test
     fun inactiveRoot_propagateFocusSendsRequestToOwner_systemCanGrantFocus() {
-        runOnUiThread {
-            // Arrange.
-            val rootFocusModifier = createFocusModifier(Inactive).also {
-                composeTestRule.setContent { Box(modifier = it) }
-            }
+        // Arrange.
+        lateinit var rootFocusModifier: FocusModifier
+        composeTestRule.setFocusableContent {
+            rootFocusModifier = FocusModifierImpl(Inactive)
+            Box(modifier = rootFocusModifier)
+        }
 
-            // Act.
+        // Act.
+        runOnIdleCompose {
             rootFocusModifier.focusNode.requestFocus(propagateFocus)
+        }
 
-            // Assert.
+        // Assert.
+        runOnIdleCompose {
             assertThat(rootFocusModifier.focusDetailedState).isEqualTo(Active)
         }
     }
 
     @Test
     fun inactiveRootWithChildren_propagateFocusSendsRequestToOwner_systemCanGrantFocus() {
-        runOnUiThread {
-            // Arrange.
-            val rootFocusModifier = createFocusModifier(Inactive)
-            val childFocusModifier = createFocusModifier(Inactive)
-            composeTestRule.setContent {
-                Box(modifier = rootFocusModifier) {
-                    Box(modifier = childFocusModifier)
-                }
+        // Arrange.
+        lateinit var rootFocusModifier: FocusModifier
+        lateinit var childFocusModifier: FocusModifier
+        composeTestRule.setFocusableContent {
+            rootFocusModifier = FocusModifierImpl(Inactive)
+            childFocusModifier = FocusModifierImpl(Inactive)
+            Box(modifier = rootFocusModifier) {
+                Box(modifier = childFocusModifier)
             }
+        }
 
-            // Act.
+        // Act.
+        runOnIdleCompose {
             rootFocusModifier.focusNode.requestFocus(propagateFocus)
+        }
 
-            // Assert.
+        // Assert.
+        runOnIdleCompose {
             when (propagateFocus) {
                 true -> {
                     // Unchanged.
@@ -185,23 +215,28 @@
 
     @Test
     fun inactiveNonRootWithChilcren() {
-        runOnUiThread {
-            // Arrange.
-            val parentFocusModifier = createFocusModifier(Active)
-            val focusModifier = createFocusModifier(Inactive)
-            val childFocusModifier = createFocusModifier(Inactive)
-            composeTestRule.setContent {
-                Box(modifier = parentFocusModifier) {
-                    Box(modifier = focusModifier) {
-                        Box(modifier = childFocusModifier)
-                    }
+        // Arrange.
+        lateinit var parentFocusModifier: FocusModifier
+        lateinit var focusModifier: FocusModifier
+        lateinit var childFocusModifier: FocusModifier
+        composeTestRule.setFocusableContent {
+            parentFocusModifier = FocusModifierImpl(Active)
+            focusModifier = FocusModifierImpl(Inactive)
+            childFocusModifier = FocusModifierImpl(Inactive)
+            Box(modifier = parentFocusModifier) {
+                Box(modifier = focusModifier) {
+                    Box(modifier = childFocusModifier)
                 }
             }
+        }
 
-            // Act.
+        // Act.
+        runOnIdleCompose {
             focusModifier.focusNode.requestFocus(propagateFocus)
+        }
 
-            // Assert.
+        // Assert.
+        runOnIdleCompose {
             when (propagateFocus) {
                 true -> {
                     assertThat(parentFocusModifier.focusDetailedState).isEqualTo(ActiveParent)
@@ -219,36 +254,44 @@
 
     @Test
     fun rootNode() {
-        runOnUiThread {
-            // Arrange.
-            val rootFocusModifier = createFocusModifier(Inactive).also {
-                composeTestRule.setContent { Box(modifier = it) }
-            }
+        // Arrange.
+        lateinit var rootFocusModifier: FocusModifier
+        composeTestRule.setFocusableContent {
+            rootFocusModifier = FocusModifierImpl(Inactive)
+            Box(modifier = rootFocusModifier)
+        }
 
-            // Act.
+        // Act.
+        runOnIdleCompose {
             rootFocusModifier.focusNode.requestFocus(propagateFocus)
+        }
 
-            // Assert.
+        // Assert.
+        runOnIdleCompose {
             assertThat(rootFocusModifier.focusDetailedState).isEqualTo(Active)
         }
     }
 
     @Test
     fun rootNodeWithChildren() {
-        runOnUiThread {
-            // Arrange.
-            val rootFocusModifier = createFocusModifier(Inactive)
-            val childFocusModifier = createFocusModifier(Inactive)
-            composeTestRule.setContent {
-                Box(modifier = rootFocusModifier) {
-                    Box(modifier = childFocusModifier)
-                }
+        // Arrange.
+        lateinit var rootFocusModifier: FocusModifier
+        lateinit var childFocusModifier: FocusModifier
+        composeTestRule.setFocusableContent {
+            rootFocusModifier = FocusModifierImpl(Inactive)
+            childFocusModifier = FocusModifierImpl(Inactive)
+            Box(modifier = rootFocusModifier) {
+                Box(modifier = childFocusModifier)
             }
+        }
 
-            // Act.
+        // Act.
+        runOnIdleCompose {
             rootFocusModifier.focusNode.requestFocus(propagateFocus)
+        }
 
-            // Assert.
+        // Assert.
+        runOnIdleCompose {
             when (propagateFocus) {
                 true -> assertThat(rootFocusModifier.focusDetailedState).isEqualTo(ActiveParent)
                 false -> assertThat(rootFocusModifier.focusDetailedState).isEqualTo(Active)
@@ -258,23 +301,28 @@
 
     @Test
     fun parentNodeWithNoFocusedAncestor() {
-        runOnUiThread {
-            // Arrange.
-            val grandParentFocusModifier = createFocusModifier(Inactive)
-            val parentFocusModifier = createFocusModifier(Inactive)
-            val childFocusModifier = createFocusModifier(Inactive)
-            composeTestRule.setContent {
-                Box(modifier = grandParentFocusModifier) {
-                    Box(modifier = parentFocusModifier) {
-                        Box(modifier = childFocusModifier)
-                    }
+        // Arrange.
+        lateinit var grandParentFocusModifier: FocusModifier
+        lateinit var parentFocusModifier: FocusModifier
+        lateinit var childFocusModifier: FocusModifier
+        composeTestRule.setFocusableContent {
+            grandParentFocusModifier = FocusModifierImpl(Inactive)
+            parentFocusModifier = FocusModifierImpl(Inactive)
+            childFocusModifier = FocusModifierImpl(Inactive)
+            Box(modifier = grandParentFocusModifier) {
+                Box(modifier = parentFocusModifier) {
+                    Box(modifier = childFocusModifier)
                 }
             }
+        }
 
-            // Act.
+        // Act.
+        runOnIdleCompose {
             parentFocusModifier.focusNode.requestFocus(propagateFocus)
+        }
 
-            // Assert.
+        // Assert.
+        runOnIdleCompose {
             when (propagateFocus) {
                 true -> assertThat(parentFocusModifier.focusDetailedState).isEqualTo(ActiveParent)
                 false -> assertThat(parentFocusModifier.focusDetailedState).isEqualTo(Active)
@@ -284,66 +332,79 @@
 
     @Test
     fun parentNodeWithNoFocusedAncestor_childRequestsFocus() {
-        runOnUiThread {
-            // Arrange.
-            val grandParentFocusModifier = createFocusModifier(Inactive)
-            val parentFocusModifier = createFocusModifier(Inactive)
-            val childFocusModifier = createFocusModifier(Inactive)
-            composeTestRule.setContent {
-                Box(modifier = grandParentFocusModifier) {
-                    Box(modifier = parentFocusModifier) {
-                        Box(modifier = childFocusModifier)
-                    }
+        // Arrange.
+        lateinit var grandParentFocusModifier: FocusModifier
+        lateinit var parentFocusModifier: FocusModifier
+        lateinit var childFocusModifier: FocusModifier
+        composeTestRule.setFocusableContent {
+            grandParentFocusModifier = FocusModifierImpl(Inactive)
+            parentFocusModifier = FocusModifierImpl(Inactive)
+            childFocusModifier = FocusModifierImpl(Inactive)
+            Box(modifier = grandParentFocusModifier) {
+                Box(modifier = parentFocusModifier) {
+                    Box(modifier = childFocusModifier)
                 }
             }
+        }
 
-            // Act.
+        // Act.
+        runOnIdleCompose {
             childFocusModifier.focusNode.requestFocus(propagateFocus)
-
-            // Assert.
+        }
+        // Assert.
+        runOnIdleCompose {
             assertThat(parentFocusModifier.focusDetailedState).isEqualTo(ActiveParent)
         }
     }
 
     @Test
     fun childNodeWithNoFocusedAncestor() {
-        runOnUiThread {
-            // Arrange.
-            val grandParentFocusModifier = createFocusModifier(Inactive)
-            val parentFocusModifier = createFocusModifier(Inactive)
-            val childFocusModifier = createFocusModifier(Inactive)
-            composeTestRule.setContent {
-                Box(modifier = grandParentFocusModifier) {
-                    Box(modifier = parentFocusModifier) {
-                        Box(modifier = childFocusModifier)
-                    }
+        // Arrange.
+        lateinit var grandParentFocusModifier: FocusModifier
+        lateinit var parentFocusModifier: FocusModifier
+        lateinit var childFocusModifier: FocusModifier
+        composeTestRule.setFocusableContent {
+            grandParentFocusModifier = FocusModifierImpl(Inactive)
+            parentFocusModifier = FocusModifierImpl(Inactive)
+            childFocusModifier = FocusModifierImpl(Inactive)
+            Box(modifier = grandParentFocusModifier) {
+                Box(modifier = parentFocusModifier) {
+                    Box(modifier = childFocusModifier)
                 }
             }
+        }
 
-            // Act.
+        // Act.
+        runOnIdleCompose {
             childFocusModifier.focusNode.requestFocus(propagateFocus)
+        }
 
-            // Assert.
+        // Assert.
+        runOnIdleCompose {
             assertThat(childFocusModifier.focusDetailedState).isEqualTo(Active)
         }
     }
 
     @Test
     fun requestFocus_parentIsFocused() {
-        runOnUiThread {
-            // Arrange.
-            val parentFocusModifier = createFocusModifier(Active)
-            val focusModifier = createFocusModifier(Inactive)
-            composeTestRule.setContent {
-                Box(modifier = parentFocusModifier) {
-                    Box(modifier = focusModifier)
-                }
+        // Arrange.
+        lateinit var parentFocusModifier: FocusModifier
+        lateinit var focusModifier: FocusModifier
+        composeTestRule.setFocusableContent {
+            parentFocusModifier = FocusModifierImpl(Active)
+            focusModifier = FocusModifierImpl(Inactive)
+            Box(modifier = parentFocusModifier) {
+                Box(modifier = focusModifier)
             }
+        }
 
-            // After executing requestFocus, siblingNode will be 'Active'.
+        // After executing requestFocus, siblingNode will be 'Active'.
+        runOnIdleCompose {
             focusModifier.focusNode.requestFocus(propagateFocus)
+        }
 
-            // Assert.
+        // Assert.
+        runOnIdleCompose {
             assertThat(parentFocusModifier.focusDetailedState).isEqualTo(ActiveParent)
             assertThat(focusModifier.focusDetailedState).isEqualTo(Active)
         }
@@ -351,21 +412,27 @@
 
     @Test
     fun requestFocus_childIsFocused() {
-        runOnUiThread {
-            // Arrange.
-            val parentFocusModifier = createFocusModifier(ActiveParent)
-            val focusModifier = createFocusModifier(Active)
-            composeTestRule.setContent {
-                Box(modifier = parentFocusModifier) {
-                    Box(modifier = focusModifier)
-                }
+        // Arrange.
+        lateinit var parentFocusModifier: FocusModifier
+        lateinit var focusModifier: FocusModifier
+        composeTestRule.setFocusableContent {
+            parentFocusModifier = FocusModifierImpl(ActiveParent)
+            focusModifier = FocusModifierImpl(Active)
+            Box(modifier = parentFocusModifier) {
+                Box(modifier = focusModifier)
             }
+        }
+        runOnIdleCompose {
             parentFocusModifier.focusedChild = focusModifier.focusNode
+        }
 
-            // Act.
+        // Act.
+        runOnIdleCompose {
             parentFocusModifier.focusNode.requestFocus(propagateFocus)
+        }
 
-            // Assert.
+        // Assert.
+        runOnIdleCompose {
             when (propagateFocus) {
                 true -> {
                     assertThat(parentFocusModifier.focusDetailedState).isEqualTo(ActiveParent)
@@ -381,21 +448,27 @@
 
     @Test
     fun requestFocus_childHasCapturedFocus() {
-        runOnUiThread {
-            // Arrange.
-            val parentFocusModifier = createFocusModifier(ActiveParent)
-            val focusModifier = createFocusModifier(Captured)
-            composeTestRule.setContent {
-                Box(modifier = parentFocusModifier) {
-                    Box(modifier = focusModifier)
-                }
+        // Arrange.
+        lateinit var parentFocusModifier: FocusModifier
+        lateinit var focusModifier: FocusModifier
+        composeTestRule.setFocusableContent {
+            parentFocusModifier = FocusModifierImpl(ActiveParent)
+            focusModifier = FocusModifierImpl(Captured)
+            Box(modifier = parentFocusModifier) {
+                Box(modifier = focusModifier)
             }
+        }
+        runOnIdleCompose {
             parentFocusModifier.focusedChild = focusModifier.focusNode
+        }
 
-            // Act.
+        // Act.
+        runOnIdleCompose {
             parentFocusModifier.focusNode.requestFocus(propagateFocus)
+        }
 
-            // Assert.
+        // Assert.
+        runOnIdleCompose {
             assertThat(parentFocusModifier.focusDetailedState).isEqualTo(ActiveParent)
             assertThat(focusModifier.focusDetailedState).isEqualTo(Captured)
         }
@@ -403,23 +476,30 @@
 
     @Test
     fun requestFocus_siblingIsFocused() {
-        runOnUiThread {
-            // Arrange.
-            val parentFocusModifier = createFocusModifier(ActiveParent)
-            val focusModifier = createFocusModifier(Inactive)
-            val siblingModifier = createFocusModifier(Active)
-            composeTestRule.setContent {
-                Box(modifier = parentFocusModifier) {
-                    Box(modifier = focusModifier)
-                    Box(modifier = siblingModifier)
-                }
+        // Arrange.
+        lateinit var parentFocusModifier: FocusModifier
+        lateinit var focusModifier: FocusModifier
+        lateinit var siblingModifier: FocusModifier
+        composeTestRule.setFocusableContent {
+            parentFocusModifier = FocusModifierImpl(ActiveParent)
+            focusModifier = FocusModifierImpl(Inactive)
+            siblingModifier = FocusModifierImpl(Active)
+            Box(modifier = parentFocusModifier) {
+                Box(modifier = focusModifier)
+                Box(modifier = siblingModifier)
             }
+        }
+        runOnIdleCompose {
             parentFocusModifier.focusedChild = siblingModifier.focusNode
+        }
 
-            // Act.
+        // Act.
+        runOnIdleCompose {
             focusModifier.focusNode.requestFocus(propagateFocus)
+        }
 
-            // Assert.
+        // Assert.
+        runOnIdleCompose {
             assertThat(parentFocusModifier.focusDetailedState).isEqualTo(ActiveParent)
             assertThat(focusModifier.focusDetailedState).isEqualTo(Active)
             assertThat(siblingModifier.focusDetailedState).isEqualTo(Inactive)
@@ -428,23 +508,30 @@
 
     @Test
     fun requestFocus_siblingHasCapturedFocused() {
-        runOnUiThread {
-            // Arrange.
-            val parentFocusModifier = createFocusModifier(ActiveParent)
-            val focusModifier = createFocusModifier(Inactive)
-            val siblingModifier = createFocusModifier(Captured)
-            composeTestRule.setContent {
-                Box(modifier = parentFocusModifier) {
-                    Box(modifier = focusModifier)
-                    Box(modifier = siblingModifier)
-                }
+        // Arrange.
+        lateinit var parentFocusModifier: FocusModifier
+        lateinit var focusModifier: FocusModifier
+        lateinit var siblingModifier: FocusModifier
+        composeTestRule.setFocusableContent {
+            parentFocusModifier = FocusModifierImpl(ActiveParent)
+            focusModifier = FocusModifierImpl(Inactive)
+            siblingModifier = FocusModifierImpl(Captured)
+            Box(modifier = parentFocusModifier) {
+                Box(modifier = focusModifier)
+                Box(modifier = siblingModifier)
             }
+        }
+        runOnIdleCompose {
             parentFocusModifier.focusedChild = siblingModifier.focusNode
+        }
 
-            // Act.
+        // Act.
+        runOnIdleCompose {
             focusModifier.focusNode.requestFocus(propagateFocus)
+        }
 
-            // Assert.
+        // Assert.
+        runOnIdleCompose {
             assertThat(parentFocusModifier.focusDetailedState).isEqualTo(ActiveParent)
             assertThat(focusModifier.focusDetailedState).isEqualTo(Inactive)
             assertThat(siblingModifier.focusDetailedState).isEqualTo(Captured)
@@ -453,34 +540,45 @@
 
     @Test
     fun requestFocus_cousinIsFocused() {
-        runOnUiThread {
-            // Arrange.
-            val grandParentModifier = createFocusModifier(ActiveParent)
-            val parentModifier = createFocusModifier(Inactive)
-            val focusModifier = createFocusModifier(Inactive)
-            val auntModifier = createFocusModifier(ActiveParent)
-            val cousinModifier = createFocusModifier(Active)
-            composeTestRule.setContent {
-                Box(modifier = grandParentModifier) {
-                    Box(modifier = parentModifier) {
-                        Box(modifier = focusModifier)
-                    }
-                    Box(modifier = auntModifier) {
-                        Box(modifier = cousinModifier)
-                    }
+        // Arrange.
+        lateinit var grandParentModifier: FocusModifier
+        lateinit var parentModifier: FocusModifier
+        lateinit var focusModifier: FocusModifier
+        lateinit var auntModifier: FocusModifier
+        lateinit var cousinModifier: FocusModifier
+        composeTestRule.setFocusableContent {
+            grandParentModifier = FocusModifierImpl(ActiveParent)
+            parentModifier = FocusModifierImpl(Inactive)
+            focusModifier = FocusModifierImpl(Inactive)
+            auntModifier = FocusModifierImpl(ActiveParent)
+            cousinModifier = FocusModifierImpl(Active)
+            Box(modifier = grandParentModifier) {
+                Box(modifier = parentModifier) {
+                    Box(modifier = focusModifier)
+                }
+                Box(modifier = auntModifier) {
+                    Box(modifier = cousinModifier)
                 }
             }
+        }
+        runOnIdleCompose {
             grandParentModifier.focusedChild = auntModifier.focusNode
             auntModifier.focusedChild = cousinModifier.focusNode
+        }
 
-            // Verify Setup.
+        // Verify Setup.
+        runOnIdleCompose {
             assertThat(cousinModifier.focusDetailedState).isEqualTo(Active)
             assertThat(focusModifier.focusDetailedState).isEqualTo(Inactive)
+        }
 
-            // Act.
+        // Act.
+        runOnIdleCompose {
             focusModifier.focusNode.requestFocus(propagateFocus)
+        }
 
-            // Assert.
+        // Assert.
+        runOnIdleCompose {
             assertThat(cousinModifier.focusDetailedState).isEqualTo(Inactive)
             assertThat(focusModifier.focusDetailedState).isEqualTo(Active)
         }
@@ -488,23 +586,28 @@
 
     @Test
     fun requestFocus_grandParentIsFocused() {
-        runOnUiThread {
-            // Arrange.
-            val grandParentModifier = createFocusModifier(Active)
-            val parentModifier = createFocusModifier(Inactive)
-            val focusModifier = createFocusModifier(Inactive)
-            composeTestRule.setContent {
-                Box(modifier = grandParentModifier) {
-                    Box(modifier = parentModifier) {
-                        Box(modifier = focusModifier)
-                    }
+        // Arrange.
+        lateinit var grandParentModifier: FocusModifier
+        lateinit var parentModifier: FocusModifier
+        lateinit var focusModifier: FocusModifier
+        composeTestRule.setFocusableContent {
+            grandParentModifier = FocusModifierImpl(Active)
+            parentModifier = FocusModifierImpl(Inactive)
+            focusModifier = FocusModifierImpl(Inactive)
+            Box(modifier = grandParentModifier) {
+                Box(modifier = parentModifier) {
+                    Box(modifier = focusModifier)
                 }
             }
+        }
 
-            // Act.
+        // Act.
+        runOnIdleCompose {
             focusModifier.focusNode.requestFocus(propagateFocus)
+        }
 
-            // Assert.
+        // Assert.
+        runOnIdleCompose {
             assertThat(grandParentModifier.focusDetailedState).isEqualTo(ActiveParent)
             assertThat(parentModifier.focusDetailedState).isEqualTo(ActiveParent)
             assertThat(focusModifier.focusDetailedState).isEqualTo(Active)
diff --git a/ui/ui-core/src/androidTest/java/androidx/ui/core/test/AndroidLayoutDrawTest.kt b/ui/ui-core/src/androidTest/java/androidx/ui/core/test/AndroidLayoutDrawTest.kt
index 7b1e8ab..114bcfa 100644
--- a/ui/ui-core/src/androidTest/java/androidx/ui/core/test/AndroidLayoutDrawTest.kt
+++ b/ui/ui-core/src/androidTest/java/androidx/ui/core/test/AndroidLayoutDrawTest.kt
@@ -52,7 +52,6 @@
 import androidx.ui.core.MeasureScope
 import androidx.ui.core.Modifier
 import androidx.ui.core.Owner
-import androidx.ui.core.ParentData
 import androidx.ui.core.ParentDataModifier
 import androidx.ui.core.PassThroughLayout
 import androidx.ui.core.Ref
@@ -2338,30 +2337,10 @@
                     PassThroughLayout {
                         FixedSize(50.ipx, LayoutTag("1"))
                     }
-                    PassThroughLayout {
-                        ParentData(LayoutTag("2")) {
-                            FixedSize(50.ipx, LayoutTag("1"))
-                        }
-                    }
-                    ParentData(LayoutTag("3")) {
-                        PassThroughLayout {
-                            ParentData(LayoutTag("2")) {
-                                FixedSize(50.ipx, LayoutTag("1"))
-                            }
-                        }
-                    }
-                    PassThroughLayout(LayoutTag("4")) {
-                        ParentData(LayoutTag("2")) {
-                            FixedSize(50.ipx, LayoutTag("1"))
-                        }
-                    }
                 }) { measurables, constraints, _ ->
                     assertEquals("1", measurables[0].tag)
                     val placeable = measurables[0].measure(constraints)
                     assertEquals(50.ipx, placeable.width)
-                    assertEquals("2", measurables[1].tag)
-                    assertEquals("3", measurables[2].tag)
-                    assertEquals("4", measurables[3].tag)
                     latch.countDown()
                     layout(0.ipx, 0.ipx) {}
                 }
diff --git a/ui/ui-core/src/main/java/androidx/ui/core/AndroidOwner.kt b/ui/ui-core/src/main/java/androidx/ui/core/AndroidOwner.kt
index c82e74b..9a63d23 100644
--- a/ui/ui-core/src/main/java/androidx/ui/core/AndroidOwner.kt
+++ b/ui/ui-core/src/main/java/androidx/ui/core/AndroidOwner.kt
@@ -63,8 +63,8 @@
 import androidx.ui.core.text.AndroidFontResourceLoader
 import androidx.ui.core.texttoolbar.AndroidTextToolbar
 import androidx.ui.core.texttoolbar.TextToolbar
-import androidx.ui.focus.FocusDetailedState.Active
-import androidx.ui.focus.FocusDetailedState.Inactive
+import androidx.ui.core.focus.FocusDetailedState.Active
+import androidx.ui.core.focus.FocusDetailedState.Inactive
 import androidx.ui.geometry.Size
 import androidx.ui.graphics.Canvas
 import androidx.ui.graphics.painter.drawCanvas
@@ -133,6 +133,7 @@
             }
         }
     }
+
     override val semanticsOwner: SemanticsOwner = SemanticsOwner(root)
     private var semanticsNodes: MutableMap<Int, SemanticsNodeCopy> = mutableMapOf()
     private var semanticsRoot = SemanticsNodeCopy(semanticsOwner.rootSemanticsNode)
@@ -687,7 +688,8 @@
     override fun dispatchDraw(canvas: android.graphics.Canvas) {
         // TODO(b/154633012): move this to a proper place
         if ((context.getSystemService(Context.ACCESSIBILITY_SERVICE)
-                    as AccessibilityManager).isEnabled) {
+                    as AccessibilityManager).isEnabled
+        ) {
             checkForSemanticsChanges()
         }
 
diff --git a/ui/ui-core/src/main/java/androidx/ui/core/ComponentNodes.kt b/ui/ui-core/src/main/java/androidx/ui/core/ComponentNodes.kt
index 75fd646..32f1d67 100644
--- a/ui/ui-core/src/main/java/androidx/ui/core/ComponentNodes.kt
+++ b/ui/ui-core/src/main/java/androidx/ui/core/ComponentNodes.kt
@@ -21,7 +21,7 @@
 import androidx.ui.core.pointerinput.PointerInputModifier
 import androidx.ui.core.semantics.SemanticsModifier
 import androidx.ui.core.semantics.SemanticsWrapper
-import androidx.ui.focus.FocusModifier
+import androidx.ui.core.focus.FocusModifier
 import androidx.ui.graphics.Canvas
 import androidx.ui.unit.Density
 import androidx.ui.unit.IntPx
@@ -336,7 +336,7 @@
  * TODO(b/154633015): Deprecated in Dev11. Delete for Dev12.
  */
 @Deprecated(
-    message = "FocusNode is deprecated. Use androidx.ui.focus.FocusModifier instead.",
+    message = "FocusNode is deprecated. Use androidx.ui.core.focus.FocusModifier instead.",
     level = DeprecationLevel.ERROR
 )
 class FocusNode : ComponentNode()
@@ -658,37 +658,9 @@
             return _layoutChildren
         }
 
-    /**
-     * `true` when parentDataNode has to be rediscovered. This is when the
-     * LayoutNode has been attached.
-     */
-    private var parentDataDirty = false
-
     override val parentData: Any?
         get() = layoutNodeWrapper.parentData
 
-    /**
-     * The parentData [DataNode] for this LayoutNode.
-     */
-    internal var parentDataNode: DataNode<*>? = null
-        get() {
-            if (parentDataDirty) {
-                // walk up to find ParentData
-                field = null
-                var node = parent
-                val parentLayoutNode = parentLayoutNode
-                while (node != null && node !== parentLayoutNode) {
-                    if (node is DataNode<*> && node.key === ParentDataKey) {
-                        field = node
-                        break
-                    }
-                    node = node.parent
-                }
-                parentDataDirty = false
-            }
-            return field
-        }
-
     internal val innerLayoutNodeWrapper: LayoutNodeWrapper = InnerPlaceable(this)
     internal var layoutNodeWrapper = innerLayoutNodeWrapper
 
@@ -708,6 +680,19 @@
     private var outerZIndexModifier: ZIndexModifier? = null
 
     /**
+     * The inner-most layer wrapper. Used for performance for LayoutNodeWrapper.findLayer().
+     */
+    internal var innerLayerWrapper: LayerWrapper? = null
+
+    /**
+     * Returns the inner-most layer as part of this LayoutNode or from the containing LayoutNode.
+     * This is added for performance so that LayoutNodeWrapper.findLayer() can be faster.
+     */
+    internal fun findLayer(): OwnedLayer? {
+        return innerLayerWrapper?.layer ?: parentLayoutNode?.findLayer()
+    }
+
+    /**
      * The [Modifier] currently applied to this node.
      */
     var modifier: Modifier = Modifier
@@ -721,6 +706,7 @@
             onPositionedCallbacks.clear()
             onChildPositionedCallbacks.clear()
             outerZIndexModifier = null
+            innerLayerWrapper = null
             layoutNodeWrapper = modifier.foldOut(innerLayoutNodeWrapper) { mod, toWrap ->
                 var wrapper = toWrap
                 // The order in which the following blocks occur matters.  For example, the
@@ -737,7 +723,11 @@
                     wrapper = ModifiedDrawNode(wrapper, mod)
                 }
                 if (mod is DrawLayerModifier) {
-                    wrapper = LayerWrapper(wrapper, mod)
+                    val layerWrapper = LayerWrapper(wrapper, mod)
+                    wrapper = layerWrapper
+                    if (innerLayerWrapper == null) {
+                        innerLayerWrapper = layerWrapper
+                    }
                 }
                 if (mod is FocusModifier) {
                     require(mod is FocusModifierImpl)
@@ -792,7 +782,6 @@
     override fun attach(owner: Owner) {
         super.attach(owner)
         requestRemeasure()
-        parentDataDirty = true
         parentLayoutNode?.layoutChildrenDirty = true
         layoutNodeWrapper.attach()
         onAttach?.invoke(owner)
@@ -811,7 +800,6 @@
             parentLayoutNode.layoutChildrenDirty = true
             parentLayoutNode.requestRemeasure()
         }
-        parentDataDirty = true
         alignmentLinesQueryOwner = null
         onDetach?.invoke(owner)
         layoutNodeWrapper.detach()
@@ -1185,7 +1173,6 @@
  * for all ancestors.
  */
 fun ComponentNode.findClosestParentNode(selector: (ComponentNode) -> Boolean): ComponentNode? {
-    // TODO(b/143866294): move this to the testing side after the hierarchy isn't flattened anymore
     var currentParent = parent
     while (currentParent != null) {
         if (selector(currentParent)) {
diff --git a/ui/ui-core/src/main/java/androidx/ui/core/InnerPlaceable.kt b/ui/ui-core/src/main/java/androidx/ui/core/InnerPlaceable.kt
index 5da930c..0e6d8ca 100644
--- a/ui/ui-core/src/main/java/androidx/ui/core/InnerPlaceable.kt
+++ b/ui/ui-core/src/main/java/androidx/ui/core/InnerPlaceable.kt
@@ -28,6 +28,7 @@
 import androidx.ui.unit.PxPosition
 import androidx.ui.unit.toPxSize
 import androidx.ui.util.fastAny
+import androidx.ui.util.fastFirstOrNull
 import androidx.ui.util.fastForEach
 
 internal class InnerPlaceable(
@@ -59,11 +60,10 @@
     override val parentData: Any?
         @Suppress("DEPRECATION")
         get() = if (layoutNode.handlesParentData) {
-            layoutNode.parentDataNode?.value
+            null
         } else {
-            layoutNode.parentDataNode?.value
-                ?: layoutNode.layoutChildren
-                    .firstOrNull { it.layoutNodeWrapper.parentData != null }?.parentData
+            layoutNode.layoutChildren
+                    .fastFirstOrNull { it.parentData != null }?.parentData
         }
 
     override fun findFocusWrapperWrappingThisWrapper() =
@@ -187,4 +187,4 @@
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/ui/ui-core/src/main/java/androidx/ui/core/Layout.kt b/ui/ui-core/src/main/java/androidx/ui/core/Layout.kt
index 16b05d0..47c2b40 100644
--- a/ui/ui-core/src/main/java/androidx/ui/core/Layout.kt
+++ b/ui/ui-core/src/main/java/androidx/ui/core/Layout.kt
@@ -36,6 +36,7 @@
 import androidx.ui.unit.ipx
 import androidx.ui.unit.max
 import androidx.ui.unit.min
+import androidx.ui.util.fastForEach
 
 /**
  * [Layout] is the main core component for layout. It can be used to measure and position
@@ -199,7 +200,7 @@
             val width = placeables.maxBy { it.width }?.width ?: constraints.minWidth
             val height = placeables.maxBy { it.height }?.height ?: constraints.minHeight
             layout(width, height) {
-                placeables.forEach { it.place(IntPx.Zero, IntPx.Zero) }
+                placeables.fastForEach { it.place(IntPx.Zero, IntPx.Zero) }
             }
         }
         MeasuringIntrinsicsMeasureBlocks(measureBlock)
@@ -207,8 +208,7 @@
     LayoutNode(
         modifier = currentComposer.materialize(modifier),
         measureBlocks = measureBlocks,
-        handlesParentData =
-        false
+        handlesParentData = false
     ) {
         children()
     }
@@ -569,7 +569,7 @@
             val layoutChildren = root.layoutChildren
             var maxWidth: IntPx = constraints.minWidth
             var maxHeight: IntPx = constraints.minHeight
-            layoutChildren.forEach {
+            layoutChildren.fastForEach {
                 it.measure(constraints, layoutDirection)
                 maxWidth = max(maxWidth, it.width)
                 maxHeight = max(maxHeight, it.height)
@@ -578,7 +578,7 @@
             maxHeight = min(maxHeight, constraints.maxHeight)
 
             return measureScope.layout(maxWidth, maxHeight) {
-                layoutChildren.forEach { it.place(IntPx.Zero, IntPx.Zero) }
+                layoutChildren.fastForEach { it.place(IntPx.Zero, IntPx.Zero) }
             }
         }
     }
diff --git a/ui/ui-core/src/main/java/androidx/ui/core/LayoutNodeWrapper.kt b/ui/ui-core/src/main/java/androidx/ui/core/LayoutNodeWrapper.kt
index bc2fe55..b660d948 100644
--- a/ui/ui-core/src/main/java/androidx/ui/core/LayoutNodeWrapper.kt
+++ b/ui/ui-core/src/main/java/androidx/ui/core/LayoutNodeWrapper.kt
@@ -290,7 +290,13 @@
     /**
      * Returns the layer that this wrapper will draw into.
      */
-    open fun findLayer(): OwnedLayer? = wrappedBy?.findLayer()
+    open fun findLayer(): OwnedLayer? {
+        return if (layoutNode.innerLayerWrapper != null) {
+            wrappedBy?.findLayer()
+        } else {
+            layoutNode.findLayer()
+        }
+    }
 
     /**
      * Returns the first [ModifiedFocusNode] in the wrapper list that wraps this
diff --git a/ui/ui-core/src/main/java/androidx/ui/core/ModifiedParentDataNode.kt b/ui/ui-core/src/main/java/androidx/ui/core/ModifiedParentDataNode.kt
index 5d3f681..44e2e86 100644
--- a/ui/ui-core/src/main/java/androidx/ui/core/ModifiedParentDataNode.kt
+++ b/ui/ui-core/src/main/java/androidx/ui/core/ModifiedParentDataNode.kt
@@ -26,7 +26,6 @@
              * ParentData provided through the parentData node will override the data provided
              * through a modifier
              */
-            layoutNode.parentDataNode?.value
-                ?: layoutNode.measureScope.modifyParentData(wrapped.parentData)
+            layoutNode.measureScope.modifyParentData(wrapped.parentData)
         }
 }
\ No newline at end of file
diff --git a/ui/ui-core/src/main/java/androidx/ui/core/ParentData.kt b/ui/ui-core/src/main/java/androidx/ui/core/ParentData.kt
deleted file mode 100644
index 1767efb..0000000
--- a/ui/ui-core/src/main/java/androidx/ui/core/ParentData.kt
+++ /dev/null
@@ -1,42 +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.compose.Composable
-
-/**
- * Provide data for the parent of a [Layout], which can then be read from the
- * corresponding [Measurable].
- *
- * A containing [Layout] sometimes needs to mark children with attributes that can later
- * be read during layout. [data] is assigned to the [Measurable.parentData] to be read.
- * Normally [ParentData] is completely controlled by the containing Layout. For example,
- * Row and Column layout models use parent data to access the flex value of their children
- * during measurement (though that is achieved using the Inflexible and Flexible modifiers,
- * rather than using this widget).
- *
- */
-@Deprecated(
-    "ParentData composable is deprecated. You should either create a modifier which implements " +
-            "ParentDataModifier interface, or use LayoutTag modifier if you simply need to tag " +
-            "layout children to recognize them inside the measure block."
-)
-@Composable
-inline fun ParentData(data: Any, crossinline children: @Composable () -> Unit) {
-    DataNode(key = ParentDataKey, value = data) {
-        children()
-    }
-}
diff --git a/ui/ui-core/src/main/java/androidx/ui/core/Wrapper.kt b/ui/ui-core/src/main/java/androidx/ui/core/Wrapper.kt
index 93bdff0..b75aac0 100644
--- a/ui/ui-core/src/main/java/androidx/ui/core/Wrapper.kt
+++ b/ui/ui-core/src/main/java/androidx/ui/core/Wrapper.kt
@@ -148,32 +148,12 @@
     // on the main thread.
     recomposer: Recomposer = Recomposer.current(),
     content: @Composable () -> Unit
-): Composition = setContent(this, recomposer, content)
-
-/**
- * Composes the given composable into the given activity. The composable will become the root view
- * of the given activity.
- *
- * @param content Composable that will be the content of the activity.
- */
-@Deprecated(
-    "Your activity should extend androidx.activity.ComponentActivity " +
-            "or AppCompatActivity"
-)
-fun Activity.setContent(
-    content: @Composable () -> Unit
-): Composition = setContent(null, Recomposer.current(), content)
-
-private fun Activity.setContent(
-    lifecycleOwner: LifecycleOwner?,
-    recomposer: Recomposer,
-    content: @Composable () -> Unit
 ): Composition {
     FrameManager.ensureStarted()
     val composeView: AndroidOwner = window.decorView
         .findViewById<ViewGroup>(android.R.id.content)
         .getChildAt(0) as? AndroidOwner
-        ?: createOwner(this, lifecycleOwner).also {
+        ?: createOwner(this, this).also {
             setContentView(it.view, DefaultLayoutParams)
         }
     return doSetContent(this, composeView, recomposer, content)
diff --git a/ui/ui-core/src/main/java/androidx/ui/focus/FocusModifier.kt b/ui/ui-core/src/main/java/androidx/ui/core/focus/FocusModifier.kt
similarity index 80%
rename from ui/ui-core/src/main/java/androidx/ui/focus/FocusModifier.kt
rename to ui/ui-core/src/main/java/androidx/ui/core/focus/FocusModifier.kt
index f5cc7ea..281627c 100644
--- a/ui/ui-core/src/main/java/androidx/ui/focus/FocusModifier.kt
+++ b/ui/ui-core/src/main/java/androidx/ui/core/focus/FocusModifier.kt
@@ -14,8 +14,10 @@
  * limitations under the License.
  */
 
-package androidx.ui.focus
+package androidx.ui.core.focus
 
+import androidx.compose.Composable
+import androidx.compose.remember
 import androidx.ui.core.Modifier
 
 /**
@@ -56,4 +58,16 @@
      * @return true if the focus was successfully released. false otherwise.
      */
     fun freeFocus(): Boolean
-}
\ No newline at end of file
+}
+
+/**
+ * Use this function to create an instance of [FocusModifier]. Adding a [FocusModifier] to a
+ * [Composable] makes it focusable.
+ */
+@Composable
+fun FocusModifier(): FocusModifier = remember { FocusModifierImpl(FocusDetailedState.Inactive) }
+
+/**
+ * This function returns the [FocusState] for the component wrapped by this [FocusModifier].
+ */
+val FocusModifier.focusState: FocusState get() = focusDetailedState.focusState()
\ No newline at end of file
diff --git a/ui/ui-core/src/main/java/androidx/ui/core/focus/FocusModifierImpl.kt b/ui/ui-core/src/main/java/androidx/ui/core/focus/FocusModifierImpl.kt
index 7e49169..dc207f1 100644
--- a/ui/ui-core/src/main/java/androidx/ui/core/focus/FocusModifierImpl.kt
+++ b/ui/ui-core/src/main/java/androidx/ui/core/focus/FocusModifierImpl.kt
@@ -17,11 +17,6 @@
 package androidx.ui.core.focus
 
 import androidx.compose.Model
-import androidx.ui.focus.FocusDetailedState
-import androidx.ui.focus.FocusModifier
-
-fun createFocusModifier(focusDetailedState: FocusDetailedState): FocusModifier =
-    FocusModifierImpl(focusDetailedState)
 
 @Model
 internal class FocusModifierImpl(
diff --git a/ui/ui-core/src/main/java/androidx/ui/focus/FocusState.kt b/ui/ui-core/src/main/java/androidx/ui/core/focus/FocusState.kt
similarity index 96%
rename from ui/ui-core/src/main/java/androidx/ui/focus/FocusState.kt
rename to ui/ui-core/src/main/java/androidx/ui/core/focus/FocusState.kt
index e2cae0c..bc5ec1b 100644
--- a/ui/ui-core/src/main/java/androidx/ui/focus/FocusState.kt
+++ b/ui/ui-core/src/main/java/androidx/ui/core/focus/FocusState.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright 2019 The Android Open Source Project
+ * Copyright 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package androidx.ui.focus
+package androidx.ui.core.focus
 
 /**
  * Different states of the focus system.
diff --git a/ui/ui-core/src/main/java/androidx/ui/focus/Focusable.kt b/ui/ui-core/src/main/java/androidx/ui/core/focus/Focusable.kt
similarity index 89%
rename from ui/ui-core/src/main/java/androidx/ui/focus/Focusable.kt
rename to ui/ui-core/src/main/java/androidx/ui/core/focus/Focusable.kt
index a5c081d..9bdea93 100644
--- a/ui/ui-core/src/main/java/androidx/ui/focus/Focusable.kt
+++ b/ui/ui-core/src/main/java/androidx/ui/core/focus/Focusable.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright 2019 The Android Open Source Project
+ * Copyright 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package androidx.ui.focus
+package androidx.ui.core.focus
 
 import androidx.compose.Composable
 
@@ -36,7 +36,7 @@
  */
 @Suppress("UNUSED_PARAMETER")
 @Deprecated(
-    message = "Focusable is deprecated. Use androidx.ui.focus.FocusModifier instead.",
+    message = "Focusable is deprecated. Use androidx.ui.core.focus.FocusModifier instead.",
     level = DeprecationLevel.ERROR
 )
 @Composable
@@ -51,7 +51,7 @@
  */
 @Deprecated(
     message = "FocusOperator is used along with a Focusable. Focusable is deprecated in favor of " +
-            "androidx.ui.focus.FocusModifier.",
+            "androidx.ui.core.focus.FocusModifier.",
     level = DeprecationLevel.ERROR
 )
 class FocusOperator
\ No newline at end of file
diff --git a/ui/ui-core/src/main/java/androidx/ui/core/focus/ModifiedFocusNode.kt b/ui/ui-core/src/main/java/androidx/ui/core/focus/ModifiedFocusNode.kt
index c4bdf20..395348d 100644
--- a/ui/ui-core/src/main/java/androidx/ui/core/focus/ModifiedFocusNode.kt
+++ b/ui/ui-core/src/main/java/androidx/ui/core/focus/ModifiedFocusNode.kt
@@ -17,11 +17,11 @@
 
 import androidx.ui.core.DelegatingLayoutNodeWrapper
 import androidx.ui.core.LayoutNodeWrapper
-import androidx.ui.focus.FocusDetailedState.Active
-import androidx.ui.focus.FocusDetailedState.ActiveParent
-import androidx.ui.focus.FocusDetailedState.Captured
-import androidx.ui.focus.FocusDetailedState.Disabled
-import androidx.ui.focus.FocusDetailedState.Inactive
+import androidx.ui.core.focus.FocusDetailedState.Active
+import androidx.ui.core.focus.FocusDetailedState.ActiveParent
+import androidx.ui.core.focus.FocusDetailedState.Captured
+import androidx.ui.core.focus.FocusDetailedState.Disabled
+import androidx.ui.core.focus.FocusDetailedState.Inactive
 
 internal class ModifiedFocusNode(
     wrapped: LayoutNodeWrapper,
diff --git a/ui/ui-core/src/main/java/androidx/ui/core/semantics/SemanticsNode.kt b/ui/ui-core/src/main/java/androidx/ui/core/semantics/SemanticsNode.kt
index 0140972..cc555e0 100644
--- a/ui/ui-core/src/main/java/androidx/ui/core/semantics/SemanticsNode.kt
+++ b/ui/ui-core/src/main/java/androidx/ui/core/semantics/SemanticsNode.kt
@@ -344,7 +344,6 @@
  * for all ancestors.
  */
 fun SemanticsNode.findClosestParentNode(selector: (SemanticsNode) -> Boolean): SemanticsNode? {
-    // TODO(b/143866294): move this to the testing side after the hierarchy isn't flattened anymore
     var currentParent = parent
     while (currentParent != null) {
         if (currentParent.isSemanticBoundary && selector(currentParent)) {
diff --git a/ui/ui-core/src/main/java/androidx/ui/focus/FocusModifierProvider.kt b/ui/ui-core/src/main/java/androidx/ui/focus/FocusModifierProvider.kt
deleted file mode 100644
index 53e1f6a..0000000
--- a/ui/ui-core/src/main/java/androidx/ui/focus/FocusModifierProvider.kt
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.ui.focus
-
-import androidx.compose.Composable
-import androidx.compose.remember
-import androidx.ui.core.focus.createFocusModifier
-
-/**
- * Use this function to create an instance of [FocusModifier]. Adding a [FocusModifier] to a
- * [Composable] makes it focusable.
- */
-@Composable
-fun FocusModifier(): FocusModifier = remember { createFocusModifier(FocusDetailedState.Inactive) }
-
-/**
- * This function returns the [FocusState] for the component wrapped by this [FocusModifier].
- */
-val FocusModifier.focusState: FocusState get() = focusDetailedState.focusState()
\ No newline at end of file
diff --git a/ui/ui-core/src/main/java/androidx/ui/node/ViewInterop.kt b/ui/ui-core/src/main/java/androidx/ui/node/ViewInterop.kt
index 8985b93..7bd8279 100644
--- a/ui/ui-core/src/main/java/androidx/ui/node/ViewInterop.kt
+++ b/ui/ui-core/src/main/java/androidx/ui/node/ViewInterop.kt
@@ -32,6 +32,7 @@
 import androidx.ui.unit.IntPx
 import androidx.ui.unit.ipx
 import androidx.ui.unit.isFinite
+import androidx.ui.util.fastFirstOrNull
 import androidx.ui.viewinterop.AndroidViewHolder
 
 /**
@@ -157,7 +158,7 @@
 
     inline fun <T : ViewAdapter> get(id: Int, factory: () -> T): T {
         @Suppress("UNCHECKED_CAST")
-        val existing = adapters.firstOrNull { it.id == id } as? T
+        val existing = adapters.fastFirstOrNull { it.id == id } as? T
         if (existing != null) return existing
         val next = factory()
         adapters.add(next)
diff --git a/ui/ui-desktop/.gitignore b/ui/ui-desktop/.gitignore
new file mode 100644
index 0000000..7f0f0e2
--- /dev/null
+++ b/ui/ui-desktop/.gitignore
@@ -0,0 +1 @@
+compose-libs
diff --git a/ui/ui-desktop/android-emu/build.gradle b/ui/ui-desktop/android-emu/build.gradle
index 82dc30c..31dbd9a 100644
--- a/ui/ui-desktop/android-emu/build.gradle
+++ b/ui/ui-desktop/android-emu/build.gradle
@@ -22,14 +22,13 @@
 import static androidx.build.dependencies.DependenciesKt.*
 
 plugins {
-    id("AndroidXPlugin")
-    id("com.android.library")
-    id("AndroidXUiPlugin")
     id("kotlin-multiplatform")
 }
 
 kotlin {
-    jvm("desktop")
+    jvm("desktop") {
+        withJava()
+    }
 
     sourceSets {
         commonMain.dependencies {
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/java/android/annotation/IntRange.java b/ui/ui-desktop/android-emu/src/desktopMain/java/android/annotation/IntRange.java
new file mode 100644
index 0000000..a7ba1b4
--- /dev/null
+++ b/ui/ui-desktop/android-emu/src/desktopMain/java/android/annotation/IntRange.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.annotation;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Denotes that the annotated element should be an int or long in the given range
+ * <p>
+ * Example:
+ * <pre><code>
+ *  &#64;IntRange(from=0,to=255)
+ *  public int getAlpha() {
+ *      ...
+ *  }
+ * </code></pre>
+ *
+ */
+@Retention(SOURCE)
+@Target({METHOD, PARAMETER, FIELD, LOCAL_VARIABLE, ANNOTATION_TYPE})
+public @interface IntRange {
+    /** Smallest value, inclusive */
+    long from() default Long.MIN_VALUE;
+
+    /** Largest value, inclusive */
+    long to() default Long.MAX_VALUE;
+}
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/java/android/annotation/NonNull.java b/ui/ui-desktop/android-emu/src/desktopMain/java/android/annotation/NonNull.java
new file mode 100644
index 0000000..ff38cfe
--- /dev/null
+++ b/ui/ui-desktop/android-emu/src/desktopMain/java/android/annotation/NonNull.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.annotation;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Denotes that a parameter, field or method return value can never be null.
+ * <p>
+ * This is a marker annotation and it has no specific attributes.
+ *
+ * @paramDoc This value must never be {@code null}.
+ * @returnDoc This value will never be {@code null}.
+ */
+@Retention(SOURCE)
+@Target({METHOD, PARAMETER, FIELD})
+public @interface NonNull {
+}
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/java/android/annotation/Nullable.java b/ui/ui-desktop/android-emu/src/desktopMain/java/android/annotation/Nullable.java
new file mode 100644
index 0000000..1b3cb94
--- /dev/null
+++ b/ui/ui-desktop/android-emu/src/desktopMain/java/android/annotation/Nullable.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.annotation;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Denotes that a parameter, field or method return value can be null.
+ * <p>
+ * When decorating a method call parameter, this denotes that the parameter can
+ * legitimately be null and the method will gracefully deal with it. Typically
+ * used on optional parameters.
+ * <p>
+ * When decorating a method, this denotes the method might legitimately return
+ * null.
+ * <p>
+ * This is a marker annotation and it has no specific attributes.
+ *
+ * @paramDoc This value may be {@code null}.
+ * @returnDoc This value may be {@code null}.
+ */
+@Retention(SOURCE)
+@Target({METHOD, PARAMETER, FIELD})
+public @interface Nullable {
+}
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/java/android/compat/annotation/UnsupportedAppUsage.java b/ui/ui-desktop/android-emu/src/desktopMain/java/android/compat/annotation/UnsupportedAppUsage.java
new file mode 100644
index 0000000..079816d
--- /dev/null
+++ b/ui/ui-desktop/android-emu/src/desktopMain/java/android/compat/annotation/UnsupportedAppUsage.java
@@ -0,0 +1,174 @@
+/*
+ * 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 android.compat.annotation;
+
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.CLASS;
+
+import java.lang.annotation.Repeatable;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Indicates that this non-SDK interface is used by apps. A non-SDK interface is a
+ * class member (field or method) that is not part of the public SDK. Since the
+ * member is not part of the SDK, usage by apps is not supported.
+ *
+ * <h2>If you are an Android App developer</h2>
+ *
+ * This annotation indicates that you may be able to access the member at runtime, but that
+ * this access is discouraged and not supported by Android. If there is a value
+ * for {@link #maxTargetSdk()} on the annotation, access will be restricted based
+ * on the {@code targetSdkVersion} value set in your manifest.
+ *
+ * <p>Fields and methods annotated with this are likely to be restricted, changed
+ * or removed in future Android releases. If you rely on these members for
+ * functionality that is not otherwise supported by Android, consider filing a
+ * <a href="http://g.co/dev/appcompat">feature request</a>.
+ *
+ * <h2>If you are an Android OS developer</h2>
+ *
+ * This annotation acts as a heads up that changing a given method or field
+ * may affect apps, potentially breaking them when the next Android version is
+ * released. In some cases, for members that are heavily used, this annotation
+ * may imply restrictions on changes to the member.
+ *
+ * <p>This annotation also results in access to the member being permitted by the
+ * runtime, with a warning being generated in debug builds. Which apps can access
+ * the member is determined by the value of {@link #maxTargetSdk()}.
+ *
+ * <p>For more details, see go/UnsupportedAppUsage.
+ *
+ * {@hide}
+ */
+@Retention(CLASS)
+@Target({CONSTRUCTOR, METHOD, FIELD, TYPE})
+@Repeatable(UnsupportedAppUsage.Container.class)
+public @interface UnsupportedAppUsage {
+
+    /**
+     * Associates a bug tracking the work to add a public alternative to this API. Optional.
+     *
+     * @return ID of the associated tracking bug
+     */
+    long trackingBug() default 0;
+
+    /**
+     * Indicates that usage of this API is limited to apps based on their target SDK version.
+     *
+     * <p>Access to the API is allowed if the targetSdkVersion in the apps manifest is no greater
+     * than this value. Access checks are performed at runtime.
+     *
+     * <p>This is used to give app developers a grace period to migrate off a non-SDK interface.
+     * When making Android version N, existing APIs can have a maxTargetSdk of N-1 added to them.
+     * Developers must then migrate off the API when their app is updated in future, but it will
+     * continue working in the meantime.
+     *
+     * <p>Possible values are:
+     * <ul>
+     *     <li>
+     *         An API level like {@link VersionCodes#O} - in which case the API is available up to
+     *         and including the specified release. Or, in other words, the API is blacklisted
+     *         (unavailable) from the next API level from the one specified.
+     *     </li>
+     *     <li>
+     *         absent (default value) - All apps can access this API, but doing so may result in
+     *         warnings in the log, UI warnings (on developer builds) and/or strictmode violations.
+     *         The API is likely to be further restricted in future.
+     *     </li>
+     *
+     * </ul>
+     *
+     * @return The maximum value for an apps targetSdkVersion in order to access this API.
+     */
+    int maxTargetSdk() default Integer.MAX_VALUE;
+
+    /**
+     * The signature of an implicit (not present in the source) member that forms part of the
+     * hiddenapi.
+     *
+     * <p>Allows access to non-SDK API elements that are not represented in the input source to be
+     * managed.
+     *
+     * <p>This must only be used when applying the annotation to a type, using it in any other
+     * situation is an error.
+     *
+     * @return A dex API signature.
+     */
+    String implicitMember() default "";
+
+    /**
+     * Public API alternatives to this API.
+     *
+     * <p>If non-empty, the string must be a description of the public API alternative(s) to this
+     * API. The explanation must contain at least one Javadoc link tag to public API methods or
+     * fields. e.g.:
+     * {@literal @UnsupportedAppUsage(publicAlternatives="Use {@link foo.bar.Baz#bat()} instead.")}
+     *
+     * <p>Any elements that can be deduced can be omitted, e.g.:
+     * <ul>
+     *      <li>
+     *          the class, if it's the same as for the annotated element.
+     *      </li>
+     *      <li>
+     *          the package name, if it's the same as for the annotated element.
+     *      </li>
+     *      <li>
+     *          the method parameters, if there is only one method with that name in the given
+     *          package and class.
+     *      </li>
+     * </ul>
+     * @return A Javadoc-formatted string.
+     */
+    @SuppressWarnings("JavadocReference")
+    String publicAlternatives() default "";
+
+    /**
+     * Container for {@link UnsupportedAppUsage} that allows it to be applied repeatedly to types.
+     */
+    @Retention(CLASS)
+    @Target(TYPE)
+    @interface Container {
+        UnsupportedAppUsage[] value();
+    }
+
+    /**
+     * Internal usage only.
+     *
+     * Override the default source position when generating an index of the annotations.
+     *
+     * <p>This is intended for use by tools that generate java source code, to point to the
+     * original source position of the annotation, rather than the position within the generated
+     * code. It should never be set manually.
+     *
+     * <p>The format of the value is "path/to/file:startline:startcol:endline:endcol" indicating
+     * the position of the annotation itself.
+     */
+    String overrideSourcePosition() default "";
+
+    /**
+     * Internal usage only.
+     *
+     * For debug use only. The expected dex signature to be generated for this API, used to verify
+     * parts of the build process.
+     *
+     * @return A dex API signature.
+     */
+    String expectedSignature() default "";
+}
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/BoringLayout.java b/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/BoringLayout.java
new file mode 100644
index 0000000..dd442d5
--- /dev/null
+++ b/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/BoringLayout.java
@@ -0,0 +1,501 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text;
+
+import android.compat.annotation.UnsupportedAppUsage;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.text.style.ParagraphStyle;
+
+/**
+ * A BoringLayout is a very simple Layout implementation for text that
+ * fits on a single line and is all left-to-right characters.
+ * You will probably never want to make one of these yourself;
+ * if you do, be sure to call {@link #isBoring} first to make sure
+ * the text meets the criteria.
+ * <p>This class is used by widgets to control text layout. You should not need
+ * to use this class directly unless you are implementing your own widget
+ * or custom display object, in which case
+ * you are encouraged to use a Layout instead of calling
+ * {@link android.graphics.Canvas#drawText(
+ *    java.lang.CharSequence, int, int, float, float, android.graphics.Paint)
+ *  Canvas.drawText()} directly.</p>
+ */
+public class BoringLayout extends Layout implements TextUtils.EllipsizeCallback {
+
+    /**
+     * Utility function to construct a BoringLayout instance.
+     *
+     * @param source the text to render
+     * @param paint the default paint for the layout
+     * @param outerWidth the wrapping width for the text
+     * @param align whether to left, right, or center the text
+     * @param spacingMult this value is no longer used by BoringLayout
+     * @param spacingAdd this value is no longer used by BoringLayout
+     * @param metrics {@code #Metrics} instance that contains information about FontMetrics and
+     *                line width
+     * @param includePad set whether to include extra space beyond font ascent and descent which is
+     *                   needed to avoid clipping in some scripts
+     */
+    public static BoringLayout make(CharSequence source, TextPaint paint, int outerWidth,
+            Alignment align, float spacingMult, float spacingAdd, BoringLayout.Metrics metrics,
+            boolean includePad) {
+        return new BoringLayout(source, paint, outerWidth, align, spacingMult, spacingAdd, metrics,
+                includePad);
+    }
+
+    /**
+     * Utility function to construct a BoringLayout instance.
+     *
+     * @param source the text to render
+     * @param paint the default paint for the layout
+     * @param outerWidth the wrapping width for the text
+     * @param align whether to left, right, or center the text
+     * @param spacingmult this value is no longer used by BoringLayout
+     * @param spacingadd this value is no longer used by BoringLayout
+     * @param metrics {@code #Metrics} instance that contains information about FontMetrics and
+     *                line width
+     * @param includePad set whether to include extra space beyond font ascent and descent which is
+     *                   needed to avoid clipping in some scripts
+     * @param ellipsize whether to ellipsize the text if width of the text is longer than the
+     *                  requested width
+     * @param ellipsizedWidth the width to which this Layout is ellipsizing. If {@code ellipsize} is
+     *                        {@code null}, or is {@link TextUtils.TruncateAt#MARQUEE} this value is
+     *                        not used, {@code outerWidth} is used instead
+     */
+    public static BoringLayout make(CharSequence source, TextPaint paint, int outerWidth,
+            Alignment align, float spacingmult, float spacingadd, BoringLayout.Metrics metrics,
+            boolean includePad, TextUtils.TruncateAt ellipsize, int ellipsizedWidth) {
+        return new BoringLayout(source, paint, outerWidth, align, spacingmult, spacingadd, metrics,
+                includePad, ellipsize, ellipsizedWidth);
+    }
+
+    /**
+     * Returns a BoringLayout for the specified text, potentially reusing
+     * this one if it is already suitable.  The caller must make sure that
+     * no one is still using this Layout.
+     *
+     * @param source the text to render
+     * @param paint the default paint for the layout
+     * @param outerwidth the wrapping width for the text
+     * @param align whether to left, right, or center the text
+     * @param spacingMult this value is no longer used by BoringLayout
+     * @param spacingAdd this value is no longer used by BoringLayout
+     * @param metrics {@code #Metrics} instance that contains information about FontMetrics and
+     *                line width
+     * @param includePad set whether to include extra space beyond font ascent and descent which is
+     *                   needed to avoid clipping in some scripts
+     */
+    public BoringLayout replaceOrMake(CharSequence source, TextPaint paint, int outerwidth,
+            Alignment align, float spacingMult, float spacingAdd, BoringLayout.Metrics metrics,
+            boolean includePad) {
+        replaceWith(source, paint, outerwidth, align, spacingMult, spacingAdd);
+
+        mEllipsizedWidth = outerwidth;
+        mEllipsizedStart = 0;
+        mEllipsizedCount = 0;
+
+        init(source, paint, align, metrics, includePad, true);
+        return this;
+    }
+
+    /**
+     * Returns a BoringLayout for the specified text, potentially reusing
+     * this one if it is already suitable.  The caller must make sure that
+     * no one is still using this Layout.
+     *
+     * @param source the text to render
+     * @param paint the default paint for the layout
+     * @param outerWidth the wrapping width for the text
+     * @param align whether to left, right, or center the text
+     * @param spacingMult this value is no longer used by BoringLayout
+     * @param spacingAdd this value is no longer used by BoringLayout
+     * @param metrics {@code #Metrics} instance that contains information about FontMetrics and
+     *                line width
+     * @param includePad set whether to include extra space beyond font ascent and descent which is
+     *                   needed to avoid clipping in some scripts
+     * @param ellipsize whether to ellipsize the text if width of the text is longer than the
+     *                  requested width
+     * @param ellipsizedWidth the width to which this Layout is ellipsizing. If {@code ellipsize} is
+     *                        {@code null}, or is {@link TextUtils.TruncateAt#MARQUEE} this value is
+     *                        not used, {@code outerwidth} is used instead
+     */
+    public BoringLayout replaceOrMake(CharSequence source, TextPaint paint, int outerWidth,
+            Alignment align, float spacingMult, float spacingAdd, BoringLayout.Metrics metrics,
+            boolean includePad, TextUtils.TruncateAt ellipsize, int ellipsizedWidth) {
+        boolean trust;
+
+        if (ellipsize == null || ellipsize == TextUtils.TruncateAt.MARQUEE) {
+            replaceWith(source, paint, outerWidth, align, spacingMult, spacingAdd);
+
+            mEllipsizedWidth = outerWidth;
+            mEllipsizedStart = 0;
+            mEllipsizedCount = 0;
+            trust = true;
+        } else {
+            replaceWith(TextUtils.ellipsize(source, paint, ellipsizedWidth, ellipsize, true, this),
+                    paint, outerWidth, align, spacingMult, spacingAdd);
+
+            mEllipsizedWidth = ellipsizedWidth;
+            trust = false;
+        }
+
+        init(getText(), paint, align, metrics, includePad, trust);
+        return this;
+    }
+
+    /**
+     * @param source the text to render
+     * @param paint the default paint for the layout
+     * @param outerwidth the wrapping width for the text
+     * @param align whether to left, right, or center the text
+     * @param spacingMult this value is no longer used by BoringLayout
+     * @param spacingAdd this value is no longer used by BoringLayout
+     * @param metrics {@code #Metrics} instance that contains information about FontMetrics and
+     *                line width
+     * @param includePad set whether to include extra space beyond font ascent and descent which is
+     *                   needed to avoid clipping in some scripts
+     */
+    public BoringLayout(CharSequence source, TextPaint paint, int outerwidth, Alignment align,
+            float spacingMult, float spacingAdd, BoringLayout.Metrics metrics, boolean includePad) {
+        super(source, paint, outerwidth, align, spacingMult, spacingAdd);
+
+        mEllipsizedWidth = outerwidth;
+        mEllipsizedStart = 0;
+        mEllipsizedCount = 0;
+
+        init(source, paint, align, metrics, includePad, true);
+    }
+
+    /**
+     *
+     * @param source the text to render
+     * @param paint the default paint for the layout
+     * @param outerWidth the wrapping width for the text
+     * @param align whether to left, right, or center the text
+     * @param spacingMult this value is no longer used by BoringLayout
+     * @param spacingAdd this value is no longer used by BoringLayout
+     * @param metrics {@code #Metrics} instance that contains information about FontMetrics and
+     *                line width
+     * @param includePad set whether to include extra space beyond font ascent and descent which is
+     *                   needed to avoid clipping in some scripts
+     * @param ellipsize whether to ellipsize the text if width of the text is longer than the
+     *                  requested {@code outerwidth}
+     * @param ellipsizedWidth the width to which this Layout is ellipsizing. If {@code ellipsize} is
+     *                        {@code null}, or is {@link TextUtils.TruncateAt#MARQUEE} this value is
+     *                        not used, {@code outerwidth} is used instead
+     */
+    public BoringLayout(CharSequence source, TextPaint paint, int outerWidth, Alignment align,
+            float spacingMult, float spacingAdd, BoringLayout.Metrics metrics, boolean includePad,
+            TextUtils.TruncateAt ellipsize, int ellipsizedWidth) {
+        /*
+         * It is silly to have to call super() and then replaceWith(),
+         * but we can't use "this" for the callback until the call to
+         * super() finishes.
+         */
+        super(source, paint, outerWidth, align, spacingMult, spacingAdd);
+
+        boolean trust;
+
+        if (ellipsize == null || ellipsize == TextUtils.TruncateAt.MARQUEE) {
+            mEllipsizedWidth = outerWidth;
+            mEllipsizedStart = 0;
+            mEllipsizedCount = 0;
+            trust = true;
+        } else {
+            replaceWith(TextUtils.ellipsize(source, paint, ellipsizedWidth, ellipsize, true, this),
+                        paint, outerWidth, align, spacingMult, spacingAdd);
+
+            mEllipsizedWidth = ellipsizedWidth;
+            trust = false;
+        }
+
+        init(getText(), paint, align, metrics, includePad, trust);
+    }
+
+    /* package */ void init(CharSequence source, TextPaint paint, Alignment align,
+            BoringLayout.Metrics metrics, boolean includePad, boolean trustWidth) {
+        int spacing;
+
+        if (source instanceof String && align == Layout.Alignment.ALIGN_NORMAL) {
+            mDirect = source.toString();
+        } else {
+            mDirect = null;
+        }
+
+        mPaint = paint;
+
+        if (includePad) {
+            spacing = metrics.bottom - metrics.top;
+            mDesc = metrics.bottom;
+        } else {
+            spacing = metrics.descent - metrics.ascent;
+            mDesc = metrics.descent;
+        }
+
+        mBottom = spacing;
+
+        if (trustWidth) {
+            mMax = metrics.width;
+        } else {
+            /*
+             * If we have ellipsized, we have to actually calculate the
+             * width because the width that was passed in was for the
+             * full text, not the ellipsized form.
+             */
+            TextLine line = TextLine.obtain();
+            line.set(paint, source, 0, source.length(), Layout.DIR_LEFT_TO_RIGHT,
+                    Layout.DIRS_ALL_LEFT_TO_RIGHT, false, null,
+                    mEllipsizedStart, mEllipsizedStart + mEllipsizedCount);
+            mMax = (int) Math.ceil(line.metrics(null));
+            TextLine.recycle(line);
+        }
+
+        if (includePad) {
+            mTopPadding = metrics.top - metrics.ascent;
+            mBottomPadding = metrics.bottom - metrics.descent;
+        }
+    }
+
+    /**
+     * Determine and compute metrics if given text can be handled by BoringLayout.
+     *
+     * @param text a text
+     * @param paint a paint
+     * @return layout metric for the given text. null if given text is unable to be handled by
+     *         BoringLayout.
+     */
+    public static Metrics isBoring(CharSequence text, TextPaint paint) {
+        return isBoring(text, paint, TextDirectionHeuristics.FIRSTSTRONG_LTR, null);
+    }
+
+    /**
+     * Determine and compute metrics if given text can be handled by BoringLayout.
+     *
+     * @param text a text
+     * @param paint a paint
+     * @param metrics a metrics object to be recycled. If null is passed, this function creat new
+     *                object.
+     * @return layout metric for the given text. If metrics is not null, this method fills values
+     *         to given metrics object instead of allocating new metrics object. null if given text
+     *         is unable to be handled by BoringLayout.
+     */
+    public static Metrics isBoring(CharSequence text, TextPaint paint, Metrics metrics) {
+        return isBoring(text, paint, TextDirectionHeuristics.FIRSTSTRONG_LTR, metrics);
+    }
+
+    /**
+     * Returns true if the text contains any RTL characters, bidi format characters, or surrogate
+     * code units.
+     */
+    private static boolean hasAnyInterestingChars(CharSequence text, int textLength) {
+        final int maxBufLen = 500;
+        final char[] buffer = TextUtils.obtain(maxBufLen);
+        try {
+            for (int start = 0; start < textLength; start += maxBufLen) {
+                final int end = Math.min(start + maxBufLen, textLength);
+
+                // No need to worry about getting half codepoints, since we consider surrogate code
+                // units "interesting" as soon we see one.
+                TextUtils.getChars(text, start, end, buffer, 0);
+
+                final int len = end - start;
+                for (int i = 0; i < len; i++) {
+                    final char c = buffer[i];
+                    if (c == '\n' || c == '\t' || TextUtils.couldAffectRtl(c)) {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        } finally {
+            TextUtils.recycle(buffer);
+        }
+    }
+
+    /**
+     * Returns null if not boring; the width, ascent, and descent in the
+     * provided Metrics object (or a new one if the provided one was null)
+     * if boring.
+     */
+    @UnsupportedAppUsage
+    public static Metrics isBoring(CharSequence text, TextPaint paint,
+            TextDirectionHeuristic textDir, Metrics metrics) {
+        final int textLength = text.length();
+        if (hasAnyInterestingChars(text, textLength)) {
+            return null;  // There are some interesting characters. Not boring.
+        }
+        if (textDir != null && textDir.isRtl(text, 0, textLength)) {
+            return null;  // The heuristic considers the whole text RTL. Not boring.
+        }
+        if (text instanceof Spanned) {
+            Spanned sp = (Spanned) text;
+            Object[] styles = sp.getSpans(0, textLength, ParagraphStyle.class);
+            if (styles.length > 0) {
+                return null;  // There are some ParagraphStyle spans. Not boring.
+            }
+        }
+
+        Metrics fm = metrics;
+        if (fm == null) {
+            fm = new Metrics();
+        } else {
+            fm.reset();
+        }
+
+        TextLine line = TextLine.obtain();
+        line.set(paint, text, 0, textLength, Layout.DIR_LEFT_TO_RIGHT,
+                Layout.DIRS_ALL_LEFT_TO_RIGHT, false, null,
+                0 /* ellipsisStart, 0 since text has not been ellipsized at this point */,
+                0 /* ellipsisEnd, 0 since text has not been ellipsized at this point */);
+        fm.width = (int) Math.ceil(line.metrics(fm));
+        TextLine.recycle(line);
+
+        return fm;
+    }
+
+    @Override
+    public int getHeight() {
+        return mBottom;
+    }
+
+    @Override
+    public int getLineCount() {
+        return 1;
+    }
+
+    @Override
+    public int getLineTop(int line) {
+        if (line == 0) {
+            return 0;
+        } else {
+            return mBottom;
+        }
+    }
+
+    @Override
+    public int getLineDescent(int line) {
+        return mDesc;
+    }
+
+    @Override
+    public int getLineStart(int line) {
+        if (line == 0) {
+            return 0;
+        } else {
+            return getText().length();
+        }
+    }
+
+    @Override
+    public int getParagraphDirection(int line) {
+        return DIR_LEFT_TO_RIGHT;
+    }
+
+    @Override
+    public boolean getLineContainsTab(int line) {
+        return false;
+    }
+
+    @Override
+    public float getLineMax(int line) {
+        return mMax;
+    }
+
+    @Override
+    public float getLineWidth(int line) {
+        return (line == 0 ? mMax : 0);
+    }
+
+    @Override
+    public final Directions getLineDirections(int line) {
+        return Layout.DIRS_ALL_LEFT_TO_RIGHT;
+    }
+
+    @Override
+    public int getTopPadding() {
+        return mTopPadding;
+    }
+
+    @Override
+    public int getBottomPadding() {
+        return mBottomPadding;
+    }
+
+    @Override
+    public int getEllipsisCount(int line) {
+        return mEllipsizedCount;
+    }
+
+    @Override
+    public int getEllipsisStart(int line) {
+        return mEllipsizedStart;
+    }
+
+    @Override
+    public int getEllipsizedWidth() {
+        return mEllipsizedWidth;
+    }
+
+    // Override draw so it will be faster.
+    @Override
+    public void draw(Canvas c, Path highlight, Paint highlightpaint,
+                     int cursorOffset) {
+        if (mDirect != null && highlight == null) {
+            c.drawText(mDirect, 0, mBottom - mDesc, mPaint);
+        } else {
+            super.draw(c, highlight, highlightpaint, cursorOffset);
+        }
+    }
+
+    /**
+     * Callback for the ellipsizer to report what region it ellipsized.
+     */
+    public void ellipsized(int start, int end) {
+        mEllipsizedStart = start;
+        mEllipsizedCount = end - start;
+    }
+
+    private String mDirect;
+    private Paint mPaint;
+
+    /* package */ int mBottom, mDesc;   // for Direct
+    private int mTopPadding, mBottomPadding;
+    private float mMax;
+    private int mEllipsizedWidth, mEllipsizedStart, mEllipsizedCount;
+
+    /**
+     * Metrics.
+     */
+    public static class Metrics extends Paint.FontMetricsInt {
+        public int width;
+
+        @Override public String toString() {
+            return super.toString() + " width=" + width;
+        }
+
+        private void reset() {
+            top = 0;
+            bottom = 0;
+            ascent = 0;
+            descent = 0;
+            width = 0;
+            leading = 0;
+        }
+    }
+}
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/GetChars.java b/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/GetChars.java
new file mode 100644
index 0000000..7a7d5be
--- /dev/null
+++ b/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/GetChars.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text;
+
+/**
+ * Please implement this interface if your CharSequence has a
+ * getChars() method like the one in String that is faster than
+ * calling charAt() multiple times.
+ */
+public interface GetChars extends CharSequence {
+    /**
+     * Exactly like String.getChars(): copy chars <code>start</code>
+     * through <code>end - 1</code> from this CharSequence into <code>dest</code>
+     * beginning at offset <code>destoff</code>.
+     */
+    void getChars(int start, int end, char[] dest, int destoff);
+}
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/NoCopySpan.java b/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/NoCopySpan.java
new file mode 100644
index 0000000..4cbe062
--- /dev/null
+++ b/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/NoCopySpan.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text;
+
+/**
+ * This interface should be added to a span object that should not be copied
+ * into a new Spanned when performing a slice or copy operation on the original
+ * Spanned it was placed in.
+ */
+public interface NoCopySpan {
+    /**
+     * Convenience equivalent for when you would just want a new Object() for
+     * a span but want it to be no-copy.  Use this instead.
+     */
+    class Concrete implements NoCopySpan {
+    }
+}
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/SpanWatcher.java b/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/SpanWatcher.java
new file mode 100644
index 0000000..e1eee36
--- /dev/null
+++ b/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/SpanWatcher.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text;
+
+/**
+ * When an object of this type is attached to a Spannable, its methods
+ * will be called to notify it that other markup objects have been
+ * added, changed, or removed.
+ */
+public interface SpanWatcher extends NoCopySpan {
+    /**
+     * This method is called to notify you that the specified object
+     * has been attached to the specified range of the text.
+     */
+    void onSpanAdded(Spannable text, Object what, int start, int end);
+    /**
+     * This method is called to notify you that the specified object
+     * has been detached from the specified range of the text.
+     */
+    void onSpanRemoved(Spannable text, Object what, int start, int end);
+    /**
+     * This method is called to notify you that the specified object
+     * has been relocated from the range <code>ostart&hellip;oend</code>
+     * to the new range <code>nstart&hellip;nend</code> of the text.
+     */
+    void onSpanChanged(Spannable text, Object what, int ostart, int oend,
+                       int nstart, int nend);
+}
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/Spannable.java b/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/Spannable.java
new file mode 100644
index 0000000..e374fba
--- /dev/null
+++ b/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/Spannable.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text;
+
+/**
+ * This is the interface for text to which markup objects can be
+ * attached and detached.  Not all Spannable classes have mutable text;
+ * see {@link Editable} for that.
+ */
+public interface Spannable extends Spanned {
+    /**
+     * Attach the specified markup object to the range <code>start&hellip;end</code>
+     * of the text, or move the object to that range if it was already
+     * attached elsewhere.  See {@link Spanned} for an explanation of
+     * what the flags mean.  The object can be one that has meaning only
+     * within your application, or it can be one that the text system will
+     * use to affect text display or behavior.  Some noteworthy ones are
+     * the subclasses of {@link android.text.style.CharacterStyle} and
+     * {@link android.text.style.ParagraphStyle}, and
+     * {@link android.text.TextWatcher} and
+     * {@link android.text.SpanWatcher}.
+     */
+    void setSpan(Object what, int start, int end, int flags);
+
+    /**
+     * Remove the specified object from the range of text to which it
+     * was attached, if any.  It is OK to remove an object that was never
+     * attached in the first place.
+     */
+    void removeSpan(Object what);
+
+    /**
+     * Remove the specified object from the range of text to which it
+     * was attached, if any.  It is OK to remove an object tShat was never
+     * attached in the first place.
+     *
+     * See {@link Spanned} for an explanation of what the flags mean.
+     *
+     */
+    default void removeSpan(Object what, int flags) {
+        removeSpan(what);
+    }
+
+    /**
+     * Factory used by TextView to create new {@link Spannable Spannables}. You can subclass
+     * it to provide something other than {@link SpannableString}.
+     *
+     * @see android.widget.TextView#setSpannableFactory(Factory)
+     */
+    class Factory {
+        private static Spannable.Factory sInstance = new Spannable.Factory();
+
+        /**
+         * Returns the standard Spannable Factory.
+         */
+        public static Spannable.Factory getInstance() {
+            return sInstance;
+        }
+
+        /**
+         * Returns a new SpannableString from the specified CharSequence.
+         * You can override this to provide a different kind of Spannable.
+         */
+        public Spannable newSpannable(CharSequence source) {
+            return new SpannableString(source);
+        }
+    }
+}
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/SpannableString.java b/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/SpannableString.java
new file mode 100644
index 0000000..49484e7
--- /dev/null
+++ b/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/SpannableString.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text;
+
+/**
+ * This is the class for text whose content is immutable but to which
+ * markup objects can be attached and detached.
+ * For mutable text, see {@link SpannableStringBuilder}.
+ */
+public class SpannableString
+        extends SpannableStringInternal
+        implements CharSequence, GetChars, Spannable {
+
+    /**
+     * @param source           source object to copy from
+     * @param ignoreNoCopySpan whether to copy NoCopySpans in the {@code source}
+     */
+    public SpannableString(CharSequence source, boolean ignoreNoCopySpan) {
+        super(source, 0, source.length(), ignoreNoCopySpan);
+    }
+
+    /**
+     * For the backward compatibility reasons, this constructor copies all spans including {@link
+     * android.text.NoCopySpan}.
+     *
+     * @param source source text
+     */
+    public SpannableString(CharSequence source) {
+        this(source, false /* ignoreNoCopySpan */);  // preserve existing NoCopySpan behavior
+    }
+
+    /**
+     * Ctor.
+     */
+    private SpannableString(CharSequence source, int start, int end) {
+        // preserve existing NoCopySpan behavior
+        super(source, start, end, false /* ignoreNoCopySpan */);
+    }
+
+    /**
+     * valueOf.
+     */
+    public static SpannableString valueOf(CharSequence source) {
+        if (source instanceof SpannableString) {
+            return (SpannableString) source;
+        } else {
+            return new SpannableString(source);
+        }
+    }
+
+    /**
+     * setSpan.
+     */
+    public void setSpan(Object what, int start, int end, int flags) {
+        super.setSpan(what, start, end, flags);
+    }
+
+    /**
+     * removeSpan.
+     */
+    public void removeSpan(Object what) {
+        super.removeSpan(what);
+    }
+
+    /**
+     * subSequence.
+     */
+    public final CharSequence subSequence(int start, int end) {
+        return new SpannableString(this, start, end);
+    }
+}
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/SpannableStringInternal.java b/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/SpannableStringInternal.java
new file mode 100644
index 0000000..f327845
--- /dev/null
+++ b/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/SpannableStringInternal.java
@@ -0,0 +1,588 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text;
+
+import android.compat.annotation.UnsupportedAppUsage;
+
+import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.GrowingArrayUtils;
+
+import libcore.util.EmptyArray;
+
+import java.lang.reflect.Array;
+
+/* package */ abstract class SpannableStringInternal {
+    /* package */ SpannableStringInternal(CharSequence source,
+                                          int start, int end, boolean ignoreNoCopySpan) {
+        if (start == 0 && end == source.length()) {
+            mText = source.toString();
+        } else {
+            mText = source.toString().substring(start, end);
+        }
+        mSpans = EmptyArray.OBJECT;
+        // Invariant: mSpanData.length = mSpans.length * COLUMNS
+        mSpanData = EmptyArray.INT;
+
+        if (source instanceof Spanned) {
+            if (source instanceof SpannableStringInternal) {
+                copySpans((SpannableStringInternal) source, start, end, ignoreNoCopySpan);
+            } else {
+                copySpans((Spanned) source, start, end, ignoreNoCopySpan);
+            }
+        }
+    }
+
+    /**
+     * This unused method is left since this is listed in hidden api list.
+     *
+     * Due to backward compatibility reasons, we copy even NoCopySpan by default
+     */
+    @UnsupportedAppUsage
+    /* package */ SpannableStringInternal(CharSequence source, int start, int end) {
+        this(source, start, end, false /* ignoreNoCopySpan */);
+    }
+
+    /**
+     * Copies another {@link Spanned} object's spans between [start, end] into this object.
+     *
+     * @param src Source object to copy from.
+     * @param start Start index in the source object.
+     * @param end End index in the source object.
+     * @param ignoreNoCopySpan whether to copy NoCopySpans in the {@code source}
+     */
+    private void copySpans(Spanned src, int start, int end, boolean ignoreNoCopySpan) {
+        Object[] spans = src.getSpans(start, end, Object.class);
+
+        for (int i = 0; i < spans.length; i++) {
+            if (ignoreNoCopySpan && spans[i] instanceof NoCopySpan) {
+                continue;
+            }
+            int st = src.getSpanStart(spans[i]);
+            int en = src.getSpanEnd(spans[i]);
+            int fl = src.getSpanFlags(spans[i]);
+
+            if (st < start) st = start;
+            if (en > end) en = end;
+
+            setSpan(spans[i], st - start, en - start, fl, false/*enforceParagraph*/);
+        }
+    }
+
+    /**
+     * Copies a {@link SpannableStringInternal} object's spans between [start, end] into this
+     * object.
+     *
+     * @param src Source object to copy from.
+     * @param start Start index in the source object.
+     * @param end End index in the source object.
+     * @param ignoreNoCopySpan copy NoCopySpan for backward compatible reasons.
+     */
+    private void copySpans(SpannableStringInternal src, int start, int end,
+            boolean ignoreNoCopySpan) {
+        int count = 0;
+        final int[] srcData = src.mSpanData;
+        final Object[] srcSpans = src.mSpans;
+        final int limit = src.mSpanCount;
+        boolean hasNoCopySpan = false;
+
+        for (int i = 0; i < limit; i++) {
+            int spanStart = srcData[i * COLUMNS + START];
+            int spanEnd = srcData[i * COLUMNS + END];
+            if (isOutOfCopyRange(start, end, spanStart, spanEnd)) continue;
+            if (srcSpans[i] instanceof NoCopySpan) {
+                hasNoCopySpan = true;
+                if (ignoreNoCopySpan) {
+                    continue;
+                }
+            }
+            count++;
+        }
+
+        if (count == 0) return;
+
+        if (!hasNoCopySpan && start == 0 && end == src.length()) {
+            mSpans = ArrayUtils.newUnpaddedObjectArray(src.mSpans.length);
+            mSpanData = new int[src.mSpanData.length];
+            mSpanCount = src.mSpanCount;
+            System.arraycopy(src.mSpans, 0, mSpans, 0, src.mSpans.length);
+            System.arraycopy(src.mSpanData, 0, mSpanData, 0, mSpanData.length);
+        } else {
+            mSpanCount = count;
+            mSpans = ArrayUtils.newUnpaddedObjectArray(mSpanCount);
+            mSpanData = new int[mSpans.length * COLUMNS];
+            for (int i = 0, j = 0; i < limit; i++) {
+                int spanStart = srcData[i * COLUMNS + START];
+                int spanEnd = srcData[i * COLUMNS + END];
+                if (isOutOfCopyRange(start, end, spanStart, spanEnd)
+                        || (ignoreNoCopySpan && srcSpans[i] instanceof NoCopySpan)) {
+                    continue;
+                }
+                if (spanStart < start) spanStart = start;
+                if (spanEnd > end) spanEnd = end;
+
+                mSpans[j] = srcSpans[i];
+                mSpanData[j * COLUMNS + START] = spanStart - start;
+                mSpanData[j * COLUMNS + END] = spanEnd - start;
+                mSpanData[j * COLUMNS + FLAGS] = srcData[i * COLUMNS + FLAGS];
+                j++;
+            }
+        }
+    }
+
+    /**
+     * Checks if [spanStart, spanEnd] interval is excluded from [start, end].
+     *
+     * @return True if excluded, false if included.
+     */
+    @UnsupportedAppUsage
+    private boolean isOutOfCopyRange(int start, int end, int spanStart, int spanEnd) {
+        if (spanStart > end || spanEnd < start) return true;
+        if (spanStart != spanEnd && start != end) {
+            if (spanStart == end || spanEnd == start) return true;
+        }
+        return false;
+    }
+
+    public final int length() {
+        return mText.length();
+    }
+
+    public final char charAt(int i) {
+        return mText.charAt(i);
+    }
+
+    public final String toString() {
+        return mText;
+    }
+
+    /* subclasses must do subSequence() to preserve type */
+
+    public final void getChars(int start, int end, char[] dest, int off) {
+        mText.getChars(start, end, dest, off);
+    }
+
+    @UnsupportedAppUsage
+    /* package */ void setSpan(Object what, int start, int end, int flags) {
+        setSpan(what, start, end, flags, true/*enforceParagraph*/);
+    }
+
+    @UnsupportedAppUsage
+    private boolean isIndexFollowsNextLine(int index) {
+        return index != 0 && index != length() && charAt(index - 1) != '\n';
+    }
+
+    @UnsupportedAppUsage
+    private void setSpan(Object what, int start, int end, int flags, boolean enforceParagraph) {
+        int nstart = start;
+        int nend = end;
+
+        checkRange("setSpan", start, end);
+
+        if ((flags & Spannable.SPAN_PARAGRAPH) == Spannable.SPAN_PARAGRAPH) {
+            if (isIndexFollowsNextLine(start)) {
+                if (!enforceParagraph) {
+                    // do not set the span
+                    return;
+                }
+                throw new RuntimeException("PARAGRAPH span must start at paragraph boundary"
+                        + " (" + start + " follows " + charAt(start - 1) + ")");
+            }
+
+            if (isIndexFollowsNextLine(end)) {
+                if (!enforceParagraph) {
+                    // do not set the span
+                    return;
+                }
+                throw new RuntimeException("PARAGRAPH span must end at paragraph boundary"
+                        + " (" + end + " follows " + charAt(end - 1) + ")");
+            }
+        }
+
+        int count = mSpanCount;
+        Object[] spans = mSpans;
+        int[] data = mSpanData;
+
+        for (int i = 0; i < count; i++) {
+            if (spans[i] == what) {
+                int ostart = data[i * COLUMNS + START];
+                int oend = data[i * COLUMNS + END];
+
+                data[i * COLUMNS + START] = start;
+                data[i * COLUMNS + END] = end;
+                data[i * COLUMNS + FLAGS] = flags;
+
+                sendSpanChanged(what, ostart, oend, nstart, nend);
+                return;
+            }
+        }
+
+        if (mSpanCount + 1 >= mSpans.length) {
+            Object[] newtags = ArrayUtils.newUnpaddedObjectArray(
+                    GrowingArrayUtils.growSize(mSpanCount));
+            int[] newdata = new int[newtags.length * 3];
+
+            System.arraycopy(mSpans, 0, newtags, 0, mSpanCount);
+            System.arraycopy(mSpanData, 0, newdata, 0, mSpanCount * 3);
+
+            mSpans = newtags;
+            mSpanData = newdata;
+        }
+
+        mSpans[mSpanCount] = what;
+        mSpanData[mSpanCount * COLUMNS + START] = start;
+        mSpanData[mSpanCount * COLUMNS + END] = end;
+        mSpanData[mSpanCount * COLUMNS + FLAGS] = flags;
+        mSpanCount++;
+
+        if (this instanceof Spannable) {
+            sendSpanAdded(what, nstart, nend);
+        }
+    }
+
+    @UnsupportedAppUsage
+    /* package */ void removeSpan(Object what) {
+        removeSpan(what, 0 /* flags */);
+    }
+
+    /**
+     * removeSpan
+     */
+    public void removeSpan(Object what, int flags) {
+        int count = mSpanCount;
+        Object[] spans = mSpans;
+        int[] data = mSpanData;
+
+        for (int i = count - 1; i >= 0; i--) {
+            if (spans[i] == what) {
+                int ostart = data[i * COLUMNS + START];
+                int oend = data[i * COLUMNS + END];
+
+                int c = count - (i + 1);
+
+                System.arraycopy(spans, i + 1, spans, i, c);
+                System.arraycopy(data, (i + 1) * COLUMNS,
+                        data, i * COLUMNS, c * COLUMNS);
+
+                mSpanCount--;
+
+                if ((flags & Spanned.SPAN_INTERMEDIATE) == 0) {
+                    sendSpanRemoved(what, ostart, oend);
+                }
+                return;
+            }
+        }
+    }
+
+    @UnsupportedAppUsage
+    public int getSpanStart(Object what) {
+        int count = mSpanCount;
+        Object[] spans = mSpans;
+        int[] data = mSpanData;
+
+        for (int i = count - 1; i >= 0; i--) {
+            if (spans[i] == what) {
+                return data[i * COLUMNS + START];
+            }
+        }
+
+        return -1;
+    }
+
+    @UnsupportedAppUsage
+    public int getSpanEnd(Object what) {
+        int count = mSpanCount;
+        Object[] spans = mSpans;
+        int[] data = mSpanData;
+
+        for (int i = count - 1; i >= 0; i--) {
+            if (spans[i] == what) {
+                return data[i * COLUMNS + END];
+            }
+        }
+
+        return -1;
+    }
+
+    @UnsupportedAppUsage
+    public int getSpanFlags(Object what) {
+        int count = mSpanCount;
+        Object[] spans = mSpans;
+        int[] data = mSpanData;
+
+        for (int i = count - 1; i >= 0; i--) {
+            if (spans[i] == what) {
+                return data[i * COLUMNS + FLAGS];
+            }
+        }
+
+        return 0;
+    }
+
+    @UnsupportedAppUsage
+    public <T> T[] getSpans(int queryStart, int queryEnd, Class<T> kind) {
+        int count = 0;
+
+        int spanCount = mSpanCount;
+        Object[] spans = mSpans;
+        int[] data = mSpanData;
+        Object[] ret = null;
+        Object ret1 = null;
+
+        for (int i = 0; i < spanCount; i++) {
+            int spanStart = data[i * COLUMNS + START];
+            int spanEnd = data[i * COLUMNS + END];
+
+            if (spanStart > queryEnd) {
+                continue;
+            }
+            if (spanEnd < queryStart) {
+                continue;
+            }
+
+            if (spanStart != spanEnd && queryStart != queryEnd) {
+                if (spanStart == queryEnd) {
+                    continue;
+                }
+                if (spanEnd == queryStart) {
+                    continue;
+                }
+            }
+
+            // verify span class as late as possible, since it is expensive
+            if (kind != null && kind != Object.class && !kind.isInstance(spans[i])) {
+                continue;
+            }
+
+            if (count == 0) {
+                ret1 = spans[i];
+                count++;
+            } else {
+                if (count == 1) {
+                    ret = (Object[]) Array.newInstance(kind, spanCount - i + 1);
+                    ret[0] = ret1;
+                }
+
+                int prio = data[i * COLUMNS + FLAGS] & Spanned.SPAN_PRIORITY;
+                if (prio != 0) {
+                    int j;
+
+                    for (j = 0; j < count; j++) {
+                        int p = getSpanFlags(ret[j]) & Spanned.SPAN_PRIORITY;
+
+                        if (prio > p) {
+                            break;
+                        }
+                    }
+
+                    System.arraycopy(ret, j, ret, j + 1, count - j);
+                    ret[j] = spans[i];
+                    count++;
+                } else {
+                    ret[count++] = spans[i];
+                }
+            }
+        }
+
+        if (count == 0) {
+            return (T[]) ArrayUtils.emptyArray(kind);
+        }
+        if (count == 1) {
+            ret = (Object[]) Array.newInstance(kind, 1);
+            ret[0] = ret1;
+            return (T[]) ret;
+        }
+        if (count == ret.length) {
+            return (T[]) ret;
+        }
+
+        Object[] nret = (Object[]) Array.newInstance(kind, count);
+        System.arraycopy(ret, 0, nret, 0, count);
+        return (T[]) nret;
+    }
+
+    @UnsupportedAppUsage
+    public int nextSpanTransition(int start, int limit, Class kind) {
+        int count = mSpanCount;
+        Object[] spans = mSpans;
+        int[] data = mSpanData;
+
+        if (kind == null) {
+            kind = Object.class;
+        }
+
+        for (int i = 0; i < count; i++) {
+            int st = data[i * COLUMNS + START];
+            int en = data[i * COLUMNS + END];
+
+            if (st > start && st < limit && kind.isInstance(spans[i])) {
+                limit = st;
+            }
+            if (en > start && en < limit && kind.isInstance(spans[i])) {
+                limit = en;
+            }
+        }
+
+        return limit;
+    }
+
+    @UnsupportedAppUsage
+    private void sendSpanAdded(Object what, int start, int end) {
+        SpanWatcher[] recip = getSpans(start, end, SpanWatcher.class);
+        int n = recip.length;
+
+        for (int i = 0; i < n; i++) {
+            recip[i].onSpanAdded((Spannable) this, what, start, end);
+        }
+    }
+
+    @UnsupportedAppUsage
+    private void sendSpanRemoved(Object what, int start, int end) {
+        SpanWatcher[] recip = getSpans(start, end, SpanWatcher.class);
+        int n = recip.length;
+
+        for (int i = 0; i < n; i++) {
+            recip[i].onSpanRemoved((Spannable) this, what, start, end);
+        }
+    }
+
+    @UnsupportedAppUsage
+    private void sendSpanChanged(Object what, int s, int e, int st, int en) {
+        SpanWatcher[] recip = getSpans(Math.min(s, st), Math.max(e, en),
+                                       SpanWatcher.class);
+        int n = recip.length;
+
+        for (int i = 0; i < n; i++) {
+            recip[i].onSpanChanged((Spannable) this, what, s, e, st, en);
+        }
+    }
+
+    @UnsupportedAppUsage
+    private static String region(int start, int end) {
+        return "(" + start + " ... " + end + ")";
+    }
+
+    @UnsupportedAppUsage
+    private void checkRange(final String operation, int start, int end) {
+        if (end < start) {
+            throw new IndexOutOfBoundsException(operation + " "
+                                                + region(start, end)
+                                                + " has end before start");
+        }
+
+        int len = length();
+
+        if (start > len || end > len) {
+            throw new IndexOutOfBoundsException(operation + " "
+                                                + region(start, end)
+                                                + " ends beyond length " + len);
+        }
+
+        if (start < 0 || end < 0) {
+            throw new IndexOutOfBoundsException(operation + " "
+                                                + region(start, end)
+                                                + " starts before 0");
+        }
+    }
+
+    // Same as SpannableStringBuilder
+    @Override
+    public boolean equals(Object o) {
+        if (o instanceof Spanned
+                && toString().equals(o.toString())) {
+            final Spanned other = (Spanned) o;
+            // Check span data
+            final Object[] otherSpans = other.getSpans(0, other.length(), Object.class);
+            final Object[] thisSpans = getSpans(0, length(), Object.class);
+            if (mSpanCount == otherSpans.length) {
+                for (int i = 0; i < mSpanCount; ++i) {
+                    final Object thisSpan = thisSpans[i];
+                    final Object otherSpan = otherSpans[i];
+                    if (thisSpan == this) {
+                        if (other != otherSpan
+                                || getSpanStart(thisSpan) != other.getSpanStart(otherSpan)
+                                || getSpanEnd(thisSpan) != other.getSpanEnd(otherSpan)
+                                || getSpanFlags(thisSpan) != other.getSpanFlags(otherSpan)) {
+                            return false;
+                        }
+                    } else if (!thisSpan.equals(otherSpan)
+                            || getSpanStart(thisSpan) != other.getSpanStart(otherSpan)
+                            || getSpanEnd(thisSpan) != other.getSpanEnd(otherSpan)
+                            || getSpanFlags(thisSpan) != other.getSpanFlags(otherSpan)) {
+                        return false;
+                    }
+                }
+                return true;
+            }
+        }
+        return false;
+    }
+
+    // Same as SpannableStringBuilder
+    @Override
+    public int hashCode() {
+        int hash = toString().hashCode();
+        hash = hash * 31 + mSpanCount;
+        for (int i = 0; i < mSpanCount; ++i) {
+            Object span = mSpans[i];
+            if (span != this) {
+                hash = hash * 31 + span.hashCode();
+            }
+            hash = hash * 31 + getSpanStart(span);
+            hash = hash * 31 + getSpanEnd(span);
+            hash = hash * 31 + getSpanFlags(span);
+        }
+        return hash;
+    }
+
+    /**
+     * Following two unused methods are left since these are listed in hidden api list.
+     *
+     * Due to backward compatibility reasons, we copy even NoCopySpan by default
+     */
+    @UnsupportedAppUsage
+    private void copySpans(Spanned src, int start, int end) {
+        copySpans(src, start, end, false);
+    }
+
+    @UnsupportedAppUsage
+    private void copySpans(SpannableStringInternal src, int start, int end) {
+        copySpans(src, start, end, false);
+    }
+
+
+
+    @UnsupportedAppUsage
+    private String mText;
+    @UnsupportedAppUsage
+    private Object[] mSpans;
+    @UnsupportedAppUsage
+    private int[] mSpanData;
+    @UnsupportedAppUsage
+    private int mSpanCount;
+
+    @UnsupportedAppUsage
+    /* package */ static final Object[] EMPTY = new Object[0];
+
+    @UnsupportedAppUsage
+    private static final int START = 0;
+    @UnsupportedAppUsage
+    private static final int END = 1;
+    @UnsupportedAppUsage
+    private static final int FLAGS = 2;
+    @UnsupportedAppUsage
+    private static final int COLUMNS = 3;
+}
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/Spanned.java b/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/Spanned.java
new file mode 100644
index 0000000..998b8b0
--- /dev/null
+++ b/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/Spanned.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text;
+
+/**
+ * This is the interface for text that has markup objects attached to
+ * ranges of it.  Not all text classes have mutable markup or text;
+ * see {@link Spannable} for mutable markup and {@link Editable} for
+ * mutable text.
+ */
+public interface Spanned extends CharSequence {
+    /**
+     * Bitmask of bits that are relevant for controlling point/mark behavior
+     * of spans.
+     *
+     * MARK and POINT are conceptually located <i>between</i> two adjacent characters.
+     * A MARK is "attached" to the character before, while a POINT will stick to the character
+     * after. The insertion cursor is conceptually located between the MARK and the POINT.
+     *
+     * As a result, inserting a new character between a MARK and a POINT will leave the MARK
+     * unchanged, while the POINT will be shifted, now located after the inserted character and
+     * still glued to the same character after it.
+     *
+     * Depending on whether the insertion happens at the beginning or the end of a span, the span
+     * will hence be expanded to <i>include</i> the new character (when the span is using a MARK at
+     * its beginning or a POINT at its end) or it will be <i>excluded</i>.
+     *
+     * Note that <i>before</i> and <i>after</i> here refer to offsets in the String, which are
+     * independent from the visual representation of the text (left-to-right or right-to-left).
+     */
+    int SPAN_POINT_MARK_MASK = 0x33;
+
+    /**
+     * 0-length spans with type SPAN_MARK_MARK behave like text marks:
+     * they remain at their original offset when text is inserted
+     * at that offset. Conceptually, the text is added after the mark.
+     */
+    int SPAN_MARK_MARK =   0x11;
+
+    /**
+     * SPAN_MARK_POINT is a synonym for {@link #SPAN_INCLUSIVE_INCLUSIVE}.
+     */
+    int SPAN_MARK_POINT =  0x12;
+
+    /**
+     * SPAN_POINT_MARK is a synonym for {@link #SPAN_EXCLUSIVE_EXCLUSIVE}.
+     */
+    int SPAN_POINT_MARK =  0x21;
+
+    /**
+     * 0-length spans with type SPAN_POINT_POINT behave like cursors:
+     * they are pushed forward by the length of the insertion when text
+     * is inserted at their offset.
+     * The text is conceptually inserted before the point.
+     */
+    int SPAN_POINT_POINT = 0x22;
+
+    /**
+     * SPAN_PARAGRAPH behaves like SPAN_INCLUSIVE_EXCLUSIVE
+     * (SPAN_MARK_MARK), except that if either end of the span is
+     * at the end of the buffer, that end behaves like _POINT
+     * instead (so SPAN_INCLUSIVE_INCLUSIVE if it starts in the
+     * middle and ends at the end, or SPAN_EXCLUSIVE_INCLUSIVE
+     * if it both starts and ends at the end).
+     * <p>
+     * Its endpoints must be the start or end of the buffer or
+     * immediately after a \n character, and if the \n
+     * that anchors it is deleted, the endpoint is pulled to the
+     * next \n that follows in the buffer (or to the end of
+     * the buffer). If a span with SPAN_PARAGRAPH flag is pasted
+     * into another text and the paragraph boundary constraint
+     * is not satisfied, the span is discarded.
+     */
+    int SPAN_PARAGRAPH = 0x33;
+
+    /**
+     * Non-0-length spans of type SPAN_INCLUSIVE_EXCLUSIVE expand
+     * to include text inserted at their starting point but not at their
+     * ending point.  When 0-length, they behave like marks.
+     */
+    int SPAN_INCLUSIVE_EXCLUSIVE = SPAN_MARK_MARK;
+
+    /**
+     * Spans of type SPAN_INCLUSIVE_INCLUSIVE expand
+     * to include text inserted at either their starting or ending point.
+     */
+    int SPAN_INCLUSIVE_INCLUSIVE = SPAN_MARK_POINT;
+
+    /**
+     * Spans of type SPAN_EXCLUSIVE_EXCLUSIVE do not expand
+     * to include text inserted at either their starting or ending point.
+     * They can never have a length of 0 and are automatically removed
+     * from the buffer if all the text they cover is removed.
+     */
+    int SPAN_EXCLUSIVE_EXCLUSIVE = SPAN_POINT_MARK;
+
+    /**
+     * Non-0-length spans of type SPAN_EXCLUSIVE_INCLUSIVE expand
+     * to include text inserted at their ending point but not at their
+     * starting point.  When 0-length, they behave like points.
+     */
+    int SPAN_EXCLUSIVE_INCLUSIVE = SPAN_POINT_POINT;
+
+    /**
+     * This flag is set on spans that are being used to apply temporary
+     * styling information on the composing text of an input method, so that
+     * they can be found and removed when the composing text is being
+     * replaced.
+     */
+    int SPAN_COMPOSING = 0x100;
+
+    /**
+     * This flag will be set for intermediate span changes, meaning there
+     * is guaranteed to be another change following it.  Typically it is
+     * used for {@link Selection} which automatically uses this with the first
+     * offset it sets when updating the selection.
+     */
+    int SPAN_INTERMEDIATE = 0x200;
+
+    /**
+     * The bits numbered SPAN_USER_SHIFT and above are available
+     * for callers to use to store scalar data associated with their
+     * span object.
+     */
+    int SPAN_USER_SHIFT = 24;
+
+    /**
+     * The bits specified by the SPAN_USER bitfield are available
+     * for callers to use to store scalar data associated with their
+     * span object.
+     */
+    int SPAN_USER = 0xFFFFFFFF << SPAN_USER_SHIFT;
+
+    /**
+     * The bits numbered just above SPAN_PRIORITY_SHIFT determine the order
+     * of change notifications -- higher numbers go first.  You probably
+     * don't need to set this; it is used so that when text changes, the
+     * text layout gets the chance to update itself before any other
+     * callbacks can inquire about the layout of the text.
+     */
+    int SPAN_PRIORITY_SHIFT = 16;
+
+    /**
+     * The bits specified by the SPAN_PRIORITY bitmap determine the order
+     * of change notifications -- higher numbers go first.  You probably
+     * don't need to set this; it is used so that when text changes, the
+     * text layout gets the chance to update itself before any other
+     * callbacks can inquire about the layout of the text.
+     */
+    int SPAN_PRIORITY = 0xFF << SPAN_PRIORITY_SHIFT;
+
+    /**
+     * Return an array of the markup objects attached to the specified
+     * slice of this CharSequence and whose type is the specified type
+     * or a subclass of it.  Specify Object.class for the type if you
+     * want all the objects regardless of type.
+     */
+    <T> T[] getSpans(int start, int end, Class<T> type);
+
+    /**
+     * Return the beginning of the range of text to which the specified
+     * markup object is attached, or -1 if the object is not attached.
+     */
+    int getSpanStart(Object tag);
+
+    /**
+     * Return the end of the range of text to which the specified
+     * markup object is attached, or -1 if the object is not attached.
+     */
+    int getSpanEnd(Object tag);
+
+    /**
+     * Return the flags that were specified when {@link Spannable#setSpan} was
+     * used to attach the specified markup object, or 0 if the specified
+     * object has not been attached.
+     */
+    int getSpanFlags(Object tag);
+
+    /**
+     * Return the first offset greater than <code>start</code> where a markup
+     * object of class <code>type</code> begins or ends, or <code>limit</code>
+     * if there are no starts or ends greater than <code>start</code> but less
+     * than <code>limit</code>. Specify <code>null</code> or Object.class for
+     * the type if you want every transition regardless of type.
+     */
+    int nextSpanTransition(int start, int limit, Class type);
+}
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/TextDirectionHeuristic.java b/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/TextDirectionHeuristic.java
new file mode 100644
index 0000000..88a35c1
--- /dev/null
+++ b/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/TextDirectionHeuristic.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text;
+
+/**
+ * Interface for objects that use a heuristic for guessing at the paragraph direction
+ * by examining text.
+ */
+public interface TextDirectionHeuristic {
+    /**
+     * Guess if a chars array is in the RTL direction or not.
+     *
+     * @param array the char array.
+     * @param start start index, inclusive.
+     * @param count the length to check, must not be negative and not greater than
+     *          {@code array.length - start}.
+     * @return true if all chars in the range are to be considered in a RTL direction,
+     *          false otherwise.
+     */
+    boolean isRtl(char[] array, int start, int count);
+
+    /**
+     * Guess if a {@code CharSequence} is in the RTL direction or not.
+     *
+     * @param cs the CharSequence.
+     * @param start start index, inclusive.
+     * @param count the length to check, must not be negative and not greater than
+     *            {@code CharSequence.length() - start}.
+     * @return true if all chars in the range are to be considered in a RTL direction,
+     *          false otherwise.
+     */
+    boolean isRtl(CharSequence cs, int start, int count);
+}
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/TextDirectionHeuristics.java b/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/TextDirectionHeuristics.java
new file mode 100644
index 0000000..4feab0d
--- /dev/null
+++ b/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/TextDirectionHeuristics.java
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text;
+
+
+import android.view.View;
+
+import java.nio.CharBuffer;
+
+/**
+ * Some objects that implement {@link TextDirectionHeuristic}. Use these with
+ * the {@link BidiFormatter#unicodeWrap unicodeWrap()} methods in {@link BidiFormatter}.
+ * Also notice that these direction heuristics correspond to the same types of constants
+ * provided in the {@link android.view.View} class for {@link android.view.View#setTextDirection
+ * setTextDirection()}, such as {@link android.view.View#TEXT_DIRECTION_RTL}.
+ * <p>To support versions lower than {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2},
+ * you can use the support library's {@link android.support.v4.text.TextDirectionHeuristicsCompat}
+ * class.
+ */
+public class TextDirectionHeuristics {
+
+    /**
+     * Always decides that the direction is left to right.
+     */
+    public static final TextDirectionHeuristic LTR =
+            new TextDirectionHeuristicInternal(null /* no algorithm */, false);
+
+    /**
+     * Always decides that the direction is right to left.
+     */
+    public static final TextDirectionHeuristic RTL =
+            new TextDirectionHeuristicInternal(null /* no algorithm */, true);
+
+    /**
+     * Determines the direction based on the first strong directional character, including bidi
+     * format chars, falling back to left to right if it finds none. This is the default behavior
+     * of the Unicode Bidirectional Algorithm.
+     */
+    public static final TextDirectionHeuristic FIRSTSTRONG_LTR =
+            new TextDirectionHeuristicInternal(FirstStrong.INSTANCE, false);
+
+    /**
+     * Determines the direction based on the first strong directional character, including bidi
+     * format chars, falling back to right to left if it finds none. This is similar to the default
+     * behavior of the Unicode Bidirectional Algorithm, just with different fallback behavior.
+     */
+    public static final TextDirectionHeuristic FIRSTSTRONG_RTL =
+            new TextDirectionHeuristicInternal(FirstStrong.INSTANCE, true);
+
+    /**
+     * If the text contains any strong right to left non-format character, determines that the
+     * direction is right to left, falling back to left to right if it finds none.
+     */
+    public static final TextDirectionHeuristic ANYRTL_LTR =
+            new TextDirectionHeuristicInternal(AnyStrong.INSTANCE_RTL, false);
+
+    /**
+     * Force the paragraph direction to the Locale direction. Falls back to left to right.
+     */
+    public static final TextDirectionHeuristic LOCALE = TextDirectionHeuristicLocale.INSTANCE;
+
+    /**
+     * State constants for taking care about true / false / unknown
+     */
+    private static final int STATE_TRUE = 0;
+    private static final int STATE_FALSE = 1;
+    private static final int STATE_UNKNOWN = 2;
+
+    /* Returns STATE_TRUE for strong RTL characters, STATE_FALSE for strong LTR characters, and
+     * STATE_UNKNOWN for everything else.
+     */
+    private static int isRtlCodePoint(int codePoint) {
+        switch (Character.getDirectionality(codePoint)) {
+            case Character.DIRECTIONALITY_LEFT_TO_RIGHT:
+                return STATE_FALSE;
+            case Character.DIRECTIONALITY_RIGHT_TO_LEFT:
+            case Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC:
+                return STATE_TRUE;
+            case Character.DIRECTIONALITY_UNDEFINED:
+                // Unassigned characters still have bidi direction, defined at:
+                // http://www.unicode.org/Public/UCD/latest/ucd/extracted/DerivedBidiClass.txt
+
+                if ((0x0590 <= codePoint && codePoint <= 0x08FF)
+                        || (0xFB1D <= codePoint && codePoint <= 0xFDCF)
+                        || (0xFDF0 <= codePoint && codePoint <= 0xFDFF)
+                        || (0xFE70 <= codePoint && codePoint <= 0xFEFF)
+                        || (0x10800 <= codePoint && codePoint <= 0x10FFF)
+                        || (0x1E800 <= codePoint && codePoint <= 0x1EFFF)) {
+                    // Unassigned RTL character
+                    return STATE_TRUE;
+                } else if (
+                    // Potentially-unassigned Default_Ignorable. Ranges are from unassigned
+                    // characters that have Unicode property Other_Default_Ignorable_Code_Point
+                    // plus some enlargening to cover bidi isolates and simplify checks.
+                        (0x2065 <= codePoint && codePoint <= 0x2069)
+                                || (0xFFF0 <= codePoint && codePoint <= 0xFFF8)
+                                || (0xE0000 <= codePoint && codePoint <= 0xE0FFF)
+                                // Non-character
+                                || (0xFDD0 <= codePoint && codePoint <= 0xFDEF)
+                                || ((codePoint & 0xFFFE) == 0xFFFE)
+                                // Currency symbol
+                                || (0x20A0 <= codePoint && codePoint <= 0x20CF)
+                                // Unpaired surrogate
+                                || (0xD800 <= codePoint && codePoint <= 0xDFFF)) {
+                    return STATE_UNKNOWN;
+                } else {
+                    // Unassigned LTR character
+                    return STATE_FALSE;
+                }
+            default:
+                return STATE_UNKNOWN;
+        }
+    }
+
+    /**
+     * Computes the text direction based on an algorithm.  Subclasses implement
+     * {@link #defaultIsRtl} to handle cases where the algorithm cannot determine the
+     * direction from the text alone.
+     */
+    private abstract static class TextDirectionHeuristicImpl implements TextDirectionHeuristic {
+        private final TextDirectionAlgorithm mAlgorithm;
+
+        TextDirectionHeuristicImpl(TextDirectionAlgorithm algorithm) {
+            mAlgorithm = algorithm;
+        }
+
+        /**
+         * Return true if the default text direction is rtl.
+         */
+        protected abstract boolean defaultIsRtl();
+
+        @Override
+        public boolean isRtl(char[] array, int start, int count) {
+            return isRtl(CharBuffer.wrap(array), start, count);
+        }
+
+        @Override
+        public boolean isRtl(CharSequence cs, int start, int count) {
+            if (cs == null || start < 0 || count < 0 || cs.length() - count < start) {
+                throw new IllegalArgumentException();
+            }
+            if (mAlgorithm == null) {
+                return defaultIsRtl();
+            }
+            return doCheck(cs, start, count);
+        }
+
+        private boolean doCheck(CharSequence cs, int start, int count) {
+            switch (mAlgorithm.checkRtl(cs, start, count)) {
+                case STATE_TRUE:
+                    return true;
+                case STATE_FALSE:
+                    return false;
+                default:
+                    return defaultIsRtl();
+            }
+        }
+    }
+
+    private static class TextDirectionHeuristicInternal extends TextDirectionHeuristicImpl {
+        private final boolean mDefaultIsRtl;
+
+        private TextDirectionHeuristicInternal(TextDirectionAlgorithm algorithm,
+                boolean defaultIsRtl) {
+            super(algorithm);
+            mDefaultIsRtl = defaultIsRtl;
+        }
+
+        @Override
+        protected boolean defaultIsRtl() {
+            return mDefaultIsRtl;
+        }
+    }
+
+    /**
+     * Interface for an algorithm to guess the direction of a paragraph of text.
+     */
+    private interface TextDirectionAlgorithm {
+        /**
+         * Returns whether the range of text is RTL according to the algorithm.
+         */
+        int checkRtl(CharSequence cs, int start, int count);
+    }
+
+    /**
+     * Algorithm that uses the first strong directional character to determine the paragraph
+     * direction. This is the standard Unicode Bidirectional Algorithm (steps P2 and P3), with the
+     * exception that if no strong character is found, UNKNOWN is returned.
+     */
+    private static class FirstStrong implements TextDirectionAlgorithm {
+        @Override
+        public int checkRtl(CharSequence cs, int start, int count) {
+            int result = STATE_UNKNOWN;
+            int openIsolateCount = 0;
+            for (int cp, i = start, end = start + count;
+                    i < end && result == STATE_UNKNOWN;
+                    i += Character.charCount(cp)) {
+                cp = Character.codePointAt(cs, i);
+                if (0x2066 <= cp && cp <= 0x2068) { // Opening isolates
+                    openIsolateCount += 1;
+                } else if (cp == 0x2069) { // POP DIRECTIONAL ISOLATE (PDI)
+                    if (openIsolateCount > 0) openIsolateCount -= 1;
+                } else if (openIsolateCount == 0) {
+                    // Only consider the characters outside isolate pairs
+                    result = isRtlCodePoint(cp);
+                }
+            }
+            return result;
+        }
+
+        private FirstStrong() {
+        }
+
+        public static final FirstStrong INSTANCE = new FirstStrong();
+    }
+
+    /**
+     * Algorithm that uses the presence of any strong directional character of the type indicated
+     * in the constructor parameter to determine the direction of text.
+     *
+     * Characters inside isolate pairs are skipped.
+     */
+    private static class AnyStrong implements TextDirectionAlgorithm {
+        private final boolean mLookForRtl;
+
+        @Override
+        public int checkRtl(CharSequence cs, int start, int count) {
+            boolean haveUnlookedFor = false;
+            int openIsolateCount = 0;
+            for (int cp, i = start, end = start + count; i < end; i += Character.charCount(cp)) {
+                cp = Character.codePointAt(cs, i);
+                if (0x2066 <= cp && cp <= 0x2068) { // Opening isolates
+                    openIsolateCount += 1;
+                } else if (cp == 0x2069) { // POP DIRECTIONAL ISOLATE (PDI)
+                    if (openIsolateCount > 0) openIsolateCount -= 1;
+                } else if (openIsolateCount == 0) {
+                    // Only consider the characters outside isolate pairs
+                    switch (isRtlCodePoint(cp)) {
+                        case STATE_TRUE:
+                            if (mLookForRtl) {
+                                return STATE_TRUE;
+                            }
+                            haveUnlookedFor = true;
+                            break;
+                        case STATE_FALSE:
+                            if (!mLookForRtl) {
+                                return STATE_FALSE;
+                            }
+                            haveUnlookedFor = true;
+                            break;
+                        default:
+                            break;
+                    }
+                }
+            }
+            if (haveUnlookedFor) {
+                return mLookForRtl ? STATE_FALSE : STATE_TRUE;
+            }
+            return STATE_UNKNOWN;
+        }
+
+        private AnyStrong(boolean lookForRtl) {
+            this.mLookForRtl = lookForRtl;
+        }
+
+        public static final AnyStrong INSTANCE_RTL = new AnyStrong(true);
+        public static final AnyStrong INSTANCE_LTR = new AnyStrong(false);
+    }
+
+    /**
+     * Algorithm that uses the Locale direction to force the direction of a paragraph.
+     */
+    private static class TextDirectionHeuristicLocale extends TextDirectionHeuristicImpl {
+
+        TextDirectionHeuristicLocale() {
+            super(null);
+        }
+
+        @Override
+        protected boolean defaultIsRtl() {
+            // TODO: fix me!
+            final int dir =
+                    View.LAYOUT_DIRECTION_LTR; // TextUtils.getLayoutDirectionFromLocale(java
+            // .util.Locale.getDefault());
+            return (dir == View.LAYOUT_DIRECTION_RTL);
+        }
+
+        public static final TextDirectionHeuristicLocale INSTANCE =
+                new TextDirectionHeuristicLocale();
+    }
+}
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/TextUtils.java b/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/TextUtils.java
new file mode 100644
index 0000000..33f69ba
--- /dev/null
+++ b/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/TextUtils.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text;
+
+import android.compat.annotation.UnsupportedAppUsage;
+
+import com.android.internal.util.ArrayUtils;
+
+/**
+ * TextUtils.
+ */
+public class TextUtils {
+    private static final String ELLIPSIS_NORMAL = "\u2026"; // HORIZONTAL ELLIPSIS (…)
+    private static final String ELLIPSIS_TWO_DOTS = "\u2025"; // TWO DOT LEADER (‥)
+
+    /**
+     * getChars
+     */
+    public static void getChars(CharSequence s, int start, int end,
+            char[] dest, int destoff) {
+        Class<? extends CharSequence> c = s.getClass();
+        if (c == String.class) {
+            ((String) s).getChars(start, end, dest, destoff);
+        } else if (c == StringBuffer.class) {
+            ((StringBuffer) s).getChars(start, end, dest, destoff);
+        } else if (c == StringBuilder.class) {
+            ((StringBuilder) s).getChars(start, end, dest, destoff);
+        } else if (s instanceof GetChars) {
+            ((GetChars) s).getChars(start, end, dest, destoff);
+        } else {
+            for (int i = start; i < end; i++) {
+                dest[destoff++] = s.charAt(i);
+            }
+        }
+    }
+
+    /**
+     * ellipsize.
+     */
+    public static CharSequence ellipsize(CharSequence text,
+            TextPaint p,
+            float avail, TruncateAt where) {
+        return ellipsize(text, p, avail, where, false, null);
+    }
+
+    /**
+     * ellipsize.
+     */
+    public static CharSequence ellipsize(CharSequence text,
+            TextPaint paint,
+            float avail, TruncateAt where,
+            boolean preserveLength,
+            EllipsizeCallback callback) {
+        return ellipsize(text, paint, avail, where, preserveLength, callback,
+                TextDirectionHeuristics.FIRSTSTRONG_LTR,
+                getEllipsisString(where));
+    }
+
+    /**
+     * ellipsize
+     */
+    public static CharSequence ellipsize(
+            CharSequence text,
+            TextPaint paint,
+            float avail, TruncateAt where,
+            boolean preserveLength,
+            EllipsizeCallback callback,
+            TextDirectionHeuristic textDir, String ellipsis) {
+        // TODO: incorrect
+        return text;
+    }
+
+    /**
+     * getEllipsisString
+     */
+    public static String getEllipsisString(TextUtils.TruncateAt method) {
+        return (method == TextUtils.TruncateAt.END_SMALL) ? ELLIPSIS_TWO_DOTS : ELLIPSIS_NORMAL;
+    }
+
+    /**
+     * obtain
+     */
+    static char[] obtain(int len) {
+        return ArrayUtils.newUnpaddedCharArray(len);
+    }
+
+    /**
+     * recycle
+     */
+    static void recycle(char[] temp) {
+    }
+
+    /**
+     * couldAffectRtl
+     */
+    static boolean couldAffectRtl(char c) {
+        return (0x0590 <= c && c <= 0x08FF) ||  // RTL scripts
+                c == 0x200E ||  // Bidi format character
+                c == 0x200F ||  // Bidi format character
+                (0x202A <= c && c <= 0x202E) ||  // Bidi format characters
+                (0x2066 <= c && c <= 0x2069) ||  // Bidi format characters
+                (0xD800 <= c && c <= 0xDFFF) ||  // Surrogate pairs
+                (0xFB1D <= c && c <= 0xFDFF) ||  // Hebrew and Arabic presentation forms
+                (0xFE70 <= c && c <= 0xFEFE);  // Arabic presentation forms
+    }
+
+    /**
+     * TruncateAt.
+     */
+    public enum TruncateAt {
+        START,
+        MIDDLE,
+        END,
+        MARQUEE,
+        @UnsupportedAppUsage
+        END_SMALL
+    }
+
+    /**
+     * EllipsizeCallback
+     */
+    public interface EllipsizeCallback {
+        /**
+         * This method is called to report that the specified region of
+         * text was ellipsized away by a call to {@link #ellipsize}.
+         */
+        void ellipsized(int start, int end);
+    }
+}
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/style/CharacterStyle.java b/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/style/CharacterStyle.java
new file mode 100644
index 0000000..19be4be8
--- /dev/null
+++ b/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/style/CharacterStyle.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text.style;
+
+import android.text.TextPaint;
+
+/**
+ * The classes that affect character-level text formatting extend this
+ * class.  Most extend its subclass {@link MetricAffectingSpan}, but simple
+ * ones may just implement {@link UpdateAppearance}.
+ */
+public abstract class CharacterStyle {
+    abstract void updateDrawState(TextPaint tp);
+
+    /**
+     * A given CharacterStyle can only applied to a single region of a given
+     * Spanned.  If you need to attach the same CharacterStyle to multiple
+     * regions, you can use this method to wrap it with a new object that
+     * will have the same effect but be a distinct object so that it can
+     * also be attached without conflict.
+     */
+    public static CharacterStyle wrap(CharacterStyle cs) {
+        if (cs instanceof MetricAffectingSpan) {
+            return new MetricAffectingSpan.Passthrough((MetricAffectingSpan) cs);
+        } else {
+            return new Passthrough(cs);
+        }
+    }
+
+    /**
+     * Returns "this" for most CharacterStyles, but for CharacterStyles
+     * that were generated by {@link #wrap}, returns the underlying
+     * CharacterStyle.
+     */
+    public CharacterStyle getUnderlying() {
+        return this;
+    }
+
+    /**
+     * A Passthrough CharacterStyle is one that
+     * passes {@link #updateDrawState} calls through to the
+     * specified CharacterStyle while still being a distinct object,
+     * and is therefore able to be attached to the same Spannable
+     * to which the specified CharacterStyle is already attached.
+     */
+    private static class Passthrough extends CharacterStyle {
+        private CharacterStyle mStyle;
+
+        /**
+         * Creates a new Passthrough of the specfied CharacterStyle.
+         */
+        Passthrough(CharacterStyle cs) {
+            mStyle = cs;
+        }
+
+        /**
+         * Passes updateDrawState through to the underlying CharacterStyle.
+         */
+        @Override
+        public void updateDrawState(TextPaint tp) {
+            mStyle.updateDrawState(tp);
+        }
+
+        /**
+         * Returns the CharacterStyle underlying this one, or the one
+         * underlying it if it too is a Passthrough.
+         */
+        @Override
+        public CharacterStyle getUnderlying() {
+            return mStyle.getUnderlying();
+        }
+    }
+}
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/style/MetricAffectingSpan.java b/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/style/MetricAffectingSpan.java
new file mode 100644
index 0000000..61b7947
--- /dev/null
+++ b/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/style/MetricAffectingSpan.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text.style;
+
+import android.annotation.NonNull;
+import android.text.TextPaint;
+
+/**
+ * The classes that affect character-level text formatting in a way that
+ * changes the width or height of characters extend this class.
+ */
+public abstract class MetricAffectingSpan
+        extends CharacterStyle
+        implements UpdateLayout {
+
+    /**
+     * Classes that extend MetricAffectingSpan implement this method to update the text formatting
+     * in a way that can change the width or height of characters.
+     *
+     * @param textPaint the paint used for drawing the text
+     */
+    public abstract void updateMeasureState(@NonNull TextPaint textPaint);
+
+    /**
+     * Returns "this" for most MetricAffectingSpans, but for
+     * MetricAffectingSpans that were generated by {@link #wrap},
+     * returns the underlying MetricAffectingSpan.
+     */
+    @Override
+    public MetricAffectingSpan getUnderlying() {
+        return this;
+    }
+
+    /**
+     * A Passthrough MetricAffectingSpan is one that
+     * passes {@link #updateDrawState} and {@link #updateMeasureState}
+     * calls through to the specified MetricAffectingSpan
+     * while still being a distinct object,
+     * and is therefore able to be attached to the same Spannable
+     * to which the specified MetricAffectingSpan is already attached.
+     */
+    /* package */ static class Passthrough extends MetricAffectingSpan {
+        private MetricAffectingSpan mStyle;
+
+        /**
+         * Creates a new Passthrough of the specfied MetricAffectingSpan.
+         */
+        Passthrough(@NonNull MetricAffectingSpan cs) {
+            mStyle = cs;
+        }
+
+        /**
+         * Passes updateDrawState through to the underlying MetricAffectingSpan.
+         */
+        @Override
+        public void updateDrawState(@NonNull TextPaint tp) {
+            mStyle.updateDrawState(tp);
+        }
+
+        /**
+         * Passes updateMeasureState through to the underlying MetricAffectingSpan.
+         */
+        @Override
+        public void updateMeasureState(@NonNull TextPaint tp) {
+            mStyle.updateMeasureState(tp);
+        }
+
+        /**
+         * Returns the MetricAffectingSpan underlying this one, or the one
+         * underlying it if it too is a Passthrough.
+         */
+        @Override
+        public MetricAffectingSpan getUnderlying() {
+            return mStyle.getUnderlying();
+        }
+    }
+}
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/style/ParagraphStyle.java b/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/style/ParagraphStyle.java
new file mode 100644
index 0000000..c213f96
--- /dev/null
+++ b/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/style/ParagraphStyle.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text.style;
+
+/**
+ * The classes that affect paragraph-level text formatting implement
+ * this interface.
+ */
+public interface ParagraphStyle {
+}
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/style/ReplacementSpan.java b/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/style/ReplacementSpan.java
new file mode 100644
index 0000000..e1b9ee1
--- /dev/null
+++ b/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/style/ReplacementSpan.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text.style;
+
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.text.TextPaint;
+
+/**
+ * Replacement span.
+ */
+public abstract class ReplacementSpan extends MetricAffectingSpan {
+
+    /**
+     * Returns the width of the span. Extending classes can set the height of the span by updating
+     * attributes of {@link android.graphics.Paint.FontMetricsInt}. If the span covers the whole
+     * text, and the height is not set,
+     * {@link #draw(Canvas, CharSequence, int, int, float, int, int, int, Paint)} will not be
+     * called for the span.
+     *
+     * @param paint Paint instance.
+     * @param text Current text.
+     * @param start Start character index for span.
+     * @param end End character index for span.
+     * @param fm Font metrics, can be null.
+     * @return Width of the span.
+     */
+    public abstract int getSize(@NonNull Paint paint, CharSequence text,
+                        @IntRange(from = 0) int start, @IntRange(from = 0) int end,
+                        @Nullable Paint.FontMetricsInt fm);
+
+    /**
+     * Draws the span into the canvas.
+     *
+     * @param canvas Canvas into which the span should be rendered.
+     * @param text Current text.
+     * @param start Start character index for span.
+     * @param end End character index for span.
+     * @param x Edge of the replacement closest to the leading margin.
+     * @param top Top of the line.
+     * @param y Baseline.
+     * @param bottom Bottom of the line.
+     * @param paint Paint instance.
+     */
+    public abstract void draw(@NonNull Canvas canvas, CharSequence text,
+                              @IntRange(from = 0) int start, @IntRange(from = 0) int end, float x,
+                              int top, int y, int bottom, @NonNull Paint paint);
+
+    /**
+     * This method does nothing, since ReplacementSpans are measured
+     * explicitly instead of affecting Paint properties.
+     */
+    public void updateMeasureState(TextPaint p) { }
+
+    /**
+     * This method does nothing, since ReplacementSpans are drawn
+     * explicitly instead of affecting Paint properties.
+     */
+    public void updateDrawState(TextPaint ds) { }
+}
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/style/UpdateAppearance.java b/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/style/UpdateAppearance.java
new file mode 100644
index 0000000..7112347
--- /dev/null
+++ b/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/style/UpdateAppearance.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text.style;
+
+/**
+ * The classes that affect character-level text in a way that modifies their
+ * appearance when one is added or removed must implement this interface.  Note
+ * that if the class also impacts size or other metrics, it should instead
+ * implement {@link UpdateLayout}.
+ */
+public interface UpdateAppearance {
+}
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/style/UpdateLayout.java b/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/style/UpdateLayout.java
new file mode 100644
index 0000000..591075e
--- /dev/null
+++ b/ui/ui-desktop/android-emu/src/desktopMain/java/android/text/style/UpdateLayout.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text.style;
+
+/**
+ * The classes that affect character-level text formatting in a way that
+ * triggers a text layout update when one is added or removed must implement
+ * this interface.  This interface also includes {@link UpdateAppearance}
+ * since such a change implicitly also impacts the appearance.
+ */
+public interface UpdateLayout extends UpdateAppearance { }
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/java/android/util/LayoutDirection.java b/ui/ui-desktop/android-emu/src/desktopMain/java/android/util/LayoutDirection.java
new file mode 100644
index 0000000..5dfdad0
--- /dev/null
+++ b/ui/ui-desktop/android-emu/src/desktopMain/java/android/util/LayoutDirection.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.util;
+
+/**
+ * A class for defining layout directions. A layout direction can be left-to-right (LTR)
+ * or right-to-left (RTL). It can also be inherited (from a parent) or deduced from the default
+ * language script of a locale.
+ */
+public final class LayoutDirection {
+
+    // No instantiation
+    private LayoutDirection() {}
+
+    /**
+     * An undefined layout direction.
+     */
+    public static final int UNDEFINED = -1;
+
+    /**
+     * Horizontal layout direction is from Left to Right.
+     */
+    public static final int LTR = 0;
+
+    /**
+     * Horizontal layout direction is from Right to Left.
+     */
+    public static final int RTL = 1;
+
+    /**
+     * Horizontal layout direction is inherited.
+     */
+    public static final int INHERIT = 2;
+
+    /**
+     * Horizontal layout direction is deduced from the default language script for the locale.
+     */
+    public static final int LOCALE = 3;
+}
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/java/com/android/internal/util/ArrayUtils.java b/ui/ui-desktop/android-emu/src/desktopMain/java/com/android/internal/util/ArrayUtils.java
new file mode 100644
index 0000000..04fab97
--- /dev/null
+++ b/ui/ui-desktop/android-emu/src/desktopMain/java/com/android/internal/util/ArrayUtils.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.android.internal.util;
+
+import android.compat.annotation.UnsupportedAppUsage;
+
+import java.lang.reflect.Array;
+
+/**
+ * ArrayUtils contains some methods that you can call to find out
+ * the most efficient increments by which to grow arrays.
+ */
+public class ArrayUtils {
+    private ArrayUtils() { /* cannot be instantiated */ }
+
+    /**
+     * newUnpaddedObjectArray
+     */
+    public static Object[] newUnpaddedObjectArray(int minLen) {
+        return new Object[minLen];
+    }
+
+    /**
+     * newUnpaddedArray
+     */
+    @UnsupportedAppUsage
+    @SuppressWarnings("unchecked")
+    public static <T> T[] newUnpaddedArray(Class<T> clazz, int minLen) {
+        return (T[]) Array.newInstance(clazz, minLen);
+    }
+
+    /**
+     * newUnpaddedIntArray
+     */
+    public static int[] newUnpaddedIntArray(int minLen) {
+        return new int[minLen];
+    }
+
+    /**
+     * newUnpaddedLongArray
+     */
+    public static long[] newUnpaddedLongArray(int minLen) {
+        return new long[minLen];
+    }
+
+    /**
+     * newUnpaddedFloatArray
+     */
+    public static float[] newUnpaddedFloatArray(int minLen) {
+        return new float[minLen];
+    }
+
+    /**
+     * newUnpaddedBooleanArray
+     */
+    public static boolean[] newUnpaddedBooleanArray(int minLen) {
+        return new boolean[minLen];
+    }
+
+    /**
+     * newUnpaddedCharArray
+     */
+    public static char[] newUnpaddedCharArray(int minLen) {
+        return new char[minLen];
+    }
+
+    /**
+     * emptyArray
+     */
+    public static <T> T[] emptyArray(Class<T> kind) {
+        return (T[]) Array.newInstance(kind, 0);
+    }
+}
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/java/com/android/internal/util/GrowingArrayUtils.java b/ui/ui-desktop/android-emu/src/desktopMain/java/com/android/internal/util/GrowingArrayUtils.java
new file mode 100644
index 0000000..ffe6de7
--- /dev/null
+++ b/ui/ui-desktop/android-emu/src/desktopMain/java/com/android/internal/util/GrowingArrayUtils.java
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.android.internal.util;
+
+import android.compat.annotation.UnsupportedAppUsage;
+
+/**
+ * A helper class that aims to provide comparable growth performance to ArrayList, but on primitive
+ * arrays. Common array operations are implemented for efficient use in dynamic containers.
+ *
+ * All methods in this class assume that the length of an array is equivalent to its capacity and
+ * NOT the number of elements in the array. The current size of the array is always passed in as a
+ * parameter.
+ *
+ */
+public final class GrowingArrayUtils {
+
+    /**
+     * Appends an element to the end of the array, growing the array if there is no more room.
+     * @param array The array to which to append the element. This must NOT be null.
+     * @param currentSize The number of elements in the array. Must be less than or equal to
+     *                    array.length.
+     * @param element The element to append.
+     * @return the array to which the element was appended. This may be different than the given
+     *         array.
+     */
+    @UnsupportedAppUsage
+    public static <T> T[] append(T[] array, int currentSize, T element) {
+        assert currentSize <= array.length;
+
+        if (currentSize + 1 > array.length) {
+            @SuppressWarnings("unchecked")
+            T[] newArray = ArrayUtils.newUnpaddedArray(
+                    (Class<T>) array.getClass().getComponentType(), growSize(currentSize));
+            System.arraycopy(array, 0, newArray, 0, currentSize);
+            array = newArray;
+        }
+        array[currentSize] = element;
+        return array;
+    }
+
+    /**
+     * Primitive int version of {@link #append(Object[], int, Object)}.
+     */
+    @UnsupportedAppUsage
+    public static int[] append(int[] array, int currentSize, int element) {
+        assert currentSize <= array.length;
+
+        if (currentSize + 1 > array.length) {
+            int[] newArray = ArrayUtils.newUnpaddedIntArray(growSize(currentSize));
+            System.arraycopy(array, 0, newArray, 0, currentSize);
+            array = newArray;
+        }
+        array[currentSize] = element;
+        return array;
+    }
+
+    /**
+     * Primitive long version of {@link #append(Object[], int, Object)}.
+     */
+    public static long[] append(long[] array, int currentSize, long element) {
+        assert currentSize <= array.length;
+
+        if (currentSize + 1 > array.length) {
+            long[] newArray = ArrayUtils.newUnpaddedLongArray(growSize(currentSize));
+            System.arraycopy(array, 0, newArray, 0, currentSize);
+            array = newArray;
+        }
+        array[currentSize] = element;
+        return array;
+    }
+
+    /**
+     * Primitive boolean version of {@link #append(Object[], int, Object)}.
+     */
+    public static boolean[] append(boolean[] array, int currentSize, boolean element) {
+        assert currentSize <= array.length;
+
+        if (currentSize + 1 > array.length) {
+            boolean[] newArray = ArrayUtils.newUnpaddedBooleanArray(growSize(currentSize));
+            System.arraycopy(array, 0, newArray, 0, currentSize);
+            array = newArray;
+        }
+        array[currentSize] = element;
+        return array;
+    }
+
+    /**
+     * Primitive float version of {@link #append(Object[], int, Object)}.
+     */
+    public static float[] append(float[] array, int currentSize, float element) {
+        assert currentSize <= array.length;
+
+        if (currentSize + 1 > array.length) {
+            float[] newArray = ArrayUtils.newUnpaddedFloatArray(growSize(currentSize));
+            System.arraycopy(array, 0, newArray, 0, currentSize);
+            array = newArray;
+        }
+        array[currentSize] = element;
+        return array;
+    }
+
+    /**
+     * Inserts an element into the array at the specified index, growing the array if there is no
+     * more room.
+     *
+     * @param array The array to which to append the element. Must NOT be null.
+     * @param currentSize The number of elements in the array. Must be less than or equal to
+     *                    array.length.
+     * @param element The element to insert.
+     * @return the array to which the element was appended. This may be different than the given
+     *         array.
+     */
+    public static <T> T[] insert(T[] array, int currentSize, int index, T element) {
+        assert currentSize <= array.length;
+
+        if (currentSize + 1 <= array.length) {
+            System.arraycopy(array, index, array, index + 1, currentSize - index);
+            array[index] = element;
+            return array;
+        }
+
+        @SuppressWarnings("unchecked")
+        T[] newArray = ArrayUtils.newUnpaddedArray((Class<T>) array.getClass().getComponentType(),
+                growSize(currentSize));
+        System.arraycopy(array, 0, newArray, 0, index);
+        newArray[index] = element;
+        System.arraycopy(array, index, newArray, index + 1, array.length - index);
+        return newArray;
+    }
+
+    /**
+     * Primitive int version of {@link #insert(Object[], int, int, Object)}.
+     */
+    public static int[] insert(int[] array, int currentSize, int index, int element) {
+        assert currentSize <= array.length;
+
+        if (currentSize + 1 <= array.length) {
+            System.arraycopy(array, index, array, index + 1, currentSize - index);
+            array[index] = element;
+            return array;
+        }
+
+        int[] newArray = ArrayUtils.newUnpaddedIntArray(growSize(currentSize));
+        System.arraycopy(array, 0, newArray, 0, index);
+        newArray[index] = element;
+        System.arraycopy(array, index, newArray, index + 1, array.length - index);
+        return newArray;
+    }
+
+    /**
+     * Primitive long version of {@link #insert(Object[], int, int, Object)}.
+     */
+    public static long[] insert(long[] array, int currentSize, int index, long element) {
+        assert currentSize <= array.length;
+
+        if (currentSize + 1 <= array.length) {
+            System.arraycopy(array, index, array, index + 1, currentSize - index);
+            array[index] = element;
+            return array;
+        }
+
+        long[] newArray = ArrayUtils.newUnpaddedLongArray(growSize(currentSize));
+        System.arraycopy(array, 0, newArray, 0, index);
+        newArray[index] = element;
+        System.arraycopy(array, index, newArray, index + 1, array.length - index);
+        return newArray;
+    }
+
+    /**
+     * Primitive boolean version of {@link #insert(Object[], int, int, Object)}.
+     */
+    public static boolean[] insert(boolean[] array, int currentSize, int index, boolean element) {
+        assert currentSize <= array.length;
+
+        if (currentSize + 1 <= array.length) {
+            System.arraycopy(array, index, array, index + 1, currentSize - index);
+            array[index] = element;
+            return array;
+        }
+
+        boolean[] newArray = ArrayUtils.newUnpaddedBooleanArray(growSize(currentSize));
+        System.arraycopy(array, 0, newArray, 0, index);
+        newArray[index] = element;
+        System.arraycopy(array, index, newArray, index + 1, array.length - index);
+        return newArray;
+    }
+
+    /**
+     * Given the current size of an array, returns an ideal size to which the array should grow.
+     * This is typically double the given size, but should not be relied upon to do so in the
+     * future.
+     */
+    public static int growSize(int currentSize) {
+        return currentSize <= 4 ? 8 : currentSize * 2;
+    }
+
+    // Uninstantiable
+    private GrowingArrayUtils() {}
+}
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/java/libcore/util/EmptyArray.java b/ui/ui-desktop/android-emu/src/desktopMain/java/libcore/util/EmptyArray.java
new file mode 100644
index 0000000..df47d6e
--- /dev/null
+++ b/ui/ui-desktop/android-emu/src/desktopMain/java/libcore/util/EmptyArray.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.util;
+
+/**
+ * Empty primitive arrays.
+ */
+public final class EmptyArray {
+    private EmptyArray() {}
+
+    public static final boolean[] BOOLEAN = new boolean[0];
+    public static final byte[] BYTE = new byte[0];
+    public static final char[] CHAR = new char[0];
+    public static final double[] DOUBLE = new double[0];
+    public static final float[] FLOAT = new float[0];
+    public static final int[] INT = new int[0];
+    public static final long[] LONG = new long[0];
+
+    public static final Class<?>[] CLASS = new Class[0];
+    public static final Object[] OBJECT = new Object[0];
+    public static final String[] STRING = new String[0];
+    public static final Throwable[] THROWABLE = new Throwable[0];
+    public static final StackTraceElement[] STACK_TRACE_ELEMENT = new StackTraceElement[0];
+    public static final java.lang.reflect.Type[] TYPE = new java.lang.reflect.Type[0];
+    public static final java.lang.reflect.TypeVariable[] TYPE_VARIABLE =
+        new java.lang.reflect.TypeVariable[0];
+}
+
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/graphics/Canvas.kt b/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/graphics/Canvas.kt
index 54f7b9d..6a991eb 100644
--- a/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/graphics/Canvas.kt
+++ b/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/graphics/Canvas.kt
@@ -18,15 +18,123 @@
 
 import org.jetbrains.skija.Canvas
 import org.jetbrains.skija.Rect
+import org.jetbrains.skija.RoundedRect
 
-public class Canvas(private val canvas: org.jetbrains.skija.Canvas) {
+public class Canvas(val skijaCanvas: org.jetbrains.skija.Canvas) {
+    var skijaFont = org.jetbrains.skija.Font(Typeface.DEFAULT.skijaTypeface, 30f)
 
     fun translate(x: Float, y: Float) {
-        canvas.translate(x, y)
+        skijaCanvas.translate(x, y)
+    }
+
+    fun drawLine(
+        startX: Float,
+        startY: Float,
+        stopX: Float,
+        stopY: Float,
+        paint: Paint
+    ) {
+        skijaCanvas.drawLine(
+            startX,
+            startY,
+            stopX,
+            stopY,
+            paint.skijaPaint
+        )
     }
 
     fun drawRect(rect: android.graphics.RectF, paint: android.graphics.Paint) {
         val skijaRect = Rect.makeLTRB(rect.left, rect.top, rect.right, rect.bottom)
-        canvas.drawRect(skijaRect, paint.skijaPaint)
+        skijaCanvas.drawRect(skijaRect, paint.skijaPaint)
+    }
+
+    fun drawRect(
+        left: Float,
+        top: Float,
+        right: Float,
+        bottom: Float,
+        paint: android.graphics.Paint
+    ) {
+        val skijaRect = Rect.makeLTRB(left, top, right, bottom)
+        skijaCanvas.drawRect(skijaRect, paint.skijaPaint)
+    }
+
+    fun drawArc(
+        left: Float,
+        top: Float,
+        right: Float,
+        bottom: Float,
+        startAngle: Float,
+        sweepAngle: Float,
+        useCenter: Boolean,
+        paint: Paint
+    ) {
+        skijaCanvas.drawArc(
+            left,
+            top,
+            right,
+            bottom,
+            startAngle,
+            sweepAngle,
+            !useCenter,
+            paint.skijaPaint
+        )
+    }
+
+    fun drawText(
+        text: CharSequence,
+        start: Int,
+        end: Int,
+        x: Float,
+        y: Float,
+        paint: Paint
+    ) {
+        val buffer = skijaFont.hbFont.shape(text.toString(), org.jetbrains.skija.FontFeature.EMPTY)
+        skijaCanvas.drawTextBuffer(buffer, x, y, skijaFont.skFont, paint.skijaPaint)
+    }
+
+    fun drawText(
+        text: String,
+        x: Float,
+        y: Float,
+        paint: Paint
+    ) {
+        drawText(text, 0, text.length, x, y, paint)
+    }
+
+    fun drawRoundRect(
+        left: Float,
+        top: Float,
+        right: Float,
+        bottom: Float,
+        rx: Float,
+        ry: Float,
+        paint: android.graphics.Paint
+    ) {
+        val skijaRoundedRect = RoundedRect.makeLTRB(left, top, right, bottom, rx, ry)
+        skijaCanvas.drawRoundedRect(skijaRoundedRect, paint.skijaPaint)
+    }
+
+    fun clipRect(left: Float, top: Float, right: Float, bottom: Float, op: Region.Op): Boolean {
+        val skijaRect = Rect.makeLTRB(left, top, right, bottom)
+        skijaCanvas.clipRect(skijaRect, op.skija)
+        return true
+    }
+
+    fun clipPath(path: Path, op: Region.Op): Boolean {
+        skijaCanvas.clipPath(path.skijaPath, op.skija)
+        return true
+    }
+
+    fun scale(sx: Float, sy: Float) {
+        skijaCanvas.scale(sx, sy)
+    }
+
+    fun save(): Int {
+        return skijaCanvas.save()
+    }
+
+    fun restore() {
+        skijaCanvas.restore()
     }
 }
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/graphics/Outline.kt b/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/graphics/Outline.kt
new file mode 100644
index 0000000..9f4d6f8
--- /dev/null
+++ b/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/graphics/Outline.kt
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics
+
+class Outline {
+    var alpha: Float = 1f
+
+    var rect: Rect? = null
+    var radius: Float? = null
+    var path: Path? = null
+
+    fun set(outline: Outline) {
+        rect = outline.rect
+        radius = outline.radius
+        path = outline.path
+    }
+
+    fun isEmpty() = rect == null && radius == null && path == null
+
+    fun canClip() = true
+
+    fun setEmpty() {
+        rect = null
+        radius = null
+        path = null
+    }
+
+    fun setRect(left: Int, top: Int, right: Int, bottom: Int) {
+        rect = Rect(left, top, right, bottom)
+        radius = null
+        path = null
+    }
+
+    fun setRoundRect(left: Int, top: Int, right: Int, bottom: Int, radius: Float) {
+        rect = Rect(left, top, right, bottom)
+        this.radius = radius
+        path = null
+    }
+
+    fun setConvexPath(convexPath: Path) {
+        path = convexPath
+        rect = null
+        radius = null
+    }
+}
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/graphics/Paint.kt b/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/graphics/Paint.kt
index d9e25f7..08cebc6 100644
--- a/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/graphics/Paint.kt
+++ b/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/graphics/Paint.kt
@@ -16,35 +16,109 @@
 
 package android.graphics
 
-class Paint {
-    enum class Style {
-        FILL,
-        FILL_AND_STROKE,
-        STROKE
+open class Paint {
+    enum class Style(val skija: org.jetbrains.skija.Paint.Style) {
+        FILL(org.jetbrains.skija.Paint.Style.FILL),
+        FILL_AND_STROKE(org.jetbrains.skija.Paint.Style.STROKE_AND_FILL),
+        STROKE(org.jetbrains.skija.Paint.Style.STROKE)
     }
 
-    enum class Cap {
-        BUTT,
-        ROUND,
-        SQUARE
+    enum class Cap(val skija: org.jetbrains.skija.Paint.Cap) {
+        BUTT(org.jetbrains.skija.Paint.Cap.BUTT),
+        ROUND(org.jetbrains.skija.Paint.Cap.ROUND),
+        SQUARE(org.jetbrains.skija.Paint.Cap.SQUARE)
     }
 
-    enum class Join {
-        BEVEL,
-        MITER,
-        ROUND
+    enum class Join(val skija: org.jetbrains.skija.Paint.Join) {
+        BEVEL(org.jetbrains.skija.Paint.Join.BEVEL),
+        MITER(org.jetbrains.skija.Paint.Join.MITER),
+        ROUND((org.jetbrains.skija.Paint.Join.ROUND))
     }
 
-    constructor(flags: Int) {}
+    open class FontMetricsInt {
+        @JvmField
+        var top: Int = 0
+        @JvmField
+        var ascent: Int = 0
+        @JvmField
+        var descent: Int = 0
+        @JvmField
+        var bottom: Int = 0
+        @JvmField
+        var leading: Int = 0
+
+        override fun toString(): String {
+            return "FontMetricsInt: top=" + top + " ascent=" + ascent +
+                    " descent=" + descent + " bottom=" + bottom +
+                    " leading=" + leading
+        }
+    }
 
     val skijaPaint = org.jetbrains.skija.Paint()
 
+    constructor(flags: Int) {
+        if (flags and 1 == 1) {
+            skijaPaint.setAntiAlias(true)
+        }
+    }
+
     var color: Int
         get() = skijaPaint.getColor().toInt()
         set(value) {
             skijaPaint.setColor(value.toLong())
         }
-    var strokeWidth: Float = 0f
-    var style: Style = Style.STROKE
-    var stokeCap: Cap = Cap.BUTT
+    var strokeWidth: Float
+        get() = skijaPaint.getStrokeWidth()
+        set(value) {
+            skijaPaint.setStrokeWidth(value)
+        }
+    var style: Style
+        get() = Style.values().first { it.skija == skijaPaint.getStyle() }
+        set(value) {
+            skijaPaint.setStyle(value.skija)
+        }
+    var strokeCap: Cap
+        get() = Cap.values().first { it.skija == skijaPaint.getStrokeCap() }
+        set(value) {
+            skijaPaint.setStrokeCap(value.skija)
+        }
+    var strokeMiter: Float
+        get() = skijaPaint.getStrokeMiter().toFloat()
+        set(value) {
+            skijaPaint.setStrokeMiter(value)
+        }
+    var strokeJoin: Join
+        get() = Join.values().first { it.skija == skijaPaint.getStrokeJoin() }
+        set(value) {
+            skijaPaint.setStrokeJoin(value.skija)
+        }
+    var antiAlias: Boolean
+        get() = skijaPaint.isAntiAlias()
+        set(value) {
+            skijaPaint.setAntiAlias(value)
+        }
+
+    var textSize: Float = 0f
+
+    private var typeface: Typeface? = null
+    fun getTypeface(): Typeface? = typeface
+    fun setTypeface(newTypeface: Typeface?): Typeface? {
+        val oldTypeface = typeface
+        typeface = newTypeface
+        return oldTypeface
+    }
+    var textLocale: java.util.Locale = java.util.Locale.getDefault()
+    var fontFeatureSettings: String? = null
+    var textScaleX: Float = 1f
+    var textSkewX: Float = 1f
+
+    fun setShadowLayer(radius: Float, dx: Float, dy: Float, shadowColor: Int) {
+        println("Paint.setShadowLayer")
+    }
+
+    fun setPathEffect(effect: PathEffect?): PathEffect? {
+        if (effect != null)
+            println("setPathEffect not implemented yet")
+        return effect
+    }
 }
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/graphics/Path.kt b/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/graphics/Path.kt
index 0b6dba7..61cdafe 100644
--- a/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/graphics/Path.kt
+++ b/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/graphics/Path.kt
@@ -16,4 +16,6 @@
 
 package android.graphics
 
-class Path
\ No newline at end of file
+class Path {
+    val skijaPath = org.jetbrains.skija.Path()
+}
\ No newline at end of file
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/graphics/PathEffect.kt b/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/graphics/PathEffect.kt
new file mode 100644
index 0000000..0a668ef
--- /dev/null
+++ b/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/graphics/PathEffect.kt
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics
+
+open class PathEffect
\ No newline at end of file
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/graphics/Rect.kt b/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/graphics/Rect.kt
new file mode 100644
index 0000000..2ce6324
--- /dev/null
+++ b/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/graphics/Rect.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics
+
+class Rect(
+    var left: Int,
+    var top: Int,
+    var right: Int,
+    var bottom: Int
+) {
+    constructor() : this(0, 0, 0, 0)
+
+    fun set(left: Int, top: Int, right: Int, bottom: Int) {
+        this.left = left
+        this.top = top
+        this.right = right
+        this.bottom = bottom
+    }
+}
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/graphics/Region.kt b/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/graphics/Region.kt
new file mode 100644
index 0000000..7426cbd
--- /dev/null
+++ b/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/graphics/Region.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+class Region {
+    enum class Op(val skija: org.jetbrains.skija.Canvas.ClipOp) {
+        DIFFERENCE(org.jetbrains.skija.Canvas.ClipOp.DIFFERENCE),
+        INTERSECT(org.jetbrains.skija.Canvas.ClipOp.INTERSECT)
+    }
+}
\ No newline at end of file
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/graphics/Typeface.kt b/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/graphics/Typeface.kt
new file mode 100644
index 0000000..9b3aebe
--- /dev/null
+++ b/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/graphics/Typeface.kt
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics
+
+private const val NORMAL_FONT_NAME = "NotoSans-Regular"
+private const val BOLD_FONT_NAME = "NotoSans-Bold"
+private const val ITALIC_FONT_NAME = "NotoSans-Italic"
+private const val BOLD_ITALIC_FONT_NAME = "NotoSans-BoldItalic"
+
+class Typeface(val skijaTypeface: org.jetbrains.skija.Typeface) {
+    companion object {
+        // TODO: Skija should make it possible to make fonts from non-file in-memory source
+        val NORMAL_TYPEFACE = Typeface(org.jetbrains.skija.Typeface.makeFromFile(
+            getFontPathAsString(NORMAL_FONT_NAME)))
+        val BOLD_TYPEFACE = Typeface(org.jetbrains.skija.Typeface.makeFromFile(
+            getFontPathAsString(BOLD_FONT_NAME)))
+        val ITALIC_TYPEFACE = Typeface(org.jetbrains.skija.Typeface.makeFromFile(
+            getFontPathAsString(ITALIC_FONT_NAME)))
+        val BOLD_ITALIC_TYPEFACE = Typeface(org.jetbrains.skija.Typeface.makeFromFile(
+            getFontPathAsString(BOLD_ITALIC_FONT_NAME)))
+
+        @JvmField
+        val DEFAULT = NORMAL_TYPEFACE
+
+        @JvmField
+        val NORMAL = 0x0
+
+        @JvmField
+        val BOLD = 0x1
+
+        @JvmField
+        val ITALIC = 0x2
+
+        @JvmField
+        val BOLD_ITALIC = 0x3
+
+        @JvmStatic
+        fun defaultFromStyle(style: Int): Typeface = when (style) {
+            BOLD -> BOLD_TYPEFACE
+            ITALIC -> ITALIC_TYPEFACE
+            BOLD_ITALIC -> BOLD_ITALIC_TYPEFACE
+            else -> DEFAULT
+        }
+    }
+}
+
+fun getFontPathAsString(font: String): String {
+    return Typeface::class.java.getClassLoader().getResource("$font.ttf").getFile()
+}
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/text/Layout.kt b/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/text/Layout.kt
new file mode 100644
index 0000000..e88e804
--- /dev/null
+++ b/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/text/Layout.kt
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text
+
+import android.graphics.Canvas
+import android.graphics.Paint
+import android.graphics.Path
+import android.compat.annotation.UnsupportedAppUsage
+
+open class Layout(
+    var mText: CharSequence,
+    paint: TextPaint,
+    width: Int,
+    align: Alignment,
+    spacingmult: Float,
+    spacingadd: Float
+) {
+    enum class Alignment {
+        ALIGN_NORMAL,
+        ALIGN_OPPOSITE,
+        ALIGN_CENTER,
+        /** @hide */
+        @UnsupportedAppUsage
+        ALIGN_LEFT,
+        /** @hide */
+        @UnsupportedAppUsage
+        ALIGN_RIGHT,
+    }
+
+    class Directions(val mDirections: IntArray)
+
+    class TabStops(val increment: Float, val spans: Array<Any>)
+
+    companion object {
+        @JvmStatic
+        fun getDesiredWidth(source: CharSequence, start: Int, end: Int, paint: TextPaint): Float {
+            return minOf(end - start + 1, source.length) * 1f
+        }
+
+        @JvmField
+        val DIR_LEFT_TO_RIGHT = 1
+
+        @JvmField
+        val DIR_RIGHT_TO_LEFT = -1
+
+        @JvmField
+        val RUN_LENGTH_MASK = 0x03ffffff
+
+        @JvmField
+        val RUN_LEVEL_SHIFT = 26
+
+        @JvmField
+        val RUN_RTL_FLAG = 1 shl RUN_LEVEL_SHIFT
+
+        @JvmField
+        val DIRS_ALL_LEFT_TO_RIGHT = Directions(intArrayOf(0, RUN_LENGTH_MASK))
+
+        @JvmField
+        val DIRS_ALL_RIGHT_TO_LEFT = Directions(intArrayOf(0, RUN_LENGTH_MASK or RUN_RTL_FLAG))
+    }
+
+    fun replaceWith(
+        text: CharSequence,
+        paint: TextPaint,
+        width: Int,
+        align: Alignment,
+        spacingmult: Float,
+        spacingadd: Float
+    ) {
+        println("Layout.replaceWith")
+        mText = text
+    }
+
+    fun getText(): CharSequence = mText
+
+    open fun getHeight(): Int {
+        return 0
+    }
+
+    open fun getLineCount(): Int {
+        return 1
+    }
+
+    open fun getLineTop(line: Int): Int {
+        return 0
+    }
+
+    open fun getLineDescent(line: Int): Int {
+        return 0
+    }
+
+    open fun getLineStart(line: Int): Int {
+        return 0
+    }
+
+    open fun getParagraphDirection(line: Int): Int {
+        return DIR_LEFT_TO_RIGHT
+    }
+
+    open fun getLineContainsTab(line: Int): Boolean {
+        return false
+    }
+
+    open fun getLineMax(line: Int): Float {
+        return 0f
+    }
+
+    open fun getLineWidth(line: Int): Float {
+        return 0f
+    }
+
+    open fun getLineDirections(line: Int): Directions {
+        return Layout.DIRS_ALL_LEFT_TO_RIGHT
+    }
+
+    open fun getTopPadding(): Int {
+        return 0
+    }
+
+    open fun getBottomPadding(): Int {
+        return 0
+    }
+
+    open fun getEllipsisCount(line: Int): Int {
+        return 0
+    }
+
+    open fun getEllipsisStart(line: Int): Int {
+        return 0
+    }
+
+    open fun getEllipsizedWidth(): Int {
+        return 0
+    }
+
+    open fun draw(c: Canvas) {
+        println("Layout.draw1: $mText")
+        draw(c, null, null, 0)
+    }
+
+    open fun draw(canvas: Canvas, highlight: Path?, highlightpaint: Paint?, cursorOffset: Int) {
+        println("Layout.draw2")
+        drawText(canvas, 0, 1)
+    }
+
+    fun drawText(canvas: Canvas, firstLine: Int, lastLine: Int) {
+        println("Layout.drawText: $firstLine .. $lastLine")
+        canvas.drawText(mText, 0, mText.length, 0.5f, 0.5f, mWorkPaint)
+    }
+
+    fun getLineBaseline(line: Int): Int {
+        return getLineTop(line + 1) - getLineDescent(line)
+    }
+
+    val mWorkPaint = TextPaint(0)
+}
\ No newline at end of file
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/text/StaticLayout.kt b/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/text/StaticLayout.kt
new file mode 100644
index 0000000..4e50e5f
--- /dev/null
+++ b/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/text/StaticLayout.kt
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text
+
+class StaticLayout(
+    text: CharSequence,
+    paint: TextPaint,
+    width: Int,
+    align: Alignment,
+    spacingmult: Float,
+    spacingadd: Float
+) : Layout(text, paint, width, align, spacingmult, spacingadd)
\ No newline at end of file
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/text/TextLine.kt b/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/text/TextLine.kt
new file mode 100644
index 0000000..127a50c
--- /dev/null
+++ b/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/text/TextLine.kt
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text
+
+import android.graphics.Paint.FontMetricsInt
+import android.text.Layout.Directions
+import android.text.Layout.TabStops
+
+class TextLine() {
+    var mText: CharSequence = ""
+    var mLen = 0
+
+    companion object {
+        @JvmStatic
+        fun obtain(): TextLine = TextLine()
+
+        @JvmStatic
+        fun recycle(line: TextLine) {
+        }
+    }
+
+    fun metrics(fmi: FontMetricsInt): Float {
+        println("TextLine.metrics")
+        return mLen * 1f
+    }
+
+    fun set(
+        paint: TextPaint,
+        text: CharSequence,
+        start: Int,
+        limit: Int,
+        dir: Int,
+        directions: Directions,
+        hasTabs: Boolean,
+        tabStops: TabStops?,
+        ellipsisStart: Int,
+        ellipsisEnd: Int
+    ) {
+        println("TextLine.set")
+        mText = text
+        mLen = limit - start
+    }
+}
\ No newline at end of file
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/text/TextPaint.kt b/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/text/TextPaint.kt
new file mode 100644
index 0000000..aeff02b
--- /dev/null
+++ b/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/text/TextPaint.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text
+
+import android.graphics.Paint
+
+class TextPaint(flags: Int) : Paint(flags)
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/util/Log.kt b/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/util/Log.kt
new file mode 100644
index 0000000..64411f9
--- /dev/null
+++ b/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/util/Log.kt
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.util
+
+object Log {
+    fun v(scope: String, msg: String) {
+        println("$scope: msg")
+    }
+    fun e(scope: String, msg: String) {
+        println("$scope: $msg")
+    }
+}
\ No newline at end of file
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/view/View.kt b/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/view/View.kt
index d00265a..24d3a6d 100644
--- a/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/view/View.kt
+++ b/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/view/View.kt
@@ -18,8 +18,25 @@
 
 import android.content.Context
 import android.graphics.Canvas
+import android.graphics.Rect
+import android.util.LayoutDirection
 
 open class View(val context: Context) {
+    companion object {
+        @JvmField
+        val LAYOUT_DIRECTION_LTR = LayoutDirection.LTR
+        @JvmField
+        val LAYOUT_DIRECTION_RTL = LayoutDirection.RTL
+
+        @JvmStatic
+        fun generateViewId(): Int {
+            // TODO: atomic in Android.
+            return sNextGeneratedId++
+        }
+
+        var sNextGeneratedId: Int = 1
+    }
+
     open class AccessibilityDelegate()
 
     interface OnApplyWindowInsetsListener {
@@ -43,7 +60,7 @@
 
     fun requestLayout() {}
 
-    fun invalidate() {}
+    open fun invalidate() {}
 
     open fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {}
 
@@ -62,7 +79,7 @@
         companion object {
             @JvmStatic
             fun getMode(measureSpec: Int): Int {
-                return 1073741824 // EXACTLY
+                return -2147483648 // AT_MOST
             }
 
             @JvmStatic
@@ -71,4 +88,47 @@
             }
         }
     }
+
+    var id: Int = 0
+
+    var alpha: Float = 1.0f
+    var scaleX: Float = 1.0f
+    var scaleY: Float = 1.0f
+    var translationX: Float = 0.0f
+    var translationY: Float = 0.0f
+    var elevation: Float = 0.0f
+    var rotation: Float = 0.0f
+    var rotationX: Float = 0.0f
+    var rotationY: Float = 0.0f
+    var pivotX: Float = 0.0f
+    var pivotY: Float = 0.0f
+
+    var left: Int = 0
+    var top: Int = 0
+    var right: Int = 0
+    var bottom: Int = 0
+    val width: Int get() = right - left
+    val height: Int get() = bottom - top
+
+    var clipToBounds: Boolean = false
+    var clipBounds: Rect? = null
+
+    var clipToOutline: Boolean = false
+
+    var outlineProvider: ViewOutlineProvider? = null
+
+    var drawingTime: Long = 0
+
+    var mRecreateDisplayList: Boolean = false
+
+    fun layout(left: Int, top: Int, right: Int, bottom: Int) {
+        this.left = left
+        this.top = top
+        this.right = right
+        this.bottom = bottom
+    }
+
+    fun updateDisplayListIfDirty() {
+        println("View.updateDisplayListIfDirty")
+    }
 }
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/view/ViewGroup.kt b/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/view/ViewGroup.kt
index 2e2b1e4..b8b37bb 100644
--- a/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/view/ViewGroup.kt
+++ b/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/view/ViewGroup.kt
@@ -17,6 +17,10 @@
 package android.view
 
 import android.content.Context
+import android.graphics.Canvas
+import android.graphics.Outline
+import android.graphics.Rect
+import org.jetbrains.skija.RoundedRect
 
 abstract class ViewGroup(context: Context) : View(context) {
     var clipChildren: Boolean = true
@@ -29,10 +33,69 @@
         children.clear()
     }
 
+    fun addView(child: android.view.View) {
+        children.add(child)
+    }
+
     fun addView(child: android.view.View, params: ViewGroup.LayoutParams?) {
         children.add(child)
     }
 
+    fun drawChild(canvas: Canvas, view: View, drawingTime: Long): Boolean {
+        canvas.save()
+        canvas.translate(
+            view.left.toFloat() + view.translationX,
+            view.top.toFloat() + view.translationY
+        )
+        if (view.clipToBounds && view.clipBounds != null) {
+            canvas.clipRect(view.clipBounds!!)
+        }
+        if (view.clipToOutline) {
+            val outline = Outline()
+            view.outlineProvider?.getOutline(view, outline)
+            canvas.clipOutline(outline)
+        }
+        if (view.scaleX != 1f || view.scaleY != 1f) {
+            canvas.scale(view.scaleX, view.scaleY)
+        }
+
+        view.dispatchDraw(canvas)
+        canvas.restore()
+        return true
+    }
+
+    private fun Canvas.clipRect(rect: Rect) {
+        clipRect(
+            rect.left.toFloat(),
+            rect.top.toFloat(),
+            rect.right.toFloat(),
+            rect.bottom.toFloat(),
+            Region.Op.INTERSECT
+        )
+    }
+
+    private fun Canvas.clipOutline(outline: Outline) {
+        val rect = outline.rect
+        val radius = outline.radius
+        val path = outline.path
+        if (path != null) {
+            clipPath(path, Region.Op.INTERSECT)
+        } else if (radius != null && rect != null) {
+            skijaCanvas.clipRoundedRect(
+                RoundedRect.makeLTRB(
+                    rect.left.toFloat(),
+                    rect.top.toFloat(),
+                    rect.right.toFloat(),
+                    rect.bottom.toFloat(),
+                    radius,
+                    radius
+                )
+            )
+        } else if (rect != null) {
+            clipRect(rect)
+        }
+    }
+
     class LayoutParams(width: Int, height: Int) {
         companion object {
             const val WRAP_CONTENT = 0
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/view/ViewOutlineProvider.kt b/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/view/ViewOutlineProvider.kt
new file mode 100644
index 0000000..4539838
--- /dev/null
+++ b/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/view/ViewOutlineProvider.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view
+
+abstract class ViewOutlineProvider {
+    abstract fun getOutline(view: View, outline: android.graphics.Outline)
+}
\ No newline at end of file
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/view/accessibility/AccessibilityManager.kt b/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/view/accessibility/AccessibilityManager.kt
index e5229ba..4b85146 100644
--- a/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/view/accessibility/AccessibilityManager.kt
+++ b/ui/ui-desktop/android-emu/src/desktopMain/kotlin/android/view/accessibility/AccessibilityManager.kt
@@ -16,4 +16,6 @@
 
 package android.view.accessibility
 
-class AccessibilityManager()
+class AccessibilityManager() {
+    fun isEnabled(): Boolean = false
+}
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/kotlin/androidx/ui/core/R.kt b/ui/ui-desktop/android-emu/src/desktopMain/kotlin/androidx/ui/core/R.kt
new file mode 100644
index 0000000..dea489c
--- /dev/null
+++ b/ui/ui-desktop/android-emu/src/desktopMain/kotlin/androidx/ui/core/R.kt
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.ui.core
+
+class R {
+    class id {
+        companion object {
+            @JvmField
+            val wrapped_composition_tag = 0
+            @JvmField
+            val accessibility_custom_action_0 = 0
+            @JvmField
+            val accessibility_custom_action_1 = 1
+            @JvmField
+            val accessibility_custom_action_2 = 2
+            @JvmField
+            val accessibility_custom_action_3 = 3
+            @JvmField
+            val accessibility_custom_action_4 = 4
+            @JvmField
+            val accessibility_custom_action_5 = 5
+            @JvmField
+            val accessibility_custom_action_6 = 6
+            @JvmField
+            val accessibility_custom_action_7 = 7
+            @JvmField
+            val accessibility_custom_action_8 = 8
+            @JvmField
+            val accessibility_custom_action_9 = 9
+            @JvmField
+            val accessibility_custom_action_10 = 10
+            @JvmField
+            val accessibility_custom_action_11 = 11
+            @JvmField
+            val accessibility_custom_action_12 = 12
+            @JvmField
+            val accessibility_custom_action_13 = 13
+            @JvmField
+            val accessibility_custom_action_14 = 14
+            @JvmField
+            val accessibility_custom_action_15 = 15
+            @JvmField
+            val accessibility_custom_action_16 = 16
+            @JvmField
+            val accessibility_custom_action_17 = 17
+            @JvmField
+            val accessibility_custom_action_18 = 18
+            @JvmField
+            val accessibility_custom_action_19 = 19
+            @JvmField
+            val accessibility_custom_action_20 = 20
+            @JvmField
+            val accessibility_custom_action_21 = 21
+            @JvmField
+            val accessibility_custom_action_22 = 22
+            @JvmField
+            val accessibility_custom_action_23 = 23
+            @JvmField
+            val accessibility_custom_action_24 = 24
+            @JvmField
+            val accessibility_custom_action_25 = 25
+            @JvmField
+            val accessibility_custom_action_26 = 26
+            @JvmField
+            val accessibility_custom_action_27 = 27
+            @JvmField
+            val accessibility_custom_action_28 = 28
+            @JvmField
+            val accessibility_custom_action_29 = 29
+            @JvmField
+            val accessibility_custom_action_30 = 30
+            @JvmField
+            val accessibility_custom_action_31 = 31
+        }
+    }
+}
diff --git a/ui/ui-desktop/android-emu/src/desktopMain/kotlin/androidx/ui/core/ViewLayer.kt b/ui/ui-desktop/android-emu/src/desktopMain/kotlin/androidx/ui/core/ViewLayer.kt
new file mode 100644
index 0000000..e71105e
--- /dev/null
+++ b/ui/ui-desktop/android-emu/src/desktopMain/kotlin/androidx/ui/core/ViewLayer.kt
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.ui.core
+
+import android.content.Context
+import android.view.View
+
+class ViewLayer(context: Context) : View(context) {
+    init {
+        id = generateViewId()
+    }
+}
\ No newline at end of file
diff --git a/ui/ui-desktop/build.gradle b/ui/ui-desktop/build.gradle
index e29bfe7..b482b0d 100644
--- a/ui/ui-desktop/build.gradle
+++ b/ui/ui-desktop/build.gradle
@@ -17,7 +17,9 @@
 import androidx.build.LibraryGroups
 import androidx.build.LibraryVersions
 import androidx.build.Publish
+import androidx.build.SupportConfigKt
 import java.nio.file.Files
+import java.nio.file.FileSystems
 import java.nio.file.Paths
 import java.nio.file.StandardCopyOption
 import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
@@ -35,6 +37,7 @@
 import java.io.FileOutputStream
 import java.nio.file.Files
 import java.nio.file.StandardCopyOption
+import java.util.regex.Pattern
 import java.util.zip.ZipEntry
 import java.util.zip.ZipInputStream
 
@@ -52,8 +55,6 @@
     mavenLocal()
 }
 
-
-
 configurations {
     ui_components
     compose_compiler_jar
@@ -103,6 +104,7 @@
         }
 
         jvmMain {
+            resources.srcDirs += new File(SupportConfigKt.getExternalProjectPath(project), "noto-fonts/other/")
         }
 
         jvmMain.dependencies {
@@ -139,13 +141,11 @@
         "ui-animation-core",
         "ui-core",
         "ui-foundation",
-        "ui-framework",
         "ui-geometry",
         "ui-graphics",
         "ui-layout",
         "ui-livedata",
         "ui-material",
-        "ui-platform",
         "ui-saved-instance-state",
         "ui-test",
         "ui-text",
@@ -177,7 +177,7 @@
     ZipInputStream stream = new ZipInputStream(bis)
     ZipEntry entry = null
     while ((entry = stream.getNextEntry()) != null) {
-        if(!entry.name.equals("classes.jar")) continue;
+        if (!entry.name.equals("classes.jar")) continue;
         FileOutputStream fos = new FileOutputStream(jar)
         BufferedOutputStream bos = new BufferedOutputStream(fos, buffer.size())
         int len = 0
@@ -194,23 +194,45 @@
 
 
 // Find in dependencies first (BFS) task's output ending with `name`.
-String findInDeps(Task root, String name) {
+String findInDeps(Task root, Closure<Boolean> matcher) {
     // Do BFS by deps.
     def queue = new java.util.ArrayDeque<Task>()
+    def seen = new java.util.HashSet<Task>()
     queue.addLast(root)
     while (queue.size() > 0) {
         def task = queue.pop()
-        def classes = task.outputs.files.files.find { it.name.endsWith(name) }
+        seen.add(task)
+        def classes = task.outputs.files.files.find { matcher(it.absolutePath) }
         if (classes != null) {
             return classes.absolutePath
         }
         task.taskDependencies.getDependencies(task).each {
-            queue.addLast(it)
+            if (!seen.contains(it))
+                queue.addLast(it)
         }
     }
     return null
 }
 
+java.nio.file.FileSystem getFS(URI uri) {
+    try {
+        def result = FileSystems.getFileSystem(uri)
+        return result
+    } catch (java.nio.file.FileSystemNotFoundException e) {
+        def env = new HashMap<String, String>()
+        return FileSystems.newFileSystem(uri, env)
+    }
+}
+
+void addToJar(String jarName, String entryName, String entryContentPath) {
+    def jarPath = Paths.get(jarName)
+    def uri = URI.create("jar:" + jarPath.toUri());
+    def fs = getFS(uri)
+    def pathInZipFile = fs.getPath("/" + entryName)
+    Files.copy(Paths.get(entryContentPath), pathInZipFile, StandardCopyOption.REPLACE_EXISTING)
+    fs.close()
+}
+
 task extractJars {
     doLast {
         // Find all JAR files matching components.
@@ -218,16 +240,30 @@
         uiComponents.each { component ->
             def depProject = project(":ui:" + component)
             def task = depProject.tasks.named("assemble").get()
-            def srcJar = findInDeps(task, "classes.jar")
+            def srcJar = findInDeps(task, { absolutePath ->
+                absolutePath.endsWith("classes.jar") && absolutePath.contains(component)
+            })
             if (srcJar == null) {
                 throw new Error("cannot find classes.jar in "+ task)
             } else {
                 def destJar = composeClassDir + component + ".jar"
                 Files.copy(Paths.get(srcJar), Paths.get(destJar), StandardCopyOption.REPLACE_EXISTING)
+                // TODO: restore missing kotlin_module and remove this code.
+                def missingModuleDir = findInDeps(task, { absolutePath ->
+                    absolutePath.indexOf("kotlin-classes/release") != -1
+                })
+                if (missingModuleDir == null)
+                    throw new Error("cannot find build dir")
+                def shortName = "META-INF/" + component + "_release.kotlin_module"
+                def missingModule = missingModuleDir + "/" + shortName
+                addToJar(destJar, shortName, missingModule)
             }
         }
-        def frameworkProject = project(":ui:ui-framework")
-        def srcJar = findInDeps(frameworkProject.tasks.named("assemble").get(), "compose-compiler.jar")
+        def frameworkProject = project(":compose:compose-compiler")
+        def srcJar = findInDeps(frameworkProject.tasks.named("assemble").get(), {
+            absolutePath ->
+            Pattern.matches(".*/compose-compiler.*.jar", absolutePath)
+        })
         if (srcJar == null)
             throw new Error("cannot find compose-compiler.jar")
         Files.copy(Paths.get(srcJar),
@@ -258,6 +294,7 @@
     dependsOn("extractJars")
     kotlinOptions {
         useIR = true
+        jvmTarget = "1.8"
         freeCompilerArgs += [
                 // TODO: hack, apply compose plugin better.
                 "-Xplugin=${project.rootDir.absolutePath}/ui-desktop/compose-libs/compose-compiler.jar",
diff --git a/ui/ui-desktop/src/jvmMain/kotlin/androidx/ui/desktop/SkiaWindow.kt b/ui/ui-desktop/src/jvmMain/kotlin/androidx/ui/desktop/SkiaWindow.kt
index 6946fdc..72353f5 100644
--- a/ui/ui-desktop/src/jvmMain/kotlin/androidx/ui/desktop/SkiaWindow.kt
+++ b/ui/ui-desktop/src/jvmMain/kotlin/androidx/ui/desktop/SkiaWindow.kt
@@ -35,6 +35,8 @@
     var renderTarget: BackendRenderTarget? = null
     var surface: Surface? = null
     var canvas: Canvas? = null
+    var textureId: Int = 0
+    val intBuf1 = IntBuffer.allocate(1)
 
     fun clear() {
         if (surface != null) {
@@ -43,6 +45,7 @@
         if (renderTarget != null) {
             renderTarget!!.close()
         }
+        textureId = 0
     }
 }
 
@@ -73,6 +76,7 @@
         val profile = GLProfile.get(GLProfile.GL3)
         val capabilities = GLCapabilities(profile)
         glCanvas = GLCanvas(capabilities)
+        capabilities.doubleBuffered = true
         val skijaState = SkijaState()
         glCanvas.autoSwapBufferMode = true
 
@@ -84,12 +88,12 @@
                 width: Int,
                 height: Int
             ) {
-                initSkija(glCanvas, skijaState)
+                initSkija(glCanvas, skijaState, false)
                 renderer!!.onReshape(width, height)
             }
 
             override fun init(drawable: GLAutoDrawable?) {
-                initSkija(glCanvas, skijaState)
+                initSkija(glCanvas, skijaState, true)
                 renderer!!.onInit()
             }
 
@@ -99,11 +103,15 @@
 
             override fun display(drawable: GLAutoDrawable?) {
                 skijaState.apply {
+                    val gl = drawable!!.gl!!
+                    gl.glBindTexture(GL.GL_TEXTURE_2D, textureId)
                     canvas!!.clear(0xFFFFFFFF)
                     renderer!!.onRender(
                         canvas!!, glCanvas.width, glCanvas.height
                     )
                     context!!.flush()
+                    gl.glGetIntegerv(GL.GL_TEXTURE_BINDING_2D, intBuf1)
+                    textureId = intBuf1[0]
                 }
             }
         })
@@ -128,7 +136,7 @@
         }
     }
 
-    private fun initSkija(glCanvas: GLCanvas, skijaState: SkijaState) {
+    private fun initSkija(glCanvas: GLCanvas, skijaState: SkijaState, reinitTexture: Boolean) {
         with(skijaState) {
             val width = glCanvas.width
             val height = glCanvas.height
@@ -154,6 +162,10 @@
             )
             canvas = surface!!.canvas
             canvas!!.scale(dpi, dpi)
+            if (reinitTexture) {
+                glCanvas.gl.glGetIntegerv(GL.GL_TEXTURE_BINDING_2D, intBuf1)
+                skijaState.textureId = intBuf1[0]
+            }
         }
     }
 }
diff --git a/ui/ui-desktop/src/jvmMain/kotlin/androidx/ui/desktop/Wrapper.kt b/ui/ui-desktop/src/jvmMain/kotlin/androidx/ui/desktop/Wrapper.kt
index 85e3647..e985ef9 100644
--- a/ui/ui-desktop/src/jvmMain/kotlin/androidx/ui/desktop/Wrapper.kt
+++ b/ui/ui-desktop/src/jvmMain/kotlin/androidx/ui/desktop/Wrapper.kt
@@ -23,11 +23,7 @@
 import androidx.animation.ManualAnimationClock
 import androidx.compose.Composable
 import androidx.compose.Recomposer
-import androidx.ui.core.Modifier
-import androidx.ui.core.Owner
 import androidx.ui.core.setContent
-import androidx.ui.layout.padding
-import androidx.ui.unit.dp
 
 import javax.swing.SwingUtilities
 
@@ -35,23 +31,29 @@
 
 fun SkiaWindow.setContent(content: @Composable () -> Unit) {
     SwingUtilities.invokeLater {
-        println("start composing!")
-
-        rootAnimationClockFactory = { ManualAnimationClock(0L) }
+        val fps = 60
+        val clocks = mutableListOf<ManualAnimationClock>()
+        rootAnimationClockFactory = {
+            ManualAnimationClock(0L).also {
+                clocks.add(it)
+            }
+        }
         val context = object : Context() {}
         val viewGroup = object : ViewGroup(context) {}
         viewGroup.setContent(Recomposer.current(), content)
         val view = viewGroup.getChildAt(0)
-        // we need this to override the root drawLayer() - RenderNode are not ported yet
-        (view as Owner).root.modifier = Modifier.padding(0.dp)
         view.onAttachedToWindow()
 
-        this.renderer = Renderer(view)
-        this.setFps(60)
+        this.renderer = Renderer(view, clocks, fps)
+        this.setFps(fps)
     }
 }
 
-private class Renderer(val view: View) : SkiaRenderer {
+private class Renderer(
+    val view: View,
+    val clocks: List<ManualAnimationClock>,
+    val fps: Int
+) : SkiaRenderer {
     var androidCanvas: android.graphics.Canvas? = null
 
     override fun onInit() {
@@ -65,6 +67,9 @@
     }
 
     override fun onRender(canvas: Canvas, width: Int, height: Int) {
+        clocks.forEach {
+            it.clockTimeMillis += 1000 / fps
+        }
         if (androidCanvas == null) {
             androidCanvas = android.graphics.Canvas(canvas)
         }
diff --git a/ui/ui-desktop/src/jvmMain/kotlin/androidx/ui/desktop/example/Main.kt b/ui/ui-desktop/src/jvmMain/kotlin/androidx/ui/desktop/example/Main.kt
index 2ff5111..894f704 100644
--- a/ui/ui-desktop/src/jvmMain/kotlin/androidx/ui/desktop/example/Main.kt
+++ b/ui/ui-desktop/src/jvmMain/kotlin/androidx/ui/desktop/example/Main.kt
@@ -16,14 +16,23 @@
 package androidx.ui.desktop.example
 
 import androidx.compose.Composable
+import androidx.ui.core.Alignment
+import androidx.ui.core.Modifier
 import androidx.ui.graphics.Color
 import androidx.ui.desktop.SkiaWindow
 import androidx.ui.desktop.setContent
-import androidx.ui.foundation.Box
+import androidx.ui.foundation.Text
 import androidx.ui.foundation.drawBackground
-import androidx.ui.core.Modifier
+import androidx.ui.layout.Arrangement
+import androidx.ui.layout.Column
 import androidx.ui.layout.fillMaxSize
-import androidx.ui.layout.padding
+import androidx.ui.layout.wrapContentSize
+import androidx.ui.layout.preferredHeight
+import androidx.ui.material.Button
+import androidx.ui.material.CircularProgressIndicator
+import androidx.ui.material.ExtendedFloatingActionButton
+import androidx.ui.material.Scaffold
+import androidx.ui.material.TopAppBar
 import androidx.ui.unit.dp
 
 import javax.swing.WindowConstants
@@ -47,6 +56,36 @@
 
 @Composable
 fun App() {
-    Box(Modifier.fillMaxSize(), backgroundColor = Color.Green)
-    Box(Modifier.padding(40.dp) + Modifier.drawBackground(color = Color.Blue))
+    Scaffold(
+        topAppBar = {
+            TopAppBar(
+                title = { Text("Desktop Compose") }
+            )
+        },
+        floatingActionButton = {
+            ExtendedFloatingActionButton(
+                text = { Text("BUTTON") },
+                 }
+            )
+        },
+        bodyContent = { modifier ->
+            Column(modifier.fillMaxSize(), Arrangement.SpaceEvenly) {
+                Text(
+                    text = "Привет! 你好! Desktop Compose!",
+                    color = Color.Black,
+                    modifier = Modifier
+                        .drawBackground(Color.Blue)
+                        .preferredHeight(56.dp)
+                        .wrapContentSize(Alignment.Center)
+                )
+                var text = "Base"
+                Button(>
+                    text = "Clicked"
+                }) {
+                    Text(text)
+                }
+                CircularProgressIndicator()
+            }
+        }
+    )
 }
diff --git a/ui/ui-foundation/OWNERS b/ui/ui-foundation/OWNERS
index dd5e772..22210830 100644
--- a/ui/ui-foundation/OWNERS
+++ b/ui/ui-foundation/OWNERS
@@ -4,6 +4,7 @@
 malkov@google.com
 lpf@google.com
 tianliu@google.com
+soboleva@google.com
 
 # Text
 haoyuchang@google.com
diff --git a/ui/ui-foundation/api/0.1.0-dev12.txt b/ui/ui-foundation/api/0.1.0-dev12.txt
index 1b934f3..333d7fad 100644
--- a/ui/ui-foundation/api/0.1.0-dev12.txt
+++ b/ui/ui-foundation/api/0.1.0-dev12.txt
@@ -53,17 +53,10 @@
     method public static void Dialog(kotlin.jvm.functions.Function0<kotlin.Unit> onCloseRequest, kotlin.jvm.functions.Function0<kotlin.Unit> children);
   }
 
-  public final class DrawBackground implements androidx.ui.core.DrawModifier {
-    method public androidx.ui.foundation.DrawBackground copy(androidx.ui.graphics.Paint paint, androidx.ui.graphics.Shape shape);
-    method public void draw(androidx.ui.core.ContentDrawScope);
-  }
-
   public final class DrawBackgroundKt {
-    method @Deprecated public static androidx.ui.foundation.DrawBackground DrawBackground(androidx.ui.graphics.Brush brush, androidx.ui.graphics.Shape shape = androidx.ui.graphics.RectangleShapeKt.RectangleShape);
-    method @Deprecated public static androidx.ui.foundation.DrawBackground DrawBackground-qSsqlCY(long color, androidx.ui.graphics.Shape shape = androidx.ui.graphics.RectangleShapeKt.RectangleShape);
-    method public static androidx.ui.core.Modifier drawBackground(androidx.ui.core.Modifier, androidx.ui.graphics.Paint paint, androidx.ui.graphics.Shape shape);
-    method public static androidx.ui.core.Modifier drawBackground(androidx.ui.core.Modifier, androidx.ui.graphics.Brush brush, androidx.ui.graphics.Shape shape = androidx.ui.graphics.RectangleShapeKt.RectangleShape);
-    method public static androidx.ui.core.Modifier drawBackground-IZZjS-Q(androidx.ui.core.Modifier, long color, androidx.ui.graphics.Shape shape = androidx.ui.graphics.RectangleShapeKt.RectangleShape);
+    method @Deprecated public static androidx.ui.core.Modifier drawBackground(androidx.ui.core.Modifier, androidx.ui.graphics.Paint paint, androidx.ui.graphics.Shape shape);
+    method public static androidx.ui.core.Modifier drawBackground(androidx.ui.core.Modifier, androidx.ui.graphics.Brush brush, androidx.ui.graphics.Shape shape = androidx.ui.graphics.RectangleShapeKt.RectangleShape, @FloatRange(from=0.0, to=1.0) float alpha = 1.0f, androidx.ui.graphics.painter.DrawStyle style = Fill, androidx.ui.graphics.ColorFilter? colorFilter = null, androidx.ui.graphics.BlendMode blendMode = CanvasScope.DefaultBlendMode);
+    method public static androidx.ui.core.Modifier drawBackground-s1Ed2t0(androidx.ui.core.Modifier, long color, androidx.ui.graphics.Shape shape = androidx.ui.graphics.RectangleShapeKt.RectangleShape, @FloatRange(from=0.0, to=1.0) float alpha = 1.0f, androidx.ui.graphics.painter.DrawStyle style = Fill, androidx.ui.graphics.ColorFilter? colorFilter = null, androidx.ui.graphics.BlendMode blendMode = CanvasScope.DefaultBlendMode);
   }
 
   public final class DrawBorder implements androidx.ui.core.DrawModifier {
diff --git a/ui/ui-foundation/api/current.txt b/ui/ui-foundation/api/current.txt
index 1b934f3..333d7fad 100644
--- a/ui/ui-foundation/api/current.txt
+++ b/ui/ui-foundation/api/current.txt
@@ -53,17 +53,10 @@
     method public static void Dialog(kotlin.jvm.functions.Function0<kotlin.Unit> onCloseRequest, kotlin.jvm.functions.Function0<kotlin.Unit> children);
   }
 
-  public final class DrawBackground implements androidx.ui.core.DrawModifier {
-    method public androidx.ui.foundation.DrawBackground copy(androidx.ui.graphics.Paint paint, androidx.ui.graphics.Shape shape);
-    method public void draw(androidx.ui.core.ContentDrawScope);
-  }
-
   public final class DrawBackgroundKt {
-    method @Deprecated public static androidx.ui.foundation.DrawBackground DrawBackground(androidx.ui.graphics.Brush brush, androidx.ui.graphics.Shape shape = androidx.ui.graphics.RectangleShapeKt.RectangleShape);
-    method @Deprecated public static androidx.ui.foundation.DrawBackground DrawBackground-qSsqlCY(long color, androidx.ui.graphics.Shape shape = androidx.ui.graphics.RectangleShapeKt.RectangleShape);
-    method public static androidx.ui.core.Modifier drawBackground(androidx.ui.core.Modifier, androidx.ui.graphics.Paint paint, androidx.ui.graphics.Shape shape);
-    method public static androidx.ui.core.Modifier drawBackground(androidx.ui.core.Modifier, androidx.ui.graphics.Brush brush, androidx.ui.graphics.Shape shape = androidx.ui.graphics.RectangleShapeKt.RectangleShape);
-    method public static androidx.ui.core.Modifier drawBackground-IZZjS-Q(androidx.ui.core.Modifier, long color, androidx.ui.graphics.Shape shape = androidx.ui.graphics.RectangleShapeKt.RectangleShape);
+    method @Deprecated public static androidx.ui.core.Modifier drawBackground(androidx.ui.core.Modifier, androidx.ui.graphics.Paint paint, androidx.ui.graphics.Shape shape);
+    method public static androidx.ui.core.Modifier drawBackground(androidx.ui.core.Modifier, androidx.ui.graphics.Brush brush, androidx.ui.graphics.Shape shape = androidx.ui.graphics.RectangleShapeKt.RectangleShape, @FloatRange(from=0.0, to=1.0) float alpha = 1.0f, androidx.ui.graphics.painter.DrawStyle style = Fill, androidx.ui.graphics.ColorFilter? colorFilter = null, androidx.ui.graphics.BlendMode blendMode = CanvasScope.DefaultBlendMode);
+    method public static androidx.ui.core.Modifier drawBackground-s1Ed2t0(androidx.ui.core.Modifier, long color, androidx.ui.graphics.Shape shape = androidx.ui.graphics.RectangleShapeKt.RectangleShape, @FloatRange(from=0.0, to=1.0) float alpha = 1.0f, androidx.ui.graphics.painter.DrawStyle style = Fill, androidx.ui.graphics.ColorFilter? colorFilter = null, androidx.ui.graphics.BlendMode blendMode = CanvasScope.DefaultBlendMode);
   }
 
   public final class DrawBorder implements androidx.ui.core.DrawModifier {
diff --git a/ui/ui-foundation/api/public_plus_experimental_0.1.0-dev12.txt b/ui/ui-foundation/api/public_plus_experimental_0.1.0-dev12.txt
index 1b934f3..333d7fad 100644
--- a/ui/ui-foundation/api/public_plus_experimental_0.1.0-dev12.txt
+++ b/ui/ui-foundation/api/public_plus_experimental_0.1.0-dev12.txt
@@ -53,17 +53,10 @@
     method public static void Dialog(kotlin.jvm.functions.Function0<kotlin.Unit> onCloseRequest, kotlin.jvm.functions.Function0<kotlin.Unit> children);
   }
 
-  public final class DrawBackground implements androidx.ui.core.DrawModifier {
-    method public androidx.ui.foundation.DrawBackground copy(androidx.ui.graphics.Paint paint, androidx.ui.graphics.Shape shape);
-    method public void draw(androidx.ui.core.ContentDrawScope);
-  }
-
   public final class DrawBackgroundKt {
-    method @Deprecated public static androidx.ui.foundation.DrawBackground DrawBackground(androidx.ui.graphics.Brush brush, androidx.ui.graphics.Shape shape = androidx.ui.graphics.RectangleShapeKt.RectangleShape);
-    method @Deprecated public static androidx.ui.foundation.DrawBackground DrawBackground-qSsqlCY(long color, androidx.ui.graphics.Shape shape = androidx.ui.graphics.RectangleShapeKt.RectangleShape);
-    method public static androidx.ui.core.Modifier drawBackground(androidx.ui.core.Modifier, androidx.ui.graphics.Paint paint, androidx.ui.graphics.Shape shape);
-    method public static androidx.ui.core.Modifier drawBackground(androidx.ui.core.Modifier, androidx.ui.graphics.Brush brush, androidx.ui.graphics.Shape shape = androidx.ui.graphics.RectangleShapeKt.RectangleShape);
-    method public static androidx.ui.core.Modifier drawBackground-IZZjS-Q(androidx.ui.core.Modifier, long color, androidx.ui.graphics.Shape shape = androidx.ui.graphics.RectangleShapeKt.RectangleShape);
+    method @Deprecated public static androidx.ui.core.Modifier drawBackground(androidx.ui.core.Modifier, androidx.ui.graphics.Paint paint, androidx.ui.graphics.Shape shape);
+    method public static androidx.ui.core.Modifier drawBackground(androidx.ui.core.Modifier, androidx.ui.graphics.Brush brush, androidx.ui.graphics.Shape shape = androidx.ui.graphics.RectangleShapeKt.RectangleShape, @FloatRange(from=0.0, to=1.0) float alpha = 1.0f, androidx.ui.graphics.painter.DrawStyle style = Fill, androidx.ui.graphics.ColorFilter? colorFilter = null, androidx.ui.graphics.BlendMode blendMode = CanvasScope.DefaultBlendMode);
+    method public static androidx.ui.core.Modifier drawBackground-s1Ed2t0(androidx.ui.core.Modifier, long color, androidx.ui.graphics.Shape shape = androidx.ui.graphics.RectangleShapeKt.RectangleShape, @FloatRange(from=0.0, to=1.0) float alpha = 1.0f, androidx.ui.graphics.painter.DrawStyle style = Fill, androidx.ui.graphics.ColorFilter? colorFilter = null, androidx.ui.graphics.BlendMode blendMode = CanvasScope.DefaultBlendMode);
   }
 
   public final class DrawBorder implements androidx.ui.core.DrawModifier {
diff --git a/ui/ui-foundation/api/public_plus_experimental_current.txt b/ui/ui-foundation/api/public_plus_experimental_current.txt
index 1b934f3..333d7fad 100644
--- a/ui/ui-foundation/api/public_plus_experimental_current.txt
+++ b/ui/ui-foundation/api/public_plus_experimental_current.txt
@@ -53,17 +53,10 @@
     method public static void Dialog(kotlin.jvm.functions.Function0<kotlin.Unit> onCloseRequest, kotlin.jvm.functions.Function0<kotlin.Unit> children);
   }
 
-  public final class DrawBackground implements androidx.ui.core.DrawModifier {
-    method public androidx.ui.foundation.DrawBackground copy(androidx.ui.graphics.Paint paint, androidx.ui.graphics.Shape shape);
-    method public void draw(androidx.ui.core.ContentDrawScope);
-  }
-
   public final class DrawBackgroundKt {
-    method @Deprecated public static androidx.ui.foundation.DrawBackground DrawBackground(androidx.ui.graphics.Brush brush, androidx.ui.graphics.Shape shape = androidx.ui.graphics.RectangleShapeKt.RectangleShape);
-    method @Deprecated public static androidx.ui.foundation.DrawBackground DrawBackground-qSsqlCY(long color, androidx.ui.graphics.Shape shape = androidx.ui.graphics.RectangleShapeKt.RectangleShape);
-    method public static androidx.ui.core.Modifier drawBackground(androidx.ui.core.Modifier, androidx.ui.graphics.Paint paint, androidx.ui.graphics.Shape shape);
-    method public static androidx.ui.core.Modifier drawBackground(androidx.ui.core.Modifier, androidx.ui.graphics.Brush brush, androidx.ui.graphics.Shape shape = androidx.ui.graphics.RectangleShapeKt.RectangleShape);
-    method public static androidx.ui.core.Modifier drawBackground-IZZjS-Q(androidx.ui.core.Modifier, long color, androidx.ui.graphics.Shape shape = androidx.ui.graphics.RectangleShapeKt.RectangleShape);
+    method @Deprecated public static androidx.ui.core.Modifier drawBackground(androidx.ui.core.Modifier, androidx.ui.graphics.Paint paint, androidx.ui.graphics.Shape shape);
+    method public static androidx.ui.core.Modifier drawBackground(androidx.ui.core.Modifier, androidx.ui.graphics.Brush brush, androidx.ui.graphics.Shape shape = androidx.ui.graphics.RectangleShapeKt.RectangleShape, @FloatRange(from=0.0, to=1.0) float alpha = 1.0f, androidx.ui.graphics.painter.DrawStyle style = Fill, androidx.ui.graphics.ColorFilter? colorFilter = null, androidx.ui.graphics.BlendMode blendMode = CanvasScope.DefaultBlendMode);
+    method public static androidx.ui.core.Modifier drawBackground-s1Ed2t0(androidx.ui.core.Modifier, long color, androidx.ui.graphics.Shape shape = androidx.ui.graphics.RectangleShapeKt.RectangleShape, @FloatRange(from=0.0, to=1.0) float alpha = 1.0f, androidx.ui.graphics.painter.DrawStyle style = Fill, androidx.ui.graphics.ColorFilter? colorFilter = null, androidx.ui.graphics.BlendMode blendMode = CanvasScope.DefaultBlendMode);
   }
 
   public final class DrawBorder implements androidx.ui.core.DrawModifier {
diff --git a/ui/ui-foundation/api/restricted_0.1.0-dev12.txt b/ui/ui-foundation/api/restricted_0.1.0-dev12.txt
index 1b934f3..333d7fad 100644
--- a/ui/ui-foundation/api/restricted_0.1.0-dev12.txt
+++ b/ui/ui-foundation/api/restricted_0.1.0-dev12.txt
@@ -53,17 +53,10 @@
     method public static void Dialog(kotlin.jvm.functions.Function0<kotlin.Unit> onCloseRequest, kotlin.jvm.functions.Function0<kotlin.Unit> children);
   }
 
-  public final class DrawBackground implements androidx.ui.core.DrawModifier {
-    method public androidx.ui.foundation.DrawBackground copy(androidx.ui.graphics.Paint paint, androidx.ui.graphics.Shape shape);
-    method public void draw(androidx.ui.core.ContentDrawScope);
-  }
-
   public final class DrawBackgroundKt {
-    method @Deprecated public static androidx.ui.foundation.DrawBackground DrawBackground(androidx.ui.graphics.Brush brush, androidx.ui.graphics.Shape shape = androidx.ui.graphics.RectangleShapeKt.RectangleShape);
-    method @Deprecated public static androidx.ui.foundation.DrawBackground DrawBackground-qSsqlCY(long color, androidx.ui.graphics.Shape shape = androidx.ui.graphics.RectangleShapeKt.RectangleShape);
-    method public static androidx.ui.core.Modifier drawBackground(androidx.ui.core.Modifier, androidx.ui.graphics.Paint paint, androidx.ui.graphics.Shape shape);
-    method public static androidx.ui.core.Modifier drawBackground(androidx.ui.core.Modifier, androidx.ui.graphics.Brush brush, androidx.ui.graphics.Shape shape = androidx.ui.graphics.RectangleShapeKt.RectangleShape);
-    method public static androidx.ui.core.Modifier drawBackground-IZZjS-Q(androidx.ui.core.Modifier, long color, androidx.ui.graphics.Shape shape = androidx.ui.graphics.RectangleShapeKt.RectangleShape);
+    method @Deprecated public static androidx.ui.core.Modifier drawBackground(androidx.ui.core.Modifier, androidx.ui.graphics.Paint paint, androidx.ui.graphics.Shape shape);
+    method public static androidx.ui.core.Modifier drawBackground(androidx.ui.core.Modifier, androidx.ui.graphics.Brush brush, androidx.ui.graphics.Shape shape = androidx.ui.graphics.RectangleShapeKt.RectangleShape, @FloatRange(from=0.0, to=1.0) float alpha = 1.0f, androidx.ui.graphics.painter.DrawStyle style = Fill, androidx.ui.graphics.ColorFilter? colorFilter = null, androidx.ui.graphics.BlendMode blendMode = CanvasScope.DefaultBlendMode);
+    method public static androidx.ui.core.Modifier drawBackground-s1Ed2t0(androidx.ui.core.Modifier, long color, androidx.ui.graphics.Shape shape = androidx.ui.graphics.RectangleShapeKt.RectangleShape, @FloatRange(from=0.0, to=1.0) float alpha = 1.0f, androidx.ui.graphics.painter.DrawStyle style = Fill, androidx.ui.graphics.ColorFilter? colorFilter = null, androidx.ui.graphics.BlendMode blendMode = CanvasScope.DefaultBlendMode);
   }
 
   public final class DrawBorder implements androidx.ui.core.DrawModifier {
diff --git a/ui/ui-foundation/api/restricted_current.txt b/ui/ui-foundation/api/restricted_current.txt
index 1b934f3..333d7fad 100644
--- a/ui/ui-foundation/api/restricted_current.txt
+++ b/ui/ui-foundation/api/restricted_current.txt
@@ -53,17 +53,10 @@
     method public static void Dialog(kotlin.jvm.functions.Function0<kotlin.Unit> onCloseRequest, kotlin.jvm.functions.Function0<kotlin.Unit> children);
   }
 
-  public final class DrawBackground implements androidx.ui.core.DrawModifier {
-    method public androidx.ui.foundation.DrawBackground copy(androidx.ui.graphics.Paint paint, androidx.ui.graphics.Shape shape);
-    method public void draw(androidx.ui.core.ContentDrawScope);
-  }
-
   public final class DrawBackgroundKt {
-    method @Deprecated public static androidx.ui.foundation.DrawBackground DrawBackground(androidx.ui.graphics.Brush brush, androidx.ui.graphics.Shape shape = androidx.ui.graphics.RectangleShapeKt.RectangleShape);
-    method @Deprecated public static androidx.ui.foundation.DrawBackground DrawBackground-qSsqlCY(long color, androidx.ui.graphics.Shape shape = androidx.ui.graphics.RectangleShapeKt.RectangleShape);
-    method public static androidx.ui.core.Modifier drawBackground(androidx.ui.core.Modifier, androidx.ui.graphics.Paint paint, androidx.ui.graphics.Shape shape);
-    method public static androidx.ui.core.Modifier drawBackground(androidx.ui.core.Modifier, androidx.ui.graphics.Brush brush, androidx.ui.graphics.Shape shape = androidx.ui.graphics.RectangleShapeKt.RectangleShape);
-    method public static androidx.ui.core.Modifier drawBackground-IZZjS-Q(androidx.ui.core.Modifier, long color, androidx.ui.graphics.Shape shape = androidx.ui.graphics.RectangleShapeKt.RectangleShape);
+    method @Deprecated public static androidx.ui.core.Modifier drawBackground(androidx.ui.core.Modifier, androidx.ui.graphics.Paint paint, androidx.ui.graphics.Shape shape);
+    method public static androidx.ui.core.Modifier drawBackground(androidx.ui.core.Modifier, androidx.ui.graphics.Brush brush, androidx.ui.graphics.Shape shape = androidx.ui.graphics.RectangleShapeKt.RectangleShape, @FloatRange(from=0.0, to=1.0) float alpha = 1.0f, androidx.ui.graphics.painter.DrawStyle style = Fill, androidx.ui.graphics.ColorFilter? colorFilter = null, androidx.ui.graphics.BlendMode blendMode = CanvasScope.DefaultBlendMode);
+    method public static androidx.ui.core.Modifier drawBackground-s1Ed2t0(androidx.ui.core.Modifier, long color, androidx.ui.graphics.Shape shape = androidx.ui.graphics.RectangleShapeKt.RectangleShape, @FloatRange(from=0.0, to=1.0) float alpha = 1.0f, androidx.ui.graphics.painter.DrawStyle style = Fill, androidx.ui.graphics.ColorFilter? colorFilter = null, androidx.ui.graphics.BlendMode blendMode = CanvasScope.DefaultBlendMode);
   }
 
   public final class DrawBorder implements androidx.ui.core.DrawModifier {
diff --git a/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/TextFieldFocusTest.kt b/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/TextFieldFocusTest.kt
index 4e5d527..7aaa314 100644
--- a/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/TextFieldFocusTest.kt
+++ b/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/TextFieldFocusTest.kt
@@ -22,7 +22,7 @@
 import androidx.test.filters.LargeTest
 import androidx.ui.core.Modifier
 import androidx.ui.core.TestTag
-import androidx.ui.focus.FocusModifier
+import androidx.ui.core.focus.FocusModifier
 import androidx.ui.input.EditorValue
 import androidx.ui.layout.width
 import androidx.ui.test.createComposeRule
diff --git a/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/TextFieldTest.kt b/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/TextFieldTest.kt
index 716f611..5a019b5 100644
--- a/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/TextFieldTest.kt
+++ b/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/TextFieldTest.kt
@@ -27,9 +27,9 @@
 import androidx.ui.core.TestTag
 import androidx.ui.core.TextInputServiceAmbient
 import androidx.ui.core.onPositioned
-import androidx.ui.focus.FocusModifier
-import androidx.ui.focus.FocusState
-import androidx.ui.focus.focusState
+import androidx.ui.core.focus.FocusModifier
+import androidx.ui.core.focus.FocusState
+import androidx.ui.core.focus.focusState
 import androidx.ui.graphics.Color
 import androidx.ui.graphics.RectangleShape
 import androidx.ui.input.CommitTextEditOp
diff --git a/ui/ui-foundation/src/main/java/androidx/ui/foundation/DrawBackground.kt b/ui/ui-foundation/src/main/java/androidx/ui/foundation/DrawBackground.kt
index b2767ad..d7fbdae 100644
--- a/ui/ui-foundation/src/main/java/androidx/ui/foundation/DrawBackground.kt
+++ b/ui/ui-foundation/src/main/java/androidx/ui/foundation/DrawBackground.kt
@@ -16,117 +16,129 @@
 
 package androidx.ui.foundation
 
-import androidx.compose.Composable
-import androidx.compose.remember
+import androidx.annotation.FloatRange
 import androidx.ui.core.ContentDrawScope
 import androidx.ui.core.DrawModifier
 import androidx.ui.core.Modifier
-import androidx.ui.core.composed
 import androidx.ui.geometry.Size
-import androidx.ui.geometry.toRect
+import androidx.ui.graphics.BlendMode
 import androidx.ui.graphics.Brush
 import androidx.ui.graphics.Color
+import androidx.ui.graphics.ColorFilter
 import androidx.ui.graphics.Outline
 import androidx.ui.graphics.Paint
 import androidx.ui.graphics.RectangleShape
 import androidx.ui.graphics.Shape
-import androidx.ui.graphics.SolidColor
 import androidx.ui.graphics.drawOutline
+import androidx.ui.graphics.painter.CanvasScope
+import androidx.ui.graphics.painter.DrawStyle
+import androidx.ui.graphics.painter.Fill
 import androidx.ui.graphics.painter.drawCanvas
 import androidx.ui.unit.Px
 import androidx.ui.unit.PxSize
+import androidx.ui.unit.toRect
 
 /**
- * Returns a [DrawModifier] that draws [shape] with a solid [color], with the size of the
- * layout's rectangle.
+ * Draws [shape] with [paint] behind the content.
+ */
+@Deprecated("Prefer usage of drawBackground(color, shape) or " +
+        "drawBackground(brush, shape)",
+    ReplaceWith("Modifier.drawBackground(color, shape)"))
+fun Modifier.drawBackground(
+    paint: Paint,
+    shape: Shape
+) = this + DrawBackground(
+                shape,
+                {
+                    drawCanvas { canvas, size ->
+                        canvas.drawRect(size.toRect(), paint)
+                    }
+                },
+                { outline ->
+                    drawCanvas { canvas, _ ->
+                        canvas.drawOutline(outline, paint)
+                    }
+                }
+            )
+
+/**
+ * Draws [shape] with a solid [color] behind the content.
  *
  * @sample androidx.ui.foundation.samples.DrawBackgroundColor
  *
  * @param color color to paint background with
  * @param shape desired shape of the background
  */
-@Suppress("DEPRECATION")
-@Deprecated(
-    "Use Modifier.drawBackground",
-    replaceWith = ReplaceWith(
-        "Modifier.drawBackground(color, shape)",
-        "androidx.ui.core.Modifier",
-        "androidx.ui.foundation.drawBackground",
-        "androidx.ui.foundation.shape.RectangleShape"
-    )
-)
-@Composable
-fun DrawBackground(color: Color, shape: Shape = RectangleShape): DrawBackground =
-    DrawBackground(SolidColor(color), shape)
+fun Modifier.drawBackground(
+    color: Color,
+    shape: Shape = RectangleShape,
+    @FloatRange(from = 0.0, to = 1.0) alpha: Float = CanvasScope.DefaultAlpha,
+    style: DrawStyle = Fill,
+    colorFilter: ColorFilter? = null,
+    blendMode: BlendMode = CanvasScope.DefaultBlendMode
+) = this + DrawBackground(
+                shape,
+                {
+                    drawRect(
+                        color,
+                        alpha = alpha,
+                        style = style,
+                        colorFilter = colorFilter,
+                        blendMode = blendMode
+                    )
+                },
+                { outline ->
+                    drawOutline(
+                        outline,
+                        color,
+                        alpha = alpha,
+                        style = style,
+                        colorFilter = colorFilter,
+                        blendMode = blendMode
+                    )
+                }
+            )
 
 /**
- * Returns a [DrawModifier] that draws [shape] with [brush], with the size of the layout's
- * rectangle.
+ * Draws [shape] with [brush] behind the content.
  *
  * @sample androidx.ui.foundation.samples.DrawBackgroundShapedBrush
  *
  * @param brush brush to paint background with
  * @param shape desired shape of the background
  */
-@Deprecated(
-    "Use Modifier.drawBackground",
-    replaceWith = ReplaceWith(
-        "Modifier.drawBackground(brush, shape)",
-        "androidx.ui.core.Modifier",
-        "androidx.ui.foundation.drawBackground",
-        "androidx.ui.foundation.shape.RectangleShape"
-    )
-)
-@Composable
-fun DrawBackground(brush: Brush, shape: Shape = RectangleShape): DrawBackground {
-    return remember(shape, brush) {
-        val paint = Paint().also {
-            brush.applyTo(it)
-        }
-        DrawBackground(paint, shape)
-    }
-}
-
-/**
- * Draws [shape] with [paint] behind the content.
- */
-fun Modifier.drawBackground(
-    paint: Paint,
-    shape: Shape
-) = this + DrawBackground(paint, shape)
-
-/**
- * Draws [shape] with a solid [color] behind the content.
- *
- * @param color color to paint background with
- * @param shape desired shape of the background
- */
-fun Modifier.drawBackground(
-    color: Color,
-    shape: Shape = RectangleShape
-) = drawBackground(SolidColor(color), shape)
-
-/**
- * Draws [shape] with [brush] behind the content.
- *
- * @param brush brush to paint background with
- * @param shape desired shape of the background
- */
 fun Modifier.drawBackground(
     brush: Brush,
-    shape: Shape = RectangleShape
-) = composed {
-    drawBackground(
-        remember(brush) {
-            Paint().also { brush.applyTo(it) }
-        },
-        shape
-    )
-}
+    shape: Shape = RectangleShape,
+    @FloatRange(from = 0.0, to = 1.0) alpha: Float = CanvasScope.DefaultAlpha,
+    style: DrawStyle = Fill,
+    colorFilter: ColorFilter? = null,
+    blendMode: BlendMode = CanvasScope.DefaultBlendMode
+) = this + DrawBackground(
+                shape,
+                { drawRect(
+                        brush = brush,
+                        alpha = alpha,
+                        style = style,
+                        colorFilter = colorFilter,
+                        blendMode = blendMode
+                    )
+                },
+                { outline ->
+                    drawOutline(outline,
+                        brush,
+                        alpha = alpha,
+                        style = style,
+                        colorFilter = colorFilter,
+                        blendMode = blendMode
+                    )
+                }
+            )
 
-data class DrawBackground internal constructor(
-    private val paint: Paint,
-    private val shape: Shape
+private data class DrawBackground internal constructor(
+    private val shape: Shape,
+    private val drawRect: ContentDrawScope.() -> Unit,
+    private val drawOutline: ContentDrawScope.(outline: Outline) -> Unit
 ) : DrawModifier {
 
     // naive cache outline calculation if size is the same
@@ -134,23 +146,21 @@
     private var lastOutline: Outline? = null
 
     override fun ContentDrawScope.draw() {
-        drawCanvas { canvas, _ ->
-            if (shape === RectangleShape) {
-                // shortcut to avoid Outline calculation and allocation
-                canvas.drawRect(size.toRect(), paint)
-            } else {
-                val localOutline =
-                    if (size == lastSize) {
-                        lastOutline!!
-                    } else {
-                        val pxSize = PxSize(Px(size.width), Px(size.height))
-                        shape.createOutline(pxSize, this)
-                    }
-                canvas.drawOutline(localOutline, paint)
-                lastOutline = localOutline
-                lastSize = size
-            }
-            drawContent()
+        if (shape === RectangleShape) {
+            // shortcut to avoid Outline calculation and allocation
+            drawRect()
+        } else {
+            val localOutline =
+                if (size == lastSize) {
+                    lastOutline!!
+                } else {
+                    val pxSize = PxSize(Px(size.width), Px(size.height))
+                    shape.createOutline(pxSize, this)
+                }
+            drawOutline(localOutline)
+            lastOutline = localOutline
+            lastSize = size
         }
+        drawContent()
     }
 }
\ No newline at end of file
diff --git a/ui/ui-foundation/src/main/java/androidx/ui/foundation/DrawBorder.kt b/ui/ui-foundation/src/main/java/androidx/ui/foundation/DrawBorder.kt
index 77c5a40..9e6ca6f 100644
--- a/ui/ui-foundation/src/main/java/androidx/ui/foundation/DrawBorder.kt
+++ b/ui/ui-foundation/src/main/java/androidx/ui/foundation/DrawBorder.kt
@@ -20,25 +20,25 @@
 import androidx.compose.remember
 import androidx.ui.core.ContentDrawScope
 import androidx.ui.core.DrawModifier
+import androidx.ui.core.DrawScope
 import androidx.ui.core.Modifier
 import androidx.ui.core.composed
 import androidx.ui.geometry.Offset
 import androidx.ui.geometry.Rect
+import androidx.ui.geometry.Size
 import androidx.ui.geometry.isSimple
 import androidx.ui.geometry.outerRect
 import androidx.ui.graphics.Brush
-import androidx.ui.graphics.Canvas
 import androidx.ui.graphics.Color
 import androidx.ui.graphics.Outline
-import androidx.ui.graphics.Paint
-import androidx.ui.graphics.PaintingStyle
 import androidx.ui.graphics.Path
 import androidx.ui.graphics.PathOperation
 import androidx.ui.graphics.RectangleShape
 import androidx.ui.graphics.Shape
 import androidx.ui.graphics.SolidColor
 import androidx.ui.graphics.addOutline
-import androidx.ui.graphics.painter.drawCanvas
+import androidx.ui.graphics.painter.Fill
+import androidx.ui.graphics.painter.Stroke
 import androidx.ui.unit.Density
 import androidx.ui.unit.Dp
 import androidx.ui.unit.Px
@@ -171,57 +171,47 @@
 
     override fun ContentDrawScope.draw() {
         val density = this
-        drawCanvas { canvas, _ ->
-            with(cache) {
-                drawContent()
-                modifierSize = PxSize(Px(size.width), Px(size.height))
-                val outline = modifierSizeOutline(density)
-                val borderSize =
-                    if (borderWidth == Dp.Hairline) 1f else borderWidth.value * density.density
-                brush.applyTo(paint)
-                paint.strokeWidth = borderSize
-
-                if (borderSize <= 0 || size.minDimension <= 0.0f) {
-                    return
-                } else if (outline is Outline.Rectangle) {
-                    drawRoundRectBorder(borderSize, outline.rect, 0f, canvas, paint)
-                } else if (outline is Outline.Rounded && outline.rrect.isSimple) {
-                    val radius = outline.rrect.bottomLeftRadiusY
-                    drawRoundRectBorder(
-                        borderSize,
-                        outline.rrect.outerRect(),
-                        radius,
-                        canvas,
-                        paint
-                    )
-                } else {
-                    val path = borderPath(density, borderSize)
-                    paint.style = PaintingStyle.fill
-                    canvas.drawPath(path, paint)
-                }
+        with(cache) {
+            drawContent()
+            modifierSize = PxSize(Px(size.width), Px(size.height))
+            val outline = modifierSizeOutline(density)
+            val borderSize =
+                if (borderWidth == Dp.Hairline) 1f else borderWidth.value * density.density
+            if (borderSize <= 0 || size.minDimension <= 0.0f) {
+                return
+            } else if (outline is Outline.Rectangle) {
+                drawRoundRectBorder(borderSize, outline.rect, 0f, brush)
+            } else if (outline is Outline.Rounded && outline.rrect.isSimple) {
+                val radius = outline.rrect.bottomLeftRadiusY
+                drawRoundRectBorder(
+                    borderSize,
+                    outline.rrect.outerRect(),
+                    radius,
+                    brush
+                )
+            } else {
+                drawPath(borderPath(density, borderSize), brush)
             }
         }
     }
 
-    private fun drawRoundRectBorder(
+    private fun DrawScope.drawRoundRectBorder(
         borderSize: Float,
         rect: Rect,
         radius: Float,
-        canvas: Canvas,
-        paint: Paint
+        brush: Brush
     ) {
         val fillWithBorder = borderSize * 2 >= rect.minDimension
-        paint.style = if (fillWithBorder) PaintingStyle.fill else PaintingStyle.stroke
+        val style = if (fillWithBorder) Fill else Stroke(borderSize)
 
         val delta = if (fillWithBorder) 0f else borderSize / 2
-        canvas.drawRoundRect(
-            left = rect.left + delta,
-            top = rect.top + delta,
-            right = rect.right - delta,
-            bottom = rect.bottom - delta,
+        drawRoundRect(
+            brush,
+            topLeft = Offset(rect.left + delta, rect.top + delta),
+            size = Size(rect.width - 2 * delta, rect.height - 2 * delta),
             radiusX = radius,
             radiusY = radius,
-            paint = paint
+            style = style
         )
     }
 
@@ -255,8 +245,6 @@
     private var dirtyOutline = true
     private var outline: Outline? = null
 
-    val paint = Paint().apply { isAntiAlias = true }
-
     var lastShape: Shape? = null
         set(value) {
             if (value != field) {
diff --git a/ui/ui-foundation/src/main/java/androidx/ui/foundation/TextField.kt b/ui/ui-foundation/src/main/java/androidx/ui/foundation/TextField.kt
index 7491312..6ca3992 100644
--- a/ui/ui-foundation/src/main/java/androidx/ui/foundation/TextField.kt
+++ b/ui/ui-foundation/src/main/java/androidx/ui/foundation/TextField.kt
@@ -24,7 +24,7 @@
 import androidx.compose.state
 import androidx.ui.core.Modifier
 import androidx.ui.core.drawBehind
-import androidx.ui.focus.FocusModifier
+import androidx.ui.core.focus.FocusModifier
 import androidx.ui.geometry.Offset
 import androidx.ui.geometry.Rect
 import androidx.ui.graphics.Color
diff --git a/ui/ui-geometry/api/api_lint.ignore b/ui/ui-geometry/api/api_lint.ignore
index db1ca8b..ea11d6f 100644
--- a/ui/ui-geometry/api/api_lint.ignore
+++ b/ui/ui-geometry/api/api_lint.ignore
@@ -1,13 +1,9 @@
 // Baseline format: 1.0
+AcronymName: androidx.ui.geometry.Rect.Companion#fromCircle-hSKLB2U(long, float):
+    Acronyms should not be capitalized in method names: was `fromCircle-hSKLB2U`, should this be `fromCircle-hSklB2U`?
 AcronymName: androidx.ui.geometry.Rect.Companion#fromLTRB(float, float, float, float):
     Acronyms should not be capitalized in method names: was `fromLTRB`, should this be `fromLtrb`?
 AcronymName: androidx.ui.geometry.Rect.Companion#fromLTWH(float, float, float, float):
     Acronyms should not be capitalized in method names: was `fromLTWH`, should this be `fromLtwh`?
-
-
-KotlinOperator: androidx.ui.geometry.RRect#contains(androidx.ui.geometry.Offset):
-    Note that adding the `operator` keyword would allow calling this method using operator syntax
-KotlinOperator: androidx.ui.geometry.Rect#contains(androidx.ui.geometry.Offset):
-    Note that adding the `operator` keyword would allow calling this method using operator syntax
-KotlinOperator: androidx.ui.geometry.Size#contains(androidx.ui.geometry.Offset):
-    Note that adding the `operator` keyword would allow calling this method using operator syntax
+AcronymName: androidx.ui.geometry.Size.Companion#lerp-T-c3OIQ(long, long, float):
+    Acronyms should not be capitalized in method names: was `lerp-T-c3OIQ`, should this be `lerp-T-c3Oiq`?
diff --git a/ui/ui-geometry/build.gradle b/ui/ui-geometry/build.gradle
index b6e818e..7a07948 100644
--- a/ui/ui-geometry/build.gradle
+++ b/ui/ui-geometry/build.gradle
@@ -25,26 +25,29 @@
     id("AndroidXPlugin")
     id("com.android.library")
     id("AndroidXUiPlugin")
-    id("org.jetbrains.kotlin.android")
+    id("kotlin-multiplatform")
 }
 
-dependencies {
-    implementation(KOTLIN_STDLIB)
+kotlin {
+    android()
+    sourceSets {
+        commonMain.dependencies {
+            implementation(KOTLIN_STDLIB_COMMON)
 
-    api "androidx.annotation:annotation:1.1.0"
-    implementation project(":ui:ui-util")
+            implementation project(":ui:ui-util")
+            implementation project(":compose:compose-runtime")
+        }
+        jvmMain.dependencies {
+            implementation(KOTLIN_STDLIB)
+        }
+        androidMain.dependencies {
+            api "androidx.annotation:annotation:1.1.0"
+        }
 
-    implementation project(":compose:compose-runtime")
-
-    testImplementation(ANDROIDX_TEST_RULES)
-    testImplementation(ANDROIDX_TEST_RUNNER)
-    testImplementation(JUNIT)
-    testImplementation(TRUTH)
-
-    androidTestImplementation(ANDROIDX_TEST_RULES)
-    androidTestImplementation(ANDROIDX_TEST_RUNNER)
-    androidTestImplementation(ESPRESSO_CORE)
-    androidTestImplementation(JUNIT)
+        commonTest.dependencies {
+            implementation kotlin("test-junit")
+        }
+    }
 }
 
 androidx {
@@ -58,8 +61,7 @@
 
 tasks.withType(KotlinCompile).configureEach {
     kotlinOptions {
-        freeCompilerArgs += ["-Xuse-experimental=kotlin.Experimental", "-XXLanguage:+InlineClasses"]
+        freeCompilerArgs += ["-XXLanguage:+InlineClasses"]
         useIR = true
     }
-}
-
+}
\ No newline at end of file
diff --git a/ui/ui-geometry/src/main/AndroidManifest.xml b/ui/ui-geometry/src/androidMain/AndroidManifest.xml
similarity index 100%
rename from ui/ui-geometry/src/main/AndroidManifest.xml
rename to ui/ui-geometry/src/androidMain/AndroidManifest.xml
diff --git a/ui/ui-geometry/src/main/java/androidx/ui/geometry/Offset.kt b/ui/ui-geometry/src/commonMain/kotlin/androidx/ui/geometry/Offset.kt
similarity index 100%
rename from ui/ui-geometry/src/main/java/androidx/ui/geometry/Offset.kt
rename to ui/ui-geometry/src/commonMain/kotlin/androidx/ui/geometry/Offset.kt
diff --git a/ui/ui-geometry/src/main/java/androidx/ui/geometry/OffsetBase.kt b/ui/ui-geometry/src/commonMain/kotlin/androidx/ui/geometry/OffsetBase.kt
similarity index 100%
rename from ui/ui-geometry/src/main/java/androidx/ui/geometry/OffsetBase.kt
rename to ui/ui-geometry/src/commonMain/kotlin/androidx/ui/geometry/OffsetBase.kt
diff --git a/ui/ui-geometry/src/main/java/androidx/ui/geometry/RRect.kt b/ui/ui-geometry/src/commonMain/kotlin/androidx/ui/geometry/RRect.kt
similarity index 94%
rename from ui/ui-geometry/src/main/java/androidx/ui/geometry/RRect.kt
rename to ui/ui-geometry/src/commonMain/kotlin/androidx/ui/geometry/RRect.kt
index 6ba68ed..e093dab 100644
--- a/ui/ui-geometry/src/main/java/androidx/ui/geometry/RRect.kt
+++ b/ui/ui-geometry/src/commonMain/kotlin/androidx/ui/geometry/RRect.kt
@@ -19,6 +19,8 @@
 import androidx.ui.util.lerp
 import androidx.ui.util.toStringAsFixed
 import kotlin.math.absoluteValue
+import kotlin.math.max
+import kotlin.math.min
 
 /**
  * An immutable rounded rectangle with custom radii for all four corners.
@@ -101,7 +103,7 @@
     private fun minRadius(min: Float, radius1: Float, radius2: Float, limit: Float): Float {
         val sum = radius1 + radius2
         return if (sum > limit && sum != 0.0f) {
-            Math.min(min, limit / sum)
+            min(min, limit / sum)
         } else {
             min
         }
@@ -216,7 +218,7 @@
 
     companion object {
         /** A rounded rectangle with all the values set to zero. */
-        @JvmStatic
+        @kotlin.jvm.JvmStatic
         val Zero = RRect(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)
     }
 }
@@ -416,12 +418,12 @@
  * respective quadrant bisector.
  */
 fun RRect.safeInnerRect(): Rect {
-    val insetFactor = 0.29289321881f; // 1-cos(pi/4)
+    val insetFactor = 0.29289321881f // 1-cos(pi/4)
 
-    val leftRadius = Math.max(bottomLeftRadiusX, topLeftRadiusX)
-    val topRadius = Math.max(topLeftRadiusY, topRightRadiusY)
-    val rightRadius = Math.max(topRightRadiusX, bottomRightRadiusX)
-    val bottomRadius = Math.max(bottomRightRadiusY, bottomLeftRadiusY)
+    val leftRadius = max(bottomLeftRadiusX, topLeftRadiusX)
+    val topRadius = max(topLeftRadiusY, topRightRadiusY)
+    val rightRadius = max(topRightRadiusX, bottomRightRadiusX)
+    val bottomRadius = max(bottomRightRadiusY, bottomLeftRadiusY)
 
     return Rect.fromLTRB(
         left + leftRadius * insetFactor,
@@ -440,10 +442,10 @@
  * or height.
  */
 fun RRect.middleRect(): Rect {
-    val leftRadius = Math.max(bottomLeftRadiusX, topLeftRadiusX)
-    val topRadius = Math.max(topLeftRadiusY, topRightRadiusY)
-    val rightRadius = Math.max(topRightRadiusX, bottomRightRadiusX)
-    val bottomRadius = Math.max(bottomRightRadiusY, bottomLeftRadiusY)
+    val leftRadius = max(bottomLeftRadiusX, topLeftRadiusX)
+    val topRadius = max(topLeftRadiusY, topRightRadiusY)
+    val rightRadius = max(topRightRadiusX, bottomRightRadiusX)
+    val bottomRadius = max(bottomRightRadiusY, bottomLeftRadiusY)
     return Rect.fromLTRB(
         left + leftRadius,
         top + topRadius,
@@ -459,8 +461,8 @@
  * resulting [Rect] will have negative width or height.
  */
 fun RRect.wideMiddleRect(): Rect {
-    val topRadius = Math.max(topLeftRadiusY, topRightRadiusY)
-    val bottomRadius = Math.max(bottomRightRadiusY, bottomLeftRadiusY)
+    val topRadius = max(topLeftRadiusY, topRightRadiusY)
+    val bottomRadius = max(bottomRightRadiusY, bottomLeftRadiusY)
     return Rect.fromLTRB(
         left,
         top + topRadius,
@@ -476,8 +478,8 @@
  * resulting [Rect] will have negative width or height.
  */
 fun RRect.tallMiddleRect(): Rect {
-    val leftRadius = Math.max(bottomLeftRadiusX, topLeftRadiusX)
-    val rightRadius = Math.max(topRightRadiusX, bottomRightRadiusX)
+    val leftRadius = max(bottomLeftRadiusX, topLeftRadiusX)
+    val rightRadius = max(topRightRadiusX, bottomRightRadiusX)
     return Rect.fromLTRB(
         left + leftRadius,
         top,
@@ -527,13 +529,13 @@
  * The lesser of the magnitudes of the [RRect.width] and the [RRect.height] of this
  * rounded rectangle.
  */
-val RRect.shortestSide get(): Float = Math.min(width.absoluteValue, height.absoluteValue)
+val RRect.shortestSide get(): Float = min(width.absoluteValue, height.absoluteValue)
 
 /**
  * The greater of the magnitudes of the [RRect.width] and the [RRect.height] of this
  * rounded rectangle.
  */
-val RRect.longestSide get(): Float = Math.max(width.absoluteValue, height.absoluteValue)
+val RRect.longestSide get(): Float = max(width.absoluteValue, height.absoluteValue)
 
 /**
  * The offset to the point halfway between the left and right and the top and
diff --git a/ui/ui-geometry/src/main/java/androidx/ui/geometry/Radius.kt b/ui/ui-geometry/src/commonMain/kotlin/androidx/ui/geometry/Radius.kt
similarity index 100%
rename from ui/ui-geometry/src/main/java/androidx/ui/geometry/Radius.kt
rename to ui/ui-geometry/src/commonMain/kotlin/androidx/ui/geometry/Radius.kt
diff --git a/ui/ui-geometry/src/main/java/androidx/ui/geometry/Rect.kt b/ui/ui-geometry/src/commonMain/kotlin/androidx/ui/geometry/Rect.kt
similarity index 92%
rename from ui/ui-geometry/src/main/java/androidx/ui/geometry/Rect.kt
rename to ui/ui-geometry/src/commonMain/kotlin/androidx/ui/geometry/Rect.kt
index d24d2e5..dbf06c5 100644
--- a/ui/ui-geometry/src/main/java/androidx/ui/geometry/Rect.kt
+++ b/ui/ui-geometry/src/commonMain/kotlin/androidx/ui/geometry/Rect.kt
@@ -69,10 +69,10 @@
          */
         fun fromCircle(center: Offset, radius: Float): Rect {
             return Rect(
-                    center.dx - radius,
-                    center.dy - radius,
-                    center.dx + radius,
-                    center.dy + radius
+                center.dx - radius,
+                center.dy - radius,
+                center.dx + radius,
+                center.dy + radius
             )
         }
 
@@ -82,10 +82,10 @@
          */
         fun fromPoints(a: Offset, b: Offset): Rect {
             return Rect(
-                    Math.min(a.dx, b.dx),
-                    Math.min(a.dy, b.dy),
-                    Math.max(a.dx, b.dx),
-                    Math.max(a.dy, b.dy)
+                min(a.dx, b.dx),
+                min(a.dy, b.dy),
+                max(a.dx, b.dx),
+                max(a.dy, b.dy)
             )
         }
 
@@ -171,10 +171,10 @@
      */
     fun translate(translateX: Float, translateY: Float): Rect {
         return fromLTRB(
-                left + translateX,
-                top + translateY,
-                right + translateX,
-                bottom + translateY
+            left + translateX,
+            top + translateY,
+            right + translateX,
+            bottom + translateY
         )
     }
 
@@ -194,10 +194,10 @@
      */
     fun intersect(other: Rect): Rect {
         return fromLTRB(
-                Math.max(left, other.left),
-                Math.max(top, other.top),
-                Math.min(right, other.right),
-                Math.min(bottom, other.bottom)
+            max(left, other.left),
+            max(top, other.top),
+            min(right, other.right),
+            min(bottom, other.bottom)
         )
     }
 
@@ -207,10 +207,10 @@
      */
     fun expandToInclude(other: Rect): Rect {
         return fromLTRB(
-                Math.min(left, other.left),
-                Math.min(top, other.top),
-                Math.max(right, other.right),
-                Math.max(bottom, other.bottom)
+            min(left, other.left),
+            min(top, other.top),
+            max(right, other.right),
+            max(bottom, other.bottom)
         )
     }
 
diff --git a/ui/ui-geometry/src/main/java/androidx/ui/geometry/Size.kt b/ui/ui-geometry/src/commonMain/kotlin/androidx/ui/geometry/Size.kt
similarity index 100%
rename from ui/ui-geometry/src/main/java/androidx/ui/geometry/Size.kt
rename to ui/ui-geometry/src/commonMain/kotlin/androidx/ui/geometry/Size.kt
diff --git a/ui/ui-geometry/src/test/java/androidx/ui/geometry/RRectTest.kt b/ui/ui-geometry/src/unitTest/kotlin/androidx/ui/geometry/RRectTest.kt
similarity index 100%
rename from ui/ui-geometry/src/test/java/androidx/ui/geometry/RRectTest.kt
rename to ui/ui-geometry/src/unitTest/kotlin/androidx/ui/geometry/RRectTest.kt
diff --git a/ui/ui-geometry/src/test/java/androidx/ui/geometry/RectTest.kt b/ui/ui-geometry/src/unitTest/kotlin/androidx/ui/geometry/RectTest.kt
similarity index 100%
rename from ui/ui-geometry/src/test/java/androidx/ui/geometry/RectTest.kt
rename to ui/ui-geometry/src/unitTest/kotlin/androidx/ui/geometry/RectTest.kt
diff --git a/ui/ui-graphics/api/api_lint.ignore b/ui/ui-graphics/api/api_lint.ignore
index 6bbb26a..8d69f10 100644
--- a/ui/ui-graphics/api/api_lint.ignore
+++ b/ui/ui-graphics/api/api_lint.ignore
@@ -1,4 +1,8 @@
 // Baseline format: 1.0
+AcronymName: androidx.ui.graphics.Canvas#drawCircle-NfwrgZA(long, float, androidx.ui.graphics.Paint):
+    Acronyms should not be capitalized in method names: was `drawCircle-NfwrgZA`, should this be `drawCircle-NfwrgZa`?
+AcronymName: androidx.ui.graphics.Canvas#drawImage--AHD2Ng(androidx.ui.graphics.ImageAsset, long, androidx.ui.graphics.Paint):
+    Acronyms should not be capitalized in method names: was `drawImage--AHD2Ng`, should this be `drawImage--AhD2Ng`?
 AcronymName: androidx.ui.graphics.ColorFilter.Companion#tint-QEYXlZo(long):
     Acronyms should not be capitalized in method names: was `tint-QEYXlZo`, should this be `tint-QeyXlZo`?
 AcronymName: androidx.ui.graphics.ColorKt#isSet-QEYXlZo(long):
@@ -15,8 +19,18 @@
     Acronyms should not be capitalized in method names: was `setColor-QEYXlZo`, should this be `setColor-QeyXlZo`?
 AcronymName: androidx.ui.graphics.SolidColor#copy-QEYXlZo(long):
     Acronyms should not be capitalized in method names: was `copy-QEYXlZo`, should this be `copy-QeyXlZo`?
+AcronymName: androidx.ui.graphics.painter.CanvasScope#drawCircle-uHGJFV8(androidx.ui.graphics.Brush, float, long, float, androidx.ui.graphics.painter.DrawStyle, androidx.ui.graphics.ColorFilter, androidx.ui.graphics.BlendMode):
+    Acronyms should not be capitalized in method names: was `drawCircle-uHGJFV8`, should this be `drawCircle-uHgjfV8`?
+AcronymName: androidx.ui.graphics.painter.CanvasScope#drawLine-PWBr8KI(androidx.ui.graphics.Brush, long, long, androidx.ui.graphics.painter.Stroke, float, androidx.ui.graphics.ColorFilter, androidx.ui.graphics.BlendMode):
+    Acronyms should not be capitalized in method names: was `drawLine-PWBr8KI`, should this be `drawLine-PwBr8Ki`?
+AcronymName: androidx.ui.graphics.painter.CanvasScope#drawOval-EPCrxCw(long, long, long, float, androidx.ui.graphics.painter.DrawStyle, androidx.ui.graphics.ColorFilter, androidx.ui.graphics.BlendMode):
+    Acronyms should not be capitalized in method names: was `drawOval-EPCrxCw`, should this be `drawOval-EpCrxCw`?
+AcronymName: androidx.ui.graphics.painter.CanvasScope#drawRect-EPCrxCw(long, long, long, float, androidx.ui.graphics.painter.DrawStyle, androidx.ui.graphics.ColorFilter, androidx.ui.graphics.BlendMode):
+    Acronyms should not be capitalized in method names: was `drawRect-EPCrxCw`, should this be `drawRect-EpCrxCw`?
 AcronymName: androidx.ui.graphics.painter.ColorPainter#copy-QEYXlZo(long):
     Acronyms should not be capitalized in method names: was `copy-QEYXlZo`, should this be `copy-QeyXlZo`?
+AcronymName: androidx.ui.graphics.painter.ImagePainter#copy-gqgapXI(androidx.ui.graphics.ImageAsset, long, long):
+    Acronyms should not be capitalized in method names: was `copy-gqgapXI`, should this be `copy-gqgapXi`?
 
 
 ArrayReturn: androidx.ui.graphics.BrushKt#HorizontalGradient-G0qqrXo(kotlin.Pair<java.lang.Float,androidx.ui.graphics.Color>[], float, float, androidx.ui.graphics.TileMode) parameter #0:
@@ -37,6 +51,46 @@
     Must avoid boxed primitives (`java.lang.Float`)
 
 
+BuilderSetStyle: androidx.ui.graphics.vector.PathBuilder#arcTo(float, float, float, boolean, boolean, float, float):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.ui.graphics.vector.PathBuilder.arcTo(float,float,float,boolean,boolean,float,float)
+BuilderSetStyle: androidx.ui.graphics.vector.PathBuilder#arcToRelative(float, float, float, boolean, boolean, float, float):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.ui.graphics.vector.PathBuilder.arcToRelative(float,float,float,boolean,boolean,float,float)
+BuilderSetStyle: androidx.ui.graphics.vector.PathBuilder#close():
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.ui.graphics.vector.PathBuilder.close()
+BuilderSetStyle: androidx.ui.graphics.vector.PathBuilder#curveTo(float, float, float, float, float, float):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.ui.graphics.vector.PathBuilder.curveTo(float,float,float,float,float,float)
+BuilderSetStyle: androidx.ui.graphics.vector.PathBuilder#curveToRelative(float, float, float, float, float, float):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.ui.graphics.vector.PathBuilder.curveToRelative(float,float,float,float,float,float)
+BuilderSetStyle: androidx.ui.graphics.vector.PathBuilder#horizontalLineTo(float):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.ui.graphics.vector.PathBuilder.horizontalLineTo(float)
+BuilderSetStyle: androidx.ui.graphics.vector.PathBuilder#horizontalLineToRelative(float):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.ui.graphics.vector.PathBuilder.horizontalLineToRelative(float)
+BuilderSetStyle: androidx.ui.graphics.vector.PathBuilder#lineTo(float, float):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.ui.graphics.vector.PathBuilder.lineTo(float,float)
+BuilderSetStyle: androidx.ui.graphics.vector.PathBuilder#lineToRelative(float, float):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.ui.graphics.vector.PathBuilder.lineToRelative(float,float)
+BuilderSetStyle: androidx.ui.graphics.vector.PathBuilder#moveTo(float, float):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.ui.graphics.vector.PathBuilder.moveTo(float,float)
+BuilderSetStyle: androidx.ui.graphics.vector.PathBuilder#moveToRelative(float, float):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.ui.graphics.vector.PathBuilder.moveToRelative(float,float)
+BuilderSetStyle: androidx.ui.graphics.vector.PathBuilder#quadTo(float, float, float, float):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.ui.graphics.vector.PathBuilder.quadTo(float,float,float,float)
+BuilderSetStyle: androidx.ui.graphics.vector.PathBuilder#quadToRelative(float, float, float, float):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.ui.graphics.vector.PathBuilder.quadToRelative(float,float,float,float)
+BuilderSetStyle: androidx.ui.graphics.vector.PathBuilder#reflectiveCurveTo(float, float, float, float):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.ui.graphics.vector.PathBuilder.reflectiveCurveTo(float,float,float,float)
+BuilderSetStyle: androidx.ui.graphics.vector.PathBuilder#reflectiveCurveToRelative(float, float, float, float):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.ui.graphics.vector.PathBuilder.reflectiveCurveToRelative(float,float,float,float)
+BuilderSetStyle: androidx.ui.graphics.vector.PathBuilder#reflectiveQuadTo(float, float):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.ui.graphics.vector.PathBuilder.reflectiveQuadTo(float,float)
+BuilderSetStyle: androidx.ui.graphics.vector.PathBuilder#reflectiveQuadToRelative(float, float):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.ui.graphics.vector.PathBuilder.reflectiveQuadToRelative(float,float)
+BuilderSetStyle: androidx.ui.graphics.vector.PathBuilder#verticalLineTo(float):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.ui.graphics.vector.PathBuilder.verticalLineTo(float)
+BuilderSetStyle: androidx.ui.graphics.vector.PathBuilder#verticalLineToRelative(float):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.ui.graphics.vector.PathBuilder.verticalLineToRelative(float)
+
+
 DocumentExceptions: androidx.ui.graphics.vectormath.Matrix3#get(androidx.ui.graphics.vectormath.MatrixColumn):
     Method Matrix3.get 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.graphics.vectormath.Matrix3#get(int):
diff --git a/ui/ui-layout/OWNERS b/ui/ui-layout/OWNERS
index 97f86be..0b1cdfa 100644
--- a/ui/ui-layout/OWNERS
+++ b/ui/ui-layout/OWNERS
@@ -1,2 +1,3 @@
 mount@google.com
 popam@google.com
+soboleva@google.com
diff --git a/ui/ui-layout/api/api_lint.ignore b/ui/ui-layout/api/api_lint.ignore
index cffda90..a86577a 100644
--- a/ui/ui-layout/api/api_lint.ignore
+++ b/ui/ui-layout/api/api_lint.ignore
@@ -25,6 +25,8 @@
     Acronyms should not be capitalized in method names: was `offset-qJOR85M`, should this be `offset-qJoR85M`?
 AcronymName: androidx.ui.layout.LayoutPaddingKt#padding-qJOR85M(androidx.ui.core.Modifier, float, float):
     Acronyms should not be capitalized in method names: was `padding-qJOR85M`, should this be `padding-qJoR85M`?
+AcronymName: androidx.ui.layout.LayoutSizeKt#defaultMinSizeConstraints-qJOR85M(androidx.ui.core.Modifier, float, float):
+    Acronyms should not be capitalized in method names: was `defaultMinSizeConstraints-qJOR85M`, should this be `defaultMinSizeConstraints-qJoR85M`?
 AcronymName: androidx.ui.layout.LayoutSizeKt#heightIn-qJOR85M(androidx.ui.core.Modifier, float, float):
     Acronyms should not be capitalized in method names: was `heightIn-qJOR85M`, should this be `heightIn-qJoR85M`?
 AcronymName: androidx.ui.layout.LayoutSizeKt#preferredHeightIn-qJOR85M(androidx.ui.core.Modifier, float, float):
diff --git a/ui/ui-material/OWNERS b/ui/ui-material/OWNERS
index 40a5c8b..844cef9 100644
--- a/ui/ui-material/OWNERS
+++ b/ui/ui-material/OWNERS
@@ -3,3 +3,4 @@
 andreykulikov@google.com
 malkov@google.com
 lpf@google.com
+soboleva@google.com
\ No newline at end of file
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/ProgressIndicator.kt b/ui/ui-material/src/main/java/androidx/ui/material/ProgressIndicator.kt
index 4f32ee2..2f23a18 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/ProgressIndicator.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/ProgressIndicator.kt
@@ -26,6 +26,7 @@
 import androidx.compose.Composable
 import androidx.ui.animation.Transition
 import androidx.ui.core.DensityAmbient
+import androidx.ui.core.DrawScope
 import androidx.ui.core.Modifier
 import androidx.ui.core.LayoutDirection
 import androidx.ui.foundation.Canvas
@@ -126,12 +127,11 @@
     }
 }
 
-private fun CanvasScope.drawLinearIndicator(
+private fun DrawScope.drawLinearIndicator(
     startFraction: Float,
     endFraction: Float,
     color: Color,
-    stroke: Stroke,
-    layoutDirection: LayoutDirection = LayoutDirection.Ltr
+    stroke: Stroke
 ) {
     val width = size.width
     val height = size.height
@@ -146,11 +146,10 @@
     drawLine(color, Offset(barStart, yOffset), Offset(barEnd, yOffset), stroke)
 }
 
-private fun CanvasScope.drawLinearIndicatorBackground(
+private fun DrawScope.drawLinearIndicatorBackground(
     color: Color,
-    stroke: Stroke,
-    layoutDirection: LayoutDirection = LayoutDirection.Ltr
-) = drawLinearIndicator(0f, 1f, color, stroke, layoutDirection)
+    stroke: Stroke
+) = drawLinearIndicator(0f, 1f, color, stroke)
 
 /**
  * A determinate circular progress indicator that represents progress by drawing an arc ranging from
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/Tab.kt b/ui/ui-material/src/main/java/androidx/ui/material/Tab.kt
index 1b94655..375390a 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/Tab.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/Tab.kt
@@ -67,6 +67,7 @@
 import androidx.ui.unit.max
 import androidx.ui.unit.sp
 import androidx.ui.unit.toPx
+import androidx.ui.util.fastFirstOrNull
 
 /**
  * A TabRow contains a row of [Tab]s, and displays an indicator underneath the currently
@@ -285,13 +286,13 @@
 
                 // The divider is measured with its own height, and width equal to the total width
                 // of the tab row, and then placed on top of the tabs.
-                measurables.firstOrNull { it.tag == dividerTag }
+                measurables.fastFirstOrNull { it.tag == dividerTag }
                     ?.measure(constraints.copy(minWidth = layoutWidth, maxWidth = layoutWidth))
                     ?.run { place(IntPx.Zero, layoutHeight - height) }
 
                 // The indicator container is measured to fill the entire space occupied by the tab
                 // row, and then placed on top of the divider.
-                measurables.firstOrNull { it.tag == indicatorTag }
+                measurables.fastFirstOrNull { it.tag == indicatorTag }
                     ?.measure(Constraints.fixed(layoutWidth, layoutHeight))
                     ?.place(IntPx.Zero, IntPx.Zero)
             }
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/TextField.kt b/ui/ui-material/src/main/java/androidx/ui/material/TextField.kt
index 5d9d446..49d1333 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/TextField.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/TextField.kt
@@ -42,7 +42,7 @@
 import androidx.ui.core.drawBehind
 import androidx.ui.core.offset
 import androidx.ui.core.tag
-import androidx.ui.focus.FocusModifier
+import androidx.ui.core.focus.FocusModifier
 import androidx.ui.foundation.Box
 import androidx.ui.foundation.Clickable
 import androidx.ui.foundation.ContentColorAmbient
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/internal/StateDraggable.kt b/ui/ui-material/src/main/java/androidx/ui/material/internal/StateDraggable.kt
index 3b2f6c0..6758f33 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/internal/StateDraggable.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/internal/StateDraggable.kt
@@ -30,6 +30,7 @@
 import androidx.ui.foundation.animation.fling
 import androidx.ui.foundation.gestures.DragDirection
 import androidx.ui.foundation.gestures.draggable
+import androidx.ui.util.fastFirstOrNull
 
 /**
  * Higher-level component that allows dragging around anchored positions binded to different states
@@ -74,7 +75,7 @@
     val forceAnimationCheck = state { true }
 
     val anchors = remember(anchorsToState) { anchorsToState.map { it.first } }
-    val currentValue = anchorsToState.firstOrNull { it.second == state }!!.first
+    val currentValue = anchorsToState.fastFirstOrNull { it.second == state }!!.first
     val flingConfig =
         AnchorsFlingConfig(anchors, animationBuilder,  reason, finalValue, _ ->
             if (reason != AnimationEndReason.Interrupted) {
diff --git a/ui/ui-test/api/api_lint.ignore b/ui/ui-test/api/api_lint.ignore
index f23a46e..3138bb5 100644
--- a/ui/ui-test/api/api_lint.ignore
+++ b/ui/ui-test/api/api_lint.ignore
@@ -1,6 +1,8 @@
 // Baseline format: 1.0
 AcronymName: androidx.ui.test.BitmapHelpersKt#assertPixelColor-9bBi3KA(android.graphics.Bitmap, long, int, int, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.Color,java.lang.String>):
     Acronyms should not be capitalized in method names: was `assertPixelColor-9bBi3KA`, should this be `assertPixelColor-9bBi3Ka`?
+AcronymName: androidx.ui.test.BitmapHelpersKt#assertShape-2l1GYV8(android.graphics.Bitmap, androidx.ui.unit.Density, float, float, long, long, androidx.ui.graphics.Shape, float):
+    Acronyms should not be capitalized in method names: was `assertShape-2l1GYV8`, should this be `assertShape-2l1GyV8`?
 AcronymName: androidx.ui.test.BitmapHelpersKt#assertShape-nbwoFSQ(android.graphics.Bitmap, androidx.ui.unit.Density, androidx.ui.graphics.Shape, long, long, androidx.ui.graphics.Shape, float, float, float, float, float, float, float):
     Acronyms should not be capitalized in method names: was `assertShape-nbwoFSQ`, should this be `assertShape-nbwoFsq`?
 
diff --git a/ui/ui-test/src/androidTest/java/androidx/ui/test/IsDisplayedTest.kt b/ui/ui-test/src/androidTest/java/androidx/ui/test/IsDisplayedTest.kt
new file mode 100644
index 0000000..728707c
--- /dev/null
+++ b/ui/ui-test/src/androidTest/java/androidx/ui/test/IsDisplayedTest.kt
@@ -0,0 +1,165 @@
+/*
+ * 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
+
+import androidx.compose.Composable
+import androidx.compose.getValue
+import androidx.compose.mutableStateOf
+import androidx.compose.setValue
+import androidx.test.filters.MediumTest
+import androidx.ui.core.Layout
+import androidx.ui.core.Modifier
+import androidx.ui.foundation.Box
+import androidx.ui.foundation.VerticalScroller
+import androidx.ui.graphics.Color
+import androidx.ui.layout.Column
+import androidx.ui.layout.Row
+import androidx.ui.layout.Stack
+import androidx.ui.layout.fillMaxHeight
+import androidx.ui.layout.fillMaxWidth
+import androidx.ui.layout.height
+import androidx.ui.layout.size
+import androidx.ui.layout.width
+import androidx.ui.test.util.BoundaryNode
+import androidx.ui.unit.Dp
+import androidx.ui.unit.dp
+import androidx.ui.unit.ipx
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@MediumTest
+@RunWith(JUnit4::class)
+class IsDisplayedTest {
+
+    @get:Rule
+    val composeTestRule = createComposeRule(disableTransitions = true)
+
+    private val colors = listOf(Color.Red, Color.Green, Color.Blue)
+
+    @Composable
+    private fun Item(i: Int, width: Dp? = null, height: Dp? = null) {
+        BoundaryNode("item$i") {
+            Box(
+                modifier = with(Modifier) { width?.let { width(it) } ?: fillMaxWidth() } +
+                        with(Modifier) { height?.let { height(it) } ?: fillMaxHeight() },
+                backgroundColor = colors[i % colors.size]
+            )
+        }
+    }
+
+    @Composable
+    fun PlaceConditionally(place: Boolean, child: @Composable () -> Unit) {
+        Layout(children = child) { measurables, constraints, _ ->
+            if (place) {
+                val placeable = measurables[0].measure(constraints)
+                layout(placeable.width, placeable.height) {
+                    placeable.place(0.ipx, 0.ipx)
+                }
+            } else {
+                layout(0.ipx, 0.ipx) {}
+            }
+        }
+    }
+
+    @Test
+    fun componentInScrollable_isDisplayed() {
+        composeTestRule.setContent {
+            VerticalScroller(modifier = Modifier.size(100.dp)) {
+                Column {
+                    repeat(10) { Item(it, height = 30.dp) }
+                }
+            }
+        }
+
+        findByTag("item0")
+            .assertIsDisplayed()
+    }
+
+    @Test
+    fun componentInScrollable_isNotDisplayed() {
+        composeTestRule.setContent {
+            VerticalScroller(modifier = Modifier.size(100.dp)) {
+                Column {
+                    repeat(10) { Item(it, height = 30.dp) }
+                }
+            }
+        }
+
+        findByTag("item4")
+            .assertIsNotDisplayed()
+    }
+
+    @Test
+    fun togglePlacement() {
+        var place by mutableStateOf(true)
+
+        composeTestRule.setContent {
+            PlaceConditionally(place) {
+                // Item instead of BoundaryNode because we need non-zero size
+                Item(0)
+            }
+        }
+
+        findByTag("item0")
+            .assertIsDisplayed()
+
+        runOnIdleCompose {
+            place = false
+        }
+
+        findByTag("item0")
+            .assertIsNotDisplayed()
+    }
+
+    @Test
+    fun toggleParentPlacement() {
+        var place by mutableStateOf(true)
+
+        composeTestRule.setContent {
+            PlaceConditionally(place) {
+                Stack {
+                    // Item instead of BoundaryNode because we need non-zero size
+                    Item(0)
+                }
+            }
+        }
+
+        findByTag("item0")
+            .assertIsDisplayed()
+
+        runOnIdleCompose {
+            place = false
+        }
+
+        findByTag("item0")
+            .assertIsNotDisplayed()
+    }
+
+    @Test
+    fun rowTooSmall() {
+        composeTestRule.setContent {
+            Row(modifier = Modifier.size(100.dp)) {
+                repeat(10) { Item(it, width = 30.dp) }
+            }
+        }
+
+        findByTag("item9")
+            .assertIsNotDisplayed()
+    }
+}
diff --git a/ui/ui-test/src/androidTest/java/androidx/ui/test/IsDisplayedTests.kt b/ui/ui-test/src/androidTest/java/androidx/ui/test/IsDisplayedTests.kt
deleted file mode 100644
index fca460a..0000000
--- a/ui/ui-test/src/androidTest/java/androidx/ui/test/IsDisplayedTests.kt
+++ /dev/null
@@ -1,284 +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.test
-
-import androidx.compose.Composable
-import androidx.compose.Model
-import androidx.test.filters.MediumTest
-import androidx.ui.core.Alignment
-import androidx.ui.core.Layout
-import androidx.ui.core.Modifier
-import androidx.ui.core.TestTag
-import androidx.ui.foundation.Box
-import androidx.ui.foundation.Canvas
-import androidx.ui.foundation.Text
-import androidx.ui.foundation.VerticalScroller
-import androidx.ui.graphics.Color
-import androidx.ui.layout.Column
-import androidx.ui.layout.Row
-import androidx.ui.layout.Stack
-import androidx.ui.layout.padding
-import androidx.ui.layout.preferredSize
-import androidx.ui.semantics.ScrollTo
-import androidx.ui.semantics.Semantics
-import androidx.ui.text.TextStyle
-import androidx.ui.unit.IntPx
-import androidx.ui.unit.Px
-import androidx.ui.unit.dp
-import androidx.ui.unit.ipx
-import androidx.ui.unit.px
-import androidx.ui.unit.sp
-import com.google.common.truth.Truth.assertThat
-import org.junit.Assert
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
-
-@MediumTest
-@RunWith(JUnit4::class)
-class IsDisplayedTests {
-
-    @get:Rule
-    val composeTestRule = createComposeRule(disableTransitions = true)
-
-    @Test
-    fun componentInScrollable_isDisplayed() {
-        createScrollableContent()
-
-        findByText("2")
-            .assertIsDisplayed()
-    }
-
-    @Test
-    fun componentInScrollable_isNotDisplayed() {
-        createScrollableContent()
-
-        findByText("50")
-            .assertIsNotDisplayed()
-    }
-
-    private fun createScrollableContent() {
-        composeTestRule.setContent {
-            val style = TextStyle(fontSize = 30.sp)
-            VerticalScroller(modifier = Modifier.padding(10.dp)) {
-                Column {
-                    for (i in 1..100) {
-                        Semantics(container = true) {
-                            Text(text = i.toString(), style = style)
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    @Test
-    fun toggleParentVisibility() {
-        /*
-        - topNode
-        -- secondNode
-        --- thirdNode
-        ---- Text
-         */
-
-        val model = AssertsUiTestsModel(true)
-
-        composeTestRule.setContent {
-            val lastNode = @Composable {
-                Stack {
-                    Semantics(container = true) {
-                        Text("Foo")
-                    }
-                }
-            }
-
-            val thirdNode = @Composable {
-                Stack {
-                    lastNode()
-                }
-            }
-
-            val secondNode = @Composable {
-                Layout({
-                    thirdNode()
-                }) { measurables, constraints, _ ->
-                    if (model.value) {
-                        val placeable = measurables[0].measure(constraints)
-                        layout(placeable.width, placeable.height) {
-                            placeable.place(0.ipx, 0.ipx)
-                        }
-                    } else {
-                        layout(0.ipx, 0.ipx) {}
-                    }
-                }
-            }
-
-            val topNode = @Composable {
-                Layout({
-                    secondNode()
-                }) { measurables, constraints, _ ->
-                    if (model.value) {
-                        val placeable = measurables[0].measure(constraints)
-                        layout(placeable.width, placeable.height) {
-                            placeable.place(0.ipx, 0.ipx)
-                        }
-                    } else {
-                        layout(0.ipx, 0.ipx) {
-                        }
-                    }
-                }
-            }
-
-            topNode()
-        }
-
-        findByText("Foo")
-            .assertIsDisplayed()
-
-        runOnUiThread {
-            model.value = false
-        }
-
-        findByText("Foo")
-            .assertIsNotDisplayed()
-    }
-
-    @Test
-    fun rowTooSmall() {
-        composeTestRule.setContent {
-            val style = TextStyle(fontSize = 30.sp)
-            Stack {
-                // TODO(popam): remove this when a modifier can be used instead
-                Layout(
-                    children = {
-                        Row {
-                            for (i in 1..100) {
-                                Semantics(container = true) {
-                                    Text(text = i.toString(), style = style)
-                                }
-                            }
-                        }
-                    },
-                    modifier = Modifier.gravity(Alignment.Center)
-                ) { measurables, constraints, _ ->
-                    val placeable =
-                        measurables[0].measure(constraints.copy(maxWidth = IntPx.Infinity))
-                    layout(placeable.width, placeable.height) {
-                        placeable.place(0.ipx, 0.ipx)
-                    }
-                }
-            }
-        }
-
-        findByText("90")
-            .assertIsNotDisplayed()
-    }
-
-    @Test
-    fun checkSemanticsAction_scrollTo_isCalled() {
-        var wasScrollToCalled = false
-        val tag = "myTag"
-
-        composeTestRule.setContent {
-            Semantics(container = true, properties = {
-                ScrollTo(action = { _, _ ->
-                    wasScrollToCalled = true
-                    return@ScrollTo true
-                })
-            }) {
-                Box {
-                    TestTag(tag) {
-                        Semantics(container = true) {
-                            Box()
-                        }
-                    }
-                }
-            }
-        }
-
-        runOnIdleCompose {
-            Assert.assertTrue(!wasScrollToCalled)
-        }
-
-        findByTag(tag)
-            .doScrollTo()
-
-        runOnIdleCompose {
-            Assert.assertTrue(wasScrollToCalled)
-        }
-    }
-
-    @Test
-    fun checkSemanticsAction_scrollTo_coordAreCorrect() {
-        var currentScrollPositionY = 0.px
-        var currentScrollPositionX = 0.px
-        var elementHeight = 0.px
-        val tag = "myTag"
-
-        val drawRect = @Composable { color: Color ->
-            Semantics(container = true) {
-                Canvas(Modifier.preferredSize(100.dp)) {
-                    drawRect(color)
-
-                    elementHeight = Px(size.height)
-                }
-            }
-        }
-
-        composeTestRule.setContent {
-            // Need to make the "scrolling" container the semantics boundary so that it
-            // doesn't try to include the padding
-            Semantics(container = true, properties = {
-                ScrollTo(action = { x, y ->
-                    currentScrollPositionY = y
-                    currentScrollPositionX = x
-                    return@ScrollTo true
-                })
-            }) {
-                val red = Color(alpha = 0xFF, red = 0xFF, green = 0, blue = 0)
-                val blue = Color(alpha = 0xFF, red = 0, green = 0, blue = 0xFF)
-                val green = Color(alpha = 0xFF, red = 0, green = 0xFF, blue = 0)
-
-                Column {
-                    drawRect(red)
-                    drawRect(blue)
-                    TestTag(tag) {
-                        drawRect(green)
-                    }
-                }
-            }
-        }
-
-        runOnIdleCompose {
-            assertThat(currentScrollPositionY).isEqualTo(0.px)
-            assertThat(currentScrollPositionX).isEqualTo(0.px)
-        }
-
-        findByTag(tag)
-            .doScrollTo() // scroll to third element
-
-        runOnIdleCompose {
-            val expected = elementHeight * 2
-            assertThat(currentScrollPositionY).isEqualTo(expected)
-            assertThat(currentScrollPositionX).isEqualTo(0.px)
-        }
-    }
-}
-
-@Model
-class AssertsUiTestsModel(var value: Boolean)
\ No newline at end of file
diff --git a/ui/ui-test/src/androidTest/java/androidx/ui/test/ScrollToTest.kt b/ui/ui-test/src/androidTest/java/androidx/ui/test/ScrollToTest.kt
new file mode 100644
index 0000000..c8f1e9f
--- /dev/null
+++ b/ui/ui-test/src/androidTest/java/androidx/ui/test/ScrollToTest.kt
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.ui.test
+
+import androidx.compose.Composable
+import androidx.ui.core.Modifier
+import androidx.ui.core.TestTag
+import androidx.ui.foundation.Box
+import androidx.ui.foundation.Canvas
+import androidx.ui.graphics.Color
+import androidx.ui.layout.Column
+import androidx.ui.layout.preferredSize
+import androidx.ui.semantics.ScrollTo
+import androidx.ui.semantics.Semantics
+import androidx.ui.unit.Px
+import androidx.ui.unit.dp
+import androidx.ui.unit.px
+import com.google.common.truth.Truth
+import org.junit.Assert
+import org.junit.Rule
+import org.junit.Test
+
+class ScrollToTest {
+    @get:Rule
+    val composeTestRule = createComposeRule(disableTransitions = true)
+
+    @Test
+    fun checkSemanticsAction_scrollTo_isCalled() {
+        var wasScrollToCalled = false
+        val tag = "myTag"
+
+        composeTestRule.setContent {
+            Semantics(container = true, properties = {
+                ScrollTo(action = { _, _ ->
+                    wasScrollToCalled = true
+                    return@ScrollTo true
+                })
+            }) {
+                Box {
+                    TestTag(tag) {
+                        Semantics(container = true) {
+                            Box()
+                        }
+                    }
+                }
+            }
+        }
+
+        runOnIdleCompose {
+            Assert.assertTrue(!wasScrollToCalled)
+        }
+
+        findByTag(tag)
+            .doScrollTo()
+
+        runOnIdleCompose {
+            Assert.assertTrue(wasScrollToCalled)
+        }
+    }
+
+    @Test
+    fun checkSemanticsAction_scrollTo_coordAreCorrect() {
+        var currentScrollPositionY = 0.px
+        var currentScrollPositionX = 0.px
+        var elementHeight = 0.px
+        val tag = "myTag"
+
+        val drawRect = @Composable { color: Color ->
+            Semantics(container = true) {
+                Canvas(Modifier.preferredSize(100.dp)) {
+                    drawRect(color)
+
+                    elementHeight = Px(size.height)
+                }
+            }
+        }
+
+        composeTestRule.setContent {
+            // Need to make the "scrolling" container the semantics boundary so that it
+            // doesn't try to include the padding
+            Semantics(container = true, properties = {
+                ScrollTo(action = { x, y ->
+                    currentScrollPositionY = y
+                    currentScrollPositionX = x
+                    return@ScrollTo true
+                })
+            }) {
+                val red = Color(alpha = 0xFF, red = 0xFF, green = 0, blue = 0)
+                val blue = Color(alpha = 0xFF, red = 0, green = 0, blue = 0xFF)
+                val green = Color(alpha = 0xFF, red = 0, green = 0xFF, blue = 0)
+
+                Column {
+                    drawRect(red)
+                    drawRect(blue)
+                    TestTag(tag) {
+                        drawRect(green)
+                    }
+                }
+            }
+        }
+
+        runOnIdleCompose {
+            Truth.assertThat(currentScrollPositionY).isEqualTo(0.px)
+            Truth.assertThat(currentScrollPositionX).isEqualTo(0.px)
+        }
+
+        findByTag(tag)
+            .doScrollTo() // scroll to third element
+
+        runOnIdleCompose {
+            val expected = elementHeight * 2
+            Truth.assertThat(currentScrollPositionY).isEqualTo(expected)
+            Truth.assertThat(currentScrollPositionX).isEqualTo(0.px)
+        }
+    }
+}
diff --git a/ui/ui-test/src/androidTest/java/androidx/ui/test/SynchronizationMethodsTest.kt b/ui/ui-test/src/androidTest/java/androidx/ui/test/SynchronizationMethodsTest.kt
index a2c7d34..aa24a07f 100644
--- a/ui/ui-test/src/androidTest/java/androidx/ui/test/SynchronizationMethodsTest.kt
+++ b/ui/ui-test/src/androidTest/java/androidx/ui/test/SynchronizationMethodsTest.kt
@@ -17,6 +17,7 @@
 package androidx.ui.test
 
 import androidx.test.filters.MediumTest
+import androidx.ui.test.android.AndroidOwnerRegistry
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -35,7 +36,6 @@
     @Test
     fun runOnUiThread_void() {
         var called = false
-
         runOnUiThread { called = true }
         assertThat(called).isTrue()
     }
@@ -48,21 +48,35 @@
 
     @Test
     fun runOnIdleCompose() {
-        val result = runOnIdleCompose { "Hello" }
-        assertThat(result).isEqualTo("Hello")
+        withAndroidOwnerRegistry {
+            val result = runOnIdleCompose { "Hello" }
+            assertThat(result).isEqualTo("Hello")
+        }
     }
 
     @Test
     fun runOnIdleCompose_void() {
-        var called = false
-
-        runOnIdleCompose { called = true }
-        assertThat(called).isTrue()
+        withAndroidOwnerRegistry {
+            var called = false
+            runOnIdleCompose { called = true }
+            assertThat(called).isTrue()
+        }
     }
 
     @Test
     fun runOnIdleCompose_nullable() {
-        val result: String? = runOnIdleCompose { null }
-        assertThat(result).isEqualTo(null)
+        withAndroidOwnerRegistry {
+            val result: String? = runOnIdleCompose { null }
+            assertThat(result).isEqualTo(null)
+        }
+    }
+
+    private fun withAndroidOwnerRegistry(block: () -> Unit) {
+        AndroidOwnerRegistry.setupRegistry()
+        try {
+            block()
+        } finally {
+            AndroidOwnerRegistry.tearDownRegistry()
+        }
     }
 }
\ No newline at end of file
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 077b462..00dc01c 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
@@ -16,6 +16,8 @@
 
 package androidx.ui.test
 
+import androidx.ui.core.AndroidOwner
+import androidx.ui.core.ComponentNode
 import androidx.ui.core.LayoutNode
 import androidx.ui.core.findClosestParentNode
 import androidx.ui.core.semantics.SemanticsNode
@@ -23,9 +25,9 @@
 import androidx.ui.geometry.Rect
 import androidx.ui.semantics.AccessibilityRangeInfo
 import androidx.ui.semantics.SemanticsProperties
-import androidx.ui.test.android.SynchronizedTreeCollector
 import androidx.ui.unit.PxBounds
 import androidx.ui.unit.PxPosition
+import androidx.ui.unit.PxSize
 import androidx.ui.unit.height
 import androidx.ui.unit.px
 import androidx.ui.unit.toPx
@@ -288,38 +290,41 @@
     // hierarchy check - check layout nodes are visible
     val errorMessageOnFail = "Failed to perform isDisplayed check."
     val node = fetchSemanticsNode(errorMessageOnFail)
-    if (node.componentNode.findClosestParentNode {
-            it is LayoutNode && !it.isPlaced
-        } != null) {
+
+    fun isNotPlaced(node: ComponentNode): Boolean {
+        return node is LayoutNode && !node.isPlaced
+    }
+
+    val componentNode = node.componentNode
+    if (isNotPlaced(componentNode) || componentNode.findClosestParentNode(::isNotPlaced) != null) {
         return false
     }
 
     // check node doesn't clip unintentionally (e.g. row too small for content)
     val globalRect = node.globalBounds
-    if (!isInScreenBounds(globalRect)) {
+    if (!node.isInScreenBounds()) {
         return false
     }
 
     return (globalRect.width > 0.px && globalRect.height > 0.px)
 }
 
-internal fun isInScreenBounds(rectangle: PxBounds): Boolean {
-    if (rectangle.width == 0.px && rectangle.height == 0.px) {
+private fun SemanticsNode.isInScreenBounds(): Boolean {
+    val nodeBounds = globalBounds
+    if (nodeBounds.width == 0.px && nodeBounds.height == 0.px) {
         return false
     }
-    val displayMetrics = SynchronizedTreeCollector.collectOwners()
-        .findActivity()
-        .resources
-        .displayMetrics
 
-    val bottomRight = PxPosition(
-        displayMetrics.widthPixels.px,
-        displayMetrics.heightPixels.px
+    val displayMetrics = (componentNode.owner as AndroidOwner).view.resources.displayMetrics
+    val screenBounds = PxBounds(
+        PxPosition.Origin,
+        PxSize(displayMetrics.widthPixels.px, displayMetrics.heightPixels.px)
     )
-    return rectangle.top >= 0.px &&
-            rectangle.left >= 0.px &&
-            rectangle.right <= bottomRight.x &&
-            rectangle.bottom <= bottomRight.y
+
+    return nodeBounds.top >= screenBounds.top &&
+            nodeBounds.left >= screenBounds.left &&
+            nodeBounds.right <= screenBounds.right &&
+            nodeBounds.bottom <= screenBounds.bottom
 }
 
 /**
diff --git a/ui/ui-test/src/main/java/androidx/ui/test/BitmapHelpers.kt b/ui/ui-test/src/main/java/androidx/ui/test/BitmapHelpers.kt
index b65642e..0173dce 100644
--- a/ui/ui-test/src/main/java/androidx/ui/test/BitmapHelpers.kt
+++ b/ui/ui-test/src/main/java/androidx/ui/test/BitmapHelpers.kt
@@ -21,11 +21,8 @@
 import android.content.ContextWrapper
 import android.graphics.Bitmap
 import android.os.Build
-import android.os.Handler
-import android.os.Looper
 import android.view.View
 import androidx.annotation.RequiresApi
-import androidx.ui.core.semantics.SemanticsNode
 import androidx.ui.geometry.Offset
 import androidx.ui.geometry.Rect
 import androidx.ui.graphics.Canvas
@@ -35,7 +32,6 @@
 import androidx.ui.graphics.Shape
 import androidx.ui.graphics.addOutline
 import androidx.ui.graphics.asAndroidPath
-import androidx.ui.test.android.SynchronizedTreeCollector
 import androidx.ui.test.android.captureRegionToBitmap
 import androidx.ui.unit.Density
 import androidx.ui.unit.Dp
@@ -50,29 +46,6 @@
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertTrue
 
-@RequiresApi(Build.VERSION_CODES.O)
-internal fun captureNodeToBitmap(node: SemanticsNode): Bitmap {
-    val collectedInfo = SynchronizedTreeCollector.collectOwners()
-
-    val exists = getAllSemanticsNodes().any { it.id == node.id }
-    if (!exists) {
-        throw AssertionError("The required node is no longer in the tree!")
-    }
-
-    val window = collectedInfo.findActivity().window
-
-    // TODO(pavlis): Consider doing assertIsDisplayed here. Will need to move things around.
-
-    // TODO(pavlis): Make sure that the Activity actually hosts the view. As in case of popup
-    // it wouldn't. This will require us rewriting the structure how we collect the nodes.
-
-    // TODO(pavlis): Add support for popups. So if we find composable hosted in popup we can
-    // grab its reference to its window (need to add a hook to popup).
-
-    val handler = Handler(Looper.getMainLooper())
-    return captureRegionToBitmap(node.globalBounds.toRect(), handler, window)
-}
-
 /**
  * Captures the underlying component's surface into bitmap.
  *
@@ -82,8 +55,9 @@
  */
 @RequiresApi(Build.VERSION_CODES.O)
 fun SemanticsNodeInteraction.captureToBitmap(): Bitmap {
-    val errorMessageOnFail = "Failed to capture a node to bitmap."
-    return captureNodeToBitmap(fetchSemanticsNode(errorMessageOnFail))
+    val node = fetchSemanticsNode("Failed to capture a node to bitmap.")
+    // TODO(pavlis): Consider doing assertIsDisplayed here. Will need to move things around.
+    return captureRegionToBitmap(node.globalBounds.toRect(), node.componentNode.owner!!)
 }
 
 /**
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 1dcf1c8..66e4164 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
@@ -91,5 +91,5 @@
 }
 
 internal fun getAllSemanticsNodes(): List<SemanticsNode> {
-    return SynchronizedTreeCollector.collectOwners().getAllSemanticNodes()
+    return SynchronizedTreeCollector.collectAllSemanticsNodes()
 }
\ No newline at end of file
diff --git a/ui/ui-test/src/main/java/androidx/ui/test/android/AndroidInputDispatcher.kt b/ui/ui-test/src/main/java/androidx/ui/test/android/AndroidInputDispatcher.kt
index bb03972..bf03018 100644
--- a/ui/ui-test/src/main/java/androidx/ui/test/android/AndroidInputDispatcher.kt
+++ b/ui/ui-test/src/main/java/androidx/ui/test/android/AndroidInputDispatcher.kt
@@ -239,7 +239,7 @@
     }
 
     /**
-     * Sends the [event] to the [CollectedOwners] and [recycles][MotionEvent.recycle] it
+     * Sends the [event] to the MotionEvent dispatcher and [recycles][MotionEvent.recycle] it
      * regardless of the result. This method blocks until the event is sent.
      */
     private fun sendAndRecycleEvent(event: MotionEvent) {
diff --git a/ui/ui-test/src/main/java/androidx/ui/test/android/AndroidOwnerRegistry.kt b/ui/ui-test/src/main/java/androidx/ui/test/android/AndroidOwnerRegistry.kt
index d62da1b..44f9aa2 100644
--- a/ui/ui-test/src/main/java/androidx/ui/test/android/AndroidOwnerRegistry.kt
+++ b/ui/ui-test/src/main/java/androidx/ui/test/android/AndroidOwnerRegistry.kt
@@ -37,7 +37,7 @@
     /**
      * Returns if the registry is setup to receive registrations from [AndroidOwner]s
      */
-    val isSetup: Boolean
+    val isSetUp: Boolean
         get() = AndroidOwner. ::onAndroidOwnerCreated
 
     /**
diff --git a/ui/ui-test/src/main/java/androidx/ui/test/android/SynchronizedTreeCollector.kt b/ui/ui-test/src/main/java/androidx/ui/test/android/SynchronizedTreeCollector.kt
index eecbc3b..5e95c72 100644
--- a/ui/ui-test/src/main/java/androidx/ui/test/android/SynchronizedTreeCollector.kt
+++ b/ui/ui-test/src/main/java/androidx/ui/test/android/SynchronizedTreeCollector.kt
@@ -16,9 +16,6 @@
 
 package androidx.ui.test.android
 
-import android.app.Activity
-import android.content.Context
-import android.content.ContextWrapper
 import android.view.Choreographer
 import androidx.compose.onCommit
 import androidx.test.espresso.Espresso
@@ -31,31 +28,32 @@
 import java.util.concurrent.TimeUnit
 
 /**
- * Collects all [AndroidOwner]s that are part of the currently visible window.
+ * Collects all [SemanticsNode]s that are part of all compose hierarchies hosted by resumed
+ * activities.
  *
  * This operation is performed only after compose is idle via Espresso.
  */
 internal object SynchronizedTreeCollector {
     /**
-     * Collects all [AndroidOwner]s that are part of the currently visible window. Can only be
-     * used when using [ComposeTestRule][androidx.ui.test.ComposeTestRule]
+     * Collects all [SemanticsNode]s from all compose hierarchies. Can only be used when using
+     * [ComposeTestRule][androidx.ui.test.ComposeTestRule].
      *
      * This is a blocking call. Returns only after compose is idle.
      *
      * Can crash in case Espresso hits time out. This is not supposed to be handled as it
      * surfaces only in incorrect tests.
      */
-    internal fun collectOwners(): CollectedOwners {
-        check(AndroidOwnerRegistry.isSetup) {
-            "Test not setup properly. Use a ComposeTestRule in your test to be able to interact " +
-                    "with composables"
-        }
+    internal fun collectAllSemanticsNodes(): List<SemanticsNode> {
+        ensureAndroidOwnerRegistryIsSetUp()
+
+        // TODO(pavlis): Instead of returning a flatMap, let all consumers handle a tree
+        //  structure. In case of multiple AndroidOwners, add a fake root
         waitForIdle()
 
-        return CollectedOwners(AndroidOwnerRegistry.getOwners().also {
+        return AndroidOwnerRegistry.getOwners().also {
             // TODO(b/153632210): This check should be done by callers of collectOwners
             check(it.isNotEmpty()) { "No AndroidOwners found. Is your Activity resumed?" }
-        })
+        }.flatMap { it.semanticsOwner.getAllSemanticsNodes() }
     }
 
     /**
@@ -85,6 +83,13 @@
         waitForOnCommitCallbacks()
     }
 
+    private fun ensureAndroidOwnerRegistryIsSetUp() {
+        check(AndroidOwnerRegistry.isSetUp) {
+            "Test not setup properly. Use a ComposeTestRule in your test to be able to interact " +
+                    "with composables"
+        }
+    }
+
     /**
      * Waits for all scheduled [onCommit] callbacks to be executed.
      */
@@ -98,6 +103,8 @@
     }
 
     private fun waitForAndroidOwners() {
+        ensureAndroidOwnerRegistryIsSetUp()
+
         fun hasAndroidOwners(): Boolean = AndroidOwnerRegistry.getOwners().isNotEmpty()
 
         if (!hasAndroidOwners()) {
@@ -120,36 +127,3 @@
         }
     }
 }
-
-/**
- * There can be multiple Compose views in the Android hierarchy and we want to interact with all
- * of them. This class merges all the [AndroidOwner]s into one, hiding the fact that the API
- * might be interacting with several Compose roots.
- */
-internal data class CollectedOwners(val owners: Set<AndroidOwner>) {
-    // Recursively search for the Activity context through (possible) ContextWrappers
-    private fun Context.getActivity(): Activity? {
-        return when (this) {
-            is Activity -> this
-            is ContextWrapper -> this.baseContext.getActivity()
-            else -> null
-        }
-    }
-
-    fun findActivity(): Activity {
-        owners.forEach {
-            val activity = it.view.context.getActivity()
-            if (activity != null) {
-                return activity
-            }
-        }
-        throw AssertionError(
-            "Out of ${owners.size} Owners, none were attached to an Activity"
-        )
-    }
-
-    fun getAllSemanticNodes(): List<SemanticsNode> {
-        // TODO(pavlis): Once we have a tree support we will just add a fake root parent here
-        return owners.flatMap { it.semanticsOwner.getAllSemanticsNodes() }
-    }
-}
diff --git a/ui/ui-test/src/main/java/androidx/ui/test/android/WindowCapture.kt b/ui/ui-test/src/main/java/androidx/ui/test/android/WindowCapture.kt
index 7f5e5b9..caf7ee8 100644
--- a/ui/ui-test/src/main/java/androidx/ui/test/android/WindowCapture.kt
+++ b/ui/ui-test/src/main/java/androidx/ui/test/android/WindowCapture.kt
@@ -16,12 +16,18 @@
 
 package androidx.ui.test.android
 
+import android.app.Activity
+import android.content.Context
+import android.content.ContextWrapper
 import android.graphics.Bitmap
 import android.os.Build
 import android.os.Handler
+import android.os.Looper
 import android.view.PixelCopy
 import android.view.Window
 import androidx.annotation.RequiresApi
+import androidx.ui.core.AndroidOwner
+import androidx.ui.core.Owner
 import androidx.ui.geometry.Rect
 import java.util.concurrent.CountDownLatch
 import java.util.concurrent.TimeUnit
@@ -29,21 +35,48 @@
 
 @RequiresApi(Build.VERSION_CODES.O)
 internal fun captureRegionToBitmap(
-    globalRect: Rect,
+    captureRect: Rect,
+    owner: Owner
+): Bitmap {
+
+    fun Context.getActivity(): Activity? {
+        return when (this) {
+            is Activity -> this
+            is ContextWrapper -> this.baseContext.getActivity()
+            else -> null
+        }
+    }
+
+    // TODO(pavlis): Make sure that the Activity actually hosts the view. As in case of popup
+    //  it wouldn't. This will require us rewriting the structure how we collect the nodes.
+
+    // TODO(pavlis): Add support for popups. So if we find composable hosted in popup we can
+    //  grab its reference to its window (need to add a hook to popup).
+
+    val window = (owner as AndroidOwner).view.context.getActivity()!!.window
+    val handler = Handler(Looper.getMainLooper())
+    return captureRegionToBitmap(captureRect, handler, window)
+}
+
+@RequiresApi(Build.VERSION_CODES.O)
+internal fun captureRegionToBitmap(
+    captureRect: Rect,
     handler: Handler,
     window: Window
 ): Bitmap {
     val destBitmap = Bitmap.createBitmap(
-        globalRect.width.roundToInt(),
-        globalRect.height.roundToInt(),
-        Bitmap.Config.ARGB_8888)
+        captureRect.width.roundToInt(),
+        captureRect.height.roundToInt(),
+        Bitmap.Config.ARGB_8888
+    )
 
     // TODO: This could go to some Android specific extensions.
     val srcRect = android.graphics.Rect(
-        globalRect.left.roundToInt(),
-        globalRect.top.roundToInt(),
-        globalRect.right.roundToInt(),
-        globalRect.bottom.roundToInt())
+        captureRect.left.roundToInt(),
+        captureRect.top.roundToInt(),
+        captureRect.right.roundToInt(),
+        captureRect.bottom.roundToInt()
+    )
 
     val latch = CountDownLatch(1)
     var copyResult = 0
diff --git a/ui/ui-text-android/api/0.1.0-dev12.txt b/ui/ui-text-android/api/0.1.0-dev12.txt
index 756ead2..182bb12 100644
--- a/ui/ui-text-android/api/0.1.0-dev12.txt
+++ b/ui/ui-text-android/api/0.1.0-dev12.txt
@@ -11,6 +11,9 @@
 
 package androidx.ui.text.platform.style {
 
+  public final class FontWeightStyleSpanKt {
+  }
+
   public final class PlaceholderSpanKt {
   }
 
diff --git a/ui/ui-text-android/api/current.txt b/ui/ui-text-android/api/current.txt
index 756ead2..182bb12 100644
--- a/ui/ui-text-android/api/current.txt
+++ b/ui/ui-text-android/api/current.txt
@@ -11,6 +11,9 @@
 
 package androidx.ui.text.platform.style {
 
+  public final class FontWeightStyleSpanKt {
+  }
+
   public final class PlaceholderSpanKt {
   }
 
diff --git a/ui/ui-text-android/api/public_plus_experimental_0.1.0-dev12.txt b/ui/ui-text-android/api/public_plus_experimental_0.1.0-dev12.txt
index 756ead2..182bb12 100644
--- a/ui/ui-text-android/api/public_plus_experimental_0.1.0-dev12.txt
+++ b/ui/ui-text-android/api/public_plus_experimental_0.1.0-dev12.txt
@@ -11,6 +11,9 @@
 
 package androidx.ui.text.platform.style {
 
+  public final class FontWeightStyleSpanKt {
+  }
+
   public final class PlaceholderSpanKt {
   }
 
diff --git a/ui/ui-text-android/api/public_plus_experimental_current.txt b/ui/ui-text-android/api/public_plus_experimental_current.txt
index 756ead2..182bb12 100644
--- a/ui/ui-text-android/api/public_plus_experimental_current.txt
+++ b/ui/ui-text-android/api/public_plus_experimental_current.txt
@@ -11,6 +11,9 @@
 
 package androidx.ui.text.platform.style {
 
+  public final class FontWeightStyleSpanKt {
+  }
+
   public final class PlaceholderSpanKt {
   }
 
diff --git a/ui/ui-text-android/api/restricted_0.1.0-dev12.txt b/ui/ui-text-android/api/restricted_0.1.0-dev12.txt
index 4d862c7..01d0e25 100644
--- a/ui/ui-text-android/api/restricted_0.1.0-dev12.txt
+++ b/ui/ui-text-android/api/restricted_0.1.0-dev12.txt
@@ -85,6 +85,31 @@
     method public void updateMeasureState(android.text.TextPaint textPaint);
   }
 
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public final class FontSpan extends android.text.style.MetricAffectingSpan {
+    ctor public FontSpan(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Boolean,? extends android.graphics.Typeface> getTypeface);
+    method public kotlin.jvm.functions.Function2<java.lang.Integer,java.lang.Boolean,android.graphics.Typeface> getGetTypeface();
+    method public void updateDrawState(android.text.TextPaint textPaint);
+    method public void updateMeasureState(android.text.TextPaint textPaint);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public final class FontWeightStyleSpan extends android.text.style.MetricAffectingSpan {
+    ctor public FontWeightStyleSpan(@IntRange(from=null, to=null) int weight, int style);
+    method public int getStyle();
+    method public int getWeight();
+    method public void updateDrawState(android.text.TextPaint textPaint);
+    method public void updateMeasureState(android.text.TextPaint textPaint);
+    field public static final androidx.ui.text.platform.style.FontWeightStyleSpan.Companion! Companion;
+    field public static final int STYLE_ITALIC = 2; // 0x2
+    field public static final int STYLE_NONE = -1; // 0xffffffff
+    field public static final int STYLE_NORMAL = 0; // 0x0
+  }
+
+  public static final class FontWeightStyleSpan.Companion {
+  }
+
+  public final class FontWeightStyleSpanKt {
+  }
+
   @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public final class LetterSpacingSpanEm extends android.text.style.MetricAffectingSpan {
     ctor public LetterSpacingSpanEm(float letterSpacing);
     method public float getLetterSpacing();
diff --git a/ui/ui-text-android/api/restricted_current.txt b/ui/ui-text-android/api/restricted_current.txt
index 4d862c7..01d0e25 100644
--- a/ui/ui-text-android/api/restricted_current.txt
+++ b/ui/ui-text-android/api/restricted_current.txt
@@ -85,6 +85,31 @@
     method public void updateMeasureState(android.text.TextPaint textPaint);
   }
 
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public final class FontSpan extends android.text.style.MetricAffectingSpan {
+    ctor public FontSpan(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Boolean,? extends android.graphics.Typeface> getTypeface);
+    method public kotlin.jvm.functions.Function2<java.lang.Integer,java.lang.Boolean,android.graphics.Typeface> getGetTypeface();
+    method public void updateDrawState(android.text.TextPaint textPaint);
+    method public void updateMeasureState(android.text.TextPaint textPaint);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public final class FontWeightStyleSpan extends android.text.style.MetricAffectingSpan {
+    ctor public FontWeightStyleSpan(@IntRange(from=null, to=null) int weight, int style);
+    method public int getStyle();
+    method public int getWeight();
+    method public void updateDrawState(android.text.TextPaint textPaint);
+    method public void updateMeasureState(android.text.TextPaint textPaint);
+    field public static final androidx.ui.text.platform.style.FontWeightStyleSpan.Companion! Companion;
+    field public static final int STYLE_ITALIC = 2; // 0x2
+    field public static final int STYLE_NONE = -1; // 0xffffffff
+    field public static final int STYLE_NORMAL = 0; // 0x0
+  }
+
+  public static final class FontWeightStyleSpan.Companion {
+  }
+
+  public final class FontWeightStyleSpanKt {
+  }
+
   @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public final class LetterSpacingSpanEm extends android.text.style.MetricAffectingSpan {
     ctor public LetterSpacingSpanEm(float letterSpacing);
     method public float getLetterSpacing();
diff --git a/ui/ui-text-android/src/androidTest/java/androidx/ui/text/platform/style/FontSpanTest.kt b/ui/ui-text-android/src/androidTest/java/androidx/ui/text/platform/style/FontSpanTest.kt
new file mode 100644
index 0000000..6cfdf55
--- /dev/null
+++ b/ui/ui-text-android/src/androidTest/java/androidx/ui/text/platform/style/FontSpanTest.kt
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.ui.text.platform.style
+
+import android.graphics.Typeface
+import android.text.TextPaint
+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 FontSpanTest {
+    @Test
+    fun updatePaint() {
+        val textPaint = TextPaint()
+        val typeface = Typeface.defaultFromStyle(Typeface.BOLD_ITALIC)
+        val span = FontSpan { _, _ -> typeface }
+
+        assertThat(textPaint.typeface).isNotSameInstanceAs(typeface)
+        span.updatePaint(textPaint)
+        assertThat(textPaint.typeface).isSameInstanceAs(typeface)
+    }
+}
\ No newline at end of file
diff --git a/ui/ui-text-android/src/androidTest/java/androidx/ui/text/platform/style/FontWeightStyleSpanTest.kt b/ui/ui-text-android/src/androidTest/java/androidx/ui/text/platform/style/FontWeightStyleSpanTest.kt
new file mode 100644
index 0000000..03deb5e
--- /dev/null
+++ b/ui/ui-text-android/src/androidTest/java/androidx/ui/text/platform/style/FontWeightStyleSpanTest.kt
@@ -0,0 +1,206 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.ui.text.platform.style
+
+import android.graphics.Typeface
+import android.graphics.fonts.FontStyle
+import android.text.TextPaint
+import androidx.test.filters.SdkSuppress
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@SmallTest
+@RunWith(JUnit4::class)
+class FontWeightStyleSpanTest {
+    @Test
+    @SdkSuppress(minSdkVersion = 28)
+    fun updatePaint_withFontWeightBold() {
+        val textPaint = TextPaint()
+        val weight = FontStyle.FONT_WEIGHT_BOLD
+        val span = FontWeightStyleSpan(weight, FontWeightStyleSpan.STYLE_NONE)
+        span.updatePaint(textPaint)
+
+        assertThat(textPaint.typeface).isNotNull()
+        assertThat(textPaint.typeface.weight).isEqualTo(weight)
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 28)
+    fun updatePaint_withFontWeightLight() {
+        val textPaint = TextPaint()
+        val weight = FontStyle.FONT_WEIGHT_LIGHT
+        val span = FontWeightStyleSpan(weight, FontWeightStyleSpan.STYLE_NONE)
+        span.updatePaint(textPaint)
+
+        assertThat(textPaint.typeface).isNotNull()
+        assertThat(textPaint.typeface.weight).isEqualTo(weight)
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 28)
+    fun updatePaint_withFontWeightBoldToNormal() {
+        val textPaint = TextPaint().apply {
+            typeface = Typeface.create(null, FontStyle.FONT_WEIGHT_BOLD, false)
+        }
+        val weight = FontStyle.FONT_WEIGHT_NORMAL
+        val span = FontWeightStyleSpan(weight, FontWeightStyleSpan.STYLE_NONE)
+        span.updatePaint(textPaint)
+
+        assertThat(textPaint.typeface.isBold).isFalse()
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 28)
+    fun updatePaint_withFontWeightNull() {
+        val textPaint = TextPaint().apply {
+            typeface = Typeface.create(null, FontStyle.FONT_WEIGHT_BOLD, true)
+        }
+        val span = FontWeightStyleSpan(0, FontWeightStyleSpan.STYLE_NORMAL)
+        span.updatePaint(textPaint)
+
+        assertThat(textPaint.typeface.weight).isEqualTo(FontStyle.FONT_WEIGHT_BOLD)
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 28)
+    fun updatePaint_withItalic() {
+        val textPaint = TextPaint()
+        val span = FontWeightStyleSpan(0, FontWeightStyleSpan.STYLE_ITALIC)
+        span.updatePaint(textPaint)
+
+        assertThat(textPaint.typeface).isNotNull()
+        assertThat(textPaint.typeface.isItalic).isTrue()
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 28)
+    fun updatePaint_withItalicNull() {
+        val textPaint = TextPaint().apply {
+            typeface = Typeface.create(null, FontStyle.FONT_WEIGHT_BOLD, true)
+        }
+        val span = FontWeightStyleSpan(
+            weight = FontStyle.FONT_WEIGHT_NORMAL,
+            style = FontWeightStyleSpan.STYLE_NONE)
+        span.updatePaint(textPaint)
+
+        assertThat(textPaint.typeface.isItalic).isTrue()
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 28)
+    fun updatePaint_noChange() {
+        val typeface = Typeface.create(null, FontStyle.FONT_WEIGHT_BOLD, true)
+        val textPaint = TextPaint().apply { this.typeface = typeface }
+        val span = FontWeightStyleSpan(FontStyle.FONT_WEIGHT_BOLD, FontWeightStyleSpan.STYLE_ITALIC)
+        span.updatePaint(textPaint)
+
+        assertThat(textPaint.typeface).isSameInstanceAs(typeface)
+    }
+
+    @Test
+    @SdkSuppress(maxSdkVersion = 27)
+    fun legacyUpdatePaint_withFontWeightBold() {
+        val textPaint = TextPaint()
+        val weight = FontStyle.FONT_WEIGHT_BOLD
+        val span = FontWeightStyleSpan(weight, FontWeightStyleSpan.STYLE_NONE)
+        span.legacyUpdatePaint(textPaint)
+
+        assertThat(textPaint.typeface).isNotNull()
+        assertThat(textPaint.typeface.isBold).isTrue()
+    }
+
+    @Test
+    @SdkSuppress(maxSdkVersion = 27)
+    fun legacyUpdatePaint_withFontWeightLight() {
+        val textPaint = TextPaint()
+        val weight = FontStyle.FONT_WEIGHT_LIGHT
+        val span = FontWeightStyleSpan(weight, FontWeightStyleSpan.STYLE_NONE)
+        span.legacyUpdatePaint(textPaint)
+
+        assertThat(textPaint.typeface).isNotNull()
+        assertThat(textPaint.typeface.isBold).isFalse()
+    }
+
+    @Test
+    @SdkSuppress(maxSdkVersion = 27)
+    fun legacyUpdatePaint_withFontWeightBoldToNormal() {
+        val textPaint = TextPaint().apply {
+            typeface = Typeface.defaultFromStyle(Typeface.BOLD)
+        }
+        val weight = FontStyle.FONT_WEIGHT_NORMAL
+        val span = FontWeightStyleSpan(weight, FontWeightStyleSpan.STYLE_NONE)
+        span.legacyUpdatePaint(textPaint)
+
+        assertThat(textPaint.typeface.isBold).isFalse()
+    }
+
+    @Test
+    @SdkSuppress(maxSdkVersion = 27)
+    fun legacyUpdatePaint_withFontWeightNull() {
+        val textPaint = TextPaint().apply {
+            typeface = Typeface.defaultFromStyle(Typeface.BOLD_ITALIC)
+        }
+        val span = FontWeightStyleSpan(0, FontWeightStyleSpan.STYLE_NORMAL)
+        span.legacyUpdatePaint(textPaint)
+
+        assertThat(textPaint.typeface.isBold).isTrue()
+    }
+
+    @Test
+    @SdkSuppress(maxSdkVersion = 27)
+    fun legacyUpdatePaint_withItalic() {
+        val textPaint = TextPaint().apply {
+            typeface = Typeface.defaultFromStyle(Typeface.BOLD)
+        }
+        val weight = FontStyle.FONT_WEIGHT_NORMAL
+        val span = FontWeightStyleSpan(weight, FontWeightStyleSpan.STYLE_NONE)
+        span.legacyUpdatePaint(textPaint)
+
+        assertThat(textPaint.typeface).isNotNull()
+        assertThat(textPaint.typeface.isBold).isFalse()
+    }
+
+    @Test
+    @SdkSuppress(maxSdkVersion = 27)
+    fun legacyUpdatePaint_withItalicNull() {
+        val textPaint = TextPaint().apply {
+            typeface = Typeface.defaultFromStyle(Typeface.BOLD_ITALIC)
+        }
+        val span = FontWeightStyleSpan(0, FontWeightStyleSpan.STYLE_NORMAL)
+        span.legacyUpdatePaint(textPaint)
+
+        assertThat(textPaint.typeface).isNotNull()
+        assertThat(textPaint.typeface.isItalic).isFalse()
+    }
+
+    @Test
+    @SdkSuppress(maxSdkVersion = 27)
+    fun legacyUpdatePaint_noChange() {
+        val typeface = Typeface.defaultFromStyle(Typeface.BOLD_ITALIC)
+        val textPaint = TextPaint().apply { this.typeface = typeface }
+        val span = FontWeightStyleSpan(
+            weight = FontStyle.FONT_WEIGHT_BOLD,
+            style = FontWeightStyleSpan.STYLE_ITALIC
+        )
+        span.legacyUpdatePaint(textPaint)
+
+        assertThat(textPaint.typeface).isSameInstanceAs(typeface)
+    }
+}
\ No newline at end of file
diff --git a/ui/ui-text-android/src/main/java/androidx/ui/text/platform/style/FontSpan.kt b/ui/ui-text-android/src/main/java/androidx/ui/text/platform/style/FontSpan.kt
new file mode 100644
index 0000000..d68e518
--- /dev/null
+++ b/ui/ui-text-android/src/main/java/androidx/ui/text/platform/style/FontSpan.kt
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.ui.text.platform.style
+
+import android.graphics.Typeface
+import android.graphics.fonts.FontStyle
+import android.os.Build
+import android.text.TextPaint
+import android.text.style.MetricAffectingSpan
+import androidx.annotation.RestrictTo
+import androidx.annotation.VisibleForTesting
+
+/**
+ * Span that changes the typeface of the text.
+ *
+ * @param getTypeface a lambda function that returns the typeface used to render the affected text.
+ * @suppress
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+class FontSpan(
+    val getTypeface: (weight: Int, isItalic: Boolean) -> Typeface
+) : MetricAffectingSpan() {
+
+    @VisibleForTesting
+    internal fun updatePaint(textPaint: TextPaint) {
+        val oldTypeface: Typeface? = textPaint.typeface
+        if (oldTypeface == null) {
+            textPaint.typeface = getTypeface(FontStyle.FONT_WEIGHT_NORMAL, false)
+            return
+        }
+        val weight = if (Build.VERSION.SDK_INT <= 28) {
+            if (oldTypeface.isBold) {
+                FontStyle.FONT_WEIGHT_BOLD
+            } else {
+                FontStyle.FONT_WEIGHT_NORMAL
+            }
+        } else {
+            oldTypeface.weight
+        }
+        textPaint.typeface = getTypeface(weight, oldTypeface.isItalic)
+    }
+
+    override fun updateDrawState(textPaint: TextPaint) {
+        updatePaint(textPaint)
+    }
+
+    override fun updateMeasureState(textPaint: TextPaint) {
+        updatePaint(textPaint)
+    }
+}
\ No newline at end of file
diff --git a/ui/ui-text-android/src/main/java/androidx/ui/text/platform/style/FontWeightStyleSpan.kt b/ui/ui-text-android/src/main/java/androidx/ui/text/platform/style/FontWeightStyleSpan.kt
new file mode 100644
index 0000000..4842c22
--- /dev/null
+++ b/ui/ui-text-android/src/main/java/androidx/ui/text/platform/style/FontWeightStyleSpan.kt
@@ -0,0 +1,151 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.ui.text.platform.style
+
+import android.graphics.Typeface
+import android.graphics.fonts.FontStyle
+import android.os.Build
+import android.text.TextPaint
+import android.text.style.MetricAffectingSpan
+import androidx.annotation.IntDef
+import androidx.annotation.IntRange
+import androidx.annotation.RequiresApi
+import androidx.annotation.RestrictTo
+import androidx.annotation.VisibleForTesting
+
+private const val AndroidBoldWeight = 600
+
+/**
+ * The span which changes the font weight and the font style of the affected text.
+ *
+ * @param weight the target font weight. If it's 0, this span won't modify the font weight.
+ * @param style the font style specified by this span. It can be STYLE_NONE, STYLE_NORMAL and
+ * STYLE_ITALIC. If STYLE_NONE is given, this span won't modify the font style.
+ *
+ * @suppress
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+class FontWeightStyleSpan(
+    @IntRange(from = 0, to = 1000)
+    val weight: Int,
+    @FontStyleMode
+    val style: Int
+) : MetricAffectingSpan() {
+    companion object {
+        const val STYLE_NONE = -1
+        const val STYLE_NORMAL = 0
+        const val STYLE_ITALIC = 2
+
+        @Retention(AnnotationRetention.SOURCE)
+        @IntDef(
+            STYLE_NONE,
+            STYLE_NORMAL,
+            STYLE_ITALIC
+        )
+        internal annotation class FontStyleMode
+    }
+
+    @VisibleForTesting
+    @RequiresApi(value = 28)
+    internal fun updatePaint(textPaint: TextPaint) {
+        val oldTypeface: Typeface? = textPaint.typeface
+        val weightChanged =
+            (weight != 0 && weight != oldTypeface?.weight)
+        val styleChanged =
+            (style != STYLE_NONE && (style == STYLE_ITALIC) != oldTypeface?.isItalic)
+        val needsUpdate = weightChanged || styleChanged
+        // Nothing to change. Early return.
+        if (!needsUpdate) {
+            return
+        }
+
+        val newWeight = if (weight != 0) {
+            weight
+        } else {
+            oldTypeface?.weight ?: FontStyle.FONT_WEIGHT_NORMAL
+        }
+
+        val newItalic = when (style) {
+            STYLE_NORMAL -> false
+            STYLE_ITALIC -> true
+            else -> oldTypeface?.isItalic ?: false
+        }
+
+        textPaint.typeface = Typeface.create(oldTypeface, newWeight, newItalic)
+    }
+
+    @VisibleForTesting
+    internal fun legacyUpdatePaint(textPaint: TextPaint) {
+        val oldTypeface: Typeface? = textPaint.typeface
+        val boldChanged =
+            (weight != 0 || isBold(weight) != oldTypeface?.isBold)
+        val styleChanged =
+            (style != STYLE_NONE && (style == STYLE_ITALIC) != oldTypeface?.isItalic)
+        val needsUpdate = boldChanged || styleChanged
+        // Nothing to change. Early return.
+        if (!needsUpdate) {
+            return
+        }
+        val newBold = if (weight != 0) {
+            isBold(weight)
+        } else {
+            oldTypeface?.isBold ?: false
+        }
+
+        val newItalic = when (style) {
+            STYLE_NORMAL -> false
+            STYLE_ITALIC -> true
+            else -> oldTypeface?.isItalic ?: false
+        }
+
+        textPaint.typeface = Typeface.create(oldTypeface, getTypefaceStyle(newBold, newItalic))
+    }
+
+    override fun updateDrawState(textPaint: TextPaint) {
+        if (Build.VERSION.SDK_INT >= 28) {
+            updatePaint(textPaint)
+        } else {
+            legacyUpdatePaint(textPaint)
+        }
+    }
+
+    override fun updateMeasureState(textPaint: TextPaint) {
+        if (Build.VERSION.SDK_INT >= 28) {
+            updatePaint(textPaint)
+        } else {
+            legacyUpdatePaint(textPaint)
+        }
+    }
+}
+
+// Helper function that checks if the given weight is bold or not.
+// It assumes weight is within [1, 1000].
+private fun isBold(weight: Int): Boolean {
+    return weight >= AndroidBoldWeight
+}
+
+internal fun getTypefaceStyle(isBold: Boolean, isItalic: Boolean): Int {
+    return if (isBold && isItalic) {
+        Typeface.BOLD_ITALIC
+    } else if (isBold) {
+        Typeface.BOLD
+    } else if (isItalic) {
+        Typeface.ITALIC
+    } else {
+        Typeface.NORMAL
+    }
+}
\ No newline at end of file
diff --git a/ui/ui-text-core/api/0.1.0-dev12.txt b/ui/ui-text-core/api/0.1.0-dev12.txt
index 946c57b..d08cf00 100644
--- a/ui/ui-text-core/api/0.1.0-dev12.txt
+++ b/ui/ui-text-core/api/0.1.0-dev12.txt
@@ -413,7 +413,7 @@
   }
 
   public final class ParagraphIntrinsicsKt {
-    method public static androidx.ui.text.ParagraphIntrinsics ParagraphIntrinsics(String text, androidx.ui.text.TextStyle style, java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.SpanStyle>> spanStyles = listOf(), java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.Placeholder>> placeholders = listOf(), androidx.ui.unit.Density density, androidx.ui.text.font.Font.ResourceLoader resourceLoader);
+    method public static androidx.ui.text.ParagraphIntrinsics ParagraphIntrinsics(String text, androidx.ui.text.TextStyle style, java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.SpanStyle>> spanStyles = emptyList(), java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.Placeholder>> placeholders = emptyList(), androidx.ui.unit.Density density, androidx.ui.text.font.Font.ResourceLoader resourceLoader);
   }
 
   public final class ParagraphKt {
diff --git a/ui/ui-text-core/api/api_lint.ignore b/ui/ui-text-core/api/api_lint.ignore
index f6d6d03..0b3a507 100644
--- a/ui/ui-text-core/api/api_lint.ignore
+++ b/ui/ui-text-core/api/api_lint.ignore
@@ -3,6 +3,28 @@
     Acronyms should not be capitalized in method names: was `copy-4Bo2vQE`, should this be `copy-4Bo2vQe`?
 
 
+BuilderSetStyle: androidx.ui.text.AnnotatedString.Builder#append(String):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.ui.text.AnnotatedString.Builder.append(String)
+BuilderSetStyle: androidx.ui.text.AnnotatedString.Builder#append(androidx.ui.text.AnnotatedString):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.ui.text.AnnotatedString.Builder.append(androidx.ui.text.AnnotatedString)
+BuilderSetStyle: androidx.ui.text.AnnotatedString.Builder#append(char):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.ui.text.AnnotatedString.Builder.append(char)
+BuilderSetStyle: androidx.ui.text.AnnotatedString.Builder#pop():
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.ui.text.AnnotatedString.Builder.pop()
+BuilderSetStyle: androidx.ui.text.AnnotatedString.Builder#pop(int):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.ui.text.AnnotatedString.Builder.pop(int)
+BuilderSetStyle: androidx.ui.text.AnnotatedString.Builder#pushStringAnnotation(String, String):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.ui.text.AnnotatedString.Builder.pushStringAnnotation(String,String)
+BuilderSetStyle: androidx.ui.text.AnnotatedString.Builder#pushStyle(androidx.ui.text.ParagraphStyle):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.ui.text.AnnotatedString.Builder.pushStyle(androidx.ui.text.ParagraphStyle)
+BuilderSetStyle: androidx.ui.text.AnnotatedString.Builder#pushStyle(androidx.ui.text.SpanStyle):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.ui.text.AnnotatedString.Builder.pushStyle(androidx.ui.text.SpanStyle)
+BuilderSetStyle: androidx.ui.text.AnnotatedString.Builder#toAnnotatedString():
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.ui.text.AnnotatedString.Builder.toAnnotatedString()
+BuilderSetStyle: androidx.ui.text.AnnotatedString.Builder#toString():
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.ui.text.AnnotatedString.Builder.toString()
+
+
 KotlinOperator: androidx.ui.text.font.FontListFontFamily#contains(androidx.ui.text.font.Font):
     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):
@@ -15,3 +37,11 @@
 
 MissingNullability: androidx.ui.text.style.BaselineShift#toString-impl(float):
     Missing nullability on method `toString-impl` return
+
+
+SetterReturnsThis: androidx.ui.text.AnnotatedString.Builder#addAnnotationString(String, String, int, int):
+    Methods must return the builder object (return type androidx.ui.text.AnnotatedString.Builder instead of void): method androidx.ui.text.AnnotatedString.Builder.addAnnotationString(String,String,int,int)
+SetterReturnsThis: androidx.ui.text.AnnotatedString.Builder#addStyle(androidx.ui.text.ParagraphStyle, int, int):
+    Methods must return the builder object (return type androidx.ui.text.AnnotatedString.Builder instead of void): method androidx.ui.text.AnnotatedString.Builder.addStyle(androidx.ui.text.ParagraphStyle,int,int)
+SetterReturnsThis: androidx.ui.text.AnnotatedString.Builder#addStyle(androidx.ui.text.SpanStyle, int, int):
+    Methods must return the builder object (return type androidx.ui.text.AnnotatedString.Builder instead of void): method androidx.ui.text.AnnotatedString.Builder.addStyle(androidx.ui.text.SpanStyle,int,int)
diff --git a/ui/ui-text-core/api/current.txt b/ui/ui-text-core/api/current.txt
index 946c57b..d08cf00 100644
--- a/ui/ui-text-core/api/current.txt
+++ b/ui/ui-text-core/api/current.txt
@@ -413,7 +413,7 @@
   }
 
   public final class ParagraphIntrinsicsKt {
-    method public static androidx.ui.text.ParagraphIntrinsics ParagraphIntrinsics(String text, androidx.ui.text.TextStyle style, java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.SpanStyle>> spanStyles = listOf(), java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.Placeholder>> placeholders = listOf(), androidx.ui.unit.Density density, androidx.ui.text.font.Font.ResourceLoader resourceLoader);
+    method public static androidx.ui.text.ParagraphIntrinsics ParagraphIntrinsics(String text, androidx.ui.text.TextStyle style, java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.SpanStyle>> spanStyles = emptyList(), java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.Placeholder>> placeholders = emptyList(), androidx.ui.unit.Density density, androidx.ui.text.font.Font.ResourceLoader resourceLoader);
   }
 
   public final class ParagraphKt {
diff --git a/ui/ui-text-core/api/public_plus_experimental_0.1.0-dev12.txt b/ui/ui-text-core/api/public_plus_experimental_0.1.0-dev12.txt
index 946c57b..d08cf00 100644
--- a/ui/ui-text-core/api/public_plus_experimental_0.1.0-dev12.txt
+++ b/ui/ui-text-core/api/public_plus_experimental_0.1.0-dev12.txt
@@ -413,7 +413,7 @@
   }
 
   public final class ParagraphIntrinsicsKt {
-    method public static androidx.ui.text.ParagraphIntrinsics ParagraphIntrinsics(String text, androidx.ui.text.TextStyle style, java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.SpanStyle>> spanStyles = listOf(), java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.Placeholder>> placeholders = listOf(), androidx.ui.unit.Density density, androidx.ui.text.font.Font.ResourceLoader resourceLoader);
+    method public static androidx.ui.text.ParagraphIntrinsics ParagraphIntrinsics(String text, androidx.ui.text.TextStyle style, java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.SpanStyle>> spanStyles = emptyList(), java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.Placeholder>> placeholders = emptyList(), androidx.ui.unit.Density density, androidx.ui.text.font.Font.ResourceLoader resourceLoader);
   }
 
   public final class ParagraphKt {
diff --git a/ui/ui-text-core/api/public_plus_experimental_current.txt b/ui/ui-text-core/api/public_plus_experimental_current.txt
index 946c57b..d08cf00 100644
--- a/ui/ui-text-core/api/public_plus_experimental_current.txt
+++ b/ui/ui-text-core/api/public_plus_experimental_current.txt
@@ -413,7 +413,7 @@
   }
 
   public final class ParagraphIntrinsicsKt {
-    method public static androidx.ui.text.ParagraphIntrinsics ParagraphIntrinsics(String text, androidx.ui.text.TextStyle style, java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.SpanStyle>> spanStyles = listOf(), java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.Placeholder>> placeholders = listOf(), androidx.ui.unit.Density density, androidx.ui.text.font.Font.ResourceLoader resourceLoader);
+    method public static androidx.ui.text.ParagraphIntrinsics ParagraphIntrinsics(String text, androidx.ui.text.TextStyle style, java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.SpanStyle>> spanStyles = emptyList(), java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.Placeholder>> placeholders = emptyList(), androidx.ui.unit.Density density, androidx.ui.text.font.Font.ResourceLoader resourceLoader);
   }
 
   public final class ParagraphKt {
diff --git a/ui/ui-text-core/api/restricted_0.1.0-dev12.txt b/ui/ui-text-core/api/restricted_0.1.0-dev12.txt
index 07f2f76..6f7ebdd 100644
--- a/ui/ui-text-core/api/restricted_0.1.0-dev12.txt
+++ b/ui/ui-text-core/api/restricted_0.1.0-dev12.txt
@@ -418,7 +418,7 @@
   }
 
   public final class ParagraphIntrinsicsKt {
-    method public static androidx.ui.text.ParagraphIntrinsics ParagraphIntrinsics(String text, androidx.ui.text.TextStyle style, java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.SpanStyle>> spanStyles = listOf(), java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.Placeholder>> placeholders = listOf(), androidx.ui.unit.Density density, androidx.ui.text.font.Font.ResourceLoader resourceLoader);
+    method public static androidx.ui.text.ParagraphIntrinsics ParagraphIntrinsics(String text, androidx.ui.text.TextStyle style, java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.SpanStyle>> spanStyles = emptyList(), java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.Placeholder>> placeholders = emptyList(), androidx.ui.unit.Density density, androidx.ui.text.font.Font.ResourceLoader resourceLoader);
   }
 
   public final class ParagraphKt {
diff --git a/ui/ui-text-core/api/restricted_current.txt b/ui/ui-text-core/api/restricted_current.txt
index 07f2f76..6f7ebdd 100644
--- a/ui/ui-text-core/api/restricted_current.txt
+++ b/ui/ui-text-core/api/restricted_current.txt
@@ -418,7 +418,7 @@
   }
 
   public final class ParagraphIntrinsicsKt {
-    method public static androidx.ui.text.ParagraphIntrinsics ParagraphIntrinsics(String text, androidx.ui.text.TextStyle style, java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.SpanStyle>> spanStyles = listOf(), java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.Placeholder>> placeholders = listOf(), androidx.ui.unit.Density density, androidx.ui.text.font.Font.ResourceLoader resourceLoader);
+    method public static androidx.ui.text.ParagraphIntrinsics ParagraphIntrinsics(String text, androidx.ui.text.TextStyle style, java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.SpanStyle>> spanStyles = emptyList(), java.util.List<androidx.ui.text.AnnotatedString.Item<androidx.ui.text.Placeholder>> placeholders = emptyList(), androidx.ui.unit.Density density, androidx.ui.text.font.Font.ResourceLoader resourceLoader);
   }
 
   public final class ParagraphKt {
diff --git a/ui/ui-text-core/src/androidTest/java/androidx/ui/text/platform/AndroidParagraphHelperTest.kt b/ui/ui-text-core/src/androidTest/java/androidx/ui/text/platform/AndroidParagraphHelperTest.kt
new file mode 100644
index 0000000..865af7f
--- /dev/null
+++ b/ui/ui-text-core/src/androidTest/java/androidx/ui/text/platform/AndroidParagraphHelperTest.kt
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.ui.text.platform
+
+import android.text.SpannableString
+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 AndroidParagraphHelperTest {
+    @Test
+    fun setSpanWithPriority_withSamePriority_returnSameSetOrder() {
+        val spanned = SpannableString("Hello World")
+        val span0 = Any()
+        val span1 = Any()
+        val span2 = Any()
+        val priority = 0
+        spanned.setSpanWithPriority(span0, 0, 1, priority)
+        spanned.setSpanWithPriority(span1, 0, 1, priority)
+        spanned.setSpanWithPriority(span2, 0, 1, priority)
+
+        val spans = spanned.getSpans(0, 1, Any::class.java)
+        assertThat(spans[0]).isSameInstanceAs(span0)
+        assertThat(spans[1]).isSameInstanceAs(span1)
+        assertThat(spans[2]).isSameInstanceAs(span2)
+    }
+
+    @Test
+    fun setSpanWithPriority_withIncreasingPriority_returnPriorityOrder() {
+        val spanned = SpannableString("Hello World")
+        val span0 = Any()
+        val span1 = Any()
+        val span2 = Any()
+        spanned.setSpanWithPriority(span0, 0, 1, 0)
+        spanned.setSpanWithPriority(span1, 0, 1, 1)
+        spanned.setSpanWithPriority(span2, 0, 1, 2)
+
+        val spans = spanned.getSpans(0, 1, Any::class.java)
+        assertThat(spans[0]).isSameInstanceAs(span2)
+        assertThat(spans[1]).isSameInstanceAs(span1)
+        assertThat(spans[2]).isSameInstanceAs(span0)
+    }
+
+    @Test
+    fun setSpanWithPriority_withDescendingPriority_returnPriorityOrder() {
+        val spanned = SpannableString("Hello World")
+        val span0 = Any()
+        val span1 = Any()
+        val span2 = Any()
+        spanned.setSpanWithPriority(span0, 0, 1, 2)
+        spanned.setSpanWithPriority(span1, 0, 1, 1)
+        spanned.setSpanWithPriority(span2, 0, 1, 0)
+
+        val spans = spanned.getSpans(0, 1, Any::class.java)
+        assertThat(spans[0]).isSameInstanceAs(span0)
+        assertThat(spans[1]).isSameInstanceAs(span1)
+        assertThat(spans[2]).isSameInstanceAs(span2)
+    }
+
+    @Test
+    fun setSpanWithPriority_withWigglingPriority_returnPriorityOrder() {
+        val spanned = SpannableString("Hello World")
+        val span0 = Any()
+        val span1 = Any()
+        val span2 = Any()
+        val span3 = Any()
+        spanned.setSpanWithPriority(span0, 0, 1, 0)
+        spanned.setSpanWithPriority(span1, 0, 1, 1)
+        spanned.setSpanWithPriority(span2, 0, 1, 0)
+        spanned.setSpanWithPriority(span3, 0, 1, 1)
+
+        val spans = spanned.getSpans(0, 1, Any::class.java)
+        assertThat(spans[0]).isSameInstanceAs(span1)
+        assertThat(spans[1]).isSameInstanceAs(span3)
+        assertThat(spans[2]).isSameInstanceAs(span0)
+        assertThat(spans[3]).isSameInstanceAs(span2)
+    }
+}
\ No newline at end of file
diff --git a/ui/ui-text-core/src/androidTest/java/androidx/ui/text/platform/AndroidParagraphTest.kt b/ui/ui-text-core/src/androidTest/java/androidx/ui/text/platform/AndroidParagraphTest.kt
index 96cde3d..b784a96 100644
--- a/ui/ui-text-core/src/androidTest/java/androidx/ui/text/platform/AndroidParagraphTest.kt
+++ b/ui/ui-text-core/src/androidTest/java/androidx/ui/text/platform/AndroidParagraphTest.kt
@@ -19,7 +19,6 @@
 import androidx.ui.text.platform.style.LetterSpacingSpanPx
 import androidx.ui.text.platform.style.ShadowSpan
 import androidx.ui.text.platform.style.SkewXSpan
-import androidx.ui.text.platform.style.TypefaceSpan
 import androidx.ui.geometry.Offset
 import androidx.ui.graphics.Color
 import androidx.ui.graphics.Shadow
@@ -37,6 +36,7 @@
 import androidx.ui.text.font.FontWeight
 import androidx.ui.text.font.asFontFamily
 import androidx.ui.text.matchers.assertThat
+import androidx.ui.text.platform.style.FontSpan
 import androidx.ui.text.style.BaselineShift
 import androidx.ui.text.style.TextAlign
 import androidx.ui.text.style.TextDecoration
@@ -49,6 +49,7 @@
 import androidx.ui.unit.sp
 import com.google.common.truth.Truth.assertThat
 import com.nhaarman.mockitokotlin2.any
+import com.nhaarman.mockitokotlin2.atLeastOnce
 import com.nhaarman.mockitokotlin2.eq
 import com.nhaarman.mockitokotlin2.mock
 import com.nhaarman.mockitokotlin2.never
@@ -714,8 +715,8 @@
 
         assertThat(paragraph.charSequence.toString()).isEqualTo(text)
         assertThat(paragraph.charSequence)
-            .hasSpan(TypefaceSpan::class, expectedStart, expectedEnd) { span ->
-                span.typeface == expectedTypeface
+            .hasSpan(FontSpan::class, expectedStart, expectedEnd) { span ->
+                span.getTypeface(FontWeight.Bold.weight, true) == expectedTypeface
             }
     }
 
@@ -751,8 +752,8 @@
 
         assertThat(paragraph.charSequence.toString()).isEqualTo(text)
         assertThat(paragraph.charSequence)
-            .hasSpan(TypefaceSpan::class, expectedStart, expectedEnd) { span ->
-                span.typeface == expectedTypeface
+            .hasSpan(FontSpan::class, expectedStart, expectedEnd) { span ->
+                span.getTypeface(FontWeight.Bold.weight, true) == expectedTypeface
             }
     }
 
@@ -883,7 +884,7 @@
             constraints = ParagraphConstraints(width = Float.MAX_VALUE)
         )
 
-        verify(typefaceAdapter, times(1)).create(
+        verify(typefaceAdapter, atLeastOnce()).create(
             fontFamily = eq(basicFontFamily),
             fontWeight = eq(FontWeight.Normal),
             fontStyle = eq(FontStyle.Normal),
@@ -895,6 +896,23 @@
     }
 
     @Test
+    fun testFontFamily_appliedAsSpan() {
+        val text = "abc"
+        val typefaceAdapter = spy(TypefaceAdapter())
+        val paragraph = simpleParagraph(
+            text = text,
+            style = TextStyle(
+                fontFamily = basicFontFamily
+            ),
+            typefaceAdapter = typefaceAdapter,
+            constraints = ParagraphConstraints(width = Float.MAX_VALUE)
+        )
+
+        val charSequence = paragraph.charSequence
+        assertThat(charSequence).hasSpan(FontSpan::class, 0, text.length)
+    }
+
+    @Test
     fun testEllipsis_withMaxLineEqualsNull_doesNotEllipsis() {
         with(defaultDensity) {
             val text = "abc"
diff --git a/ui/ui-text-core/src/main/java/androidx/ui/text/ParagraphIntrinsics.kt b/ui/ui-text-core/src/main/java/androidx/ui/text/ParagraphIntrinsics.kt
index 6e4abe5..fe529f3 100644
--- a/ui/ui-text-core/src/main/java/androidx/ui/text/ParagraphIntrinsics.kt
+++ b/ui/ui-text-core/src/main/java/androidx/ui/text/ParagraphIntrinsics.kt
@@ -45,8 +45,8 @@
 /* actual */ fun ParagraphIntrinsics(
     text: String,
     style: TextStyle,
-    spanStyles: List<AnnotatedString.Item<SpanStyle>> = listOf(),
-    placeholders: List<AnnotatedString.Item<Placeholder>> = listOf(),
+    spanStyles: List<AnnotatedString.Item<SpanStyle>> = emptyList(),
+    placeholders: List<AnnotatedString.Item<Placeholder>> = emptyList(),
     density: Density,
     resourceLoader: Font.ResourceLoader
 ): ParagraphIntrinsics {
diff --git a/ui/ui-text-core/src/main/java/androidx/ui/text/platform/AndroidParagraphHelper.kt b/ui/ui-text-core/src/main/java/androidx/ui/text/platform/AndroidParagraphHelper.kt
index 202db23..2af715f 100644
--- a/ui/ui-text-core/src/main/java/androidx/ui/text/platform/AndroidParagraphHelper.kt
+++ b/ui/ui-text-core/src/main/java/androidx/ui/text/platform/AndroidParagraphHelper.kt
@@ -18,6 +18,7 @@
 
 import android.graphics.Typeface
 import android.os.Build
+import android.text.Spannable
 import android.text.SpannableString
 import android.text.Spanned
 import android.text.TextPaint
@@ -31,6 +32,7 @@
 import android.text.style.StrikethroughSpan
 import android.text.style.UnderlineSpan
 import androidx.annotation.RequiresApi
+import androidx.annotation.VisibleForTesting
 import androidx.ui.text.platform.style.BaselineShiftSpan
 import androidx.ui.text.platform.style.FontFeatureSpan
 import androidx.ui.text.platform.style.LetterSpacingSpanEm
@@ -39,7 +41,6 @@
 import androidx.ui.text.platform.style.PlaceholderSpan
 import androidx.ui.text.platform.style.ShadowSpan
 import androidx.ui.text.platform.style.SkewXSpan
-import androidx.ui.text.platform.style.TypefaceSpan
 import androidx.ui.graphics.Color
 import androidx.ui.graphics.isSet
 import androidx.ui.unit.Density
@@ -53,18 +54,36 @@
 import androidx.ui.text.Placeholder
 import androidx.ui.text.PlaceholderVerticalAlign
 import androidx.ui.text.SpanStyle
+import androidx.ui.text.font.FontFamily
+import androidx.ui.text.font.FontListFontFamily
 import androidx.ui.text.font.FontStyle
 import androidx.ui.text.font.FontSynthesis
 import androidx.ui.text.font.FontWeight
+import androidx.ui.text.platform.style.FontSpan
+import androidx.ui.text.platform.style.FontWeightStyleSpan
 import androidx.ui.text.style.BaselineShift
 import androidx.ui.text.style.TextDecoration
 import androidx.ui.text.style.TextDirectionAlgorithm
 import androidx.ui.text.style.TextIndent
+import androidx.ui.util.fastForEach
 import kotlin.math.ceil
 import kotlin.math.roundToInt
 import android.os.LocaleList as AndroidLocaleList
 import java.util.Locale as JavaLocale
 
+// Maximum span priority supported by android framework.
+private const val SPAN_PRIORITY_MAX = 255
+// Minimum span priority supported by android framework.
+private const val SPAN_PRIORITY_MIN = 0
+// Span priority is in the range of [0, 255]. Here we used 127 as default priority(instead of 0)
+// in case some spans need  lower priority.
+private const val SPAN_PRIORITY_NORMAL = 127
+//  FontSpan must be applied after FontWeightStyleSpan, but before LetterSpacingSpan.
+private const val SPAN_PRIORITY_FONTSPAN = 1
+//  LetterSpacingSpanPx or LetterSpacingSpanEm must be applied after all other spans
+//  that change fontSize and scaleX.
+private const val SPAN_PRIORITY_LETTERSPACING = 0
+
 internal fun TextPaint.applySpanStyle(
     style: SpanStyle,
     typefaceAdapter: TypefaceAdapter,
@@ -134,10 +153,18 @@
         }
     }
 
+    // When FontFamily is a custom font(FontListFontFamily), it needs to be applied on Paint to
+    // compute empty paragraph height. Meanwhile, we also need a FontSpan for
+    // FontStyle/FontWeight span to work correctly.
     // letterSpacing with unit Sp needs to be handled by span.
     // baselineShift and bgColor is reset in the Android Layout constructor,
     // therefore we cannot apply them on paint, have to use spans.
     return SpanStyle(
+        fontFamily = if (style.fontFamily != null && style.fontFamily is FontListFontFamily) {
+            style.fontFamily
+        } else {
+            null
+        },
         letterSpacing = if (style.letterSpacing.type == TextUnitType.Sp &&
                     style.letterSpacing.value != 0f) {
             style.letterSpacing
@@ -169,26 +196,22 @@
 ): CharSequence {
     if (spanStyles.isEmpty() && textIndent == null) return text
     val spannableString = SpannableString(text)
-    //  Spans collected and applied at last. LetterSpacingSpanPx must be applied all other spans
-    //  that changes fontSize and scaleX. Notice, we can also utilize priority on span flags for
-    //  the purpose. If priority gets complicated, use flags instead.
-    val deferredSpans = mutableListOf<Triple<Any, Int, Int>>()
 
     when (lineHeight.type) {
         TextUnitType.Sp -> with(density) {
-            spannableString.setSpan(
+            spannableString.setSpanWithPriority(
                 LineHeightSpan(ceil(lineHeight.toPx().value).toInt()),
                 0,
                 text.length,
-                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
+                SPAN_PRIORITY_NORMAL
             )
         }
         TextUnitType.Em -> {
-            spannableString.setSpan(
+            spannableString.setSpanWithPriority(
                 LineHeightSpan(ceil(lineHeight.value * contextFontSize).toInt()),
                 0,
                 text.length,
-                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
+                SPAN_PRIORITY_NORMAL
             )
         }
         TextUnitType.Inherit -> {} // Do nothing
@@ -208,14 +231,14 @@
                 TextUnitType.Em -> indent.restLine.value * contextFontSize
                 TextUnitType.Inherit -> { 0f } // do nothing
             }
-            spannableString.setSpan(
+            spannableString.setSpanWithPriority(
                 LeadingMarginSpan.Standard(
                     ceil(firstLine).toInt(),
                     ceil(restLine).toInt()
                 ),
                 0,
                 text.length,
-                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
+                SPAN_PRIORITY_NORMAL
             )
         }
     }
@@ -230,118 +253,151 @@
         // Be aware that SuperscriptSpan needs to be applied before all other spans which
         // affect FontMetrics
         style.baselineShift?.let {
-            spannableString.setSpan(
+            spannableString.setSpanWithPriority(
                 BaselineShiftSpan(it.multiplier),
                 start,
                 end,
-                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
+                SPAN_PRIORITY_NORMAL
             )
         }
 
         if (style.color.isSet) {
-            spannableString.setSpan(
+            spannableString.setSpanWithPriority(
                 ForegroundColorSpan(style.color.toArgb()),
                 start,
                 end,
-                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
+                SPAN_PRIORITY_NORMAL
             )
         }
 
         style.textDecoration?.let {
             if (it.contains(TextDecoration.Underline)) {
-                spannableString.setSpan(
+                spannableString.setSpanWithPriority(
                     UnderlineSpan(),
                     start,
                     end,
-                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
+                    SPAN_PRIORITY_NORMAL
                 )
             }
             if (it.contains(TextDecoration.LineThrough)) {
-                spannableString.setSpan(
+                spannableString.setSpanWithPriority(
                     StrikethroughSpan(),
                     start,
                     end,
-                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
+                    SPAN_PRIORITY_NORMAL
                 )
             }
         }
 
         when (style.fontSize.type) {
             TextUnitType.Sp -> with(density) {
-                spannableString.setSpan(
+                spannableString.setSpanWithPriority(
                     AbsoluteSizeSpan(style.fontSize.toPx().value.roundToInt(), true),
                     start,
                     end,
-                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
+                    SPAN_PRIORITY_NORMAL
                 )
             }
             TextUnitType.Em -> {
-                spannableString.setSpan(
+                spannableString.setSpanWithPriority(
                     RelativeSizeSpan(style.fontSize.value),
                     start,
                     end,
-                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
+                    SPAN_PRIORITY_NORMAL
                 )
             }
             TextUnitType.Inherit -> {} // Do nothing
         }
 
         style.fontFeatureSettings?.let {
-            spannableString.setSpan(
+            spannableString.setSpanWithPriority(
                 FontFeatureSpan(it),
                 start,
                 end,
-                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
+                SPAN_PRIORITY_NORMAL
             )
         }
 
-        if (style.hasFontAttributes()) {
-            spannableString.setSpan(
-                TypefaceSpan(createTypeface(style, typefaceAdapter)),
+        style.fontFamily?.let {
+            spannableString.setSpanWithPriority(
+                FontSpan { weight, isItalic ->
+                    createTypeface(
+                        fontFamily = it,
+                        weight = weight,
+                        isItalic = isItalic,
+                        fontSynthesis = style.fontSynthesis,
+                        typefaceAdapter = typefaceAdapter
+                    )
+                },
                 start,
                 end,
-                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
+                if (it is FontListFontFamily) {
+                    SPAN_PRIORITY_FONTSPAN
+                } else {
+                    SPAN_PRIORITY_NORMAL
+                }
+            )
+        }
+
+        if (style.fontStyle != null || style.fontWeight != null) {
+            val weight = style.fontWeight?.weight ?: 0
+            val fontStyle = when (style.fontStyle) {
+                FontStyle.Normal -> FontWeightStyleSpan.STYLE_NORMAL
+                FontStyle.Italic -> FontWeightStyleSpan.STYLE_ITALIC
+                else -> FontWeightStyleSpan.STYLE_NONE
+            }
+            spannableString.setSpanWithPriority(
+                FontWeightStyleSpan(weight, fontStyle),
+                start,
+                end,
+                SPAN_PRIORITY_NORMAL
             )
         }
 
         style.textGeometricTransform?.let {
             if (it.scaleX != 1.0f) {
-                spannableString.setSpan(
+                spannableString.setSpanWithPriority(
                     ScaleXSpan(it.scaleX),
                     start,
                     end,
-                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
+                    SPAN_PRIORITY_NORMAL
                 )
             }
         }
 
         style.textGeometricTransform?.let {
             if (it.skewX != 0f) {
-                spannableString.setSpan(
+                spannableString.setSpanWithPriority(
                     SkewXSpan(it.skewX),
                     start,
                     end,
-                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
+                    SPAN_PRIORITY_NORMAL
                 )
             }
         }
 
         when (style.letterSpacing.type) {
             TextUnitType.Sp -> with(density) {
-                deferredSpans.add(
-                    Triple(LetterSpacingSpanPx(style.letterSpacing.toPx().value), start, end)
+                spannableString.setSpanWithPriority(
+                    LetterSpacingSpanPx(style.letterSpacing.toPx().value),
+                    start,
+                    end,
+                    SPAN_PRIORITY_LETTERSPACING
                 )
             }
             TextUnitType.Em -> {
-                deferredSpans.add(
-                    Triple(LetterSpacingSpanEm(style.letterSpacing.value), start, end)
+                spannableString.setSpanWithPriority(
+                    LetterSpacingSpanEm(style.letterSpacing.value),
+                    start,
+                    end,
+                    SPAN_PRIORITY_LETTERSPACING
                 )
             }
             TextUnitType.Inherit -> {}
         }
 
         style.localeList?.let {
-            spannableString.setSpan(
+            spannableString.setSpanWithPriority(
                 if (Build.VERSION.SDK_INT >= 24) {
                     LocaleSpan(it.toAndroidLocaleList())
                 } else {
@@ -350,32 +406,31 @@
                 },
                 start,
                 end,
-                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
+                SPAN_PRIORITY_NORMAL
             )
         }
         if (style.background.isSet) {
-            spannableString.setSpan(
+            spannableString.setSpanWithPriority(
                 BackgroundColorSpan(style.background.toArgb()),
                 start,
                 end,
-                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
+                SPAN_PRIORITY_NORMAL
             )
         }
         style.shadow?.let {
-            spannableString.setSpan(
+            spannableString.setSpanWithPriority(
                 ShadowSpan(it.color.toArgb(), it.offset.dx, it.offset.dy, it.blurRadius.value),
                 start,
                 end,
-                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
+                SPAN_PRIORITY_NORMAL
             )
         }
     }
-    for ((span, start, end) in deferredSpans) {
-        spannableString.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
-    }
-    for ((placeholder, start, end) in placeholders) {
+
+    placeholders.fastForEach {
+        val (placeholder, start, end) = it
         with(placeholder) {
-            spannableString.setSpan(
+            spannableString.setSpanWithPriority(
                 PlaceholderSpan(
                     width = width.value,
                     widthUnit = width.spanUnit,
@@ -386,13 +441,22 @@
                 ),
                 start,
                 end,
-                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
+                SPAN_PRIORITY_NORMAL
             )
         }
     }
     return spannableString
 }
 
+@VisibleForTesting
+internal fun Spannable.setSpanWithPriority(span: Any, start: Int, end: Int, priority: Int) {
+    require(priority >= SPAN_PRIORITY_MIN && priority <= SPAN_PRIORITY_MAX) {
+        "Invalid span priority: $priority must be in the range of [0, 255]."
+    }
+    val flag = (priority shl Spanned.SPAN_PRIORITY_SHIFT) or Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
+    setSpan(span, start, end, flag)
+}
+
 /**
  * Returns true if this [SpanStyle] contains any font style attributes set.
  */
@@ -409,6 +473,24 @@
     )
 }
 
+private fun createTypeface(
+    fontFamily: FontFamily?,
+    weight: Int,
+    isItalic: Boolean,
+    fontSynthesis: FontSynthesis?,
+    typefaceAdapter: TypefaceAdapter
+): Typeface {
+    val fontWeight = FontWeight(weight)
+    val fontStyle = if (isItalic) FontStyle.Italic else FontStyle.Normal
+
+    return typefaceAdapter.create(
+        fontFamily = fontFamily,
+        fontWeight = fontWeight,
+        fontStyle = fontStyle,
+        fontSynthesis = fontSynthesis ?: FontSynthesis.All
+    )
+}
+
 /**
  * For a given [TextDirectionAlgorithm] return [TextLayout] constants for text direction
  * heuristics.
@@ -451,4 +533,4 @@
         PlaceholderVerticalAlign.TextTop -> PlaceholderSpan.ALIGN_TEXT_TOP
         PlaceholderVerticalAlign.TextBottom -> PlaceholderSpan.ALIGN_TEXT_BOTTOM
         PlaceholderVerticalAlign.TextCenter -> PlaceholderSpan.ALIGN_TEXT_CENTER
-    }
\ No newline at end of file
+    }
diff --git a/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/ComposeInputFieldFocusTransition.kt b/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/ComposeInputFieldFocusTransition.kt
index 27426fb..8eaec74 100644
--- a/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/ComposeInputFieldFocusTransition.kt
+++ b/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/ComposeInputFieldFocusTransition.kt
@@ -18,7 +18,7 @@
 
 import androidx.compose.Composable
 import androidx.compose.state
-import androidx.ui.focus.FocusModifier
+import androidx.ui.core.focus.FocusModifier
 import androidx.ui.foundation.TextField
 import androidx.ui.foundation.TextFieldValue
 import androidx.ui.foundation.VerticalScroller
diff --git a/ui/ui-text/src/main/java/androidx/ui/text/CoreTextField.kt b/ui/ui-text/src/main/java/androidx/ui/text/CoreTextField.kt
index 7792233..c6f613c 100644
--- a/ui/ui-text/src/main/java/androidx/ui/text/CoreTextField.kt
+++ b/ui/ui-text/src/main/java/androidx/ui/text/CoreTextField.kt
@@ -35,9 +35,9 @@
 import androidx.ui.core.gesture.dragGestureFilter
 import androidx.ui.core.gesture.pressIndicatorGestureFilter
 import androidx.ui.core.onPositioned
-import androidx.ui.focus.FocusModifier
-import androidx.ui.focus.FocusState
-import androidx.ui.focus.focusState
+import androidx.ui.core.focus.FocusModifier
+import androidx.ui.core.focus.FocusState
+import androidx.ui.core.focus.focusState
 import androidx.ui.graphics.painter.drawCanvas
 import androidx.ui.input.EditProcessor
 import androidx.ui.input.EditorValue
@@ -274,12 +274,14 @@
 ) {
     val prevState = state { FocusState.NotFocused }
     if (focusModifier.focusState == FocusState.Focused &&
-        prevState.value == FocusState.NotFocused) {
+        prevState.value == FocusState.NotFocused
+    ) {
         onFocus()
     }
 
     if (focusModifier.focusState == FocusState.NotFocused &&
-        prevState.value == FocusState.Focused) {
+        prevState.value == FocusState.Focused
+    ) {
         onBlur(false) // TODO: Need to know if there is next focus element
     }
 
diff --git a/ui/ui-tooling/api/api_lint.ignore b/ui/ui-tooling/api/api_lint.ignore
deleted file mode 100644
index 9f69676..0000000
--- a/ui/ui-tooling/api/api_lint.ignore
+++ /dev/null
@@ -1,3 +0,0 @@
-// Baseline format: 1.0
-MissingNullability: androidx.ui.tooling.InspectableKt#getTables():
-    Missing nullability on method `getTables` return
diff --git a/ui/ui-unit/api/0.1.0-dev12.txt b/ui/ui-unit/api/0.1.0-dev12.txt
index 30a4329..95ef9ab 100644
--- a/ui/ui-unit/api/0.1.0-dev12.txt
+++ b/ui/ui-unit/api/0.1.0-dev12.txt
@@ -76,6 +76,10 @@
 
 package androidx.ui.unit {
 
+  public final class AndroidDensityKt {
+    method public static androidx.ui.unit.Density Density(android.content.Context context);
+  }
+
   public final class Bounds {
     method public float component1();
     method public float component2();
@@ -112,7 +116,6 @@
   }
 
   public final class DensityKt {
-    method public static androidx.ui.unit.Density Density(android.content.Context context);
     method public static androidx.ui.unit.Density Density(float density, float fontScale = 1f);
   }
 
diff --git a/ui/ui-unit/api/current.txt b/ui/ui-unit/api/current.txt
index 30a4329..95ef9ab 100644
--- a/ui/ui-unit/api/current.txt
+++ b/ui/ui-unit/api/current.txt
@@ -76,6 +76,10 @@
 
 package androidx.ui.unit {
 
+  public final class AndroidDensityKt {
+    method public static androidx.ui.unit.Density Density(android.content.Context context);
+  }
+
   public final class Bounds {
     method public float component1();
     method public float component2();
@@ -112,7 +116,6 @@
   }
 
   public final class DensityKt {
-    method public static androidx.ui.unit.Density Density(android.content.Context context);
     method public static androidx.ui.unit.Density Density(float density, float fontScale = 1f);
   }
 
diff --git a/ui/ui-unit/api/public_plus_experimental_0.1.0-dev12.txt b/ui/ui-unit/api/public_plus_experimental_0.1.0-dev12.txt
index 30a4329..95ef9ab 100644
--- a/ui/ui-unit/api/public_plus_experimental_0.1.0-dev12.txt
+++ b/ui/ui-unit/api/public_plus_experimental_0.1.0-dev12.txt
@@ -76,6 +76,10 @@
 
 package androidx.ui.unit {
 
+  public final class AndroidDensityKt {
+    method public static androidx.ui.unit.Density Density(android.content.Context context);
+  }
+
   public final class Bounds {
     method public float component1();
     method public float component2();
@@ -112,7 +116,6 @@
   }
 
   public final class DensityKt {
-    method public static androidx.ui.unit.Density Density(android.content.Context context);
     method public static androidx.ui.unit.Density Density(float density, float fontScale = 1f);
   }
 
diff --git a/ui/ui-unit/api/public_plus_experimental_current.txt b/ui/ui-unit/api/public_plus_experimental_current.txt
index 30a4329..95ef9ab 100644
--- a/ui/ui-unit/api/public_plus_experimental_current.txt
+++ b/ui/ui-unit/api/public_plus_experimental_current.txt
@@ -76,6 +76,10 @@
 
 package androidx.ui.unit {
 
+  public final class AndroidDensityKt {
+    method public static androidx.ui.unit.Density Density(android.content.Context context);
+  }
+
   public final class Bounds {
     method public float component1();
     method public float component2();
@@ -112,7 +116,6 @@
   }
 
   public final class DensityKt {
-    method public static androidx.ui.unit.Density Density(android.content.Context context);
     method public static androidx.ui.unit.Density Density(float density, float fontScale = 1f);
   }
 
diff --git a/ui/ui-unit/api/restricted_0.1.0-dev12.txt b/ui/ui-unit/api/restricted_0.1.0-dev12.txt
index 30a4329..95ef9ab 100644
--- a/ui/ui-unit/api/restricted_0.1.0-dev12.txt
+++ b/ui/ui-unit/api/restricted_0.1.0-dev12.txt
@@ -76,6 +76,10 @@
 
 package androidx.ui.unit {
 
+  public final class AndroidDensityKt {
+    method public static androidx.ui.unit.Density Density(android.content.Context context);
+  }
+
   public final class Bounds {
     method public float component1();
     method public float component2();
@@ -112,7 +116,6 @@
   }
 
   public final class DensityKt {
-    method public static androidx.ui.unit.Density Density(android.content.Context context);
     method public static androidx.ui.unit.Density Density(float density, float fontScale = 1f);
   }
 
diff --git a/ui/ui-unit/api/restricted_current.txt b/ui/ui-unit/api/restricted_current.txt
index 30a4329..95ef9ab 100644
--- a/ui/ui-unit/api/restricted_current.txt
+++ b/ui/ui-unit/api/restricted_current.txt
@@ -76,6 +76,10 @@
 
 package androidx.ui.unit {
 
+  public final class AndroidDensityKt {
+    method public static androidx.ui.unit.Density Density(android.content.Context context);
+  }
+
   public final class Bounds {
     method public float component1();
     method public float component2();
@@ -112,7 +116,6 @@
   }
 
   public final class DensityKt {
-    method public static androidx.ui.unit.Density Density(android.content.Context context);
     method public static androidx.ui.unit.Density Density(float density, float fontScale = 1f);
   }
 
diff --git a/ui/ui-unit/build.gradle b/ui/ui-unit/build.gradle
index cd5d933..ba8fe17 100644
--- a/ui/ui-unit/build.gradle
+++ b/ui/ui-unit/build.gradle
@@ -25,27 +25,39 @@
     id("AndroidXPlugin")
     id("com.android.library")
     id("AndroidXUiPlugin")
-    id("org.jetbrains.kotlin.android")
+    id("kotlin-multiplatform")
 }
 
-dependencies {
-    implementation(KOTLIN_STDLIB)
+kotlin {
+    android()
+    sourceSets {
+        commonMain.dependencies {
+            implementation(KOTLIN_STDLIB_COMMON)
+            api project(":ui:ui-geometry")
 
-    api "androidx.annotation:annotation:1.1.0"
-    implementation project(":ui:ui-util")
-    api project(":ui:ui-geometry")
+            implementation project(":ui:ui-util")
+            implementation project(":compose:compose-runtime")
+        }
+        jvmMain.dependencies {
+            implementation(KOTLIN_STDLIB)
+        }
+        androidMain.dependencies {
+            api "androidx.annotation:annotation:1.1.0"
+        }
 
-    implementation project(":compose:compose-runtime")
-
-    testImplementation(ANDROIDX_TEST_RULES)
-    testImplementation(ANDROIDX_TEST_RUNNER)
-    testImplementation(JUNIT)
-    testImplementation(TRUTH)
-
-    androidTestImplementation(ANDROIDX_TEST_RULES)
-    androidTestImplementation(ANDROIDX_TEST_RUNNER)
-    androidTestImplementation(ESPRESSO_CORE)
-    androidTestImplementation(JUNIT)
+        commonTest.dependencies {
+            implementation kotlin("test-junit")
+        }
+        // TODO: should be unitTest, figure out why that doesn't work
+        androidTest.dependencies {
+            implementation(TRUTH)
+        }
+        androidAndroidTest.dependencies {
+            implementation(ANDROIDX_TEST_RULES)
+            implementation(ANDROIDX_TEST_RUNNER)
+            implementation(ESPRESSO_CORE)
+        }
+    }
 }
 
 androidx {
@@ -59,7 +71,7 @@
 
 tasks.withType(KotlinCompile).configureEach {
     kotlinOptions {
-        freeCompilerArgs += ["-Xuse-experimental=kotlin.Experimental", "-XXLanguage:+InlineClasses"]
+        freeCompilerArgs += ["-XXLanguage:+InlineClasses"]
         useIR = true
     }
 }
diff --git a/ui/ui-unit/src/androidTest/AndroidManifest.xml b/ui/ui-unit/src/androidAndroidTest/AndroidManifest.xml
similarity index 100%
rename from ui/ui-unit/src/androidTest/AndroidManifest.xml
rename to ui/ui-unit/src/androidAndroidTest/AndroidManifest.xml
diff --git a/ui/ui-unit/src/androidTest/java/androidx/ui/unit/DpDeviceTest.kt b/ui/ui-unit/src/androidAndroidTest/kotlin/androidx/ui/unit/DpDeviceTest.kt
similarity index 100%
rename from ui/ui-unit/src/androidTest/java/androidx/ui/unit/DpDeviceTest.kt
rename to ui/ui-unit/src/androidAndroidTest/kotlin/androidx/ui/unit/DpDeviceTest.kt
diff --git a/ui/ui-unit/src/androidTest/java/androidx/ui/unit/SpDeviceTest.kt b/ui/ui-unit/src/androidAndroidTest/kotlin/androidx/ui/unit/SpDeviceTest.kt
similarity index 100%
rename from ui/ui-unit/src/androidTest/java/androidx/ui/unit/SpDeviceTest.kt
rename to ui/ui-unit/src/androidAndroidTest/kotlin/androidx/ui/unit/SpDeviceTest.kt
diff --git a/ui/ui-unit/src/main/AndroidManifest.xml b/ui/ui-unit/src/androidMain/AndroidManifest.xml
similarity index 100%
rename from ui/ui-unit/src/main/AndroidManifest.xml
rename to ui/ui-unit/src/androidMain/AndroidManifest.xml
diff --git a/ui/ui-unit/src/androidMain/kotlin/androidx/ui/unit/AndroidDensity.kt b/ui/ui-unit/src/androidMain/kotlin/androidx/ui/unit/AndroidDensity.kt
new file mode 100644
index 0000000..0d2c60f
--- /dev/null
+++ b/ui/ui-unit/src/androidMain/kotlin/androidx/ui/unit/AndroidDensity.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.ui.unit
+
+import android.content.Context
+
+/**
+ * Creates a [Density] for this [Context].
+ *
+ * @param context density values will be extracted from this [Context]
+ */
+fun Density(context: Context): Density =
+    Density(
+        context.resources.displayMetrics.density,
+        context.resources.configuration.fontScale
+    )
diff --git a/ui/ui-unit/src/main/java/androidx/ui/core/Constraints.kt b/ui/ui-unit/src/commonMain/kotlin/androidx/ui/core/Constraints.kt
similarity index 100%
rename from ui/ui-unit/src/main/java/androidx/ui/core/Constraints.kt
rename to ui/ui-unit/src/commonMain/kotlin/androidx/ui/core/Constraints.kt
diff --git a/ui/ui-unit/src/main/java/androidx/ui/core/Constraints2.kt b/ui/ui-unit/src/commonMain/kotlin/androidx/ui/core/Constraints2.kt
similarity index 99%
rename from ui/ui-unit/src/main/java/androidx/ui/core/Constraints2.kt
rename to ui/ui-unit/src/commonMain/kotlin/androidx/ui/core/Constraints2.kt
index 4e22058..5363d74 100644
--- a/ui/ui-unit/src/main/java/androidx/ui/core/Constraints2.kt
+++ b/ui/ui-unit/src/commonMain/kotlin/androidx/ui/core/Constraints2.kt
@@ -17,9 +17,9 @@
 
 package androidx.ui.core
 
-import androidx.annotation.IntRange
 import androidx.compose.Immutable
 import androidx.ui.unit.IntSize
+import androidx.ui.util.annotation.IntRange
 import kotlin.math.max
 
 /**
@@ -173,7 +173,7 @@
          * be considered infinite. [hasBoundedHeight] or [hasBoundedWidth] will be
          * `true` when [maxHeight] or [maxWidth] is [Infinity], respectively.
          */
-        const val Infinity = Integer.MIN_VALUE / 2
+        const val Infinity = Int.MIN_VALUE / 2
 
         /**
          * The bit distribution when the focus of the bits should be on the width, but only
diff --git a/ui/ui-unit/src/main/java/androidx/ui/core/LayoutDirection.kt b/ui/ui-unit/src/commonMain/kotlin/androidx/ui/core/LayoutDirection.kt
similarity index 100%
rename from ui/ui-unit/src/main/java/androidx/ui/core/LayoutDirection.kt
rename to ui/ui-unit/src/commonMain/kotlin/androidx/ui/core/LayoutDirection.kt
diff --git a/ui/ui-unit/src/main/java/androidx/ui/unit/Density.kt b/ui/ui-unit/src/commonMain/kotlin/androidx/ui/unit/Density.kt
similarity index 92%
rename from ui/ui-unit/src/main/java/androidx/ui/unit/Density.kt
rename to ui/ui-unit/src/commonMain/kotlin/androidx/ui/unit/Density.kt
index 839168d..915db4d 100644
--- a/ui/ui-unit/src/main/java/androidx/ui/unit/Density.kt
+++ b/ui/ui-unit/src/commonMain/kotlin/androidx/ui/unit/Density.kt
@@ -16,21 +16,9 @@
 
 package androidx.ui.unit
 
-import android.content.Context
 import androidx.ui.geometry.Rect
 
 /**
- * Creates a [Density] for this [Context].
- *
- * @param context density values will be extracted from this [Context]
- */
-fun Density(context: Context): Density =
-    Density(
-        context.resources.displayMetrics.density,
-        context.resources.configuration.fontScale
-    )
-
-/**
  * A density of the screen. Used for convert [Dp] to pixels.
  *
  * @param density The logical density of the display. This is a scaling factor for the [Dp] unit.
diff --git a/ui/ui-unit/src/main/java/androidx/ui/unit/Dp.kt b/ui/ui-unit/src/commonMain/kotlin/androidx/ui/unit/Dp.kt
similarity index 100%
rename from ui/ui-unit/src/main/java/androidx/ui/unit/Dp.kt
rename to ui/ui-unit/src/commonMain/kotlin/androidx/ui/unit/Dp.kt
diff --git a/ui/ui-unit/src/main/java/androidx/ui/unit/Duration.kt b/ui/ui-unit/src/commonMain/kotlin/androidx/ui/unit/Duration.kt
similarity index 99%
rename from ui/ui-unit/src/main/java/androidx/ui/unit/Duration.kt
rename to ui/ui-unit/src/commonMain/kotlin/androidx/ui/unit/Duration.kt
index 6a4e82c..5db5baa 100644
--- a/ui/ui-unit/src/main/java/androidx/ui/unit/Duration.kt
+++ b/ui/ui-unit/src/commonMain/kotlin/androidx/ui/unit/Duration.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-@file:JvmName("Durations")
+@file:kotlin.jvm.JvmName("Durations")
 @file:Suppress("NOTHING_TO_INLINE")
 
 package androidx.ui.unit
diff --git a/ui/ui-unit/src/main/java/androidx/ui/unit/IntPx.kt b/ui/ui-unit/src/commonMain/kotlin/androidx/ui/unit/IntPx.kt
similarity index 100%
rename from ui/ui-unit/src/main/java/androidx/ui/unit/IntPx.kt
rename to ui/ui-unit/src/commonMain/kotlin/androidx/ui/unit/IntPx.kt
diff --git a/ui/ui-unit/src/main/java/androidx/ui/unit/IntSize.kt b/ui/ui-unit/src/commonMain/kotlin/androidx/ui/unit/IntSize.kt
similarity index 100%
rename from ui/ui-unit/src/main/java/androidx/ui/unit/IntSize.kt
rename to ui/ui-unit/src/commonMain/kotlin/androidx/ui/unit/IntSize.kt
diff --git a/ui/ui-unit/src/main/java/androidx/ui/unit/Px.kt b/ui/ui-unit/src/commonMain/kotlin/androidx/ui/unit/Px.kt
similarity index 100%
rename from ui/ui-unit/src/main/java/androidx/ui/unit/Px.kt
rename to ui/ui-unit/src/commonMain/kotlin/androidx/ui/unit/Px.kt
diff --git a/ui/ui-unit/src/main/java/androidx/ui/unit/TextUnit.kt b/ui/ui-unit/src/commonMain/kotlin/androidx/ui/unit/TextUnit.kt
similarity index 97%
rename from ui/ui-unit/src/main/java/androidx/ui/unit/TextUnit.kt
rename to ui/ui-unit/src/commonMain/kotlin/androidx/ui/unit/TextUnit.kt
index 009e06f..d90d823 100644
--- a/ui/ui-unit/src/main/java/androidx/ui/unit/TextUnit.kt
+++ b/ui/ui-unit/src/commonMain/kotlin/androidx/ui/unit/TextUnit.kt
@@ -172,6 +172,8 @@
     }
 
     companion object {
+        internal val TextUnitTypes = arrayOf(TextUnitType.Inherit, TextUnitType.Sp, TextUnitType.Em)
+
         /**
          * Creates a SP unit [TextUnit].
          */
@@ -221,12 +223,7 @@
      *
      * @throws RuntimeException if unknown unknown unit type is appeared.
      */
-    val type: TextUnitType get() = when (rawType) {
-        UNIT_TYPE_INHERIT -> TextUnitType.Inherit
-        UNIT_TYPE_SP -> TextUnitType.Sp
-        UNIT_TYPE_EM -> TextUnitType.Em
-        else -> throw RuntimeException("packed TextUnit has unknown unit type.")
-    }
+    val type: TextUnitType get() = TextUnitTypes[(rawType ushr 32).toInt()]
 
     /**
      * True if this is [TextUnit.Inherit], otherwise false.
diff --git a/ui/ui-unit/src/main/java/androidx/ui/unit/Uptime.kt b/ui/ui-unit/src/commonMain/kotlin/androidx/ui/unit/Uptime.kt
similarity index 100%
rename from ui/ui-unit/src/main/java/androidx/ui/unit/Uptime.kt
rename to ui/ui-unit/src/commonMain/kotlin/androidx/ui/unit/Uptime.kt
diff --git a/ui/ui-unit/src/main/java/androidx/ui/unit/Velocity.kt b/ui/ui-unit/src/commonMain/kotlin/androidx/ui/unit/Velocity.kt
similarity index 100%
rename from ui/ui-unit/src/main/java/androidx/ui/unit/Velocity.kt
rename to ui/ui-unit/src/commonMain/kotlin/androidx/ui/unit/Velocity.kt
diff --git a/ui/ui-unit/src/test/java/androidx/ui/unit/DpTest.kt b/ui/ui-unit/src/unitTest/kotlin/androidx/ui/unit/DpTest.kt
similarity index 100%
rename from ui/ui-unit/src/test/java/androidx/ui/unit/DpTest.kt
rename to ui/ui-unit/src/unitTest/kotlin/androidx/ui/unit/DpTest.kt
diff --git a/ui/ui-unit/src/test/java/androidx/ui/unit/DurationTest.kt b/ui/ui-unit/src/unitTest/kotlin/androidx/ui/unit/DurationTest.kt
similarity index 100%
rename from ui/ui-unit/src/test/java/androidx/ui/unit/DurationTest.kt
rename to ui/ui-unit/src/unitTest/kotlin/androidx/ui/unit/DurationTest.kt
diff --git a/ui/ui-unit/src/test/java/androidx/ui/unit/IntPxTest.kt b/ui/ui-unit/src/unitTest/kotlin/androidx/ui/unit/IntPxTest.kt
similarity index 100%
rename from ui/ui-unit/src/test/java/androidx/ui/unit/IntPxTest.kt
rename to ui/ui-unit/src/unitTest/kotlin/androidx/ui/unit/IntPxTest.kt
diff --git a/ui/ui-unit/src/test/java/androidx/ui/unit/IntSizeTest.kt b/ui/ui-unit/src/unitTest/kotlin/androidx/ui/unit/IntSizeTest.kt
similarity index 100%
rename from ui/ui-unit/src/test/java/androidx/ui/unit/IntSizeTest.kt
rename to ui/ui-unit/src/unitTest/kotlin/androidx/ui/unit/IntSizeTest.kt
diff --git a/ui/ui-unit/src/test/java/androidx/ui/unit/PxTest.kt b/ui/ui-unit/src/unitTest/kotlin/androidx/ui/unit/PxTest.kt
similarity index 100%
rename from ui/ui-unit/src/test/java/androidx/ui/unit/PxTest.kt
rename to ui/ui-unit/src/unitTest/kotlin/androidx/ui/unit/PxTest.kt
diff --git a/ui/ui-unit/src/test/java/androidx/ui/unit/TextUnitTest.kt b/ui/ui-unit/src/unitTest/kotlin/androidx/ui/unit/TextUnitTest.kt
similarity index 100%
rename from ui/ui-unit/src/test/java/androidx/ui/unit/TextUnitTest.kt
rename to ui/ui-unit/src/unitTest/kotlin/androidx/ui/unit/TextUnitTest.kt
diff --git a/ui/ui-unit/src/test/java/androidx/ui/unit/UptimeTest.kt b/ui/ui-unit/src/unitTest/kotlin/androidx/ui/unit/UptimeTest.kt
similarity index 100%
rename from ui/ui-unit/src/test/java/androidx/ui/unit/UptimeTest.kt
rename to ui/ui-unit/src/unitTest/kotlin/androidx/ui/unit/UptimeTest.kt
diff --git a/ui/ui-unit/src/test/java/androidx/ui/unit/VelocityTest.kt b/ui/ui-unit/src/unitTest/kotlin/androidx/ui/unit/VelocityTest.kt
similarity index 100%
rename from ui/ui-unit/src/test/java/androidx/ui/unit/VelocityTest.kt
rename to ui/ui-unit/src/unitTest/kotlin/androidx/ui/unit/VelocityTest.kt
diff --git a/ui/ui-util/api/0.1.0-dev12.txt b/ui/ui-util/api/0.1.0-dev12.txt
index e8faee5..9286e03 100644
--- a/ui/ui-util/api/0.1.0-dev12.txt
+++ b/ui/ui-util/api/0.1.0-dev12.txt
@@ -1,6 +1,10 @@
 // Signature format: 3.0
 package androidx.ui.util {
 
+  public final class AndroidTraceKt {
+    method public static inline <T> T! trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
+  }
+
   public final class InlineClassHelperKt {
     method public static inline long packFloats(float val1, float val2);
     method public static inline long packInts(int val1, int val2);
@@ -10,8 +14,23 @@
     method public static inline int unpackInt2(long value);
   }
 
+  public final class JvmMathHelpersKt {
+    method public static String toStringAsFixed(float, int digits);
+  }
+
+  public final class JvmMiscHelpersKt {
+    method public static StringBuilder deleteAt(StringBuilder, int index);
+    method public static String format(String, java.lang.Object?... args);
+    method public static int identityHashCode(Object?);
+  }
+
+  public final class JvmSynchronizationHelperKt {
+    method public static <T> T! synchronized(Object lock, kotlin.jvm.functions.Function0<? extends T> block);
+  }
+
   public final class ListUtilsKt {
     method public static inline <T> boolean fastAny(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
+    method public static inline <T> T? fastFirstOrNull(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
     method public static inline <T> void fastForEach(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> action);
   }
 
@@ -20,15 +39,13 @@
     method public static int lerp(int start, int stop, float fraction);
     method public static long lerp(long start, long stop, float fraction);
     method public static String toHexString(int);
-    method public static String toStringAsFixed(float, int digits);
   }
 
-  public final class SynchronizationHelperKt {
-    method public static <T> T! synchronized(Object lock, kotlin.jvm.functions.Function0<? extends T> block);
-  }
+}
 
-  public final class TraceKt {
-    method public static inline <T> T! trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
+package androidx.ui.util.annotation {
+
+  public final class AndroidAnnotationKt {
   }
 
 }
diff --git a/ui/ui-util/api/current.txt b/ui/ui-util/api/current.txt
index e8faee5..9286e03 100644
--- a/ui/ui-util/api/current.txt
+++ b/ui/ui-util/api/current.txt
@@ -1,6 +1,10 @@
 // Signature format: 3.0
 package androidx.ui.util {
 
+  public final class AndroidTraceKt {
+    method public static inline <T> T! trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
+  }
+
   public final class InlineClassHelperKt {
     method public static inline long packFloats(float val1, float val2);
     method public static inline long packInts(int val1, int val2);
@@ -10,8 +14,23 @@
     method public static inline int unpackInt2(long value);
   }
 
+  public final class JvmMathHelpersKt {
+    method public static String toStringAsFixed(float, int digits);
+  }
+
+  public final class JvmMiscHelpersKt {
+    method public static StringBuilder deleteAt(StringBuilder, int index);
+    method public static String format(String, java.lang.Object?... args);
+    method public static int identityHashCode(Object?);
+  }
+
+  public final class JvmSynchronizationHelperKt {
+    method public static <T> T! synchronized(Object lock, kotlin.jvm.functions.Function0<? extends T> block);
+  }
+
   public final class ListUtilsKt {
     method public static inline <T> boolean fastAny(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
+    method public static inline <T> T? fastFirstOrNull(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
     method public static inline <T> void fastForEach(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> action);
   }
 
@@ -20,15 +39,13 @@
     method public static int lerp(int start, int stop, float fraction);
     method public static long lerp(long start, long stop, float fraction);
     method public static String toHexString(int);
-    method public static String toStringAsFixed(float, int digits);
   }
 
-  public final class SynchronizationHelperKt {
-    method public static <T> T! synchronized(Object lock, kotlin.jvm.functions.Function0<? extends T> block);
-  }
+}
 
-  public final class TraceKt {
-    method public static inline <T> T! trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
+package androidx.ui.util.annotation {
+
+  public final class AndroidAnnotationKt {
   }
 
 }
diff --git a/ui/ui-util/api/public_plus_experimental_0.1.0-dev12.txt b/ui/ui-util/api/public_plus_experimental_0.1.0-dev12.txt
index e8faee5..9286e03 100644
--- a/ui/ui-util/api/public_plus_experimental_0.1.0-dev12.txt
+++ b/ui/ui-util/api/public_plus_experimental_0.1.0-dev12.txt
@@ -1,6 +1,10 @@
 // Signature format: 3.0
 package androidx.ui.util {
 
+  public final class AndroidTraceKt {
+    method public static inline <T> T! trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
+  }
+
   public final class InlineClassHelperKt {
     method public static inline long packFloats(float val1, float val2);
     method public static inline long packInts(int val1, int val2);
@@ -10,8 +14,23 @@
     method public static inline int unpackInt2(long value);
   }
 
+  public final class JvmMathHelpersKt {
+    method public static String toStringAsFixed(float, int digits);
+  }
+
+  public final class JvmMiscHelpersKt {
+    method public static StringBuilder deleteAt(StringBuilder, int index);
+    method public static String format(String, java.lang.Object?... args);
+    method public static int identityHashCode(Object?);
+  }
+
+  public final class JvmSynchronizationHelperKt {
+    method public static <T> T! synchronized(Object lock, kotlin.jvm.functions.Function0<? extends T> block);
+  }
+
   public final class ListUtilsKt {
     method public static inline <T> boolean fastAny(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
+    method public static inline <T> T? fastFirstOrNull(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
     method public static inline <T> void fastForEach(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> action);
   }
 
@@ -20,15 +39,13 @@
     method public static int lerp(int start, int stop, float fraction);
     method public static long lerp(long start, long stop, float fraction);
     method public static String toHexString(int);
-    method public static String toStringAsFixed(float, int digits);
   }
 
-  public final class SynchronizationHelperKt {
-    method public static <T> T! synchronized(Object lock, kotlin.jvm.functions.Function0<? extends T> block);
-  }
+}
 
-  public final class TraceKt {
-    method public static inline <T> T! trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
+package androidx.ui.util.annotation {
+
+  public final class AndroidAnnotationKt {
   }
 
 }
diff --git a/ui/ui-util/api/public_plus_experimental_current.txt b/ui/ui-util/api/public_plus_experimental_current.txt
index e8faee5..9286e03 100644
--- a/ui/ui-util/api/public_plus_experimental_current.txt
+++ b/ui/ui-util/api/public_plus_experimental_current.txt
@@ -1,6 +1,10 @@
 // Signature format: 3.0
 package androidx.ui.util {
 
+  public final class AndroidTraceKt {
+    method public static inline <T> T! trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
+  }
+
   public final class InlineClassHelperKt {
     method public static inline long packFloats(float val1, float val2);
     method public static inline long packInts(int val1, int val2);
@@ -10,8 +14,23 @@
     method public static inline int unpackInt2(long value);
   }
 
+  public final class JvmMathHelpersKt {
+    method public static String toStringAsFixed(float, int digits);
+  }
+
+  public final class JvmMiscHelpersKt {
+    method public static StringBuilder deleteAt(StringBuilder, int index);
+    method public static String format(String, java.lang.Object?... args);
+    method public static int identityHashCode(Object?);
+  }
+
+  public final class JvmSynchronizationHelperKt {
+    method public static <T> T! synchronized(Object lock, kotlin.jvm.functions.Function0<? extends T> block);
+  }
+
   public final class ListUtilsKt {
     method public static inline <T> boolean fastAny(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
+    method public static inline <T> T? fastFirstOrNull(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
     method public static inline <T> void fastForEach(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> action);
   }
 
@@ -20,15 +39,13 @@
     method public static int lerp(int start, int stop, float fraction);
     method public static long lerp(long start, long stop, float fraction);
     method public static String toHexString(int);
-    method public static String toStringAsFixed(float, int digits);
   }
 
-  public final class SynchronizationHelperKt {
-    method public static <T> T! synchronized(Object lock, kotlin.jvm.functions.Function0<? extends T> block);
-  }
+}
 
-  public final class TraceKt {
-    method public static inline <T> T! trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
+package androidx.ui.util.annotation {
+
+  public final class AndroidAnnotationKt {
   }
 
 }
diff --git a/ui/ui-util/api/restricted_0.1.0-dev12.txt b/ui/ui-util/api/restricted_0.1.0-dev12.txt
index e8faee5..9286e03 100644
--- a/ui/ui-util/api/restricted_0.1.0-dev12.txt
+++ b/ui/ui-util/api/restricted_0.1.0-dev12.txt
@@ -1,6 +1,10 @@
 // Signature format: 3.0
 package androidx.ui.util {
 
+  public final class AndroidTraceKt {
+    method public static inline <T> T! trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
+  }
+
   public final class InlineClassHelperKt {
     method public static inline long packFloats(float val1, float val2);
     method public static inline long packInts(int val1, int val2);
@@ -10,8 +14,23 @@
     method public static inline int unpackInt2(long value);
   }
 
+  public final class JvmMathHelpersKt {
+    method public static String toStringAsFixed(float, int digits);
+  }
+
+  public final class JvmMiscHelpersKt {
+    method public static StringBuilder deleteAt(StringBuilder, int index);
+    method public static String format(String, java.lang.Object?... args);
+    method public static int identityHashCode(Object?);
+  }
+
+  public final class JvmSynchronizationHelperKt {
+    method public static <T> T! synchronized(Object lock, kotlin.jvm.functions.Function0<? extends T> block);
+  }
+
   public final class ListUtilsKt {
     method public static inline <T> boolean fastAny(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
+    method public static inline <T> T? fastFirstOrNull(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
     method public static inline <T> void fastForEach(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> action);
   }
 
@@ -20,15 +39,13 @@
     method public static int lerp(int start, int stop, float fraction);
     method public static long lerp(long start, long stop, float fraction);
     method public static String toHexString(int);
-    method public static String toStringAsFixed(float, int digits);
   }
 
-  public final class SynchronizationHelperKt {
-    method public static <T> T! synchronized(Object lock, kotlin.jvm.functions.Function0<? extends T> block);
-  }
+}
 
-  public final class TraceKt {
-    method public static inline <T> T! trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
+package androidx.ui.util.annotation {
+
+  public final class AndroidAnnotationKt {
   }
 
 }
diff --git a/ui/ui-util/api/restricted_current.txt b/ui/ui-util/api/restricted_current.txt
index e8faee5..9286e03 100644
--- a/ui/ui-util/api/restricted_current.txt
+++ b/ui/ui-util/api/restricted_current.txt
@@ -1,6 +1,10 @@
 // Signature format: 3.0
 package androidx.ui.util {
 
+  public final class AndroidTraceKt {
+    method public static inline <T> T! trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
+  }
+
   public final class InlineClassHelperKt {
     method public static inline long packFloats(float val1, float val2);
     method public static inline long packInts(int val1, int val2);
@@ -10,8 +14,23 @@
     method public static inline int unpackInt2(long value);
   }
 
+  public final class JvmMathHelpersKt {
+    method public static String toStringAsFixed(float, int digits);
+  }
+
+  public final class JvmMiscHelpersKt {
+    method public static StringBuilder deleteAt(StringBuilder, int index);
+    method public static String format(String, java.lang.Object?... args);
+    method public static int identityHashCode(Object?);
+  }
+
+  public final class JvmSynchronizationHelperKt {
+    method public static <T> T! synchronized(Object lock, kotlin.jvm.functions.Function0<? extends T> block);
+  }
+
   public final class ListUtilsKt {
     method public static inline <T> boolean fastAny(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
+    method public static inline <T> T? fastFirstOrNull(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
     method public static inline <T> void fastForEach(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> action);
   }
 
@@ -20,15 +39,13 @@
     method public static int lerp(int start, int stop, float fraction);
     method public static long lerp(long start, long stop, float fraction);
     method public static String toHexString(int);
-    method public static String toStringAsFixed(float, int digits);
   }
 
-  public final class SynchronizationHelperKt {
-    method public static <T> T! synchronized(Object lock, kotlin.jvm.functions.Function0<? extends T> block);
-  }
+}
 
-  public final class TraceKt {
-    method public static inline <T> T! trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
+package androidx.ui.util.annotation {
+
+  public final class AndroidAnnotationKt {
   }
 
 }
diff --git a/ui/ui-util/build.gradle b/ui/ui-util/build.gradle
index f149962..5f8d4e6 100644
--- a/ui/ui-util/build.gradle
+++ b/ui/ui-util/build.gradle
@@ -25,25 +25,32 @@
     id("AndroidXPlugin")
     id("com.android.library")
     id("AndroidXUiPlugin")
-    id("org.jetbrains.kotlin.android")
+    id("kotlin-multiplatform")
 }
 
-dependencies {
-    implementation(KOTLIN_STDLIB)
+kotlin {
+    android()
+    sourceSets {
+        commonMain.dependencies {
+            implementation(KOTLIN_STDLIB_COMMON)
 
-    api "androidx.annotation:annotation:1.1.0"
+            implementation project(":compose:compose-runtime")
+        }
+        jvmMain.dependencies {
+            implementation(KOTLIN_STDLIB)
+        }
+        androidMain.dependencies {
+            api "androidx.annotation:annotation:1.1.0"
+        }
 
-    implementation project(":compose:compose-runtime")
-
-    testImplementation(ANDROIDX_TEST_RULES)
-    testImplementation(ANDROIDX_TEST_RUNNER)
-    testImplementation(JUNIT)
-    testImplementation(TRUTH)
-
-    androidTestImplementation(ANDROIDX_TEST_RULES)
-    androidTestImplementation(ANDROIDX_TEST_RUNNER)
-    androidTestImplementation(ESPRESSO_CORE)
-    androidTestImplementation(JUNIT)
+        commonTest.dependencies {
+            implementation kotlin("test-junit")
+        }
+        // TODO: should be unitTest, figure out why that doesn't work
+        androidTest.dependencies {
+            implementation(TRUTH)
+        }
+    }
 }
 
 androidx {
@@ -57,7 +64,7 @@
 
 tasks.withType(KotlinCompile).configureEach {
     kotlinOptions {
-        freeCompilerArgs += ["-Xuse-experimental=kotlin.Experimental", "-XXLanguage:+InlineClasses"]
-//        useIR = true
+        freeCompilerArgs += ["-XXLanguage:+InlineClasses"]
+        useIR = true
     }
 }
diff --git a/ui/ui-util/src/main/AndroidManifest.xml b/ui/ui-util/src/androidMain/AndroidManifest.xml
similarity index 100%
rename from ui/ui-util/src/main/AndroidManifest.xml
rename to ui/ui-util/src/androidMain/AndroidManifest.xml
diff --git a/ui/ui-util/src/main/java/androidx/ui/util/Trace.kt b/ui/ui-util/src/androidMain/kotlin/androidx/ui/util/AndroidTrace.kt
similarity index 100%
rename from ui/ui-util/src/main/java/androidx/ui/util/Trace.kt
rename to ui/ui-util/src/androidMain/kotlin/androidx/ui/util/AndroidTrace.kt
diff --git a/ui/ui-util/src/androidMain/kotlin/androidx/ui/util/annotation/AndroidAnnotation.kt b/ui/ui-util/src/androidMain/kotlin/androidx/ui/util/annotation/AndroidAnnotation.kt
new file mode 100644
index 0000000..b407c4a
--- /dev/null
+++ b/ui/ui-util/src/androidMain/kotlin/androidx/ui/util/annotation/AndroidAnnotation.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.ui.util.annotation
+
+actual typealias ColorInt = androidx.annotation.ColorInt
+actual typealias FloatRange = androidx.annotation.FloatRange
+actual typealias IntRange = androidx.annotation.IntRange
+actual typealias Size = androidx.annotation.Size
+actual typealias GuardedBy = androidx.annotation.GuardedBy
+actual typealias VisibleForTesting = androidx.annotation.VisibleForTesting
\ No newline at end of file
diff --git a/ui/ui-util/src/main/java/androidx/ui/util/InlineClassHelper.kt b/ui/ui-util/src/commonMain/kotlin/androidx/ui/util/InlineClassHelper.kt
similarity index 100%
rename from ui/ui-util/src/main/java/androidx/ui/util/InlineClassHelper.kt
rename to ui/ui-util/src/commonMain/kotlin/androidx/ui/util/InlineClassHelper.kt
diff --git a/ui/ui-util/src/main/java/androidx/ui/util/ListUtils.kt b/ui/ui-util/src/commonMain/kotlin/androidx/ui/util/ListUtils.kt
similarity index 82%
rename from ui/ui-util/src/main/java/androidx/ui/util/ListUtils.kt
rename to ui/ui-util/src/commonMain/kotlin/androidx/ui/util/ListUtils.kt
index f032a4f..cc900d5 100644
--- a/ui/ui-util/src/main/java/androidx/ui/util/ListUtils.kt
+++ b/ui/ui-util/src/commonMain/kotlin/androidx/ui/util/ListUtils.kt
@@ -34,3 +34,11 @@
     fastForEach { if (predicate(it)) return true }
     return false
 }
+
+/**
+ * Returns the first value that [predicate] returns `true` for or `null` if nothing matches.
+ */
+inline fun <T> List<T>.fastFirstOrNull(predicate: (T) -> Boolean): T? {
+    fastForEach { if (predicate(it)) return it }
+    return null
+}
\ No newline at end of file
diff --git a/ui/ui-util/src/main/java/androidx/ui/util/MathHelpers.kt b/ui/ui-util/src/commonMain/kotlin/androidx/ui/util/MathHelpers.kt
similarity index 94%
rename from ui/ui-util/src/main/java/androidx/ui/util/MathHelpers.kt
rename to ui/ui-util/src/commonMain/kotlin/androidx/ui/util/MathHelpers.kt
index 45bc4d9..8965a5c 100644
--- a/ui/ui-util/src/main/java/androidx/ui/util/MathHelpers.kt
+++ b/ui/ui-util/src/commonMain/kotlin/androidx/ui/util/MathHelpers.kt
@@ -39,7 +39,7 @@
     return start + ((stop - start) * fraction.toDouble()).roundToLong()
 }
 
-fun Float.toStringAsFixed(digits: Int) = String.format("%.${digits}f", this)
+expect fun Float.toStringAsFixed(digits: Int): String
 
 @OptIn(kotlin.ExperimentalUnsignedTypes::class)
 fun Int.toHexString() = "0x${toUInt().toString(16).padStart(8, '0')}"
\ No newline at end of file
diff --git a/ui/ui-util/src/commonMain/kotlin/androidx/ui/util/MiscHelpers.kt b/ui/ui-util/src/commonMain/kotlin/androidx/ui/util/MiscHelpers.kt
new file mode 100644
index 0000000..802ad61
--- /dev/null
+++ b/ui/ui-util/src/commonMain/kotlin/androidx/ui/util/MiscHelpers.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.ui.util
+
+expect fun Any?.identityHashCode(): Int
+
+expect fun String.format(vararg args: Any?): String
+
+expect fun StringBuilder.deleteAt(index: Int): StringBuilder
\ No newline at end of file
diff --git a/ui/ui-util/src/commonMain/kotlin/androidx/ui/util/annotation/Annotation.kt b/ui/ui-util/src/commonMain/kotlin/androidx/ui/util/annotation/Annotation.kt
new file mode 100644
index 0000000..3bee49a
--- /dev/null
+++ b/ui/ui-util/src/commonMain/kotlin/androidx/ui/util/annotation/Annotation.kt
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.ui.util.annotation
+
+@OptionalExpectation
+@ExperimentalMultiplatform
+expect annotation class ColorInt()
+
+@OptionalExpectation
+@ExperimentalMultiplatform
+expect annotation class FloatRange(
+    val from: Double,
+    val to: Double,
+    val fromInclusive: Boolean = true,
+    val toInclusive: Boolean = true
+)
+
+@OptionalExpectation
+@ExperimentalMultiplatform
+expect annotation class IntRange(val from: Long = Long.MIN_VALUE, val to: Long = Long.MAX_VALUE)
+
+@OptionalExpectation
+@ExperimentalMultiplatform
+expect annotation class Size(
+    val value: Long = -1,
+    val min: Long = Long.MIN_VALUE,
+    val max: Long = Long.MAX_VALUE,
+    val multiple: Long = 1
+)
+
+@OptionalExpectation
+@ExperimentalMultiplatform
+expect annotation class GuardedBy(
+    val value: String
+)
+
+@OptionalExpectation
+@ExperimentalMultiplatform
+expect annotation class VisibleForTesting(
+    val otherwise: Int = 2
+)
diff --git a/ui/ui-util/src/jvmMain/kotlin/androidx/ui/util/JvmMathHelpers.kt b/ui/ui-util/src/jvmMain/kotlin/androidx/ui/util/JvmMathHelpers.kt
new file mode 100644
index 0000000..2a17e08
--- /dev/null
+++ b/ui/ui-util/src/jvmMain/kotlin/androidx/ui/util/JvmMathHelpers.kt
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.ui.util
+
+actual fun Float.toStringAsFixed(digits: Int): String = String.format("%.${digits}f", this)
diff --git a/ui/ui-util/src/jvmMain/kotlin/androidx/ui/util/JvmMiscHelpers.kt b/ui/ui-util/src/jvmMain/kotlin/androidx/ui/util/JvmMiscHelpers.kt
new file mode 100644
index 0000000..b93d83f
--- /dev/null
+++ b/ui/ui-util/src/jvmMain/kotlin/androidx/ui/util/JvmMiscHelpers.kt
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.ui.util
+
+actual fun Any?.identityHashCode(): Int = if (this == null) 0 else System.identityHashCode(this)
+
+actual fun String.format(vararg args: Any?): String = java.lang.String.format(this, *args)
+
+actual fun StringBuilder.deleteAt(index: Int): StringBuilder {
+    this.deleteCharAt(index)
+    return this
+}
\ No newline at end of file
diff --git a/ui/ui-util/src/main/java/androidx/ui/util/SynchronizationHelper.kt b/ui/ui-util/src/jvmMain/kotlin/androidx/ui/util/JvmSynchronizationHelper.kt
similarity index 98%
rename from ui/ui-util/src/main/java/androidx/ui/util/SynchronizationHelper.kt
rename to ui/ui-util/src/jvmMain/kotlin/androidx/ui/util/JvmSynchronizationHelper.kt
index c940781..9ef5426 100644
--- a/ui/ui-util/src/main/java/androidx/ui/util/SynchronizationHelper.kt
+++ b/ui/ui-util/src/jvmMain/kotlin/androidx/ui/util/JvmSynchronizationHelper.kt
@@ -23,7 +23,7 @@
 /**
  * [kotlin.synchronized][synchronized] is deprecated, and the build fails if we use
  * [kotlin.synchronized][synchronized] along with the IR compiler. As a workaround, we have this
- * function here, which is in a module that doesn't use the IR COmpiler.
+ * function here, which is in a module that doesn't use the IR Compiler.
  */
 @OptIn(ExperimentalContracts::class)
 fun <T> synchronized(lock: Any, block: () -> T): T {
diff --git a/ui/ui-util/src/test/java/androidx/ui/util/InlineClassHelperTest.kt b/ui/ui-util/src/unitTest/kotlin/androidx/ui/util/InlineClassHelperTest.kt
similarity index 100%
rename from ui/ui-util/src/test/java/androidx/ui/util/InlineClassHelperTest.kt
rename to ui/ui-util/src/unitTest/kotlin/androidx/ui/util/InlineClassHelperTest.kt
diff --git a/ui/ui-util/src/test/java/androidx/ui/util/ListUtilsTest.kt b/ui/ui-util/src/unitTest/kotlin/androidx/ui/util/ListUtilsTest.kt
similarity index 85%
rename from ui/ui-util/src/test/java/androidx/ui/util/ListUtilsTest.kt
rename to ui/ui-util/src/unitTest/kotlin/androidx/ui/util/ListUtilsTest.kt
index 8d1ae60..46ae408 100644
--- a/ui/ui-util/src/test/java/androidx/ui/util/ListUtilsTest.kt
+++ b/ui/ui-util/src/unitTest/kotlin/androidx/ui/util/ListUtilsTest.kt
@@ -18,6 +18,7 @@
 
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertFalse
+import org.junit.Assert.assertNull
 import org.junit.Assert.assertTrue
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -69,4 +70,15 @@
         val list = listOf(0, -1, -500, 1)
         assertTrue(list.fastAny { it > 0 })
     }
+
+    @Test
+    fun firstOrNullNotFound() {
+        val list = listOf(0, -1, -500)
+        assertNull(list.fastFirstOrNull { it > 0 })
+    }
+    @Test
+    fun firstOrNullFound() {
+        val list = listOf(0, -1, -500, 1)
+        assertEquals(1, list.fastFirstOrNull { it > 0 })
+    }
 }
\ No newline at end of file
diff --git a/ui/ui-util/src/test/java/androidx/ui/util/MathHelpersTest.kt b/ui/ui-util/src/unitTest/kotlin/androidx/ui/util/MathHelpersTest.kt
similarity index 100%
rename from ui/ui-util/src/test/java/androidx/ui/util/MathHelpersTest.kt
rename to ui/ui-util/src/unitTest/kotlin/androidx/ui/util/MathHelpersTest.kt
diff --git a/wear/wear/api/api_lint.ignore b/wear/wear/api/api_lint.ignore
index 194e0f2..1cbce750 100644
--- a/wear/wear/api/api_lint.ignore
+++ b/wear/wear/api/api_lint.ignore
@@ -13,10 +13,6 @@
     Inconsistent extra value; expected `androidx.wear.ambient.extra.LOWBIT_AMBIENT`, was `com.google.android.wearable.compat.extra.LOWBIT_AMBIENT`
 
 
-CallbackMethodName: androidx.wear.widget.CurvingLayoutCallback:
-    Callback method names must follow the on<Something> style: adjustAnchorOffsetXY
-
-
 ForbiddenSuperClass: androidx.wear.activity.ConfirmationActivity:
     ConfirmationActivity should not extend `Activity`. Activity subclasses are impossible to compose. Expose a composable API instead.
 
diff --git a/webkit/webkit/api/api_lint.ignore b/webkit/webkit/api/api_lint.ignore
index 2eb478a..0ec5493 100644
--- a/webkit/webkit/api/api_lint.ignore
+++ b/webkit/webkit/api/api_lint.ignore
@@ -7,6 +7,12 @@
     Method should return Collection<WebMessagePortCompat> (or subclass) instead of raw array; was `androidx.webkit.WebMessagePortCompat[]`
 
 
+BuilderSetStyle: androidx.webkit.ProxyConfig.Builder#bypassSimpleHostnames():
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.webkit.ProxyConfig.Builder.bypassSimpleHostnames()
+BuilderSetStyle: androidx.webkit.ProxyConfig.Builder#removeImplicitRules():
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.webkit.ProxyConfig.Builder.removeImplicitRules()
+
+
 IntentName: androidx.webkit.WebViewFeature#DISABLED_ACTION_MODE_MENU_ITEMS:
     Intent action constant name must be ACTION_FOO: DISABLED_ACTION_MODE_MENU_ITEMS
 
diff --git a/work/workmanager-testing/api/api_lint.ignore b/work/workmanager-testing/api/api_lint.ignore
index 583b20b..a23d747 100644
--- a/work/workmanager-testing/api/api_lint.ignore
+++ b/work/workmanager-testing/api/api_lint.ignore
@@ -1,4 +1,10 @@
 // Baseline format: 1.0
+BuilderSetStyle: androidx.work.testing.TestListenableWorkerBuilder#from(android.content.Context, Class<W>):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.work.testing.TestListenableWorkerBuilder.from(android.content.Context,Class<W>)
+BuilderSetStyle: androidx.work.testing.TestListenableWorkerBuilder#from(android.content.Context, androidx.work.WorkRequest):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.work.testing.TestListenableWorkerBuilder.from(android.content.Context,androidx.work.WorkRequest)
+
+
 MissingNullability: androidx.work.testing.TestListenableWorkerBuilderKt#TestListenableWorkerBuilder(android.content.Context, androidx.work.Data, java.util.List<? extends java.lang.String>, int, java.util.List<? extends android.net.Uri>, java.util.List<? extends java.lang.String>):
     Missing nullability on method `TestListenableWorkerBuilder` return
 MissingNullability: androidx.work.testing.TestWorkerBuilderKt#TestWorkerBuilder(android.content.Context, java.util.concurrent.Executor, androidx.work.Data, java.util.List<? extends java.lang.String>, int, java.util.List<? extends android.net.Uri>, java.util.List<? extends java.lang.String>):
diff --git a/work/workmanager/api/api_lint.ignore b/work/workmanager/api/api_lint.ignore
index 6185dcc..444e9d1 100644
--- a/work/workmanager/api/api_lint.ignore
+++ b/work/workmanager/api/api_lint.ignore
@@ -7,6 +7,44 @@
     Acronyms should not be capitalized in class names: was `SUCCESS`, should this be `Success`?
 
 
+BuilderSetStyle: androidx.work.Data.Builder#putAll(androidx.work.Data):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.work.Data.Builder.putAll(androidx.work.Data)
+BuilderSetStyle: androidx.work.Data.Builder#putAll(java.util.Map<java.lang.String,java.lang.Object>):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.work.Data.Builder.putAll(java.util.Map<java.lang.String,java.lang.Object>)
+BuilderSetStyle: androidx.work.Data.Builder#putBoolean(String, boolean):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.work.Data.Builder.putBoolean(String,boolean)
+BuilderSetStyle: androidx.work.Data.Builder#putBooleanArray(String, boolean[]):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.work.Data.Builder.putBooleanArray(String,boolean[])
+BuilderSetStyle: androidx.work.Data.Builder#putByte(String, byte):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.work.Data.Builder.putByte(String,byte)
+BuilderSetStyle: androidx.work.Data.Builder#putByteArray(String, byte[]):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.work.Data.Builder.putByteArray(String,byte[])
+BuilderSetStyle: androidx.work.Data.Builder#putDouble(String, double):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.work.Data.Builder.putDouble(String,double)
+BuilderSetStyle: androidx.work.Data.Builder#putDoubleArray(String, double[]):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.work.Data.Builder.putDoubleArray(String,double[])
+BuilderSetStyle: androidx.work.Data.Builder#putFloat(String, float):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.work.Data.Builder.putFloat(String,float)
+BuilderSetStyle: androidx.work.Data.Builder#putFloatArray(String, float[]):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.work.Data.Builder.putFloatArray(String,float[])
+BuilderSetStyle: androidx.work.Data.Builder#putInt(String, int):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.work.Data.Builder.putInt(String,int)
+BuilderSetStyle: androidx.work.Data.Builder#putIntArray(String, int[]):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.work.Data.Builder.putIntArray(String,int[])
+BuilderSetStyle: androidx.work.Data.Builder#putLong(String, long):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.work.Data.Builder.putLong(String,long)
+BuilderSetStyle: androidx.work.Data.Builder#putLongArray(String, long[]):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.work.Data.Builder.putLongArray(String,long[])
+BuilderSetStyle: androidx.work.Data.Builder#putString(String, String):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.work.Data.Builder.putString(String,String)
+BuilderSetStyle: androidx.work.Data.Builder#putStringArray(String, String[]):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.work.Data.Builder.putStringArray(String,String[])
+BuilderSetStyle: androidx.work.WorkRequest.Builder#keepResultsForAtLeast(java.time.Duration):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.work.WorkRequest.Builder.keepResultsForAtLeast(java.time.Duration)
+BuilderSetStyle: androidx.work.WorkRequest.Builder#keepResultsForAtLeast(long, java.util.concurrent.TimeUnit):
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.work.WorkRequest.Builder.keepResultsForAtLeast(long,java.util.concurrent.TimeUnit)
+
+
 MissingNullability: androidx.work.Constraints#NONE:
     Missing nullability on field `NONE` in class `class androidx.work.Constraints`
 MissingNullability: androidx.work.Constraints.Builder#setTriggerContentMaxDelay(java.time.Duration) parameter #0:
@@ -25,6 +63,8 @@
     Should avoid odd sized primitives; use `int` instead of `byte` in parameter value in androidx.work.Data.Builder.putByte(String key, byte value)
 
 
+SetterReturnsThis: androidx.work.WorkRequest.Builder#addTag(String):
+    Methods must return the builder object (return type androidx.work.WorkRequest.Builder<B,W> instead of B): method androidx.work.WorkRequest.Builder.addTag(String)
 SetterReturnsThis: androidx.work.WorkRequest.Builder#setBackoffCriteria(androidx.work.BackoffPolicy, java.time.Duration):
     Methods must return the builder object (return type androidx.work.WorkRequest.Builder<B,W> instead of B): method androidx.work.WorkRequest.Builder.setBackoffCriteria(androidx.work.BackoffPolicy,java.time.Duration)
 SetterReturnsThis: androidx.work.WorkRequest.Builder#setBackoffCriteria(androidx.work.BackoffPolicy, long, java.util.concurrent.TimeUnit):