Merge "Rename TEST_* to ANDROIDX_TEST_*" into androidx-master-dev
am: f41616320a

Change-Id: Ie44ce974b57b427d661eb5e2ef258c673ed90996
diff --git a/appcompat/resources/src/main/java/androidx/appcompat/widget/DrawableUtils.java b/appcompat/resources/src/main/java/androidx/appcompat/widget/DrawableUtils.java
index 1e788d5..819b54e 100644
--- a/appcompat/resources/src/main/java/androidx/appcompat/widget/DrawableUtils.java
+++ b/appcompat/resources/src/main/java/androidx/appcompat/widget/DrawableUtils.java
@@ -34,6 +34,7 @@
 import androidx.annotation.RestrictTo;
 import androidx.core.graphics.drawable.DrawableCompat;
 import androidx.core.graphics.drawable.WrappedDrawable;
+import androidx.core.os.BuildCompat;
 
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
@@ -70,6 +71,15 @@
      * use reflection. Since the {@code Insets} class is hidden also, we return a Rect instead.
      */
     public static Rect getOpticalBounds(Drawable drawable) {
+        if (BuildCompat.isAtLeastQ()) {
+            final android.graphics.Insets insets = drawable.getOpticalInsets();
+            final Rect result = new Rect();
+            result.left = insets.left;
+            result.right = insets.right;
+            result.top = insets.top;
+            result.bottom = insets.bottom;
+            return result;
+        }
         if (sInsetsClazz != null) {
             try {
                 // If the Drawable is wrapped, we need to manually unwrap it and process
diff --git a/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatTextViewTest.java b/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatTextViewTest.java
index 9b4e2ad..4745c02 100644
--- a/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatTextViewTest.java
+++ b/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatTextViewTest.java
@@ -41,6 +41,7 @@
 import android.os.Build;
 import android.os.LocaleList;
 import android.text.Layout;
+import android.text.PrecomputedText;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.textclassifier.TextClassificationManager;
@@ -54,6 +55,7 @@
 import androidx.appcompat.testutils.TestUtils;
 import androidx.core.content.ContextCompat;
 import androidx.core.content.res.ResourcesCompat;
+import androidx.core.os.BuildCompat;
 import androidx.core.graphics.ColorUtils;
 import androidx.core.text.PrecomputedTextCompat;
 import androidx.core.view.ViewCompat;
@@ -576,6 +578,9 @@
                 // setText may wrap the given text with SpannedString. Check the contents by casting
                 // to String.
                 assertEquals(SAMPLE_TEXT_1, tv.getText().toString());
+                if (BuildCompat.isAtLeastQ()) {
+                    assertTrue(tv.getText() instanceof PrecomputedText);
+                }
             }
         });
     }
@@ -593,6 +598,9 @@
                 tv.measure(UNLIMITED_MEASURE_SPEC, UNLIMITED_MEASURE_SPEC);
                 assertNotEquals(0.0f, tv.getMeasuredWidth());
                 assertEquals(SAMPLE_TEXT_1, tv.getText().toString());
+                if (BuildCompat.isAtLeastQ()) {
+                    assertTrue(tv.getText() instanceof PrecomputedText);
+                }
             }
         });
         executor.doExecution(0);
@@ -622,6 +630,9 @@
                 // setText may wrap the given text with SpannedString. Check the contents by casting
                 // to String.
                 assertEquals(SAMPLE_TEXT_2, tv.getText().toString());
+                if (BuildCompat.isAtLeastQ()) {
+                    assertTrue(tv.getText() instanceof PrecomputedText);
+                }
             }
         });
         executor.doExecution(0);  // Do execution of 1st runnable.
@@ -634,6 +645,9 @@
                 // setText may wrap the given text with SpannedString. Check the contents by casting
                 // to String.
                 assertEquals(SAMPLE_TEXT_2, tv.getText().toString());
+                if (BuildCompat.isAtLeastQ()) {
+                    assertTrue(tv.getText() instanceof PrecomputedText);
+                }
             }
         });
     }
diff --git a/appcompat/src/main/java/androidx/appcompat/widget/ActivityChooserView.java b/appcompat/src/main/java/androidx/appcompat/widget/ActivityChooserView.java
index a350c0d..1d93c68 100644
--- a/appcompat/src/main/java/androidx/appcompat/widget/ActivityChooserView.java
+++ b/appcompat/src/main/java/androidx/appcompat/widget/ActivityChooserView.java
@@ -46,6 +46,7 @@
 import androidx.annotation.RestrictTo;
 import androidx.appcompat.R;
 import androidx.appcompat.view.menu.ShowableListMenu;
+import androidx.core.os.BuildCompat;
 import androidx.core.view.ActionProvider;
 import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
 
@@ -222,6 +223,10 @@
 
         TypedArray attributesArray = context.obtainStyledAttributes(attrs,
                 R.styleable.ActivityChooserView, defStyle, 0);
+        if (BuildCompat.isAtLeastQ()) {
+            saveAttributeDataForStyleable(
+                    context, R.styleable.ActivityChooserView, attrs, attributesArray, defStyle, 0);
+        }
 
         mInitialActivityCount = attributesArray.getInt(
                 R.styleable.ActivityChooserView_initialActivityCount,
diff --git a/appcompat/src/main/java/androidx/appcompat/widget/ButtonBarLayout.java b/appcompat/src/main/java/androidx/appcompat/widget/ButtonBarLayout.java
index 40e7748..fc5b2ce 100644
--- a/appcompat/src/main/java/androidx/appcompat/widget/ButtonBarLayout.java
+++ b/appcompat/src/main/java/androidx/appcompat/widget/ButtonBarLayout.java
@@ -26,6 +26,7 @@
 
 import androidx.annotation.RestrictTo;
 import androidx.appcompat.R;
+import androidx.core.os.BuildCompat;
 import androidx.core.view.ViewCompat;
 
 /**
@@ -49,6 +50,9 @@
     public ButtonBarLayout(Context context, AttributeSet attrs) {
         super(context, attrs);
         final TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.ButtonBarLayout);
+        if (BuildCompat.isAtLeastQ()) {
+            saveAttributeDataForStyleable(context, R.styleable.ButtonBarLayout, attrs, ta, 0, 0);
+        }
         mAllowStacking = ta.getBoolean(R.styleable.ButtonBarLayout_allowStacking, true);
         ta.recycle();
     }
diff --git a/appcompat/src/main/java/androidx/appcompat/widget/ListPopupWindow.java b/appcompat/src/main/java/androidx/appcompat/widget/ListPopupWindow.java
index 056213e..72ef8eb 100644
--- a/appcompat/src/main/java/androidx/appcompat/widget/ListPopupWindow.java
+++ b/appcompat/src/main/java/androidx/appcompat/widget/ListPopupWindow.java
@@ -23,6 +23,7 @@
 import android.database.DataSetObserver;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
+import android.os.Build;
 import android.os.Handler;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -75,29 +76,35 @@
      */
     static final int EXPAND_LIST_TIMEOUT = 250;
 
-    private static Method sClipToWindowEnabledMethod;
+    private static Method sSetClipToWindowEnabledMethod;
     private static Method sGetMaxAvailableHeightMethod;
     private static Method sSetEpicenterBoundsMethod;
 
     static {
-        try {
-            sClipToWindowEnabledMethod = PopupWindow.class.getDeclaredMethod(
-                    "setClipToScreenEnabled", boolean.class);
-        } catch (NoSuchMethodException e) {
-            Log.i(TAG, "Could not find method setClipToScreenEnabled() on PopupWindow. Oh well.");
+        if (Build.VERSION.SDK_INT <= 28) {
+            try {
+                sSetClipToWindowEnabledMethod = PopupWindow.class.getDeclaredMethod(
+                        "setClipToScreenEnabled", boolean.class);
+            } catch (NoSuchMethodException e) {
+                Log.i(TAG,
+                        "Could not find method setClipToScreenEnabled() on PopupWindow. Oh well.");
+            }
+            try {
+                sSetEpicenterBoundsMethod = PopupWindow.class.getDeclaredMethod(
+                        "setEpicenterBounds", Rect.class);
+            } catch (NoSuchMethodException e) {
+                Log.i(TAG,
+                        "Could not find method setEpicenterBounds(Rect) on PopupWindow. Oh well.");
+            }
         }
-        try {
-            sGetMaxAvailableHeightMethod = PopupWindow.class.getDeclaredMethod(
-                    "getMaxAvailableHeight", View.class, int.class, boolean.class);
-        } catch (NoSuchMethodException e) {
-            Log.i(TAG, "Could not find method getMaxAvailableHeight(View, int, boolean)"
-                    + " on PopupWindow. Oh well.");
-        }
-        try {
-            sSetEpicenterBoundsMethod = PopupWindow.class.getDeclaredMethod(
-                    "setEpicenterBounds", Rect.class);
-        } catch (NoSuchMethodException e) {
-            Log.i(TAG, "Could not find method setEpicenterBounds(Rect) on PopupWindow. Oh well.");
+        if (Build.VERSION.SDK_INT <= 23) {
+            try {
+                sGetMaxAvailableHeightMethod = PopupWindow.class.getDeclaredMethod(
+                        "getMaxAvailableHeight", View.class, int.class, boolean.class);
+            } catch (NoSuchMethodException e) {
+                Log.i(TAG, "Could not find method getMaxAvailableHeight(View, int, boolean)"
+                        + " on PopupWindow. Oh well.");
+            }
         }
     }
 
@@ -734,12 +741,16 @@
             if (mOverlapAnchorSet) {
                 PopupWindowCompat.setOverlapAnchor(mPopup, mOverlapAnchor);
             }
-            if (sSetEpicenterBoundsMethod != null) {
-                try {
-                    sSetEpicenterBoundsMethod.invoke(mPopup, mEpicenterBounds);
-                } catch (Exception e) {
-                    Log.e(TAG, "Could not invoke setEpicenterBounds on PopupWindow", e);
+            if (Build.VERSION.SDK_INT <= 28) {
+                if (sSetEpicenterBoundsMethod != null) {
+                    try {
+                        sSetEpicenterBoundsMethod.invoke(mPopup, mEpicenterBounds);
+                    } catch (Exception e) {
+                        Log.e(TAG, "Could not invoke setEpicenterBounds on PopupWindow", e);
+                    }
                 }
+            } else {
+                mPopup.setEpicenterBounds(mEpicenterBounds);
             }
             PopupWindowCompat.showAsDropDown(mPopup, getAnchorView(), mDropDownHorizontalOffset,
                     mDropDownVerticalOffset, mDropDownGravity);
@@ -1418,25 +1429,33 @@
     }
 
     private void setPopupClipToScreenEnabled(boolean clip) {
-        if (sClipToWindowEnabledMethod != null) {
-            try {
-                sClipToWindowEnabledMethod.invoke(mPopup, clip);
-            } catch (Exception e) {
-                Log.i(TAG, "Could not call setClipToScreenEnabled() on PopupWindow. Oh well.");
+        if (Build.VERSION.SDK_INT <= 28) {
+            if (sSetClipToWindowEnabledMethod != null) {
+                try {
+                    sSetClipToWindowEnabledMethod.invoke(mPopup, clip);
+                } catch (Exception e) {
+                    Log.i(TAG, "Could not call setClipToScreenEnabled() on PopupWindow. Oh well.");
+                }
             }
+        } else {
+            mPopup.setClipToScreenEnabled(clip);
         }
     }
 
     private int getMaxAvailableHeight(View anchor, int yOffset, boolean ignoreBottomDecorations) {
-        if (sGetMaxAvailableHeightMethod != null) {
-            try {
-                return (int) sGetMaxAvailableHeightMethod.invoke(mPopup, anchor, yOffset,
-                        ignoreBottomDecorations);
-            } catch (Exception e) {
-                Log.i(TAG, "Could not call getMaxAvailableHeightMethod(View, int, boolean)"
-                        + " on PopupWindow. Using the public version.");
+        if (Build.VERSION.SDK_INT <= 23) {
+            if (sGetMaxAvailableHeightMethod != null) {
+                try {
+                    return (int) sGetMaxAvailableHeightMethod.invoke(mPopup, anchor, yOffset,
+                            ignoreBottomDecorations);
+                } catch (Exception e) {
+                    Log.i(TAG, "Could not call getMaxAvailableHeightMethod(View, int, boolean)"
+                            + " on PopupWindow. Using the public version.");
+                }
             }
+            return mPopup.getMaxAvailableHeight(anchor, yOffset);
+        } else {
+            return mPopup.getMaxAvailableHeight(anchor, yOffset, ignoreBottomDecorations);
         }
-        return mPopup.getMaxAvailableHeight(anchor, yOffset);
     }
 }
diff --git a/appcompat/src/main/java/androidx/appcompat/widget/MenuPopupWindow.java b/appcompat/src/main/java/androidx/appcompat/widget/MenuPopupWindow.java
index aa8295a..8a80b87 100644
--- a/appcompat/src/main/java/androidx/appcompat/widget/MenuPopupWindow.java
+++ b/appcompat/src/main/java/androidx/appcompat/widget/MenuPopupWindow.java
@@ -57,8 +57,10 @@
 
     static {
         try {
-            sSetTouchModalMethod = PopupWindow.class.getDeclaredMethod(
-                    "setTouchModal", boolean.class);
+            if (Build.VERSION.SDK_INT <= 28) {
+                sSetTouchModalMethod = PopupWindow.class.getDeclaredMethod(
+                        "setTouchModal", boolean.class);
+            }
         } catch (NoSuchMethodException e) {
             Log.i(TAG, "Could not find method setTouchModal() on PopupWindow. Oh well.");
         }
@@ -98,12 +100,16 @@
      * other windows behind it.
      */
     public void setTouchModal(final boolean touchModal) {
-        if (sSetTouchModalMethod != null) {
-            try {
-                sSetTouchModalMethod.invoke(mPopup, touchModal);
-            } catch (Exception e) {
-                Log.i(TAG, "Could not invoke setTouchModal() on PopupWindow. Oh well.");
+        if (Build.VERSION.SDK_INT <= 28) {
+            if (sSetTouchModalMethod != null) {
+                try {
+                    sSetTouchModalMethod.invoke(mPopup, touchModal);
+                } catch (Exception e) {
+                    Log.i(TAG, "Could not invoke setTouchModal() on PopupWindow. Oh well.");
+                }
             }
+        } else {
+            mPopup.setTouchModal(touchModal);
         }
     }
 
diff --git a/biometric/api/1.0.0-alpha04.txt b/biometric/api/1.0.0-alpha04.txt
index f517f0f..51a912e 100644
--- a/biometric/api/1.0.0-alpha04.txt
+++ b/biometric/api/1.0.0-alpha04.txt
@@ -13,6 +13,7 @@
     field public static final int ERROR_LOCKOUT_PERMANENT = 9; // 0x9
     field public static final int ERROR_NEGATIVE_BUTTON = 13; // 0xd
     field public static final int ERROR_NO_BIOMETRICS = 11; // 0xb
+    field public static final int ERROR_NO_DEVICE_CREDENTIAL = 14; // 0xe
     field public static final int ERROR_NO_SPACE = 4; // 0x4
     field public static final int ERROR_TIMEOUT = 3; // 0x3
     field public static final int ERROR_UNABLE_TO_PROCESS = 2; // 0x2
@@ -45,12 +46,16 @@
     method public CharSequence getNegativeButtonText();
     method public CharSequence? getSubtitle();
     method public CharSequence getTitle();
+    method public boolean isConfirmationRequired();
+    method public boolean isDeviceCredentialAllowed();
   }
 
   public static class BiometricPrompt.PromptInfo.Builder {
     ctor public BiometricPrompt.PromptInfo.Builder();
     method public androidx.biometric.BiometricPrompt.PromptInfo build();
+    method public androidx.biometric.BiometricPrompt.PromptInfo.Builder setConfirmationRequired(boolean);
     method public androidx.biometric.BiometricPrompt.PromptInfo.Builder setDescription(CharSequence?);
+    method @RequiresApi(29) public androidx.biometric.BiometricPrompt.PromptInfo.Builder setDeviceCredentialAllowed(boolean);
     method public androidx.biometric.BiometricPrompt.PromptInfo.Builder setNegativeButtonText(CharSequence);
     method public androidx.biometric.BiometricPrompt.PromptInfo.Builder setSubtitle(CharSequence?);
     method public androidx.biometric.BiometricPrompt.PromptInfo.Builder setTitle(CharSequence);
diff --git a/biometric/api/1.0.0-alpha05.txt b/biometric/api/1.0.0-alpha05.txt
index f517f0f..51a912e 100644
--- a/biometric/api/1.0.0-alpha05.txt
+++ b/biometric/api/1.0.0-alpha05.txt
@@ -13,6 +13,7 @@
     field public static final int ERROR_LOCKOUT_PERMANENT = 9; // 0x9
     field public static final int ERROR_NEGATIVE_BUTTON = 13; // 0xd
     field public static final int ERROR_NO_BIOMETRICS = 11; // 0xb
+    field public static final int ERROR_NO_DEVICE_CREDENTIAL = 14; // 0xe
     field public static final int ERROR_NO_SPACE = 4; // 0x4
     field public static final int ERROR_TIMEOUT = 3; // 0x3
     field public static final int ERROR_UNABLE_TO_PROCESS = 2; // 0x2
@@ -45,12 +46,16 @@
     method public CharSequence getNegativeButtonText();
     method public CharSequence? getSubtitle();
     method public CharSequence getTitle();
+    method public boolean isConfirmationRequired();
+    method public boolean isDeviceCredentialAllowed();
   }
 
   public static class BiometricPrompt.PromptInfo.Builder {
     ctor public BiometricPrompt.PromptInfo.Builder();
     method public androidx.biometric.BiometricPrompt.PromptInfo build();
+    method public androidx.biometric.BiometricPrompt.PromptInfo.Builder setConfirmationRequired(boolean);
     method public androidx.biometric.BiometricPrompt.PromptInfo.Builder setDescription(CharSequence?);
+    method @RequiresApi(29) public androidx.biometric.BiometricPrompt.PromptInfo.Builder setDeviceCredentialAllowed(boolean);
     method public androidx.biometric.BiometricPrompt.PromptInfo.Builder setNegativeButtonText(CharSequence);
     method public androidx.biometric.BiometricPrompt.PromptInfo.Builder setSubtitle(CharSequence?);
     method public androidx.biometric.BiometricPrompt.PromptInfo.Builder setTitle(CharSequence);
diff --git a/biometric/api/current.txt b/biometric/api/current.txt
index f517f0f..51a912e 100644
--- a/biometric/api/current.txt
+++ b/biometric/api/current.txt
@@ -13,6 +13,7 @@
     field public static final int ERROR_LOCKOUT_PERMANENT = 9; // 0x9
     field public static final int ERROR_NEGATIVE_BUTTON = 13; // 0xd
     field public static final int ERROR_NO_BIOMETRICS = 11; // 0xb
+    field public static final int ERROR_NO_DEVICE_CREDENTIAL = 14; // 0xe
     field public static final int ERROR_NO_SPACE = 4; // 0x4
     field public static final int ERROR_TIMEOUT = 3; // 0x3
     field public static final int ERROR_UNABLE_TO_PROCESS = 2; // 0x2
@@ -45,12 +46,16 @@
     method public CharSequence getNegativeButtonText();
     method public CharSequence? getSubtitle();
     method public CharSequence getTitle();
+    method public boolean isConfirmationRequired();
+    method public boolean isDeviceCredentialAllowed();
   }
 
   public static class BiometricPrompt.PromptInfo.Builder {
     ctor public BiometricPrompt.PromptInfo.Builder();
     method public androidx.biometric.BiometricPrompt.PromptInfo build();
+    method public androidx.biometric.BiometricPrompt.PromptInfo.Builder setConfirmationRequired(boolean);
     method public androidx.biometric.BiometricPrompt.PromptInfo.Builder setDescription(CharSequence?);
+    method @RequiresApi(29) public androidx.biometric.BiometricPrompt.PromptInfo.Builder setDeviceCredentialAllowed(boolean);
     method public androidx.biometric.BiometricPrompt.PromptInfo.Builder setNegativeButtonText(CharSequence);
     method public androidx.biometric.BiometricPrompt.PromptInfo.Builder setSubtitle(CharSequence?);
     method public androidx.biometric.BiometricPrompt.PromptInfo.Builder setTitle(CharSequence);
diff --git a/biometric/src/main/java/androidx/biometric/BiometricConstants.java b/biometric/src/main/java/androidx/biometric/BiometricConstants.java
index f4384b0..7824178 100644
--- a/biometric/src/main/java/androidx/biometric/BiometricConstants.java
+++ b/biometric/src/main/java/androidx/biometric/BiometricConstants.java
@@ -107,6 +107,11 @@
     int ERROR_NEGATIVE_BUTTON = 13;
 
     /**
+     * The device does not have pin, pattern, or password set up.
+     */
+    int ERROR_NO_DEVICE_CREDENTIAL = 14;
+
+    /**
      * @hide
      */
     @RestrictTo(RestrictTo.Scope.LIBRARY)
diff --git a/biometric/src/main/java/androidx/biometric/BiometricFragment.java b/biometric/src/main/java/androidx/biometric/BiometricFragment.java
index 5622c89..69fc1ce 100644
--- a/biometric/src/main/java/androidx/biometric/BiometricFragment.java
+++ b/biometric/src/main/java/androidx/biometric/BiometricFragment.java
@@ -22,12 +22,15 @@
 import android.os.CancellationSignal;
 import android.os.Handler;
 import android.os.Looper;
+import android.text.TextUtils;
+import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 
 import androidx.annotation.RequiresApi;
 import androidx.annotation.RestrictTo;
+import androidx.core.os.BuildCompat;
 import androidx.fragment.app.Fragment;
 
 import java.util.concurrent.Executor;
@@ -62,6 +65,7 @@
     private boolean mShowing;
     private android.hardware.biometrics.BiometricPrompt mBiometricPrompt;
     private CancellationSignal mCancellationSignal;
+    private boolean mStartRespectingCancel;
     // Do not rely on the application's executor when calling into the framework's code.
     private final Handler mHandler = new Handler(Looper.getMainLooper());
     private final Executor mExecutor = new Executor() {
@@ -170,6 +174,13 @@
      * Cancel the authentication.
      */
     protected void cancel() {
+        // TODO(b/128747871): Change to == Q
+        if (BuildCompat.isAtLeastQ() && isDeviceCredentialAllowed()) {
+            if (!mStartRespectingCancel) {
+                Log.w(TAG, "Ignoring fast cancel signal");
+                return;
+            }
+        }
         if (mCancellationSignal != null) {
             mCancellationSignal.cancel();
         }
@@ -201,19 +212,50 @@
         mBundle = bundle;
     }
 
+    public boolean isDeviceCredentialAllowed() {
+        return mBundle.getBoolean(BiometricPrompt.KEY_ALLOW_DEVICE_CREDENTIAL, false);
+    }
+
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
             Bundle savedInstanceState) {
         // Start the actual authentication when the fragment is attached.
         if (!mShowing) {
             mNegativeButtonText = mBundle.getCharSequence(BiometricPrompt.KEY_NEGATIVE_TEXT);
-            mBiometricPrompt = new android.hardware.biometrics.BiometricPrompt.Builder(getContext())
-                    .setTitle(mBundle.getCharSequence(BiometricPrompt.KEY_TITLE))
+            final android.hardware.biometrics.BiometricPrompt.Builder builder =
+                    new android.hardware.biometrics.BiometricPrompt.Builder(getContext());
+            builder.setTitle(mBundle.getCharSequence(BiometricPrompt.KEY_TITLE))
                     .setSubtitle(mBundle.getCharSequence(BiometricPrompt.KEY_SUBTITLE))
-                    .setDescription(mBundle.getCharSequence(BiometricPrompt.KEY_DESCRIPTION))
-                    .setNegativeButton(mBundle.getCharSequence(BiometricPrompt.KEY_NEGATIVE_TEXT),
-                            mClientExecutor, mNegativeButtonListener)
-                    .build();
+                    .setDescription(mBundle.getCharSequence(BiometricPrompt.KEY_DESCRIPTION));
+            // The negative text could be empty if setDeviceCredentialAllowed is true.
+            if (!TextUtils.isEmpty(mBundle.getCharSequence(BiometricPrompt.KEY_NEGATIVE_TEXT))) {
+                builder.setNegativeButton(
+                        mBundle.getCharSequence(BiometricPrompt.KEY_NEGATIVE_TEXT),
+                        mClientExecutor, mNegativeButtonListener);
+            }
+
+            if (BuildCompat.isAtLeastQ()) {
+                builder.setConfirmationRequired(
+                        mBundle.getBoolean((BiometricPrompt.KEY_REQUIRE_CONFIRMATION), true));
+                builder.setDeviceCredentialAllowed(
+                        mBundle.getBoolean(BiometricPrompt.KEY_ALLOW_DEVICE_CREDENTIAL));
+            }
+
+            if (BuildCompat.isAtLeastQ()) { // TODO(b/128747871): Change to == Q
+                if (mBundle.getBoolean(BiometricPrompt.KEY_ALLOW_DEVICE_CREDENTIAL, false)) {
+                    mStartRespectingCancel = false;
+                    mHandler.postDelayed(new Runnable() {
+                        @Override
+                        public void run() {
+                            // Hack almost over 9000, ignore cancel signal in Q if it's within the
+                            // first quarter second.
+                            mStartRespectingCancel = true;
+                        }
+                    }, 250 /* ms */);
+                }
+            }
+
+            mBiometricPrompt = builder.build();
             mCancellationSignal = new CancellationSignal();
             if (mCryptoObject == null) {
                 mBiometricPrompt.authenticate(mCancellationSignal, mExecutor,
diff --git a/biometric/src/main/java/androidx/biometric/BiometricPrompt.java b/biometric/src/main/java/androidx/biometric/BiometricPrompt.java
index efdd360..eb270cc 100644
--- a/biometric/src/main/java/androidx/biometric/BiometricPrompt.java
+++ b/biometric/src/main/java/androidx/biometric/BiometricPrompt.java
@@ -28,6 +28,8 @@
 import androidx.annotation.IntDef;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
+import androidx.core.os.BuildCompat;
 import androidx.fragment.app.FragmentActivity;
 import androidx.fragment.app.FragmentManager;
 import androidx.lifecycle.Lifecycle;
@@ -64,6 +66,8 @@
     static final String KEY_SUBTITLE = "subtitle";
     static final String KEY_DESCRIPTION = "description";
     static final String KEY_NEGATIVE_TEXT = "negative_text";
+    static final String KEY_REQUIRE_CONFIRMATION = "require_confirmation";
+    static final String KEY_ALLOW_DEVICE_CREDENTIAL = "allow_device_credential";
 
     @Retention(SOURCE)
     @IntDef({BiometricConstants.ERROR_HW_UNAVAILABLE,
@@ -77,7 +81,8 @@
             BiometricConstants.ERROR_USER_CANCELED,
             BiometricConstants.ERROR_NO_BIOMETRICS,
             BiometricConstants.ERROR_HW_NOT_PRESENT,
-            BiometricConstants.ERROR_NEGATIVE_BUTTON})
+            BiometricConstants.ERROR_NEGATIVE_BUTTON,
+            BiometricConstants.ERROR_NO_DEVICE_CREDENTIAL})
     @interface BiometricError {}
 
     /**
@@ -241,6 +246,52 @@
             }
 
             /**
+             * Optional: A hint to the system to require user confirmation after a biometric has
+             * been authenticated. For example, implicit modalities like Face and
+             * Iris authentication are passive, meaning they don't require an explicit user action
+             * to complete. When set to 'false', the user action (e.g. pressing a button)
+             * will not be required. BiometricPrompt will require confirmation by default.
+             *
+             * A typical use case for not requiring confirmation would be for low-risk transactions,
+             * such as re-authenticating a recently authenticated application. A typical use case
+             * for requiring confirmation would be for authorizing a purchase.
+             *
+             * Note that this is a hint to the system. The system may choose to ignore the flag. For
+             * example, if the user disables implicit authentication in Settings, or if it does not
+             * apply to a modality (e.g. Fingerprint). When ignored, the system will default to
+             * requiring confirmation.
+             *
+             * This method only applies to Q and above.
+             */
+            @NonNull
+            public Builder setConfirmationRequired(boolean requireConfirmation) {
+                mBundle.putBoolean(KEY_REQUIRE_CONFIRMATION, requireConfirmation);
+                return this;
+            }
+
+            /**
+             * The user will first be prompted to authenticate with biometrics, but also given the
+             * option to authenticate with their device PIN, pattern, or password. Developers should
+             * first check {@link android.app.KeyguardManager#isDeviceSecure()} before enabling
+             * this. If the device is not secure, {@link BiometricPrompt#ERROR_NO_DEVICE_CREDENTIAL}
+             * will be returned in
+             * {@link AuthenticationCallback#onAuthenticationError(int, CharSequence)}}
+             *
+             * Note that {@link Builder#setNegativeButtonText(CharSequence)} should not be set
+             * if this is set to true.
+             *
+             * @param enable When true, the prompt will fall back to ask for the user's device
+             *               credentials (PIN, pattern, or password).
+             * @return
+             */
+            @RequiresApi(29)
+            @NonNull
+            public Builder setDeviceCredentialAllowed(boolean enable) {
+                mBundle.putBoolean(KEY_ALLOW_DEVICE_CREDENTIAL, enable);
+                return this;
+            }
+
+            /**
              * Creates a {@link BiometricPrompt}.
              * @return a {@link BiometricPrompt}
              * @throws IllegalArgumentException if any of the required fields are not set.
@@ -249,12 +300,17 @@
             public PromptInfo build() {
                 final CharSequence title = mBundle.getCharSequence(KEY_TITLE);
                 final CharSequence negative = mBundle.getCharSequence(KEY_NEGATIVE_TEXT);
+                boolean allowDeviceCredential = mBundle.getBoolean(KEY_ALLOW_DEVICE_CREDENTIAL);
 
                 if (TextUtils.isEmpty(title)) {
                     throw new IllegalArgumentException("Title must be set and non-empty");
-                } else if (TextUtils.isEmpty(negative)) {
-                    throw new IllegalArgumentException("Negative button text must be set and "
-                            + "non-empty");
+                }
+                if (TextUtils.isEmpty(negative) && !allowDeviceCredential) {
+                    throw new IllegalArgumentException("Negative text must be set and non-empty");
+                }
+                if (!TextUtils.isEmpty(negative) && allowDeviceCredential) {
+                    throw new IllegalArgumentException("Can't have both negative button behavior"
+                            + " and device credential enabled");
                 }
                 return new PromptInfo(mBundle);
             }
@@ -301,6 +357,22 @@
         public CharSequence getNegativeButtonText() {
             return mBundle.getCharSequence(KEY_NEGATIVE_TEXT);
         }
+
+        /**
+         * @return See {@link Builder#setConfirmationRequired(boolean)}.
+         */
+        @Nullable
+        public boolean isConfirmationRequired() {
+            return mBundle.getBoolean(KEY_REQUIRE_CONFIRMATION);
+        }
+
+        /**
+         * @return See {@link Builder#setDeviceCredentialAllowed(boolean)}.
+         */
+        @Nullable
+        public boolean isDeviceCredentialAllowed() {
+            return mBundle.getBoolean(KEY_ALLOW_DEVICE_CREDENTIAL);
+        }
     }
 
     // Passed in from the client.
@@ -315,6 +387,11 @@
     // Created internally for devices P and above.
     BiometricFragment mBiometricFragment;
 
+    // In Q, we must ignore the first onPause if setDeviceCredentialAllowed is true, since
+    // the Q implementation launches ConfirmDeviceCredentialActivity which is an activity and
+    // puts the client app onPause.
+    boolean mPausedOnce;
+
     /**
      *  A shim to interface with the framework API and simplify the support library's API.
      *  The support library sends onAuthenticationError when the negative button is pressed.
@@ -358,11 +435,7 @@
         @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
         void onPause() {
             if (!mFragmentActivity.isChangingConfigurations()) {
-                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
-                    if (mBiometricFragment != null) {
-                        mBiometricFragment.cancel();
-                    }
-                } else {
+                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
                     // May be null if no authentication is occurring.
                     if (mFingerprintDialogFragment != null) {
                         mFingerprintDialogFragment.dismiss();
@@ -371,6 +444,26 @@
                         mFingerprintHelperFragment.cancel(
                                 FingerprintHelperFragment.USER_CANCELED_FROM_NONE);
                     }
+                } else if (BuildCompat.isAtLeastQ()) { // TODO: Change to == Q
+                    // TODO(b/123378871): Change == to >= if this bug is not resolved in R.
+                    // Ignore the first onPause if setDeviceCredentialAllowed is true, since
+                    // the Q implementation launches ConfirmDeviceCredentialActivity which is an
+                    // activity and puts the client app onPause.
+                    if (mBiometricFragment != null) {
+                        if (mBiometricFragment.isDeviceCredentialAllowed()) {
+                            if (!mPausedOnce) {
+                                mPausedOnce = true;
+                            } else {
+                                mBiometricFragment.cancel();
+                            }
+                        } else {
+                            mBiometricFragment.cancel();
+                        }
+                    }
+                } else {
+                    if (mBiometricFragment != null) {
+                        mBiometricFragment.cancel();
+                    }
                 }
             }
         }
@@ -448,6 +541,8 @@
             throw new IllegalArgumentException("PromptInfo can not be null");
         } else if (crypto == null) {
             throw new IllegalArgumentException("CryptoObject can not be null");
+        } else if (info.getBundle().getBoolean(KEY_ALLOW_DEVICE_CREDENTIAL)) {
+            throw new IllegalArgumentException("Device credential not supported with crypto");
         }
         authenticateInternal(info, crypto);
     }
@@ -470,6 +565,8 @@
         final FragmentManager fragmentManager = mFragmentActivity.getSupportFragmentManager();
 
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
+            mPausedOnce = false;
+
             // Create the fragment that wraps BiometricPrompt once.
             if (mBiometricFragment == null) {
                 mBiometricFragment = BiometricFragment.newInstance();
diff --git a/buildSrc/src/main/kotlin/androidx/build/DiffAndDocs.kt b/buildSrc/src/main/kotlin/androidx/build/DiffAndDocs.kt
index 8c1c560..2958f70 100644
--- a/buildSrc/src/main/kotlin/androidx/build/DiffAndDocs.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/DiffAndDocs.kt
@@ -80,6 +80,12 @@
         val doclavaConfiguration = root.configurations.create("doclava")
         doclavaConfiguration.dependencies.add(root.dependencies.create(DOCLAVA_DEPENDENCY))
 
+        // Pulls in the :fakeannotations project, which provides modified annotations required to
+        // generate SDK API stubs in Doclava from Metalava-generated platform SDK stubs.
+        val annotationConfiguration = root.configurations.create("annotation")
+        annotationConfiguration.dependencies.add(root.dependencies.project(
+            mapOf("path" to ":fakeannotations")))
+
         // tools.jar required for com.sun.javadoc
         // TODO this breaks the ability to use JDK 9+ for compilation.
         doclavaConfiguration.dependencies.add(root.dependencies.create(root.files(
@@ -88,7 +94,8 @@
         rules = additionalRules + TIP_OF_TREE
         docsProject = root.findProject(":docs-fake")
         anchorTask = root.tasks.register("anchorDocsTask")
-        val generateSdkApiTask = createGenerateSdkApiTask(root, doclavaConfiguration)
+        val generateSdkApiTask = createGenerateSdkApiTask(root, doclavaConfiguration,
+            annotationConfiguration)
         val now = LocalDateTime.now()
         // The diff output assumes that each library is of the same version,
         // but our libraries may each be of different versions
@@ -530,13 +537,21 @@
  * <p>
  * This is useful for federating docs against the platform SDK when no API XML file is available.
  */
-private fun createGenerateSdkApiTask(project: Project, doclavaConfig: Configuration): DoclavaTask =
+private fun createGenerateSdkApiTask(
+    project: Project,
+    doclavaConfig: Configuration,
+    annotationConfig: Configuration
+): DoclavaTask =
         project.tasks.createWithConfig("generateSdkApi", DoclavaTask::class.java) {
             dependsOn(doclavaConfig)
+            dependsOn(annotationConfig)
             description = "Generates API files for the current SDK."
             setDocletpath(doclavaConfig.resolve())
             destinationDir = project.docsDir()
+            // Strip the androidx.annotation classes injected by Metalava. They are not accessible.
             classpath = androidJarFile(project)
+                .filter { it.path.contains("androidx/annotation") }
+                .plus(project.files(annotationConfig.resolve()))
             source(project.zipTree(androidSrcJarFile(project))
                 .matching(PatternSet().include("**/*.java")))
             exclude("**/overview.html") // TODO https://issuetracker.google.com/issues/116699307
diff --git a/buildSrc/src/main/kotlin/androidx/build/PublishDocsRules.kt b/buildSrc/src/main/kotlin/androidx/build/PublishDocsRules.kt
index a02af90d..51429f8 100644
--- a/buildSrc/src/main/kotlin/androidx/build/PublishDocsRules.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/PublishDocsRules.kt
@@ -45,7 +45,7 @@
     prebuilts(LibraryGroups.CORE, "core-ktx", "1.1.0-alpha05")
     prebuilts(LibraryGroups.CURSORADAPTER, "1.0.0")
     prebuilts(LibraryGroups.CUSTOMVIEW, "1.0.0")
-    prebuilts(LibraryGroups.DOCUMENTFILE, "1.0.0")
+    ignore(LibraryGroups.DOCUMENTFILE.group)
     prebuilts(LibraryGroups.DRAWERLAYOUT, "1.0.0")
     prebuilts(LibraryGroups.DYNAMICANIMATION, "dynamicanimation-ktx", "1.0.0-alpha02")
     prebuilts(LibraryGroups.DYNAMICANIMATION, "1.1.0-alpha01")
diff --git a/buildSrc/src/main/kotlin/androidx/build/SupportConfig.kt b/buildSrc/src/main/kotlin/androidx/build/SupportConfig.kt
index 5a45ac0..85d5382 100644
--- a/buildSrc/src/main/kotlin/androidx/build/SupportConfig.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/SupportConfig.kt
@@ -27,20 +27,24 @@
 
     /**
      * The Android SDK version to use for compilation.
-     *
+     * <p>
      * Either an integer value or a pre-release platform code, prefixed with "android-" (ex.
      * "android-28" or "android-Q") as you would see within the SDK's platforms directory.
      */
-    const val COMPILE_SDK_VERSION = "android-28"
+    const val COMPILE_SDK_VERSION = "android-Q"
 
     /**
      * The Android SDK version to use for targetSdkVersion meta-data.
-     *
+     * <p>
      * Either an integer value (ex. 28), a pre-release platform code (ex. "Q") as you would see
      * within the SDK's platforms directory as android-<version>, or a released platform version
      * code as you would see within Build.VERSIONS.VERSION_CODE (ex. "HONEYCOMB" or "P").
+     * <p>
+     * <strong>Note:</strong> This must be set to an integer value or released platform version in
+     * order for tests to run on devices running released versions of the Android OS. If this is
+     * set to a pre-release version, tests will only be able to run on pre-release devices.
      */
-    const val TARGET_SDK_VERSION = "28"
+    const val TARGET_SDK_VERSION = 28
 
     fun getKeystore(project: Project): File {
         val supportRoot = (project.rootProject.property("ext") as ExtraPropertiesExtension)
diff --git a/car/core/src/main/java/androidx/car/drawer/CarDrawerAdapter.java b/car/core/src/main/java/androidx/car/drawer/CarDrawerAdapter.java
index 3bafda9..0605865 100644
--- a/car/core/src/main/java/androidx/car/drawer/CarDrawerAdapter.java
+++ b/car/core/src/main/java/androidx/car/drawer/CarDrawerAdapter.java
@@ -99,6 +99,7 @@
         void onTitleChanged(@Nullable CharSequence newTitle);
     }
 
+    @SuppressWarnings("deprecation")
     protected CarDrawerAdapter(Context context, boolean showDisabledListOnEmpty) {
         mShowDisabledListOnEmpty = showDisabledListOnEmpty;
 
diff --git a/cardview/build.gradle b/cardview/build.gradle
index c2e6dbf..f661d68 100644
--- a/cardview/build.gradle
+++ b/cardview/build.gradle
@@ -8,6 +8,7 @@
 
 dependencies {
     api(project(":annotation"))
+    implementation(project(":core"))
 }
 
 android {
diff --git a/cardview/src/main/java/androidx/cardview/widget/CardView.java b/cardview/src/main/java/androidx/cardview/widget/CardView.java
index bfaa546..140241e 100644
--- a/cardview/src/main/java/androidx/cardview/widget/CardView.java
+++ b/cardview/src/main/java/androidx/cardview/widget/CardView.java
@@ -32,6 +32,7 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.Px;
 import androidx.cardview.R;
+import androidx.core.os.BuildCompat;
 
 /**
  * A FrameLayout with a rounded corner background and shadow.
@@ -122,6 +123,10 @@
 
         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CardView, defStyleAttr,
                 R.style.CardView);
+        if (BuildCompat.isAtLeastQ()) {
+            saveAttributeDataForStyleable(
+                    context, R.styleable.CardView, attrs, a, defStyleAttr, R.style.CardView);
+        }
         ColorStateList backgroundColor;
         if (a.hasValue(R.styleable.CardView_cardBackgroundColor)) {
             backgroundColor = a.getColorStateList(R.styleable.CardView_cardBackgroundColor);
diff --git a/coordinatorlayout/src/main/java/androidx/coordinatorlayout/widget/CoordinatorLayout.java b/coordinatorlayout/src/main/java/androidx/coordinatorlayout/widget/CoordinatorLayout.java
index b4019f7..d0ff331 100644
--- a/coordinatorlayout/src/main/java/androidx/coordinatorlayout/widget/CoordinatorLayout.java
+++ b/coordinatorlayout/src/main/java/androidx/coordinatorlayout/widget/CoordinatorLayout.java
@@ -56,6 +56,7 @@
 import androidx.coordinatorlayout.R;
 import androidx.core.content.ContextCompat;
 import androidx.core.graphics.drawable.DrawableCompat;
+import androidx.core.os.BuildCompat;
 import androidx.core.util.ObjectsCompat;
 import androidx.core.util.Pools;
 import androidx.core.view.GravityCompat;
@@ -220,6 +221,17 @@
                 0, R.style.Widget_Support_CoordinatorLayout)
                 : context.obtainStyledAttributes(attrs, R.styleable.CoordinatorLayout,
                         defStyleAttr, 0);
+        if (BuildCompat.isAtLeastQ()) {
+            if (defStyleAttr == 0) {
+                saveAttributeDataForStyleable(
+                        context, R.styleable.CoordinatorLayout, attrs, a, 0,
+                        R.style.Widget_Support_CoordinatorLayout);
+            } else {
+                saveAttributeDataForStyleable(
+                        context, R.styleable.CoordinatorLayout, attrs, a, defStyleAttr, 0);
+            }
+        }
+
         final int keylineArrayRes = a.getResourceId(R.styleable.CoordinatorLayout_keylines, 0);
         if (keylineArrayRes != 0) {
             final Resources res = context.getResources();
diff --git a/core/api/1.1.0-alpha03.txt b/core/api/1.1.0-alpha03.txt
index cdd40ca..43c05b2 100644
--- a/core/api/1.1.0-alpha03.txt
+++ b/core/api/1.1.0-alpha03.txt
@@ -2354,6 +2354,7 @@
     method public boolean isScrollable();
     method public boolean isSelected();
     method public boolean isShowingHintText();
+    method public boolean isTextEntryKey();
     method public boolean isVisibleToUser();
     method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! obtain(android.view.View!);
     method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! obtain(android.view.View!, int);
@@ -2413,6 +2414,7 @@
     method public void setSource(android.view.View!);
     method public void setSource(android.view.View!, int);
     method public void setText(CharSequence!);
+    method public void setTextEntryKey(boolean);
     method public void setTextSelection(int, int);
     method public void setTooltipText(CharSequence?);
     method public void setTraversalAfter(android.view.View!);
@@ -2486,6 +2488,10 @@
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_MOVE_WINDOW;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_NEXT_AT_MOVEMENT_GRANULARITY;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_NEXT_HTML_ELEMENT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_DOWN;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_LEFT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_RIGHT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_UP;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_PASTE;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_PREVIOUS_HTML_ELEMENT;
diff --git a/core/api/1.1.0-alpha04.txt b/core/api/1.1.0-alpha04.txt
index e9cfd20..1852227 100644
--- a/core/api/1.1.0-alpha04.txt
+++ b/core/api/1.1.0-alpha04.txt
@@ -2337,6 +2337,7 @@
     method public int getTextSelectionEnd();
     method public int getTextSelectionStart();
     method public CharSequence? getTooltipText();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat.TouchDelegateInfoCompat? getTouchDelegateInfo();
     method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getTraversalAfter();
     method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getTraversalBefore();
     method public String! getViewIdResourceName();
@@ -2362,6 +2363,7 @@
     method public boolean isScrollable();
     method public boolean isSelected();
     method public boolean isShowingHintText();
+    method public boolean isTextEntryKey();
     method public boolean isVisibleToUser();
     method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! obtain(android.view.View!);
     method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! obtain(android.view.View!, int);
@@ -2421,8 +2423,10 @@
     method public void setSource(android.view.View!);
     method public void setSource(android.view.View!, int);
     method public void setText(CharSequence!);
+    method public void setTextEntryKey(boolean);
     method public void setTextSelection(int, int);
     method public void setTooltipText(CharSequence?);
+    method public void setTouchDelegateInfo(androidx.core.view.accessibility.AccessibilityNodeInfoCompat.TouchDelegateInfoCompat);
     method public void setTraversalAfter(android.view.View!);
     method public void setTraversalAfter(android.view.View!, int);
     method public void setTraversalBefore(android.view.View!);
@@ -2494,6 +2498,10 @@
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_MOVE_WINDOW;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_NEXT_AT_MOVEMENT_GRANULARITY;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_NEXT_HTML_ELEMENT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_DOWN;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_LEFT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_RIGHT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_UP;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_PASTE;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_PREVIOUS_HTML_ELEMENT;
@@ -2546,6 +2554,13 @@
     field public static final int RANGE_TYPE_PERCENT = 2; // 0x2
   }
 
+  public static final class AccessibilityNodeInfoCompat.TouchDelegateInfoCompat {
+    ctor public AccessibilityNodeInfoCompat.TouchDelegateInfoCompat(java.util.Map<android.graphics.Region,android.view.View>);
+    method public android.graphics.Region? getRegionAt(@IntRange(from=0) int);
+    method @IntRange(from=0) public int getRegionCount();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat? getTargetForRegion(android.graphics.Region);
+  }
+
   public class AccessibilityNodeProviderCompat {
     ctor public AccessibilityNodeProviderCompat();
     ctor public AccessibilityNodeProviderCompat(Object!);
diff --git a/core/api/1.1.0-alpha05.txt b/core/api/1.1.0-alpha05.txt
index 0ece2e3..5855002 100644
--- a/core/api/1.1.0-alpha05.txt
+++ b/core/api/1.1.0-alpha05.txt
@@ -2338,6 +2338,7 @@
     method public int getTextSelectionEnd();
     method public int getTextSelectionStart();
     method public CharSequence? getTooltipText();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat.TouchDelegateInfoCompat? getTouchDelegateInfo();
     method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getTraversalAfter();
     method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getTraversalBefore();
     method public String! getViewIdResourceName();
@@ -2363,6 +2364,7 @@
     method public boolean isScrollable();
     method public boolean isSelected();
     method public boolean isShowingHintText();
+    method public boolean isTextEntryKey();
     method public boolean isVisibleToUser();
     method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! obtain(android.view.View!);
     method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! obtain(android.view.View!, int);
@@ -2422,8 +2424,10 @@
     method public void setSource(android.view.View!);
     method public void setSource(android.view.View!, int);
     method public void setText(CharSequence!);
+    method public void setTextEntryKey(boolean);
     method public void setTextSelection(int, int);
     method public void setTooltipText(CharSequence?);
+    method public void setTouchDelegateInfo(androidx.core.view.accessibility.AccessibilityNodeInfoCompat.TouchDelegateInfoCompat);
     method public void setTraversalAfter(android.view.View!);
     method public void setTraversalAfter(android.view.View!, int);
     method public void setTraversalBefore(android.view.View!);
@@ -2495,6 +2499,10 @@
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_MOVE_WINDOW;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_NEXT_AT_MOVEMENT_GRANULARITY;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_NEXT_HTML_ELEMENT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_DOWN;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_LEFT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_RIGHT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_UP;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_PASTE;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_PREVIOUS_HTML_ELEMENT;
@@ -2547,6 +2555,13 @@
     field public static final int RANGE_TYPE_PERCENT = 2; // 0x2
   }
 
+  public static final class AccessibilityNodeInfoCompat.TouchDelegateInfoCompat {
+    ctor public AccessibilityNodeInfoCompat.TouchDelegateInfoCompat(java.util.Map<android.graphics.Region,android.view.View>);
+    method public android.graphics.Region? getRegionAt(@IntRange(from=0) int);
+    method @IntRange(from=0) public int getRegionCount();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat? getTargetForRegion(android.graphics.Region);
+  }
+
   public class AccessibilityNodeProviderCompat {
     ctor public AccessibilityNodeProviderCompat();
     ctor public AccessibilityNodeProviderCompat(Object!);
diff --git a/core/api/1.1.0-alpha06.txt b/core/api/1.1.0-alpha06.txt
index 3ff7f23..f9b5285 100644
--- a/core/api/1.1.0-alpha06.txt
+++ b/core/api/1.1.0-alpha06.txt
@@ -180,6 +180,7 @@
     ctor @Deprecated public NotificationCompat();
     method public static androidx.core.app.NotificationCompat.Action! getAction(android.app.Notification!, int);
     method public static int getActionCount(android.app.Notification!);
+    method public static boolean getAllowSystemGeneratedContextualActions(android.app.Notification!);
     method public static int getBadgeIconType(android.app.Notification!);
     method public static String! getCategory(android.app.Notification!);
     method public static String! getChannelId(android.app.Notification!);
@@ -282,6 +283,7 @@
     method @androidx.core.app.NotificationCompat.Action.SemanticAction public int getSemanticAction();
     method public boolean getShowsUserInterface();
     method public CharSequence! getTitle();
+    method public boolean isContextual();
     field public static final int SEMANTIC_ACTION_ARCHIVE = 5; // 0x5
     field public static final int SEMANTIC_ACTION_CALL = 10; // 0xa
     field public static final int SEMANTIC_ACTION_DELETE = 4; // 0x4
@@ -307,6 +309,7 @@
     method public androidx.core.app.NotificationCompat.Action.Builder! extend(androidx.core.app.NotificationCompat.Action.Extender!);
     method public android.os.Bundle! getExtras();
     method public androidx.core.app.NotificationCompat.Action.Builder! setAllowGeneratedReplies(boolean);
+    method public androidx.core.app.NotificationCompat.Action.Builder setContextual(boolean);
     method public androidx.core.app.NotificationCompat.Action.Builder! setSemanticAction(@androidx.core.app.NotificationCompat.Action.SemanticAction int);
     method public androidx.core.app.NotificationCompat.Action.Builder! setShowsUserInterface(boolean);
   }
@@ -368,6 +371,7 @@
     method public android.os.Bundle! getExtras();
     method @Deprecated public android.app.Notification! getNotification();
     method protected static CharSequence! limitCharSequenceLength(CharSequence!);
+    method public androidx.core.app.NotificationCompat.Builder setAllowSystemGeneratedContextualActions(boolean);
     method public androidx.core.app.NotificationCompat.Builder! setAutoCancel(boolean);
     method public androidx.core.app.NotificationCompat.Builder! setBadgeIconType(int);
     method public androidx.core.app.NotificationCompat.Builder! setCategory(String!);
@@ -655,6 +659,7 @@
     method public java.util.Set<java.lang.String>! getAllowedDataTypes();
     method public CharSequence[]! getChoices();
     method public static java.util.Map<java.lang.String,android.net.Uri>! getDataResultsFromIntent(android.content.Intent!, String!);
+    method public int getEditChoicesBeforeSending();
     method public android.os.Bundle! getExtras();
     method public CharSequence! getLabel();
     method public String! getResultKey();
@@ -662,6 +667,9 @@
     method public static int getResultsSource(android.content.Intent);
     method public boolean isDataOnly();
     method public static void setResultsSource(android.content.Intent, int);
+    field public static final int EDIT_CHOICES_BEFORE_SENDING_AUTO = 0; // 0x0
+    field public static final int EDIT_CHOICES_BEFORE_SENDING_DISABLED = 1; // 0x1
+    field public static final int EDIT_CHOICES_BEFORE_SENDING_ENABLED = 2; // 0x2
     field public static final String EXTRA_RESULTS_DATA = "android.remoteinput.resultsData";
     field public static final String RESULTS_CLIP_LABEL = "android.remoteinput.results";
     field public static final int SOURCE_CHOICE = 1; // 0x1
@@ -676,6 +684,7 @@
     method public androidx.core.app.RemoteInput.Builder setAllowDataType(String, boolean);
     method public androidx.core.app.RemoteInput.Builder setAllowFreeFormInput(boolean);
     method public androidx.core.app.RemoteInput.Builder setChoices(CharSequence[]?);
+    method public androidx.core.app.RemoteInput.Builder setEditChoicesBeforeSending(int);
     method public androidx.core.app.RemoteInput.Builder setLabel(CharSequence?);
   }
 
@@ -967,6 +976,38 @@
     method public static void setHasMipMap(android.graphics.Bitmap, boolean);
   }
 
+  public enum BlendModeCompat {
+    enum_constant public static final androidx.core.graphics.BlendModeCompat CLEAR;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat COLOR;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat COLOR_BURN;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat COLOR_DODGE;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat DARKEN;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat DIFFERENCE;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat DST;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat DST_ATOP;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat DST_IN;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat DST_OUT;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat DST_OVER;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat EXCLUSION;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat HARD_LIGHT;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat HUE;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat LIGHTEN;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat LUMINOSITY;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat MODULATE;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat MULTIPLY;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat OVERLAY;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat PLUS;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat SATURATION;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat SCREEN;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat SOFT_LIGHT;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat SRC;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat SRC_ATOP;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat SRC_IN;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat SRC_OUT;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat SRC_OVER;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat XOR;
+  }
+
   public final class ColorUtils {
     method @ColorInt public static int HSLToColor(float[]);
     method @ColorInt public static int LABToColor(@FloatRange(from=0.0f, to=100) double, @FloatRange(from=0xffffff80, to=127) double, @FloatRange(from=0xffffff80, to=127) double);
@@ -991,8 +1032,20 @@
     method @ColorInt public static int setAlphaComponent(@ColorInt int, @IntRange(from=0, to=255) int);
   }
 
+  public final class Insets {
+    method public static androidx.core.graphics.Insets of(int, int, int, int);
+    method public static androidx.core.graphics.Insets of(android.graphics.Rect);
+    field public static final androidx.core.graphics.Insets NONE;
+    field public final int bottom;
+    field public final int left;
+    field public final int right;
+    field public final int top;
+  }
+
   public final class PaintCompat {
     method public static boolean hasGlyph(android.graphics.Paint, String);
+    method public static void setBlendMode(android.graphics.Paint, androidx.core.graphics.BlendModeCompat?);
+    method public static void setBlendModeColorFilter(android.graphics.Paint, @ColorInt int, androidx.core.graphics.BlendModeCompat?);
   }
 
   public final class PathSegment {
@@ -1960,6 +2013,7 @@
     method @Deprecated public static float getScaleX(android.view.View!);
     method @Deprecated public static float getScaleY(android.view.View!);
     method public static int getScrollIndicators(android.view.View);
+    method public static java.util.List<android.graphics.Rect> getSystemGestureExclusionRects(android.view.View);
     method public static String? getTransitionName(android.view.View);
     method @Deprecated public static float getTranslationX(android.view.View!);
     method @Deprecated public static float getTranslationY(android.view.View!);
@@ -2048,6 +2102,7 @@
     method @UiThread public static void setScreenReaderFocusable(android.view.View!, boolean);
     method public static void setScrollIndicators(android.view.View, int);
     method public static void setScrollIndicators(android.view.View, int, int);
+    method public static void setSystemGestureExclusionRects(android.view.View, java.util.List<android.graphics.Rect>);
     method public static void setTooltipText(android.view.View, CharSequence?);
     method public static void setTransitionName(android.view.View, String!);
     method @Deprecated public static void setTranslationX(android.view.View!, float);
@@ -2209,14 +2264,19 @@
     method public androidx.core.view.WindowInsetsCompat! consumeStableInsets();
     method public androidx.core.view.WindowInsetsCompat! consumeSystemWindowInsets();
     method public androidx.core.view.DisplayCutoutCompat? getDisplayCutout();
+    method public androidx.core.graphics.Insets getMandatorySystemGestureInsets();
     method public int getStableInsetBottom();
     method public int getStableInsetLeft();
     method public int getStableInsetRight();
     method public int getStableInsetTop();
+    method public androidx.core.graphics.Insets getStableInsets();
+    method public androidx.core.graphics.Insets getSystemGestureInsets();
     method public int getSystemWindowInsetBottom();
     method public int getSystemWindowInsetLeft();
     method public int getSystemWindowInsetRight();
     method public int getSystemWindowInsetTop();
+    method public androidx.core.graphics.Insets getSystemWindowInsets();
+    method public androidx.core.graphics.Insets getTappableElementInsets();
     method public boolean hasInsets();
     method public boolean hasStableInsets();
     method public boolean hasSystemWindowInsets();
@@ -2308,7 +2368,7 @@
     method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! focusSearch(int);
     method public java.util.List<androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat>! getActionList();
     method public int getActions();
-    method public void getBoundsInParent(android.graphics.Rect!);
+    method @Deprecated public void getBoundsInParent(android.graphics.Rect!);
     method public void getBoundsInScreen(android.graphics.Rect!);
     method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getChild(int);
     method public int getChildCount();
@@ -2336,6 +2396,7 @@
     method public int getTextSelectionEnd();
     method public int getTextSelectionStart();
     method public CharSequence? getTooltipText();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat.TouchDelegateInfoCompat? getTouchDelegateInfo();
     method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getTraversalAfter();
     method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getTraversalBefore();
     method public String! getViewIdResourceName();
@@ -2361,6 +2422,7 @@
     method public boolean isScrollable();
     method public boolean isSelected();
     method public boolean isShowingHintText();
+    method public boolean isTextEntryKey();
     method public boolean isVisibleToUser();
     method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! obtain(android.view.View!);
     method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! obtain(android.view.View!, int);
@@ -2374,7 +2436,7 @@
     method public boolean removeChild(android.view.View!);
     method public boolean removeChild(android.view.View!, int);
     method public void setAccessibilityFocused(boolean);
-    method public void setBoundsInParent(android.graphics.Rect!);
+    method @Deprecated public void setBoundsInParent(android.graphics.Rect!);
     method public void setBoundsInScreen(android.graphics.Rect!);
     method public void setCanOpenPopup(boolean);
     method public void setCheckable(boolean);
@@ -2420,8 +2482,10 @@
     method public void setSource(android.view.View!);
     method public void setSource(android.view.View!, int);
     method public void setText(CharSequence!);
+    method public void setTextEntryKey(boolean);
     method public void setTextSelection(int, int);
     method public void setTooltipText(CharSequence?);
+    method public void setTouchDelegateInfo(androidx.core.view.accessibility.AccessibilityNodeInfoCompat.TouchDelegateInfoCompat);
     method public void setTraversalAfter(android.view.View!);
     method public void setTraversalAfter(android.view.View!, int);
     method public void setTraversalBefore(android.view.View!);
@@ -2493,6 +2557,10 @@
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_MOVE_WINDOW;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_NEXT_AT_MOVEMENT_GRANULARITY;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_NEXT_HTML_ELEMENT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_DOWN;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_LEFT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_RIGHT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_UP;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_PASTE;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_PREVIOUS_HTML_ELEMENT;
@@ -2545,6 +2613,13 @@
     field public static final int RANGE_TYPE_PERCENT = 2; // 0x2
   }
 
+  public static final class AccessibilityNodeInfoCompat.TouchDelegateInfoCompat {
+    ctor public AccessibilityNodeInfoCompat.TouchDelegateInfoCompat(java.util.Map<android.graphics.Region,android.view.View>);
+    method public android.graphics.Region? getRegionAt(@IntRange(from=0) int);
+    method @IntRange(from=0) public int getRegionCount();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat? getTargetForRegion(android.graphics.Region);
+  }
+
   public class AccessibilityNodeProviderCompat {
     ctor public AccessibilityNodeProviderCompat();
     ctor public AccessibilityNodeProviderCompat(Object!);
diff --git a/core/api/current.txt b/core/api/current.txt
index 3ff7f23..f9b5285 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -180,6 +180,7 @@
     ctor @Deprecated public NotificationCompat();
     method public static androidx.core.app.NotificationCompat.Action! getAction(android.app.Notification!, int);
     method public static int getActionCount(android.app.Notification!);
+    method public static boolean getAllowSystemGeneratedContextualActions(android.app.Notification!);
     method public static int getBadgeIconType(android.app.Notification!);
     method public static String! getCategory(android.app.Notification!);
     method public static String! getChannelId(android.app.Notification!);
@@ -282,6 +283,7 @@
     method @androidx.core.app.NotificationCompat.Action.SemanticAction public int getSemanticAction();
     method public boolean getShowsUserInterface();
     method public CharSequence! getTitle();
+    method public boolean isContextual();
     field public static final int SEMANTIC_ACTION_ARCHIVE = 5; // 0x5
     field public static final int SEMANTIC_ACTION_CALL = 10; // 0xa
     field public static final int SEMANTIC_ACTION_DELETE = 4; // 0x4
@@ -307,6 +309,7 @@
     method public androidx.core.app.NotificationCompat.Action.Builder! extend(androidx.core.app.NotificationCompat.Action.Extender!);
     method public android.os.Bundle! getExtras();
     method public androidx.core.app.NotificationCompat.Action.Builder! setAllowGeneratedReplies(boolean);
+    method public androidx.core.app.NotificationCompat.Action.Builder setContextual(boolean);
     method public androidx.core.app.NotificationCompat.Action.Builder! setSemanticAction(@androidx.core.app.NotificationCompat.Action.SemanticAction int);
     method public androidx.core.app.NotificationCompat.Action.Builder! setShowsUserInterface(boolean);
   }
@@ -368,6 +371,7 @@
     method public android.os.Bundle! getExtras();
     method @Deprecated public android.app.Notification! getNotification();
     method protected static CharSequence! limitCharSequenceLength(CharSequence!);
+    method public androidx.core.app.NotificationCompat.Builder setAllowSystemGeneratedContextualActions(boolean);
     method public androidx.core.app.NotificationCompat.Builder! setAutoCancel(boolean);
     method public androidx.core.app.NotificationCompat.Builder! setBadgeIconType(int);
     method public androidx.core.app.NotificationCompat.Builder! setCategory(String!);
@@ -655,6 +659,7 @@
     method public java.util.Set<java.lang.String>! getAllowedDataTypes();
     method public CharSequence[]! getChoices();
     method public static java.util.Map<java.lang.String,android.net.Uri>! getDataResultsFromIntent(android.content.Intent!, String!);
+    method public int getEditChoicesBeforeSending();
     method public android.os.Bundle! getExtras();
     method public CharSequence! getLabel();
     method public String! getResultKey();
@@ -662,6 +667,9 @@
     method public static int getResultsSource(android.content.Intent);
     method public boolean isDataOnly();
     method public static void setResultsSource(android.content.Intent, int);
+    field public static final int EDIT_CHOICES_BEFORE_SENDING_AUTO = 0; // 0x0
+    field public static final int EDIT_CHOICES_BEFORE_SENDING_DISABLED = 1; // 0x1
+    field public static final int EDIT_CHOICES_BEFORE_SENDING_ENABLED = 2; // 0x2
     field public static final String EXTRA_RESULTS_DATA = "android.remoteinput.resultsData";
     field public static final String RESULTS_CLIP_LABEL = "android.remoteinput.results";
     field public static final int SOURCE_CHOICE = 1; // 0x1
@@ -676,6 +684,7 @@
     method public androidx.core.app.RemoteInput.Builder setAllowDataType(String, boolean);
     method public androidx.core.app.RemoteInput.Builder setAllowFreeFormInput(boolean);
     method public androidx.core.app.RemoteInput.Builder setChoices(CharSequence[]?);
+    method public androidx.core.app.RemoteInput.Builder setEditChoicesBeforeSending(int);
     method public androidx.core.app.RemoteInput.Builder setLabel(CharSequence?);
   }
 
@@ -967,6 +976,38 @@
     method public static void setHasMipMap(android.graphics.Bitmap, boolean);
   }
 
+  public enum BlendModeCompat {
+    enum_constant public static final androidx.core.graphics.BlendModeCompat CLEAR;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat COLOR;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat COLOR_BURN;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat COLOR_DODGE;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat DARKEN;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat DIFFERENCE;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat DST;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat DST_ATOP;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat DST_IN;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat DST_OUT;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat DST_OVER;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat EXCLUSION;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat HARD_LIGHT;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat HUE;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat LIGHTEN;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat LUMINOSITY;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat MODULATE;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat MULTIPLY;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat OVERLAY;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat PLUS;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat SATURATION;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat SCREEN;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat SOFT_LIGHT;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat SRC;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat SRC_ATOP;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat SRC_IN;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat SRC_OUT;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat SRC_OVER;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat XOR;
+  }
+
   public final class ColorUtils {
     method @ColorInt public static int HSLToColor(float[]);
     method @ColorInt public static int LABToColor(@FloatRange(from=0.0f, to=100) double, @FloatRange(from=0xffffff80, to=127) double, @FloatRange(from=0xffffff80, to=127) double);
@@ -991,8 +1032,20 @@
     method @ColorInt public static int setAlphaComponent(@ColorInt int, @IntRange(from=0, to=255) int);
   }
 
+  public final class Insets {
+    method public static androidx.core.graphics.Insets of(int, int, int, int);
+    method public static androidx.core.graphics.Insets of(android.graphics.Rect);
+    field public static final androidx.core.graphics.Insets NONE;
+    field public final int bottom;
+    field public final int left;
+    field public final int right;
+    field public final int top;
+  }
+
   public final class PaintCompat {
     method public static boolean hasGlyph(android.graphics.Paint, String);
+    method public static void setBlendMode(android.graphics.Paint, androidx.core.graphics.BlendModeCompat?);
+    method public static void setBlendModeColorFilter(android.graphics.Paint, @ColorInt int, androidx.core.graphics.BlendModeCompat?);
   }
 
   public final class PathSegment {
@@ -1960,6 +2013,7 @@
     method @Deprecated public static float getScaleX(android.view.View!);
     method @Deprecated public static float getScaleY(android.view.View!);
     method public static int getScrollIndicators(android.view.View);
+    method public static java.util.List<android.graphics.Rect> getSystemGestureExclusionRects(android.view.View);
     method public static String? getTransitionName(android.view.View);
     method @Deprecated public static float getTranslationX(android.view.View!);
     method @Deprecated public static float getTranslationY(android.view.View!);
@@ -2048,6 +2102,7 @@
     method @UiThread public static void setScreenReaderFocusable(android.view.View!, boolean);
     method public static void setScrollIndicators(android.view.View, int);
     method public static void setScrollIndicators(android.view.View, int, int);
+    method public static void setSystemGestureExclusionRects(android.view.View, java.util.List<android.graphics.Rect>);
     method public static void setTooltipText(android.view.View, CharSequence?);
     method public static void setTransitionName(android.view.View, String!);
     method @Deprecated public static void setTranslationX(android.view.View!, float);
@@ -2209,14 +2264,19 @@
     method public androidx.core.view.WindowInsetsCompat! consumeStableInsets();
     method public androidx.core.view.WindowInsetsCompat! consumeSystemWindowInsets();
     method public androidx.core.view.DisplayCutoutCompat? getDisplayCutout();
+    method public androidx.core.graphics.Insets getMandatorySystemGestureInsets();
     method public int getStableInsetBottom();
     method public int getStableInsetLeft();
     method public int getStableInsetRight();
     method public int getStableInsetTop();
+    method public androidx.core.graphics.Insets getStableInsets();
+    method public androidx.core.graphics.Insets getSystemGestureInsets();
     method public int getSystemWindowInsetBottom();
     method public int getSystemWindowInsetLeft();
     method public int getSystemWindowInsetRight();
     method public int getSystemWindowInsetTop();
+    method public androidx.core.graphics.Insets getSystemWindowInsets();
+    method public androidx.core.graphics.Insets getTappableElementInsets();
     method public boolean hasInsets();
     method public boolean hasStableInsets();
     method public boolean hasSystemWindowInsets();
@@ -2308,7 +2368,7 @@
     method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! focusSearch(int);
     method public java.util.List<androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat>! getActionList();
     method public int getActions();
-    method public void getBoundsInParent(android.graphics.Rect!);
+    method @Deprecated public void getBoundsInParent(android.graphics.Rect!);
     method public void getBoundsInScreen(android.graphics.Rect!);
     method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getChild(int);
     method public int getChildCount();
@@ -2336,6 +2396,7 @@
     method public int getTextSelectionEnd();
     method public int getTextSelectionStart();
     method public CharSequence? getTooltipText();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat.TouchDelegateInfoCompat? getTouchDelegateInfo();
     method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getTraversalAfter();
     method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getTraversalBefore();
     method public String! getViewIdResourceName();
@@ -2361,6 +2422,7 @@
     method public boolean isScrollable();
     method public boolean isSelected();
     method public boolean isShowingHintText();
+    method public boolean isTextEntryKey();
     method public boolean isVisibleToUser();
     method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! obtain(android.view.View!);
     method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! obtain(android.view.View!, int);
@@ -2374,7 +2436,7 @@
     method public boolean removeChild(android.view.View!);
     method public boolean removeChild(android.view.View!, int);
     method public void setAccessibilityFocused(boolean);
-    method public void setBoundsInParent(android.graphics.Rect!);
+    method @Deprecated public void setBoundsInParent(android.graphics.Rect!);
     method public void setBoundsInScreen(android.graphics.Rect!);
     method public void setCanOpenPopup(boolean);
     method public void setCheckable(boolean);
@@ -2420,8 +2482,10 @@
     method public void setSource(android.view.View!);
     method public void setSource(android.view.View!, int);
     method public void setText(CharSequence!);
+    method public void setTextEntryKey(boolean);
     method public void setTextSelection(int, int);
     method public void setTooltipText(CharSequence?);
+    method public void setTouchDelegateInfo(androidx.core.view.accessibility.AccessibilityNodeInfoCompat.TouchDelegateInfoCompat);
     method public void setTraversalAfter(android.view.View!);
     method public void setTraversalAfter(android.view.View!, int);
     method public void setTraversalBefore(android.view.View!);
@@ -2493,6 +2557,10 @@
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_MOVE_WINDOW;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_NEXT_AT_MOVEMENT_GRANULARITY;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_NEXT_HTML_ELEMENT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_DOWN;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_LEFT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_RIGHT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_UP;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_PASTE;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_PREVIOUS_HTML_ELEMENT;
@@ -2545,6 +2613,13 @@
     field public static final int RANGE_TYPE_PERCENT = 2; // 0x2
   }
 
+  public static final class AccessibilityNodeInfoCompat.TouchDelegateInfoCompat {
+    ctor public AccessibilityNodeInfoCompat.TouchDelegateInfoCompat(java.util.Map<android.graphics.Region,android.view.View>);
+    method public android.graphics.Region? getRegionAt(@IntRange(from=0) int);
+    method @IntRange(from=0) public int getRegionCount();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat? getTargetForRegion(android.graphics.Region);
+  }
+
   public class AccessibilityNodeProviderCompat {
     ctor public AccessibilityNodeProviderCompat();
     ctor public AccessibilityNodeProviderCompat(Object!);
diff --git a/core/api/restricted_1.1.0-alpha05.txt b/core/api/restricted_1.1.0-alpha05.txt
index 5baf105..87a5dd5 100644
--- a/core/api/restricted_1.1.0-alpha05.txt
+++ b/core/api/restricted_1.1.0-alpha05.txt
@@ -255,6 +255,15 @@
     method public android.graphics.Typeface? createFromResourcesFontFile(android.content.Context!, android.content.res.Resources!, int, String!, int);
   }
 
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) @RequiresApi(29) public class TypefaceCompatApi29Impl {
+    ctor public TypefaceCompatApi29Impl();
+    method public android.graphics.Typeface? createFromFontFamilyFilesResourceEntry(android.content.Context!, androidx.core.content.res.FontResourcesParserCompat.FontFamilyFilesResourceEntry!, android.content.res.Resources!, int);
+    method public android.graphics.Typeface? createFromFontInfo(android.content.Context!, android.os.CancellationSignal?, androidx.core.provider.FontsContractCompat.FontInfo[], int);
+    method protected android.graphics.Typeface! createFromInputStream(android.content.Context!, java.io.InputStream!);
+    method public android.graphics.Typeface? createFromResourcesFontFile(android.content.Context!, android.content.res.Resources!, int, String!, int);
+    method protected androidx.core.provider.FontsContractCompat.FontInfo! findBestInfo(androidx.core.provider.FontsContractCompat.FontInfo[]!, int);
+  }
+
   @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class TypefaceCompatUtil {
     method public static void closeQuietly(java.io.Closeable!);
     method @RequiresApi(19) public static java.nio.ByteBuffer? copyToDirectBuffer(android.content.Context!, android.content.res.Resources!, int);
diff --git a/core/api/restricted_1.1.0-alpha06.txt b/core/api/restricted_1.1.0-alpha06.txt
index 9e62cfa..29a13a1 100644
--- a/core/api/restricted_1.1.0-alpha06.txt
+++ b/core/api/restricted_1.1.0-alpha06.txt
@@ -101,6 +101,9 @@
     field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public CharSequence! mTitle;
   }
 
+  @IntDef({androidx.core.app.RemoteInput.EDIT_CHOICES_BEFORE_SENDING_AUTO, androidx.core.app.RemoteInput.EDIT_CHOICES_BEFORE_SENDING_DISABLED, androidx.core.app.RemoteInput.EDIT_CHOICES_BEFORE_SENDING_ENABLED}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface RemoteInput.EditChoicesBeforeSending {
+  }
+
   @IntDef({androidx.core.app.RemoteInput.SOURCE_FREE_FORM_INPUT, androidx.core.app.RemoteInput.SOURCE_CHOICE}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface RemoteInput.Source {
   }
 
@@ -229,6 +232,10 @@
 
 package androidx.core.graphics {
 
+  public final class Insets {
+    method @RequiresApi(api=29) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static androidx.core.graphics.Insets wrap(android.graphics.Insets);
+  }
+
   public class TypefaceCompat {
     method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static android.graphics.Typeface? createFromFontInfo(android.content.Context, android.os.CancellationSignal?, androidx.core.provider.FontsContractCompat.FontInfo[], int);
     method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static android.graphics.Typeface? createFromResourcesFamilyXml(android.content.Context, androidx.core.content.res.FontResourcesParserCompat.FamilyResourceEntry, android.content.res.Resources, int, int, androidx.core.content.res.ResourcesCompat.FontCallback?, android.os.Handler?, boolean);
@@ -265,6 +272,15 @@
     method public android.graphics.Typeface? createFromResourcesFontFile(android.content.Context!, android.content.res.Resources!, int, String!, int);
   }
 
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) @RequiresApi(29) public class TypefaceCompatApi29Impl {
+    ctor public TypefaceCompatApi29Impl();
+    method public android.graphics.Typeface? createFromFontFamilyFilesResourceEntry(android.content.Context!, androidx.core.content.res.FontResourcesParserCompat.FontFamilyFilesResourceEntry!, android.content.res.Resources!, int);
+    method public android.graphics.Typeface? createFromFontInfo(android.content.Context!, android.os.CancellationSignal?, androidx.core.provider.FontsContractCompat.FontInfo[], int);
+    method protected android.graphics.Typeface! createFromInputStream(android.content.Context!, java.io.InputStream!);
+    method public android.graphics.Typeface? createFromResourcesFontFile(android.content.Context!, android.content.res.Resources!, int, String!, int);
+    method protected androidx.core.provider.FontsContractCompat.FontInfo! findBestInfo(androidx.core.provider.FontsContractCompat.FontInfo[]!, int);
+  }
+
   @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class TypefaceCompatUtil {
     method public static void closeQuietly(java.io.Closeable!);
     method @RequiresApi(19) public static java.nio.ByteBuffer? copyToDirectBuffer(android.content.Context!, android.content.res.Resources!, int);
diff --git a/core/api/restricted_current.txt b/core/api/restricted_current.txt
index 9e62cfa..29a13a1 100644
--- a/core/api/restricted_current.txt
+++ b/core/api/restricted_current.txt
@@ -101,6 +101,9 @@
     field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public CharSequence! mTitle;
   }
 
+  @IntDef({androidx.core.app.RemoteInput.EDIT_CHOICES_BEFORE_SENDING_AUTO, androidx.core.app.RemoteInput.EDIT_CHOICES_BEFORE_SENDING_DISABLED, androidx.core.app.RemoteInput.EDIT_CHOICES_BEFORE_SENDING_ENABLED}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface RemoteInput.EditChoicesBeforeSending {
+  }
+
   @IntDef({androidx.core.app.RemoteInput.SOURCE_FREE_FORM_INPUT, androidx.core.app.RemoteInput.SOURCE_CHOICE}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface RemoteInput.Source {
   }
 
@@ -229,6 +232,10 @@
 
 package androidx.core.graphics {
 
+  public final class Insets {
+    method @RequiresApi(api=29) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static androidx.core.graphics.Insets wrap(android.graphics.Insets);
+  }
+
   public class TypefaceCompat {
     method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static android.graphics.Typeface? createFromFontInfo(android.content.Context, android.os.CancellationSignal?, androidx.core.provider.FontsContractCompat.FontInfo[], int);
     method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static android.graphics.Typeface? createFromResourcesFamilyXml(android.content.Context, androidx.core.content.res.FontResourcesParserCompat.FamilyResourceEntry, android.content.res.Resources, int, int, androidx.core.content.res.ResourcesCompat.FontCallback?, android.os.Handler?, boolean);
@@ -265,6 +272,15 @@
     method public android.graphics.Typeface? createFromResourcesFontFile(android.content.Context!, android.content.res.Resources!, int, String!, int);
   }
 
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) @RequiresApi(29) public class TypefaceCompatApi29Impl {
+    ctor public TypefaceCompatApi29Impl();
+    method public android.graphics.Typeface? createFromFontFamilyFilesResourceEntry(android.content.Context!, androidx.core.content.res.FontResourcesParserCompat.FontFamilyFilesResourceEntry!, android.content.res.Resources!, int);
+    method public android.graphics.Typeface? createFromFontInfo(android.content.Context!, android.os.CancellationSignal?, androidx.core.provider.FontsContractCompat.FontInfo[], int);
+    method protected android.graphics.Typeface! createFromInputStream(android.content.Context!, java.io.InputStream!);
+    method public android.graphics.Typeface? createFromResourcesFontFile(android.content.Context!, android.content.res.Resources!, int, String!, int);
+    method protected androidx.core.provider.FontsContractCompat.FontInfo! findBestInfo(androidx.core.provider.FontsContractCompat.FontInfo[]!, int);
+  }
+
   @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class TypefaceCompatUtil {
     method public static void closeQuietly(java.io.Closeable!);
     method @RequiresApi(19) public static java.nio.ByteBuffer? copyToDirectBuffer(android.content.Context!, android.content.res.Resources!, int);
diff --git a/core/ktx/api/1.1.0-alpha06.txt b/core/ktx/api/1.1.0-alpha06.txt
index 63739d2..66891d2 100644
--- a/core/ktx/api/1.1.0-alpha06.txt
+++ b/core/ktx/api/1.1.0-alpha06.txt
@@ -169,6 +169,12 @@
     method public static inline float[] values(android.graphics.Matrix);
   }
 
+  public final class PaintKt {
+    ctor public PaintKt();
+    method public static inline void setBlendMode(android.graphics.Paint, androidx.core.graphics.BlendModeCompat? blendModeCompat);
+    method public static inline void setBlendModeColorFilter(android.graphics.Paint, @ColorInt int color, androidx.core.graphics.BlendModeCompat? blendModeCompat);
+  }
+
   public final class PathKt {
     ctor public PathKt();
     method @RequiresApi(19) public static inline infix android.graphics.Path and(android.graphics.Path, android.graphics.Path p);
diff --git a/core/ktx/api/current.txt b/core/ktx/api/current.txt
index 63739d2..66891d2 100644
--- a/core/ktx/api/current.txt
+++ b/core/ktx/api/current.txt
@@ -169,6 +169,12 @@
     method public static inline float[] values(android.graphics.Matrix);
   }
 
+  public final class PaintKt {
+    ctor public PaintKt();
+    method public static inline void setBlendMode(android.graphics.Paint, androidx.core.graphics.BlendModeCompat? blendModeCompat);
+    method public static inline void setBlendModeColorFilter(android.graphics.Paint, @ColorInt int color, androidx.core.graphics.BlendModeCompat? blendModeCompat);
+  }
+
   public final class PathKt {
     ctor public PathKt();
     method @RequiresApi(19) public static inline infix android.graphics.Path and(android.graphics.Path, android.graphics.Path p);
diff --git a/core/ktx/src/main/java/androidx/core/graphics/Paint.kt b/core/ktx/src/main/java/androidx/core/graphics/Paint.kt
new file mode 100644
index 0000000..363b850
--- /dev/null
+++ b/core/ktx/src/main/java/androidx/core/graphics/Paint.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.core.graphics
+
+import android.graphics.Paint
+import androidx.annotation.ColorInt
+
+/**
+ * Convenience method to configure the BlendMode of a Paint in a backward
+ * compatible way. This method is a no-op for BlendModes that have no equivalent
+ * on older API levels
+ */
+inline fun Paint.setBlendMode(blendModeCompat: BlendModeCompat?) {
+    PaintCompat.setBlendMode(this, blendModeCompat)
+}
+
+/**
+ * Convenience method to configure the BlendModeColorFilter of a Paint in a backward
+ * compatible way. This method falls back on PorterDuffColorFilter for API levels that
+ * do not support BlendModeColorFilter. This method is a no-op if the BlendMode provided is
+ * not supported on a given API level.
+ *
+ * Passing in null for the BlendModeCompat parameter will remove the previously configured
+ * ColorFilter on the Paint
+ */
+inline fun Paint.setBlendModeColorFilter(
+    @ColorInt color: Int,
+    blendModeCompat: BlendModeCompat?
+) {
+    PaintCompat.setBlendModeColorFilter(this, color, blendModeCompat)
+}
\ No newline at end of file
diff --git a/core/src/androidTest/java/androidx/core/app/NotificationCompatTest.java b/core/src/androidTest/java/androidx/core/app/NotificationCompatTest.java
index 049199c..ba4ae77 100644
--- a/core/src/androidTest/java/androidx/core/app/NotificationCompatTest.java
+++ b/core/src/androidTest/java/androidx/core/app/NotificationCompatTest.java
@@ -35,7 +35,9 @@
 import android.app.Notification;
 import android.app.NotificationChannel;
 import android.app.NotificationManager;
+import android.app.PendingIntent;
 import android.content.Context;
+import android.content.Intent;
 import android.graphics.BitmapFactory;
 import android.graphics.Color;
 import android.media.AudioAttributes;
@@ -48,6 +50,7 @@
 import androidx.core.R;
 import androidx.core.app.NotificationCompat.MessagingStyle.Message;
 import androidx.core.graphics.drawable.IconCompat;
+import androidx.core.os.BuildCompat;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SdkSuppress;
 import androidx.test.filters.SmallTest;
@@ -173,7 +176,8 @@
     @Test
     public void testNotificationActionBuilder_copiesRemoteInputs() throws Throwable {
         NotificationCompat.Action a = newActionBuilder()
-                .addRemoteInput(new RemoteInput("a", "b", null, false, null, null)).build();
+                .addRemoteInput(new RemoteInput("a", "b", null, false,
+                        RemoteInput.EDIT_CHOICES_BEFORE_SENDING_AUTO, null, null)).build();
 
         NotificationCompat.Action aCopy = new NotificationCompat.Action.Builder(a).build();
 
@@ -945,6 +949,76 @@
         assertEquals("example title", NotificationCompat.getContentTitle(notification));
     }
 
+    @Test
+    public void action_builder_defaultNotContextual() {
+        NotificationCompat.Action action =
+                new NotificationCompat.Action.Builder(0, "Test Title", null)
+                        .build();
+        assertFalse(action.isContextual());
+    }
+
+    @Test
+    public void action_builder_setContextual() {
+        // Without a PendingIntent the Action.Builder class throws an NPE when building a contextual
+        // action.
+        PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(), 0);
+        NotificationCompat.Action action =
+                new NotificationCompat.Action.Builder(0, "Test Title", pendingIntent)
+                        .setContextual(true)
+                        .build();
+        assertTrue(action.isContextual());
+    }
+
+    @Test
+    public void action_builder_contextual_invalidIntentCausesNpe() {
+        NotificationCompat.Action.Builder builder =
+                new NotificationCompat.Action.Builder(0, "Test Title", null)
+                        .setContextual(true);
+        try {
+            builder.build();
+            fail("Creating a contextual Action with a null PendingIntent should cause a "
+                    + " NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 28) // TODO(gsennton): this test only applies to Q+ devices.
+    public void action_contextual_toAndFromNotification() {
+        if (!BuildCompat.isAtLeastQ()) return;
+        // Without a PendingIntent the Action.Builder class throws an NPE when building a contextual
+        // action.
+        PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(), 0);
+        NotificationCompat.Action action =
+                new NotificationCompat.Action.Builder(0, "Test Title", pendingIntent)
+                        .setContextual(true)
+                        .build();
+        Notification notification = newNotificationBuilder().addAction(action).build();
+        NotificationCompat.Action result = NotificationCompat.getAction(notification, 0);
+
+        assertTrue(result.isContextual());
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.P) // TODO(gsennton): This only works on Q+
+    public void getAllowSystemGeneratedContextualActions_trueByDefault() {
+        if (!BuildCompat.isAtLeastQ()) return;
+        Notification notification =
+                new NotificationCompat.Builder(mContext, "test channel").build();
+        assertTrue(NotificationCompat.getAllowSystemGeneratedContextualActions(notification));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.P) // TODO(gsennton): This only works on Q+
+    public void getAllowSystemGeneratedContextualActions() {
+        if (!BuildCompat.isAtLeastQ()) return;
+        Notification notification = new NotificationCompat.Builder(mContext, "test channel")
+                .setAllowSystemGeneratedContextualActions(false)
+                .build();
+        assertFalse(NotificationCompat.getAllowSystemGeneratedContextualActions(notification));
+    }
+
     // Add the @Test annotation to enable this test. This test is disabled by default as it's not a
     // unit test. This will simply create 4 MessagingStyle notifications so a developer may see what
     // the end result will look like on a physical device (or emulator).
diff --git a/core/src/androidTest/java/androidx/core/app/RemoteInputTest.java b/core/src/androidTest/java/androidx/core/app/RemoteInputTest.java
index 16004b1..0a15761 100644
--- a/core/src/androidTest/java/androidx/core/app/RemoteInputTest.java
+++ b/core/src/androidTest/java/androidx/core/app/RemoteInputTest.java
@@ -20,6 +20,7 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 import android.content.Intent;
 import android.net.Uri;
@@ -53,6 +54,8 @@
         assertTrue(input.isDataOnly());
         assertFalse(input.getAllowFreeFormInput());
         assertTrue(input.getChoices() == null || input.getChoices().length == 0);
+        assertEquals(RemoteInput.EDIT_CHOICES_BEFORE_SENDING_AUTO,
+                input.getEditChoicesBeforeSending());
         assertEquals(1, input.getAllowedDataTypes().size());
         assertTrue(input.getAllowedDataTypes().contains(MIME_TYPE));
     }
@@ -64,6 +67,8 @@
         assertFalse(input.isDataOnly());
         assertTrue(input.getAllowFreeFormInput());
         assertTrue(input.getChoices() == null || input.getChoices().length == 0);
+        assertEquals(RemoteInput.EDIT_CHOICES_BEFORE_SENDING_AUTO,
+                input.getEditChoicesBeforeSending());
         assertTrue(input.getAllowedDataTypes() == null || input.getAllowedDataTypes().isEmpty());
     }
 
@@ -74,6 +79,8 @@
         assertFalse(input.isDataOnly());
         assertFalse(input.getAllowFreeFormInput());
         assertTrue(input.getChoices() != null && input.getChoices().length > 0);
+        assertEquals(RemoteInput.EDIT_CHOICES_BEFORE_SENDING_AUTO,
+                input.getEditChoicesBeforeSending());
         assertTrue(input.getAllowedDataTypes() == null || input.getAllowedDataTypes().isEmpty());
     }
 
@@ -91,10 +98,38 @@
         assertFalse(input.isDataOnly());
         assertTrue(input.getAllowFreeFormInput());
         assertTrue(input.getChoices() != null && input.getChoices().length > 0);
+        assertEquals(RemoteInput.EDIT_CHOICES_BEFORE_SENDING_AUTO,
+                input.getEditChoicesBeforeSending());
         assertEquals(1, input.getAllowedDataTypes().size());
         assertTrue(input.getAllowedDataTypes().contains(MIME_TYPE));
     }
 
+    public void testRemoteInputBuilder_setEditChoicesBeforeSending() throws Throwable {
+        RemoteInput input =
+                new RemoteInput.Builder(RESULT_KEY)
+                        .setChoices(new CharSequence[]{"first", "second"})
+                        .setEditChoicesBeforeSending(
+                                RemoteInput.EDIT_CHOICES_BEFORE_SENDING_ENABLED)
+                        .build();
+        assertEquals(RemoteInput.EDIT_CHOICES_BEFORE_SENDING_ENABLED,
+                input.getEditChoicesBeforeSending());
+    }
+
+    public void testRemoteInputBuilder_setEditChoicesBeforeSendingRequiresFreeInput()
+            throws Throwable {
+        RemoteInput.Builder builder =
+                new RemoteInput.Builder(RESULT_KEY)
+                        .setEditChoicesBeforeSending(
+                                RemoteInput.EDIT_CHOICES_BEFORE_SENDING_ENABLED)
+                        .setAllowFreeFormInput(false);
+        try {
+            builder.build();
+            fail();
+        } catch (IllegalArgumentException e) {
+            // expected.
+        }
+    }
+
     @SdkSuppress(minSdkVersion = 17)
     @Test
     public void testRemoteInputBuilder_addAndGetDataResultsFromIntent() throws Throwable {
diff --git a/core/src/androidTest/java/androidx/core/graphics/PaintTest.java b/core/src/androidTest/java/androidx/core/graphics/PaintTest.java
new file mode 100644
index 0000000..10115fa
--- /dev/null
+++ b/core/src/androidTest/java/androidx/core/graphics/PaintTest.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.core.graphics;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import android.graphics.BlendMode;
+import android.graphics.BlendModeColorFilter;
+import android.graphics.Color;
+import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
+import android.graphics.PorterDuffXfermode;
+import android.graphics.Xfermode;
+import android.os.Build;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class PaintTest {
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.Q)
+    public void testBlendModeCompatMatchesPlatform() {
+        TestHelper.verifyBlendModeMatchesCompat(BlendModeCompat.CLEAR, BlendMode.CLEAR);
+        TestHelper.verifyBlendModeMatchesCompat(BlendModeCompat.SRC, BlendMode.SRC);
+        TestHelper.verifyBlendModeMatchesCompat(BlendModeCompat.DST, BlendMode.DST);
+        TestHelper.verifyBlendModeMatchesCompat(BlendModeCompat.SRC_OVER, BlendMode.SRC_OVER);
+        TestHelper.verifyBlendModeMatchesCompat(BlendModeCompat.DST_OVER, BlendMode.DST_OVER);
+        TestHelper.verifyBlendModeMatchesCompat(BlendModeCompat.SRC_IN, BlendMode.SRC_IN);
+        TestHelper.verifyBlendModeMatchesCompat(BlendModeCompat.DST_IN, BlendMode.DST_IN);
+        TestHelper.verifyBlendModeMatchesCompat(BlendModeCompat.SRC_OUT, BlendMode.SRC_OUT);
+        TestHelper.verifyBlendModeMatchesCompat(BlendModeCompat.DST_OUT, BlendMode.DST_OUT);
+        TestHelper.verifyBlendModeMatchesCompat(BlendModeCompat.SRC_ATOP, BlendMode.SRC_ATOP);
+        TestHelper.verifyBlendModeMatchesCompat(BlendModeCompat.DST_ATOP, BlendMode.DST_ATOP);
+        TestHelper.verifyBlendModeMatchesCompat(BlendModeCompat.XOR, BlendMode.XOR);
+        TestHelper.verifyBlendModeMatchesCompat(BlendModeCompat.PLUS, BlendMode.PLUS);
+        TestHelper.verifyBlendModeMatchesCompat(BlendModeCompat.MODULATE, BlendMode.MODULATE);
+        TestHelper.verifyBlendModeMatchesCompat(BlendModeCompat.SCREEN, BlendMode.SCREEN);
+        TestHelper.verifyBlendModeMatchesCompat(BlendModeCompat.OVERLAY, BlendMode.OVERLAY);
+        TestHelper.verifyBlendModeMatchesCompat(BlendModeCompat.DARKEN, BlendMode.DARKEN);
+        TestHelper.verifyBlendModeMatchesCompat(BlendModeCompat.LIGHTEN, BlendMode.LIGHTEN);
+        TestHelper.verifyBlendModeMatchesCompat(BlendModeCompat.COLOR_DODGE, BlendMode.COLOR_DODGE);
+        TestHelper.verifyBlendModeMatchesCompat(BlendModeCompat.COLOR_BURN, BlendMode.COLOR_BURN);
+        TestHelper.verifyBlendModeMatchesCompat(BlendModeCompat.HARD_LIGHT, BlendMode.HARD_LIGHT);
+        TestHelper.verifyBlendModeMatchesCompat(BlendModeCompat.SOFT_LIGHT, BlendMode.SOFT_LIGHT);
+        TestHelper.verifyBlendModeMatchesCompat(BlendModeCompat.DIFFERENCE, BlendMode.DIFFERENCE);
+        TestHelper.verifyBlendModeMatchesCompat(BlendModeCompat.EXCLUSION, BlendMode.EXCLUSION);
+        TestHelper.verifyBlendModeMatchesCompat(BlendModeCompat.MULTIPLY, BlendMode.MULTIPLY);
+        TestHelper.verifyBlendModeMatchesCompat(BlendModeCompat.HUE, BlendMode.HUE);
+        TestHelper.verifyBlendModeMatchesCompat(BlendModeCompat.SATURATION, BlendMode.SATURATION);
+        TestHelper.verifyBlendModeMatchesCompat(BlendModeCompat.COLOR, BlendMode.COLOR);
+        TestHelper.verifyBlendModeMatchesCompat(BlendModeCompat.LUMINOSITY, BlendMode.LUMINOSITY);
+    }
+
+    @Test
+    @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.P)
+    public void testBlendModeCompatMatchesPorterDuff() {
+        verifyPorterDuffMatchesCompat(BlendModeCompat.CLEAR, PorterDuff.Mode.CLEAR);
+        verifyPorterDuffMatchesCompat(BlendModeCompat.SRC, PorterDuff.Mode.SRC);
+        verifyPorterDuffMatchesCompat(BlendModeCompat.DST, PorterDuff.Mode.DST);
+        verifyPorterDuffMatchesCompat(BlendModeCompat.SRC_OVER, PorterDuff.Mode.SRC_OVER);
+        verifyPorterDuffMatchesCompat(BlendModeCompat.DST_OVER, PorterDuff.Mode.DST_OVER);
+        verifyPorterDuffMatchesCompat(BlendModeCompat.SRC_IN, PorterDuff.Mode.SRC_IN);
+        verifyPorterDuffMatchesCompat(BlendModeCompat.DST_IN, PorterDuff.Mode.DST_IN);
+        verifyPorterDuffMatchesCompat(BlendModeCompat.SRC_OUT, PorterDuff.Mode.SRC_OUT);
+        verifyPorterDuffMatchesCompat(BlendModeCompat.DST_OUT, PorterDuff.Mode.DST_OUT);
+        verifyPorterDuffMatchesCompat(BlendModeCompat.SRC_ATOP, PorterDuff.Mode.SRC_ATOP);
+        verifyPorterDuffMatchesCompat(BlendModeCompat.DST_ATOP, PorterDuff.Mode.DST_ATOP);
+        verifyPorterDuffMatchesCompat(BlendModeCompat.XOR, PorterDuff.Mode.XOR);
+        verifyPorterDuffMatchesCompat(BlendModeCompat.PLUS, PorterDuff.Mode.ADD);
+        // b/73224934 PorterDuff Multiply maps to Skia Modulate
+        verifyPorterDuffMatchesCompat(BlendModeCompat.MODULATE, PorterDuff.Mode.MULTIPLY);
+        verifyPorterDuffMatchesCompat(BlendModeCompat.SCREEN, PorterDuff.Mode.SCREEN);
+        verifyPorterDuffMatchesCompat(BlendModeCompat.OVERLAY, PorterDuff.Mode.OVERLAY);
+        verifyPorterDuffMatchesCompat(BlendModeCompat.DARKEN, PorterDuff.Mode.DARKEN);
+        verifyPorterDuffMatchesCompat(BlendModeCompat.LIGHTEN, PorterDuff.Mode.LIGHTEN);
+        // Not supported before Q
+        verifyPorterDuffMatchesCompat(BlendModeCompat.COLOR_DODGE, null);
+        verifyPorterDuffMatchesCompat(BlendModeCompat.COLOR_BURN, null);
+        verifyPorterDuffMatchesCompat(BlendModeCompat.HARD_LIGHT, null);
+        verifyPorterDuffMatchesCompat(BlendModeCompat.SOFT_LIGHT, null);
+        verifyPorterDuffMatchesCompat(BlendModeCompat.DIFFERENCE, null);
+        verifyPorterDuffMatchesCompat(BlendModeCompat.EXCLUSION, null);
+        // Technically BlendMode.MULTIPLY should map to PorterDuff.Mode.MULTIPLY
+        // However b/73224934 PorterDuff Multiply maps to Skia Modulate
+        verifyPorterDuffMatchesCompat(BlendModeCompat.MULTIPLY, null);
+        verifyPorterDuffMatchesCompat(BlendModeCompat.HUE, null);
+        verifyPorterDuffMatchesCompat(BlendModeCompat.SATURATION, null);
+        verifyPorterDuffMatchesCompat(BlendModeCompat.COLOR, null);
+        verifyPorterDuffMatchesCompat(BlendModeCompat.LUMINOSITY, null);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.Q)
+    public void testNullBlendModeRemovesBlendModeColorFilter() {
+        Paint p = new Paint();
+        PaintCompat.setBlendModeColorFilter(p, Color.RED, BlendModeCompat.CLEAR);
+        ColorFilter filter = p.getColorFilter();
+        assertTrue(filter instanceof BlendModeColorFilter);
+
+        PaintCompat.setBlendModeColorFilter(p, 0, null);
+        assertNull(p.getColorFilter());
+    }
+
+    @Test
+    @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.P)
+    public void testNullBlendModeRemovesPorterDuffColorFilter() {
+        Paint p = new Paint();
+        PaintCompat.setBlendModeColorFilter(p, Color.RED, BlendModeCompat.CLEAR);
+        ColorFilter filter = p.getColorFilter();
+        assertTrue(filter instanceof PorterDuffColorFilter);
+
+        PaintCompat.setBlendModeColorFilter(p, 0, null);
+        assertNull(p.getColorFilter());
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.Q)
+    public void testNullBlendModeRemovesBlendMode() {
+        Paint p = new Paint();
+        PaintCompat.setBlendMode(p, BlendModeCompat.CLEAR);
+        assertEquals(BlendMode.CLEAR, p.getBlendMode());
+
+        PaintCompat.setBlendMode(p, null);
+        assertNull(p.getBlendMode());
+    }
+
+
+    @Test
+    @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.P)
+    public void testNullBlendModeRemovesXfermode() {
+        Paint p = new Paint();
+        PaintCompat.setBlendMode(p, BlendModeCompat.CLEAR);
+        verifyPorterDuffMatchesCompat(BlendModeCompat.CLEAR, PorterDuff.Mode.CLEAR);
+
+        verifyPorterDuffMatchesCompat(null, null);
+    }
+
+    /**
+     * Helper test class to hide usages of new APIs and avoid ClassNotFoundExceptions
+     * in tests
+     */
+    private static class TestHelper {
+        private static void verifyBlendModeMatchesCompat(@NonNull BlendModeCompat compat,
+                                                         @NonNull BlendMode blendMode) {
+            Paint p = new Paint();
+            PaintCompat.setBlendMode(p, compat);
+            assertEquals(blendMode, p.getBlendMode());
+        }
+    }
+
+    /**
+     * Helper method to verify that the provided {@link BlendModeCompat} instance
+     * matches the given {@link PorterDuff.Mode} which may be null if there is no
+     * equivalent PorterDuff.Mode for the BlendMode
+     */
+    private void verifyPorterDuffMatchesCompat(@Nullable BlendModeCompat compat,
+                                               @Nullable PorterDuff.Mode mode) {
+        Paint p = new Paint();
+        PaintCompat.setBlendMode(p, compat);
+        // Fields on PorterDuffXfermode are private, so verify the mapping helper method is correct
+        // and the resultant Xfermode returned from Paint#getXfermode is an instance of
+        // PorterDuffXferMode
+        Xfermode xfermode = p.getXfermode();
+        assertEquals(mode, PaintCompat.obtainPorterDuffFromCompat(compat));
+        if (mode != null) {
+            assertTrue(xfermode instanceof PorterDuffXfermode);
+        } else {
+            assertNull(xfermode);
+        }
+    }
+}
diff --git a/core/src/androidTest/java/androidx/core/view/ViewCompatTest.java b/core/src/androidTest/java/androidx/core/view/ViewCompatTest.java
index 1a70d65..e1bc913 100644
--- a/core/src/androidTest/java/androidx/core/view/ViewCompatTest.java
+++ b/core/src/androidTest/java/androidx/core/view/ViewCompatTest.java
@@ -30,11 +30,13 @@
 
 import android.app.Activity;
 import android.content.Context;
+import android.graphics.Rect;
 import android.support.v4.BaseInstrumentationTestCase;
 import android.view.Display;
 import android.view.View;
 
 import androidx.annotation.Nullable;
+import androidx.core.os.BuildCompat;
 import androidx.core.test.R;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.LargeTest;
@@ -44,7 +46,9 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.ArrayList;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 
 @RunWith(AndroidJUnit4.class)
@@ -241,6 +245,24 @@
         ViewCompat.requireViewById(container, View.NO_ID);
     }
 
+    @Test
+    public void testSystemGestureExclusionRects() {
+        final View container = mActivityTestRule.getActivity().findViewById(R.id.container);
+
+        final List<Rect> expected = new ArrayList<>();
+        expected.add(new Rect(0, 0, 25, 25));
+        final List<Rect> rects = new ArrayList<>(expected);
+
+        ViewCompat.setSystemGestureExclusionRects(container, rects);
+        final List<Rect> returnedRects = ViewCompat.getSystemGestureExclusionRects(container);
+
+        if (BuildCompat.isAtLeastQ()) {
+            assertEquals("round trip for expected rects", expected, returnedRects);
+        } else {
+            assertTrue("empty list for old device", returnedRects.isEmpty());
+        }
+    }
+
     private static boolean isViewIdGenerated(int id) {
         return (id & 0xFF000000) == 0 && (id & 0x00FFFFFF) != 0;
     }
diff --git a/core/src/androidTest/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompatTest.java b/core/src/androidTest/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompatTest.java
index 6b7746e..17ca4c0 100644
--- a/core/src/androidTest/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompatTest.java
+++ b/core/src/androidTest/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompatTest.java
@@ -17,13 +17,19 @@
 package androidx.core.view.accessibility;
 
 import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
 import static org.hamcrest.core.IsEqual.equalTo;
 import static org.junit.Assert.assertThat;
 
+import android.graphics.Region;
 import android.os.Build;
+import android.view.View;
 import android.view.accessibility.AccessibilityNodeInfo;
 
+import androidx.core.os.BuildCompat;
 import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat;
+import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.TouchDelegateInfoCompat;
+import androidx.test.InstrumentationRegistry;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SdkSuppress;
 import androidx.test.filters.SmallTest;
@@ -32,6 +38,9 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.HashMap;
+import java.util.Map;
+
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class AccessibilityNodeInfoCompatTest {
@@ -107,6 +116,16 @@
 
     @SdkSuppress(minSdkVersion = 19)
     @Test
+    public void testGetSetTextEntryKey() {
+        AccessibilityNodeInfoCompat nodeCompat = obtainedWrappedNodeCompat();
+        nodeCompat.setTextEntryKey(true);
+        assertThat(nodeCompat.isTextEntryKey(), is(true));
+        nodeCompat.setTextEntryKey(false);
+        assertThat(nodeCompat.isTextEntryKey(), is(false));
+    }
+
+    @SdkSuppress(minSdkVersion = 19)
+    @Test
     public void testAccessibilityActionsNotNull() {
         try {
             AccessibilityActionCompat actionCompat;
@@ -148,6 +167,30 @@
         }
     }
 
+    @Test
+    public void testTouchDelegateInfo() {
+        final Map<Region, View> targetMap = new HashMap<>(1);
+        final Region region = new Region(1, 1, 10, 10);
+        targetMap.put(region, new View(InstrumentationRegistry.getContext()));
+        final TouchDelegateInfoCompat delegateInfo = new TouchDelegateInfoCompat(targetMap);
+        final AccessibilityNodeInfoCompat accessibilityNodeInfoCompat =
+                obtainedWrappedNodeCompat();
+        accessibilityNodeInfoCompat.setTouchDelegateInfo(delegateInfo);
+        final TouchDelegateInfoCompat touchDelegateInfoResult =
+                accessibilityNodeInfoCompat.getTouchDelegateInfo();
+        if (BuildCompat.isAtLeastQ()) {
+            assertThat(touchDelegateInfoResult.getRegionCount(), is(1));
+            assertThat(touchDelegateInfoResult.getRegionAt(0), is(region));
+            // getTargetForRegion return null, since we are not a11y service
+            assertThat(touchDelegateInfoResult.getTargetForRegion(region), is(nullValue()));
+        } else {
+            assertThat(touchDelegateInfoResult, is(nullValue()));
+            assertThat(delegateInfo.getRegionCount(), is(0));
+            assertThat(delegateInfo.getRegionAt(0), is(nullValue()));
+            assertThat(delegateInfo.getTargetForRegion(region), is(nullValue()));
+        }
+    }
+
     private AccessibilityNodeInfoCompat obtainedWrappedNodeCompat() {
         AccessibilityNodeInfo accessibilityNodeInfo = AccessibilityNodeInfo.obtain();
         return AccessibilityNodeInfoCompat.wrap(accessibilityNodeInfo);
diff --git a/core/src/main/java/androidx/core/app/NotificationCompat.java b/core/src/main/java/androidx/core/app/NotificationCompat.java
index 17053d9..35548ee 100644
--- a/core/src/main/java/androidx/core/app/NotificationCompat.java
+++ b/core/src/main/java/androidx/core/app/NotificationCompat.java
@@ -56,6 +56,7 @@
 import androidx.annotation.RequiresApi;
 import androidx.annotation.RestrictTo;
 import androidx.core.R;
+import androidx.core.os.BuildCompat;
 import androidx.core.text.BidiFormatter;
 import androidx.core.view.GravityCompat;
 
@@ -715,6 +716,7 @@
         String mShortcutId;
         long mTimeout;
         @GroupAlertBehavior int mGroupAlertBehavior = GROUP_ALERT_ALL;
+        boolean mAllowSystemGeneratedContextualActions;
         Notification mNotification = new Notification();
 
         /**
@@ -745,6 +747,7 @@
             mNotification.audioStreamType = Notification.STREAM_DEFAULT;
             mPriority = PRIORITY_DEFAULT;
             mPeople = new ArrayList<String>();
+            mAllowSystemGeneratedContextualActions = true;
         }
 
         /**
@@ -1575,6 +1578,16 @@
         }
 
         /**
+         * Determines whether the platform can generate contextual actions for a notification.
+         * By default this is true.
+         */
+        @NonNull
+        public Builder setAllowSystemGeneratedContextualActions(boolean allowed) {
+            mAllowSystemGeneratedContextualActions = allowed;
+            return this;
+        }
+
+        /**
          * @deprecated Use {@link #build()} instead.
          */
         @Deprecated
@@ -3013,12 +3026,19 @@
                     R.layout.notification_template_custom_big, false /* fitIn1U */);
             remoteViews.removeAllViews(R.id.actions);
             boolean actionsVisible = false;
-            if (showActions && mBuilder.mActions != null) {
-                int numActions = Math.min(mBuilder.mActions.size(), MAX_ACTION_BUTTONS);
+
+            // In the UI contextual actions appear separately from the standard actions, so we
+            // filter them out here.
+            List<NotificationCompat.Action> nonContextualActions =
+                    getNonContextualActions(mBuilder.mActions);
+
+            if (showActions && nonContextualActions != null) {
+                int numActions = Math.min(nonContextualActions.size(), MAX_ACTION_BUTTONS);
                 if (numActions > 0) {
                     actionsVisible = true;
                     for (int i = 0; i < numActions; i++) {
-                        final RemoteViews button = generateActionButton(mBuilder.mActions.get(i));
+                        final RemoteViews button =
+                                generateActionButton(nonContextualActions.get(i));
                         remoteViews.addView(R.id.actions, button);
                     }
                 }
@@ -3030,6 +3050,18 @@
             return remoteViews;
         }
 
+        private static List<NotificationCompat.Action> getNonContextualActions(
+                List<NotificationCompat.Action> actions) {
+            if (actions == null) return null;
+            List<NotificationCompat.Action> nonContextualActions = new ArrayList<>();
+            for (NotificationCompat.Action action : actions) {
+                if (!action.isContextual()) {
+                    nonContextualActions.add(action);
+                }
+            }
+            return nonContextualActions;
+        }
+
         private RemoteViews generateActionButton(NotificationCompat.Action action) {
             final boolean tombstone = (action.actionIntent == null);
             RemoteViews button = new RemoteViews(mBuilder.mContext.getPackageName(),
@@ -3143,6 +3175,7 @@
         boolean mShowsUserInterface = true;
 
         private final @SemanticAction int mSemanticAction;
+        private final boolean mIsContextual;
 
         /**
          * Small icon representing the action.
@@ -3159,13 +3192,14 @@
         public PendingIntent actionIntent;
 
         public Action(int icon, CharSequence title, PendingIntent intent) {
-            this(icon, title, intent, new Bundle(), null, null, true, SEMANTIC_ACTION_NONE, true);
+            this(icon, title, intent, new Bundle(), null, null, true, SEMANTIC_ACTION_NONE, true,
+                false /* isContextual */);
         }
 
         Action(int icon, CharSequence title, PendingIntent intent, Bundle extras,
                 RemoteInput[] remoteInputs, RemoteInput[] dataOnlyRemoteInputs,
                 boolean allowGeneratedReplies, @SemanticAction int semanticAction,
-                boolean showsUserInterface) {
+                boolean showsUserInterface, boolean isContextual) {
             this.icon = icon;
             this.title = NotificationCompat.Builder.limitCharSequenceLength(title);
             this.actionIntent = intent;
@@ -3175,6 +3209,7 @@
             this.mAllowGeneratedReplies = allowGeneratedReplies;
             this.mSemanticAction = semanticAction;
             this.mShowsUserInterface = showsUserInterface;
+            this.mIsContextual = isContextual;
         }
 
         public int getIcon() {
@@ -3225,6 +3260,15 @@
         }
 
         /**
+         * Returns whether this is a contextual Action, i.e. whether the action is dependent on the
+         * notification message body. An example of a contextual action could be an action opening a
+         * map application with an address shown in the notification.
+         */
+        public boolean isContextual() {
+            return mIsContextual;
+        }
+
+        /**
          * Get the list of inputs to be collected from the user that ONLY accept data when this
          * action is sent. These remote inputs are guaranteed to return true on a call to
          * {@link RemoteInput#isDataOnly}.
@@ -3258,6 +3302,7 @@
             private ArrayList<RemoteInput> mRemoteInputs;
             private @SemanticAction int mSemanticAction;
             private boolean mShowsUserInterface = true;
+            private boolean mIsContextual;
 
             /**
              * Construct a new builder for {@link Action} object.
@@ -3266,7 +3311,8 @@
              * @param intent the {@link PendingIntent} to fire when users trigger this action
              */
             public Builder(int icon, CharSequence title, PendingIntent intent) {
-                this(icon, title, intent, new Bundle(), null, true, SEMANTIC_ACTION_NONE, true);
+                this(icon, title, intent, new Bundle(), null, true, SEMANTIC_ACTION_NONE, true,
+                        false /* isContextual */);
             }
 
             /**
@@ -3277,12 +3323,14 @@
             public Builder(Action action) {
                 this(action.icon, action.title, action.actionIntent, new Bundle(action.mExtras),
                         action.getRemoteInputs(), action.getAllowGeneratedReplies(),
-                        action.getSemanticAction(), action.mShowsUserInterface);
+                        action.getSemanticAction(), action.mShowsUserInterface,
+                        action.isContextual());
             }
 
             private Builder(int icon, CharSequence title, PendingIntent intent, Bundle extras,
                     RemoteInput[] remoteInputs, boolean allowGeneratedReplies,
-                    @SemanticAction int semanticAction, boolean showsUserInterface) {
+                    @SemanticAction int semanticAction, boolean showsUserInterface,
+                    boolean isContextual) {
                 mIcon = icon;
                 mTitle = NotificationCompat.Builder.limitCharSequenceLength(title);
                 mIntent = intent;
@@ -3292,6 +3340,7 @@
                 mAllowGeneratedReplies = allowGeneratedReplies;
                 mSemanticAction = semanticAction;
                 mShowsUserInterface = showsUserInterface;
+                mIsContextual = isContextual;
             }
 
             /**
@@ -3360,6 +3409,17 @@
             }
 
             /**
+             * Sets whether this {@link Action} is a contextual action, i.e. whether the action is
+             * dependent on the notification message body. An example of a contextual action could
+             * be an action opening a map application with an address shown in the notification.
+             */
+            @NonNull
+            public Builder setContextual(boolean isContextual) {
+                mIsContextual = isContextual;
+                return this;
+            }
+
+            /**
              * Set whether or not this {@link Action}'s {@link PendingIntent} will open a user
              * interface.
              * @param showsUserInterface {@code true} if this {@link Action}'s {@link PendingIntent}
@@ -3382,11 +3442,28 @@
             }
 
             /**
+             * Throws an NPE if we are building a contextual action missing one of the fields
+             * necessary to display the action.
+             */
+            private void checkContextualActionNullFields() {
+                if (!mIsContextual) return;
+
+                if (mIntent == null) {
+                    throw new NullPointerException(
+                            "Contextual Actions must contain a valid PendingIntent");
+                }
+            }
+
+            /**
              * Combine all of the options that have been set and return a new {@link Action}
              * object.
              * @return the built action
+             * @throws {@ref NullPointerException} if this is a contextual Action and its Intent is
+             * null.
              */
             public Action build() {
+                checkContextualActionNullFields();
+
                 List<RemoteInput> dataOnlyInputs = new ArrayList<>();
                 List<RemoteInput> textInputs = new ArrayList<>();
                 if (mRemoteInputs != null) {
@@ -3404,7 +3481,7 @@
                         ? null : textInputs.toArray(new RemoteInput[textInputs.size()]);
                 return new Action(mIcon, mTitle, mIntent, mExtras, textInputsArr,
                         dataOnlyInputsArr, mAllowGeneratedReplies, mSemanticAction,
-                        mShowsUserInterface);
+                        mShowsUserInterface, mIsContextual);
             }
         }
 
@@ -4795,6 +4872,7 @@
                     remoteInput.getLabel(),
                     remoteInput.getChoices(),
                     remoteInput.getAllowFreeFormInput(),
+                    remoteInput.getEditChoicesBeforeSending(),
                     remoteInput.getExtras(),
                     null /* allowedDataTypes */)
                     : null;
@@ -5186,7 +5264,8 @@
             for (int i = 0; i < srcArray.length; i++) {
                 android.app.RemoteInput src = srcArray[i];
                 remoteInputs[i] = new RemoteInput(src.getResultKey(), src.getLabel(),
-                        src.getChoices(), src.getAllowFreeFormInput(), src.getExtras(), null);
+                        src.getChoices(), src.getAllowFreeFormInput(),
+                        src.getEditChoicesBeforeSending(), src.getExtras(), null);
             }
         }
 
@@ -5211,9 +5290,11 @@
                     Action.EXTRA_SEMANTIC_ACTION, Action.SEMANTIC_ACTION_NONE);
         }
 
+        final boolean isContextual = BuildCompat.isAtLeastQ() ? action.isContextual() : false;
+
         return new Action(action.icon, action.title, action.actionIntent,
                 action.getExtras(), remoteInputs, null, allowGeneratedReplies,
-                semanticAction, showsUserInterface);
+                semanticAction, showsUserInterface, isContextual);
     }
 
     /** Returns the invisible actions contained within the given notification. */
@@ -5397,6 +5478,18 @@
         }
     }
 
+    /**
+     * Returns whether the platform is allowed (by the app developer) to generate contextual actions
+     * for this notification.
+     */
+    public static boolean getAllowSystemGeneratedContextualActions(Notification notification) {
+        if (BuildCompat.isAtLeastQ()) {
+            return notification.getAllowSystemGeneratedContextualActions();
+        } else {
+            return false;
+        }
+    }
+
     /** @deprecated This type should not be instantiated as it contains only static methods. */
     @Deprecated
     @SuppressWarnings("PrivateConstructorForUtilityClass")
diff --git a/core/src/main/java/androidx/core/app/NotificationCompatBuilder.java b/core/src/main/java/androidx/core/app/NotificationCompatBuilder.java
index ca2a3b7..7123157 100644
--- a/core/src/main/java/androidx/core/app/NotificationCompatBuilder.java
+++ b/core/src/main/java/androidx/core/app/NotificationCompatBuilder.java
@@ -32,6 +32,7 @@
 import android.widget.RemoteViews;
 
 import androidx.annotation.RestrictTo;
+import androidx.core.os.BuildCompat;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -205,6 +206,10 @@
                         .setVibrate(null);
             }
         }
+        if (BuildCompat.isAtLeastQ()) {
+            mBuilder.setAllowSystemGeneratedContextualActions(
+                    b.mAllowSystemGeneratedContextualActions);
+        }
     }
 
     @Override
@@ -279,6 +284,10 @@
                 actionBuilder.setSemanticAction(action.getSemanticAction());
             }
 
+            if (BuildCompat.isAtLeastQ()) {
+                actionBuilder.setContextual(action.isContextual());
+            }
+
             actionExtras.putBoolean(NotificationCompat.Action.EXTRA_SHOWS_USER_INTERFACE,
                     action.getShowsUserInterface());
             actionBuilder.addExtras(actionExtras);
diff --git a/core/src/main/java/androidx/core/app/NotificationCompatJellybean.java b/core/src/main/java/androidx/core/app/NotificationCompatJellybean.java
index 3192381..4d07e31 100644
--- a/core/src/main/java/androidx/core/app/NotificationCompatJellybean.java
+++ b/core/src/main/java/androidx/core/app/NotificationCompatJellybean.java
@@ -132,7 +132,7 @@
         }
         return new NotificationCompat.Action(icon, title, actionIntent, extras, remoteInputs,
                 dataOnlyRemoteInputs, allowGeneratedReplies,
-                NotificationCompat.Action.SEMANTIC_ACTION_NONE, true);
+                NotificationCompat.Action.SEMANTIC_ACTION_NONE, true, false /* isContextual */);
     }
 
     public static Bundle writeActionAndGetExtras(
@@ -241,7 +241,8 @@
                 fromBundleArray(getBundleArrayFromBundle(bundle, KEY_DATA_ONLY_REMOTE_INPUTS)),
                 allowGeneratedReplies,
                 bundle.getInt(KEY_SEMANTIC_ACTION),
-                bundle.getBoolean(KEY_SHOWS_USER_INTERFACE));
+                bundle.getBoolean(KEY_SHOWS_USER_INTERFACE),
+                false /* is_contextual is only supported for Q+ devices */);
     }
 
     static Bundle getBundleForAction(NotificationCompat.Action action) {
@@ -277,6 +278,7 @@
                 data.getCharSequence(KEY_LABEL),
                 data.getCharSequenceArray(KEY_CHOICES),
                 data.getBoolean(KEY_ALLOW_FREE_FORM_INPUT),
+                RemoteInput.EDIT_CHOICES_BEFORE_SENDING_AUTO, // Tap-to-edit is only supported on Q+
                 data.getBundle(KEY_EXTRAS),
                 allowedDataTypes);
     }
diff --git a/core/src/main/java/androidx/core/app/RemoteInput.java b/core/src/main/java/androidx/core/app/RemoteInput.java
index e579efd..ff68adc 100644
--- a/core/src/main/java/androidx/core/app/RemoteInput.java
+++ b/core/src/main/java/androidx/core/app/RemoteInput.java
@@ -28,6 +28,7 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.RequiresApi;
 import androidx.annotation.RestrictTo;
+import androidx.core.os.BuildCompat;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -67,21 +68,45 @@
     /** The user selected one of the choices from {@link #getChoices}. */
     public static final int SOURCE_CHOICE = 1;
 
+    /** @hide */
+    @IntDef(value = {EDIT_CHOICES_BEFORE_SENDING_AUTO, EDIT_CHOICES_BEFORE_SENDING_DISABLED,
+            EDIT_CHOICES_BEFORE_SENDING_ENABLED})
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface EditChoicesBeforeSending {}
+
+    /** The platform will determine whether choices will be edited before being sent to the app. */
+    public static final int EDIT_CHOICES_BEFORE_SENDING_AUTO = 0;
+
+    /** Tapping on a choice should send the input immediately, without letting the user edit it. */
+    public static final int EDIT_CHOICES_BEFORE_SENDING_DISABLED = 1;
+
+    /** Tapping on a choice should let the user edit the input before it is sent to the app. */
+    public static final int EDIT_CHOICES_BEFORE_SENDING_ENABLED = 2;
+
     private final String mResultKey;
     private final CharSequence mLabel;
     private final CharSequence[] mChoices;
     private final boolean mAllowFreeFormTextInput;
+    @EditChoicesBeforeSending private final int mEditChoicesBeforeSending;
     private final Bundle mExtras;
     private final Set<String> mAllowedDataTypes;
 
     RemoteInput(String resultKey, CharSequence label, CharSequence[] choices,
-            boolean allowFreeFormTextInput, Bundle extras, Set<String> allowedDataTypes) {
+            boolean allowFreeFormTextInput, @EditChoicesBeforeSending int editChoicesBeforeSending,
+            Bundle extras, Set<String> allowedDataTypes) {
         this.mResultKey = resultKey;
         this.mLabel = label;
         this.mChoices = choices;
         this.mAllowFreeFormTextInput = allowFreeFormTextInput;
+        this.mEditChoicesBeforeSending = editChoicesBeforeSending;
         this.mExtras = extras;
         this.mAllowedDataTypes = allowedDataTypes;
+        if (getEditChoicesBeforeSending() == EDIT_CHOICES_BEFORE_SENDING_ENABLED
+                && !getAllowFreeFormInput()) {
+            throw new IllegalArgumentException(
+                "setEditChoicesBeforeSending requires setAllowFreeFormInput");
+        }
     }
 
     /**
@@ -133,6 +158,14 @@
     }
 
     /**
+     * Gets whether tapping on a choice should let the user edit the input before it is sent to the
+     * app.
+     */
+    @EditChoicesBeforeSending public int getEditChoicesBeforeSending() {
+        return mEditChoicesBeforeSending;
+    }
+
+    /**
      * Get additional metadata carried around with this remote input.
      */
     public Bundle getExtras() {
@@ -149,6 +182,8 @@
         private CharSequence mLabel;
         private CharSequence[] mChoices;
         private boolean mAllowFreeFormTextInput = true;
+        @EditChoicesBeforeSending
+        private int mEditChoicesBeforeSending = EDIT_CHOICES_BEFORE_SENDING_AUTO;
 
         /**
          * Create a builder object for {@link androidx.core.app.RemoteInput} objects.
@@ -229,6 +264,19 @@
         }
 
         /**
+         * Specifies whether tapping on a choice should let the user edit the input before it is
+         * sent to the app. The default is {@link #EDIT_CHOICES_BEFORE_SENDING_AUTO}.
+         *
+         * It cannot be used if {@link #setAllowFreeFormInput} has been set to false.
+         */
+        @NonNull
+        public Builder setEditChoicesBeforeSending(
+                @EditChoicesBeforeSending int editChoicesBeforeSending) {
+            mEditChoicesBeforeSending = editChoicesBeforeSending;
+            return this;
+        }
+
+        /**
          * Merge additional metadata into this builder.
          *
          * <p>Values within the Bundle will replace existing extras values in this Builder.
@@ -264,6 +312,7 @@
                     mLabel,
                     mChoices,
                     mAllowFreeFormTextInput,
+                    mEditChoicesBeforeSending,
                     mExtras,
                     mAllowedDataTypes);
         }
@@ -510,12 +559,16 @@
 
     @RequiresApi(20)
     static android.app.RemoteInput fromCompat(RemoteInput src) {
-        return new android.app.RemoteInput.Builder(src.getResultKey())
-                .setLabel(src.getLabel())
-                .setChoices(src.getChoices())
-                .setAllowFreeFormInput(src.getAllowFreeFormInput())
-                .addExtras(src.getExtras())
-                .build();
+        android.app.RemoteInput.Builder builder =
+                new android.app.RemoteInput.Builder(src.getResultKey())
+                        .setLabel(src.getLabel())
+                        .setChoices(src.getChoices())
+                        .setAllowFreeFormInput(src.getAllowFreeFormInput())
+                        .addExtras(src.getExtras());
+        if (BuildCompat.isAtLeastQ()) {
+            builder.setEditChoicesBeforeSending(src.getEditChoicesBeforeSending());
+        }
+        return builder.build();
     }
 
     @RequiresApi(16)
diff --git a/core/src/main/java/androidx/core/graphics/BlendModeCompat.java b/core/src/main/java/androidx/core/graphics/BlendModeCompat.java
new file mode 100644
index 0000000..b7c76ff
--- /dev/null
+++ b/core/src/main/java/androidx/core/graphics/BlendModeCompat.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.core.graphics;
+
+/**
+ * Compat version of {@link android.graphics.BlendMode}, usages of {@link BlendModeCompat} will
+ * map to {@link android.graphics.PorterDuff.Mode} wherever possible
+ */
+public enum BlendModeCompat {
+
+    /**
+     * @see android.graphics.BlendMode#CLEAR
+     */
+    CLEAR,
+
+    /**
+     * @see android.graphics.BlendMode#SRC
+     */
+    SRC,
+
+    /**
+     * @see android.graphics.BlendMode#DST
+     */
+    DST,
+
+    /**
+     * @see android.graphics.BlendMode#SRC_OVER
+     */
+    SRC_OVER,
+
+    /**
+     * @see android.graphics.BlendMode#DST_OVER
+     */
+    DST_OVER,
+
+    /**
+     * @see android.graphics.BlendMode#SRC_IN
+     */
+    SRC_IN,
+
+    /**
+     * @see android.graphics.BlendMode#DST_IN
+     */
+    DST_IN,
+
+    /**
+     * @see android.graphics.BlendMode#SRC_OUT
+     */
+    SRC_OUT,
+
+    /**
+     * @see android.graphics.BlendMode#DST_OUT
+     */
+    DST_OUT,
+
+    /**
+     * @see android.graphics.BlendMode#SRC_ATOP
+     */
+    SRC_ATOP,
+
+    /**
+     * @see android.graphics.BlendMode#DST_ATOP
+     */
+    DST_ATOP,
+
+    /**
+     * @see android.graphics.BlendMode#XOR
+     */
+    XOR,
+
+    /**
+     * @see android.graphics.BlendMode#PLUS
+     */
+    PLUS,
+
+    /**
+     * @see android.graphics.BlendMode#MODULATE
+     */
+    MODULATE,
+
+    /**
+     * @see android.graphics.BlendMode#SCREEN
+     */
+    SCREEN,
+
+    /**
+     * @see android.graphics.BlendMode#OVERLAY
+     */
+    OVERLAY,
+
+    /**
+     * @see android.graphics.BlendMode#DARKEN
+     */
+    DARKEN,
+
+    /**
+     * @see android.graphics.BlendMode#LIGHTEN
+     */
+    LIGHTEN,
+
+    /**
+     * @see android.graphics.BlendMode#COLOR_DODGE
+     */
+    COLOR_DODGE,
+
+    /**
+     * @see android.graphics.BlendMode#COLOR_BURN
+     */
+    COLOR_BURN,
+
+    /**
+     * @see android.graphics.BlendMode#HARD_LIGHT
+     */
+    HARD_LIGHT,
+
+    /**
+     * @see android.graphics.BlendMode#SOFT_LIGHT
+     */
+    SOFT_LIGHT,
+
+    /**
+     * @see android.graphics.BlendMode#DIFFERENCE
+     */
+    DIFFERENCE,
+
+    /**
+     * @see android.graphics.BlendMode#EXCLUSION
+     */
+    EXCLUSION,
+
+    /**
+     * @see android.graphics.BlendMode#MULTIPLY
+     */
+    MULTIPLY,
+
+    /**
+     * @see android.graphics.BlendMode#HUE
+     */
+    HUE,
+
+    /**
+     * @see android.graphics.BlendMode#SATURATION
+     */
+    SATURATION,
+
+    /**
+     * @see android.graphics.BlendMode#COLOR
+     */
+    COLOR,
+
+    /**
+     * @see android.graphics.BlendMode#LUMINOSITY
+     */
+    LUMINOSITY
+}
diff --git a/core/src/main/java/androidx/core/graphics/Insets.java b/core/src/main/java/androidx/core/graphics/Insets.java
new file mode 100644
index 0000000..6eadbc4
--- /dev/null
+++ b/core/src/main/java/androidx/core/graphics/Insets.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.core.graphics;
+
+import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX;
+
+import android.graphics.Rect;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
+import androidx.annotation.RestrictTo;
+
+/**
+ * An Insets instance holds four integer offsets which describe changes to the four
+ * edges of a Rectangle. By convention, positive values move edges towards the
+ * centre of the rectangle.
+ * <p>
+ * Insets are immutable so may be treated as values.
+ */
+public final class Insets {
+    @NonNull
+    public static final Insets NONE = new Insets(0, 0, 0, 0);
+
+    public final int left;
+    public final int top;
+    public final int right;
+    public final int bottom;
+
+    private Insets(int left, int top, int right, int bottom) {
+        this.left = left;
+        this.top = top;
+        this.right = right;
+        this.bottom = bottom;
+    }
+
+    // Factory methods
+
+    /**
+     * Return an Insets instance with the appropriate values.
+     *
+     * @param left   the left inset
+     * @param top    the top inset
+     * @param right  the right inset
+     * @param bottom the bottom inset
+     * @return Insets instance with the appropriate values
+     */
+    @NonNull
+    public static Insets of(int left, int top, int right, int bottom) {
+        if (left == 0 && top == 0 && right == 0 && bottom == 0) {
+            return NONE;
+        }
+        return new Insets(left, top, right, bottom);
+    }
+
+    /**
+     * Return an Insets instance with the appropriate values.
+     *
+     * @param r the rectangle from which to take the values
+     * @return an Insets instance with the appropriate values
+     */
+    @NonNull
+    public static Insets of(@NonNull Rect r) {
+        return of(r.left, r.top, r.right, r.bottom);
+    }
+
+    /**
+     * Two Insets instances are equal iff they belong to the same class and their fields are
+     * pairwise equal.
+     *
+     * @param o the object to compare this instance with.
+     * @return true iff this object is equal {@code o}
+     */
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        Insets insets = (Insets) o;
+
+        if (bottom != insets.bottom) return false;
+        if (left != insets.left) return false;
+        if (right != insets.right) return false;
+        if (top != insets.top) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = left;
+        result = 31 * result + top;
+        result = 31 * result + right;
+        result = 31 * result + bottom;
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "Insets{left=" + left + ", top=" + top
+                + ", right=" + right + ", bottom=" + bottom + '}';
+    }
+
+    /**
+     * @hide
+     */
+    @RequiresApi(api = 29)
+    @NonNull
+    @RestrictTo(LIBRARY_GROUP_PREFIX)
+    public static Insets wrap(@NonNull android.graphics.Insets insets) {
+        return Insets.of(insets.left, insets.top, insets.right, insets.bottom);
+    }
+}
diff --git a/core/src/main/java/androidx/core/graphics/PaintCompat.java b/core/src/main/java/androidx/core/graphics/PaintCompat.java
index 7caa3e5..3a0424f 100644
--- a/core/src/main/java/androidx/core/graphics/PaintCompat.java
+++ b/core/src/main/java/androidx/core/graphics/PaintCompat.java
@@ -16,11 +16,20 @@
 
 package androidx.core.graphics;
 
+import android.graphics.BlendMode;
+import android.graphics.BlendModeColorFilter;
 import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
+import android.graphics.PorterDuffXfermode;
 import android.graphics.Rect;
 import android.os.Build;
 
+import androidx.annotation.ColorInt;
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
+import androidx.annotation.VisibleForTesting;
 import androidx.core.util.Pair;
 
 /**
@@ -104,6 +113,179 @@
         return !rects.first.equals(rects.second);
     }
 
+    /**
+     * Configure the corresponding BlendMode on the given paint. If the Android platform supports
+     * the blend mode natively, it will fall back on the framework implementation of either
+     * BlendMode or PorterDuff mode. If it is not supported then this method is a no-op
+     * @param paint target Paint to which the BlendMode will be applied
+     * @param blendMode BlendMode to configure on the paint if it is supported by the platform
+     *                  version. A value of null removes the BlendMode from the Paint and restores
+     *                  it to the default
+     */
+    public static void setBlendMode(@NonNull Paint paint, @Nullable BlendModeCompat blendMode) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+            paint.setBlendMode(obtainBlendModeFromCompat(blendMode));
+        } else {
+            PorterDuff.Mode mode = obtainPorterDuffFromCompat(blendMode);
+            if (mode != null) {
+                paint.setXfermode(new PorterDuffXfermode(mode));
+            } else {
+                paint.setXfermode(null);
+            }
+        }
+    }
+
+    /**
+     * Configure the tintable color filter on the given paint. If the Android platform supports
+     * the blend mode natively, it will fall back on the framework implementation of either
+     * BlendModeColorFilter or PorterDuffColorFilter. If it is not supported then this method is
+     * a no-op
+     * @param paint target Paint to which the ColorFilter will be applied
+     * @param color color which to apply the blend mode with
+     * @param blendModeCompat BlendMode to configure on the color filter if it is supported by the
+     *                        platform. A value of null removes the ColorFilter from the paint
+     */
+    public static void setBlendModeColorFilter(@NonNull Paint paint, @ColorInt int color,
+                                                     @Nullable BlendModeCompat blendModeCompat) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+            BlendMode blendMode = obtainBlendModeFromCompat(blendModeCompat);
+            if (blendMode != null) {
+                paint.setColorFilter(new BlendModeColorFilter(color, blendMode));
+            } else {
+                paint.setColorFilter(null);
+            }
+        } else {
+            PorterDuff.Mode porterDuffMode = obtainPorterDuffFromCompat(blendModeCompat);
+            if (porterDuffMode != null) {
+                paint.setColorFilter(new PorterDuffColorFilter(color, porterDuffMode));
+            } else {
+                paint.setColorFilter(null);
+            }
+        }
+    }
+
+    @RequiresApi(Build.VERSION_CODES.Q)
+    @VisibleForTesting
+    /* package */ static @Nullable BlendMode obtainBlendModeFromCompat(
+            @Nullable BlendModeCompat blendModeCompat) {
+        if (blendModeCompat != null) {
+            switch (blendModeCompat) {
+                case CLEAR:
+                    return BlendMode.CLEAR;
+                case SRC:
+                    return BlendMode.SRC;
+                case DST:
+                    return BlendMode.DST;
+                case SRC_OVER:
+                    return BlendMode.SRC_OVER;
+                case DST_OVER:
+                    return BlendMode.SRC_OVER;
+                case SRC_IN:
+                    return BlendMode.SRC_IN;
+                case DST_IN:
+                    return BlendMode.DST_IN;
+                case SRC_OUT:
+                    return BlendMode.SRC_OUT;
+                case DST_OUT:
+                    return BlendMode.DST_OUT;
+                case SRC_ATOP:
+                    return BlendMode.SRC_ATOP;
+                case DST_ATOP:
+                    return BlendMode.DST_ATOP;
+                case XOR:
+                    return BlendMode.XOR;
+                case PLUS:
+                    return BlendMode.PLUS;
+                case MODULATE:
+                    return BlendMode.MODULATE;
+                case SCREEN:
+                    return BlendMode.SCREEN;
+                case OVERLAY:
+                    return BlendMode.OVERLAY;
+                case DARKEN:
+                    return BlendMode.DARKEN;
+                case LIGHTEN:
+                    return BlendMode.LIGHTEN;
+                case COLOR_DODGE:
+                    return BlendMode.COLOR_DODGE;
+                case COLOR_BURN:
+                    return BlendMode.COLOR_BURN;
+                case HARD_LIGHT:
+                    return BlendMode.HARD_LIGHT;
+                case SOFT_LIGHT:
+                    return BlendMode.SOFT_LIGHT;
+                case DIFFERENCE:
+                    return BlendMode.DIFFERENCE;
+                case EXCLUSION:
+                    return BlendMode.EXCLUSION;
+                case MULTIPLY:
+                    return BlendMode.MULTIPLY;
+                case HUE:
+                    return BlendMode.HUE;
+                case SATURATION:
+                    return BlendMode.SATURATION;
+                case COLOR:
+                    return BlendMode.COLOR;
+                case LUMINOSITY:
+                    return BlendMode.LUMINOSITY;
+                default:
+                    return null;
+            }
+        } else {
+            return null;
+        }
+    }
+
+    @VisibleForTesting
+    /* package */ static @Nullable PorterDuff.Mode obtainPorterDuffFromCompat(
+            @Nullable BlendModeCompat blendModeCompat) {
+        if (blendModeCompat != null) {
+            switch (blendModeCompat) {
+                case CLEAR:
+                    return PorterDuff.Mode.CLEAR;
+                case SRC:
+                    return PorterDuff.Mode.SRC;
+                case DST:
+                    return PorterDuff.Mode.DST;
+                case SRC_OVER:
+                    return PorterDuff.Mode.SRC_OVER;
+                case DST_OVER:
+                    return PorterDuff.Mode.DST_OVER;
+                case SRC_IN:
+                    return PorterDuff.Mode.SRC_IN;
+                case DST_IN:
+                    return PorterDuff.Mode.DST_IN;
+                case SRC_OUT:
+                    return PorterDuff.Mode.SRC_OUT;
+                case DST_OUT:
+                    return PorterDuff.Mode.DST_OUT;
+                case SRC_ATOP:
+                    return PorterDuff.Mode.SRC_ATOP;
+                case DST_ATOP:
+                    return PorterDuff.Mode.DST_ATOP;
+                case XOR:
+                    return PorterDuff.Mode.XOR;
+                case PLUS:
+                    return PorterDuff.Mode.ADD;
+                // b/73224934 PorterDuff Multiply maps to Skia Modulate
+                case MODULATE:
+                    return PorterDuff.Mode.MULTIPLY;
+                case SCREEN:
+                    return PorterDuff.Mode.SCREEN;
+                case OVERLAY:
+                    return PorterDuff.Mode.OVERLAY;
+                case DARKEN:
+                    return PorterDuff.Mode.DARKEN;
+                case LIGHTEN:
+                    return PorterDuff.Mode.LIGHTEN;
+                default:
+                    return null;
+            }
+        } else {
+            return null;
+        }
+    }
+
     private static Pair<Rect, Rect> obtainEmptyRects() {
         Pair<Rect, Rect> rects = sRectThreadLocal.get();
         if (rects == null) {
diff --git a/core/src/main/java/androidx/core/graphics/TypefaceCompat.java b/core/src/main/java/androidx/core/graphics/TypefaceCompat.java
index a55a4134..d07da13 100644
--- a/core/src/main/java/androidx/core/graphics/TypefaceCompat.java
+++ b/core/src/main/java/androidx/core/graphics/TypefaceCompat.java
@@ -18,6 +18,7 @@
 
 import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX;
 
+import android.annotation.SuppressLint;
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Typeface;
@@ -34,16 +35,20 @@
 import androidx.core.content.res.FontResourcesParserCompat.FontFamilyFilesResourceEntry;
 import androidx.core.content.res.FontResourcesParserCompat.ProviderResourceEntry;
 import androidx.core.content.res.ResourcesCompat;
+import androidx.core.os.BuildCompat;
 import androidx.core.provider.FontsContractCompat;
 import androidx.core.provider.FontsContractCompat.FontInfo;
 
 /**
  * Helper for accessing features in {@link Typeface}.
  */
+@SuppressLint("NewApi")  // TODO: Remove this suppression once Q SDK is released.
 public class TypefaceCompat {
     private static final TypefaceCompatBaseImpl sTypefaceCompatImpl;
     static {
-        if (Build.VERSION.SDK_INT >= 28) {
+        if (BuildCompat.isAtLeastQ()) {
+            sTypefaceCompatImpl = new TypefaceCompatApi29Impl();
+        } else if (Build.VERSION.SDK_INT >= 28) {
             sTypefaceCompatImpl = new TypefaceCompatApi28Impl();
         } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
             sTypefaceCompatImpl = new TypefaceCompatApi26Impl();
diff --git a/core/src/main/java/androidx/core/graphics/TypefaceCompatApi29Impl.java b/core/src/main/java/androidx/core/graphics/TypefaceCompatApi29Impl.java
new file mode 100644
index 0000000..c05d0ae
--- /dev/null
+++ b/core/src/main/java/androidx/core/graphics/TypefaceCompatApi29Impl.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.core.graphics;
+
+import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Typeface;
+import android.graphics.fonts.Font;
+import android.graphics.fonts.FontFamily;
+import android.graphics.fonts.FontStyle;
+import android.os.CancellationSignal;
+import android.os.ParcelFileDescriptor;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
+import androidx.annotation.RestrictTo;
+import androidx.core.content.res.FontResourcesParserCompat;
+import androidx.core.provider.FontsContractCompat;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/** @hide */
+@RestrictTo(LIBRARY_GROUP)
+@RequiresApi(29)
+public class TypefaceCompatApi29Impl extends TypefaceCompatBaseImpl {
+    @Override
+    protected FontsContractCompat.FontInfo findBestInfo(FontsContractCompat.FontInfo[] fonts,
+            int style) {
+        throw new RuntimeException("Do not use this function in API 29 or later.");
+    }
+
+    // Caller must close the stream.
+    @Override
+    protected Typeface createFromInputStream(Context context, InputStream is) {
+        throw new RuntimeException("Do not use this function in API 29 or later.");
+    }
+
+    @Nullable
+    @Override
+    public Typeface createFromFontInfo(Context context,
+            @Nullable CancellationSignal cancellationSignal,
+            @NonNull FontsContractCompat.FontInfo[] fonts, int style) {
+        FontFamily.Builder familyBuilder = null;
+        final ContentResolver resolver = context.getContentResolver();
+        for (FontsContractCompat.FontInfo font : fonts) {
+            try (ParcelFileDescriptor pfd = resolver.openFileDescriptor(font.getUri(), "r",
+                    cancellationSignal)) {
+                if (pfd == null) {
+                    continue;  // keep adding succeeded fonts.
+                }
+                final Font platformFont = new Font.Builder(pfd)
+                        .setWeight(font.getWeight())
+                        .setSlant(font.isItalic() ? FontStyle.FONT_SLANT_ITALIC
+                                : FontStyle.FONT_SLANT_UPRIGHT)
+                        .setTtcIndex(font.getTtcIndex())
+                        .build();  // TODO: font variation settings?
+                if (familyBuilder == null) {
+                    familyBuilder = new FontFamily.Builder(platformFont);
+                } else {
+                    familyBuilder.addFont(platformFont);
+                }
+            } catch (IOException e) {
+                // keep adding succeeded fonts.
+            }
+        }
+        if (familyBuilder == null) {
+            return null;  // No font is added. Give up.
+        }
+        final FontStyle defaultStyle = new FontStyle(
+                (style & Typeface.BOLD) != 0 ? FontStyle.FONT_WEIGHT_BOLD
+                        : FontStyle.FONT_WEIGHT_NORMAL,
+                (style & Typeface.ITALIC) != 0 ? FontStyle.FONT_SLANT_ITALIC
+                        : FontStyle.FONT_SLANT_UPRIGHT
+        );
+        return new Typeface.CustomFallbackBuilder(familyBuilder.build())
+                .setStyle(defaultStyle)
+                .build();
+    }
+
+    @Nullable
+    @Override
+    public Typeface createFromFontFamilyFilesResourceEntry(Context context,
+            FontResourcesParserCompat.FontFamilyFilesResourceEntry familyEntry, Resources resources,
+            int style) {
+        FontFamily.Builder familyBuilder = null;
+        for (FontResourcesParserCompat.FontFileResourceEntry entry : familyEntry.getEntries()) {
+            try {
+                final Font platformFont = new Font.Builder(resources, entry.getResourceId())
+                        .setWeight(entry.getWeight())
+                        .setSlant(entry.isItalic() ? FontStyle.FONT_SLANT_ITALIC
+                                : FontStyle.FONT_SLANT_UPRIGHT)
+                        .setTtcIndex(entry.getTtcIndex())
+                        .setFontVariationSettings(entry.getVariationSettings())
+                        .build();
+                if (familyBuilder == null) {
+                    familyBuilder = new FontFamily.Builder(platformFont);
+                } else {
+                    familyBuilder.addFont(platformFont);
+                }
+            } catch (IOException e) {
+                // keep adding succeeded fonts
+            }
+        }
+        if (familyBuilder == null) {
+            return null;  // No font is added. Give up
+        }
+        final FontStyle defaultStyle = new FontStyle(
+                (style & Typeface.BOLD) != 0 ? FontStyle.FONT_WEIGHT_BOLD
+                        : FontStyle.FONT_WEIGHT_NORMAL,
+                (style & Typeface.ITALIC) != 0 ? FontStyle.FONT_SLANT_ITALIC
+                        : FontStyle.FONT_SLANT_UPRIGHT
+        );
+        return new Typeface.CustomFallbackBuilder(familyBuilder.build())
+                .setStyle(defaultStyle)
+                .build();
+    }
+
+    /**
+     * Used by Resources to load a font resource of type font file.
+     */
+    @Nullable
+    @Override
+    public Typeface createFromResourcesFontFile(
+            Context context, Resources resources, int id, String path, int style) {
+        FontFamily family = null;
+        try {
+            family = new FontFamily.Builder(new Font.Builder(resources, id).build()).build();
+        } catch (IOException e) {
+            return null;
+        }
+        final FontStyle defaultStyle = new FontStyle(
+                (style & Typeface.BOLD) != 0 ? FontStyle.FONT_WEIGHT_BOLD
+                        : FontStyle.FONT_WEIGHT_NORMAL,
+                (style & Typeface.ITALIC) != 0 ? FontStyle.FONT_SLANT_ITALIC
+                        : FontStyle.FONT_SLANT_UPRIGHT
+        );
+        return new Typeface.CustomFallbackBuilder(family).setStyle(defaultStyle).build();
+    }
+
+}
diff --git a/core/src/main/java/androidx/core/text/PrecomputedTextCompat.java b/core/src/main/java/androidx/core/text/PrecomputedTextCompat.java
index 66d1a3e..3ab3705 100644
--- a/core/src/main/java/androidx/core/text/PrecomputedTextCompat.java
+++ b/core/src/main/java/androidx/core/text/PrecomputedTextCompat.java
@@ -18,6 +18,7 @@
 
 import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX;
 
+import android.annotation.SuppressLint;
 import android.os.Build;
 import android.text.Layout;
 import android.text.PrecomputedText;
@@ -37,6 +38,7 @@
 import androidx.annotation.RequiresApi;
 import androidx.annotation.RestrictTo;
 import androidx.annotation.UiThread;
+import androidx.core.os.BuildCompat;
 import androidx.core.os.TraceCompat;
 import androidx.core.util.ObjectsCompat;
 import androidx.core.util.Preconditions;
@@ -191,9 +193,18 @@
             }
         }
 
+        @SuppressLint("NewApi")  // TODO: Remove once Q SDK is released
         Params(@NonNull TextPaint paint, @NonNull TextDirectionHeuristic textDir,
                 int strategy, int frequency) {
-            mWrapped = null;
+            if (BuildCompat.isAtLeastQ()) {
+                mWrapped = new PrecomputedText.Params.Builder(paint)
+                        .setBreakStrategy(strategy)
+                        .setHyphenationFrequency(frequency)
+                        .setTextDirection(textDir)
+                        .build();
+            } else {
+                mWrapped = null;
+            }
             mPaint = paint;
             mTextDir = textDir;
             mBreakStrategy = strategy;
@@ -206,7 +217,7 @@
             mTextDir = wrapped.getTextDirection();
             mBreakStrategy = wrapped.getBreakStrategy();
             mHyphenationFrequency = wrapped.getHyphenationFrequency();
-            mWrapped = null;
+            mWrapped = (BuildCompat.isAtLeastQ()) ? wrapped : null;
         }
 
         /**
@@ -262,11 +273,6 @@
          */
         @RestrictTo(LIBRARY_GROUP_PREFIX)
         public boolean equalsWithoutTextDirection(@NonNull Params other) {
-
-            if (mWrapped != null) {
-                return mWrapped.equals(other.mWrapped);
-            }
-
             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                 if (mBreakStrategy != other.getBreakStrategy()) {
                     return false;
@@ -422,6 +428,7 @@
      * @param params parameters that define how text will be precomputed
      * @return A {@link PrecomputedText}
      */
+    @SuppressLint("NewApi")  // TODO: Remove once Q SDK is released
     public static PrecomputedTextCompat create(@NonNull CharSequence text, @NonNull Params params) {
         Preconditions.checkNotNull(text);
         Preconditions.checkNotNull(params);
@@ -429,6 +436,11 @@
         try {
             TraceCompat.beginSection("PrecomputedText");
 
+            if (BuildCompat.isAtLeastQ() && params.mWrapped != null) {
+                return new PrecomputedTextCompat(
+                        PrecomputedText.create(text, params.mWrapped), params);
+            }
+
             ArrayList<Integer> ends = new ArrayList<>();
 
             int paraEnd = 0;
@@ -488,7 +500,7 @@
         mText = precomputed;
         mParams = params;
         mParagraphEnds = null;
-        mWrapped = null;
+        mWrapped = (BuildCompat.isAtLeastQ()) ? precomputed : null;
     }
 
     /**
@@ -515,24 +527,39 @@
     /**
      * Returns the count of paragraphs.
      */
+    @SuppressLint("NewApi")  // TODO: Remove once Q SDK is released
     public @IntRange(from = 0) int getParagraphCount() {
-        return mParagraphEnds.length;
+        if (BuildCompat.isAtLeastQ()) {
+            return mWrapped.getParagraphCount();
+        } else {
+            return mParagraphEnds.length;
+        }
     }
 
     /**
      * Returns the paragraph start offset of the text.
      */
+    @SuppressLint("NewApi")  // TODO: Remove once Q SDK is released
     public @IntRange(from = 0) int getParagraphStart(@IntRange(from = 0) int paraIndex) {
         Preconditions.checkArgumentInRange(paraIndex, 0, getParagraphCount(), "paraIndex");
-        return paraIndex == 0 ? 0 : mParagraphEnds[paraIndex - 1];
+        if (BuildCompat.isAtLeastQ()) {
+            return mWrapped.getParagraphStart(paraIndex);
+        } else {
+            return paraIndex == 0 ? 0 : mParagraphEnds[paraIndex - 1];
+        }
     }
 
     /**
      * Returns the paragraph end offset of the text.
      */
+    @SuppressLint("NewApi")  // TODO: Remove once Q SDK is released
     public @IntRange(from = 0) int getParagraphEnd(@IntRange(from = 0) int paraIndex) {
         Preconditions.checkArgumentInRange(paraIndex, 0, getParagraphCount(), "paraIndex");
-        return mParagraphEnds[paraIndex];
+        if (BuildCompat.isAtLeastQ()) {
+            return mWrapped.getParagraphEnd(paraIndex);
+        } else {
+            return mParagraphEnds[paraIndex];
+        }
     }
 
     /**
@@ -646,25 +673,35 @@
     /**
      * @throws IllegalArgumentException if {@link MetricAffectingSpan} is specified.
      */
+    @SuppressLint("NewApi")  // TODO: Remove once Q SDK is released
     @Override
     public void setSpan(Object what, int start, int end, int flags) {
         if (what instanceof MetricAffectingSpan) {
             throw new IllegalArgumentException(
                     "MetricAffectingSpan can not be set to PrecomputedText.");
         }
-        mText.setSpan(what, start, end, flags);
+        if (BuildCompat.isAtLeastQ()) {
+            mWrapped.setSpan(what, start, end, flags);
+        } else {
+            mText.setSpan(what, start, end, flags);
+        }
     }
 
     /**
      * @throws IllegalArgumentException if {@link MetricAffectingSpan} is specified.
      */
+    @SuppressLint("NewApi")  // TODO: Remove once Q SDK is released
     @Override
     public void removeSpan(Object what) {
         if (what instanceof MetricAffectingSpan) {
             throw new IllegalArgumentException(
                     "MetricAffectingSpan can not be removed from PrecomputedText.");
         }
-        mText.removeSpan(what);
+        if (BuildCompat.isAtLeastQ()) {
+            mWrapped.removeSpan(what);
+        } else {
+            mText.removeSpan(what);
+        }
     }
 
     ///////////////////////////////////////////////////////////////////////////////////////////////
@@ -672,9 +709,15 @@
     //
     // Just proxy for underlying mText if appropriate.
 
+    @SuppressLint("NewApi")  // TODO: Remove once Q SDK is released
     @Override
     public <T> T[] getSpans(int start, int end, Class<T> type) {
-        return mText.getSpans(start, end, type);
+        if (BuildCompat.isAtLeastQ()) {
+            return mWrapped.getSpans(start, end, type);
+        } else {
+            return mText.getSpans(start, end, type);
+        }
+
     }
 
     @Override
diff --git a/core/src/main/java/androidx/core/view/ViewCompat.java b/core/src/main/java/androidx/core/view/ViewCompat.java
index f5925bd..01cdd76 100644
--- a/core/src/main/java/androidx/core/view/ViewCompat.java
+++ b/core/src/main/java/androidx/core/view/ViewCompat.java
@@ -60,6 +60,7 @@
 import androidx.annotation.UiThread;
 import androidx.collection.ArrayMap;
 import androidx.core.R;
+import androidx.core.os.BuildCompat;
 import androidx.core.view.AccessibilityDelegateCompat.AccessibilityDelegateAdapter;
 import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
 import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat;
@@ -74,6 +75,7 @@
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.WeakHashMap;
@@ -906,6 +908,15 @@
 
     private static @Nullable View.AccessibilityDelegate
             getAccessibilityDelegateInternal(@NonNull View v) {
+        if (BuildCompat.isAtLeastQ()) {
+            return v.getAccessibilityDelegate();
+        } else {
+            return getAccessibilityDelegateThroughReflection(v);
+        }
+    }
+
+    private static @Nullable View.AccessibilityDelegate getAccessibilityDelegateThroughReflection(
+            @NonNull View v) {
         if (sAccessibilityDelegateCheckFailed) {
             return null; // View implementation might have changed.
         }
@@ -2488,6 +2499,40 @@
     }
 
     /**
+     * Sets a list of areas within this view's post-layout coordinate space where the system
+     * should not intercept touch or other pointing device gestures. <em>This method should
+     * be called by {@link View#onLayout(boolean, int, int, int, int)} or
+     * {@link View#onDraw(Canvas)}.</em>
+     * <p>
+     * On devices running API 28 and below, this method has no effect.
+     *
+     * @param rects A list of precision gesture regions that this view needs to function correctly
+     * @see View#setSystemGestureExclusionRects
+     */
+    public static void setSystemGestureExclusionRects(@NonNull View view,
+            @NonNull List<Rect> rects) {
+        if (BuildCompat.isAtLeastQ()) {
+            view.setSystemGestureExclusionRects(rects);
+        }
+    }
+
+    /**
+     * Retrieve the list of areas within this view's post-layout coordinate space where the system
+     * should not intercept touch or other pointing device gestures.
+     * <p>
+     * On devices running API 28 and below, this method always returns an empty list.
+     *
+     * @see View#getSystemGestureExclusionRects
+     */
+    @NonNull
+    public static List<Rect> getSystemGestureExclusionRects(@NonNull View view) {
+        if (BuildCompat.isAtLeastQ()) {
+            return view.getSystemGestureExclusionRects();
+        }
+        return Collections.emptyList();
+    }
+
+    /**
      * Controls whether the entire hierarchy under this view will save its
      * state when a state saving traversal occurs from its parent.
      *
diff --git a/core/src/main/java/androidx/core/view/ViewPropertyAnimatorCompat.java b/core/src/main/java/androidx/core/view/ViewPropertyAnimatorCompat.java
index 8963c2b..b645fb59 100644
--- a/core/src/main/java/androidx/core/view/ViewPropertyAnimatorCompat.java
+++ b/core/src/main/java/androidx/core/view/ViewPropertyAnimatorCompat.java
@@ -18,6 +18,7 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
+import android.annotation.SuppressLint;
 import android.os.Build;
 import android.view.View;
 import android.view.animation.Interpolator;
@@ -69,6 +70,7 @@
         }
 
         @Override
+        @SuppressLint("WrongConstant")
         public void onAnimationEnd(View view) {
             if (mVpa.mOldLayerType > -1) {
                 view.setLayerType(mVpa.mOldLayerType, null);
@@ -672,6 +674,7 @@
      * @see View#setLayerType(int, android.graphics.Paint)
      * @return This object, allowing calls to methods in this class to be chained.
      */
+    @SuppressLint("WrongConstant")
     public ViewPropertyAnimatorCompat withLayer() {
         View view;
         if ((view = mView.get()) != null) {
diff --git a/core/src/main/java/androidx/core/view/WindowInsetsCompat.java b/core/src/main/java/androidx/core/view/WindowInsetsCompat.java
index 4623ca3..fb4fc20 100644
--- a/core/src/main/java/androidx/core/view/WindowInsetsCompat.java
+++ b/core/src/main/java/androidx/core/view/WindowInsetsCompat.java
@@ -20,7 +20,12 @@
 
 import android.graphics.Rect;
 import android.view.WindowInsets;
+
+import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.core.graphics.Insets;
+import androidx.core.os.BuildCompat;
+import androidx.core.util.ObjectsCompat;
 
 /**
  * Describes a set of insets for window content.
@@ -372,6 +377,119 @@
         }
     }
 
+    /**
+     * Returns the system window insets in pixels.
+     *
+     * <p>The system window inset represents the area of a full-screen window that is
+     * partially or fully obscured by the status bar, navigation bar, IME or other system windows.
+     * </p>
+     *
+     * @return The system window insets
+     * @see #getSystemWindowInsetLeft()
+     * @see #getSystemWindowInsetTop()
+     * @see #getSystemWindowInsetRight()
+     * @see #getSystemWindowInsetBottom()
+     */
+    @NonNull
+    public Insets getSystemWindowInsets() {
+        if (BuildCompat.isAtLeastQ()) {
+            return Insets.wrap(((WindowInsets) mInsets).getSystemWindowInsets());
+        } else {
+            // Else we'll create a copy from the getters
+            return Insets.of(getSystemWindowInsetLeft(), getSystemWindowInsetTop(),
+                    getSystemWindowInsetRight(), getSystemWindowInsetBottom());
+        }
+    }
+
+    /**
+     * Returns the stable insets in pixels.
+     *
+     * <p>The stable inset represents the area of a full-screen window that <b>may</b> be
+     * partially or fully obscured by the system UI elements.  This value does not change
+     * based on the visibility state of those elements; for example, if the status bar is
+     * normally shown, but temporarily hidden, the stable inset will still provide the inset
+     * associated with the status bar being shown.</p>
+     *
+     * @return The stable insets
+     * @see #getStableInsetLeft()
+     * @see #getStableInsetTop()
+     * @see #getStableInsetRight()
+     * @see #getStableInsetBottom()
+     */
+    @NonNull
+    public Insets getStableInsets() {
+        if (BuildCompat.isAtLeastQ()) {
+            return Insets.wrap(((WindowInsets) mInsets).getStableInsets());
+        } else {
+            // Else we'll create a copy from the getters
+            return Insets.of(getStableInsetLeft(), getStableInsetTop(),
+                    getStableInsetRight(), getStableInsetBottom());
+        }
+    }
+
+    /**
+     * Returns the mandatory system gesture insets.
+     *
+     * <p>The mandatory system gesture insets represent the area of a window where mandatory system
+     * gestures have priority and may consume some or all touch input, e.g. due to the a system bar
+     * occupying it, or it being reserved for touch-only gestures.
+     *
+     * @see WindowInsets#getMandatorySystemGestureInsets
+     */
+    @NonNull
+    public Insets getMandatorySystemGestureInsets() {
+        if (BuildCompat.isAtLeastQ()) {
+            return Insets.wrap(((WindowInsets) mInsets).getMandatorySystemGestureInsets());
+        } else {
+            // Before Q, the mandatory system gesture insets == system window insets
+            return getSystemWindowInsets();
+        }
+    }
+
+    /**
+     * Returns the tappable element insets.
+     *
+     * <p>The tappable element insets represent how much tappable elements <b>must at least</b> be
+     * inset to remain both tappable and visually unobstructed by persistent system windows.
+     *
+     * <p>This may be smaller than {@link #getSystemWindowInsets()} if the system window is
+     * largely transparent and lets through simple taps (but not necessarily more complex gestures).
+     *
+     * @see WindowInsets#getTappableElementInsets
+     */
+    @NonNull
+    public Insets getTappableElementInsets() {
+        if (BuildCompat.isAtLeastQ()) {
+            return Insets.wrap(((WindowInsets) mInsets).getTappableElementInsets());
+        } else {
+            // Before Q, the tappable elements insets == system window insets
+            return getSystemWindowInsets();
+        }
+    }
+
+    /**
+     * Returns the system gesture insets.
+     *
+     * <p>The system gesture insets represent the area of a window where system gestures have
+     * priority and may consume some or all touch input, e.g. due to the a system bar
+     * occupying it, or it being reserved for touch-only gestures.
+     *
+     * <p>An app can declare priority over system gestures with
+     * {@link android.view.View#setSystemGestureExclusionRects} outside of the
+     * {@link #getMandatorySystemGestureInsets() mandatory system gesture insets}.
+     *
+     * @see WindowInsets#getSystemGestureInsets
+     */
+    @NonNull
+    public Insets getSystemGestureInsets() {
+        if (BuildCompat.isAtLeastQ()) {
+            return Insets.wrap(((WindowInsets) mInsets).getSystemGestureInsets());
+        } else {
+            // Before Q, the system gesture insets == system window insets
+            return getSystemWindowInsets();
+        }
+    }
+
     @Override
     public boolean equals(Object o) {
         if (this == o) {
@@ -381,7 +499,7 @@
             return false;
         }
         WindowInsetsCompat other = (WindowInsetsCompat) o;
-        return mInsets == null ? other.mInsets == null : mInsets.equals(other.mInsets);
+        return ObjectsCompat.equals(mInsets, other.mInsets);
     }
 
     @Override
diff --git a/core/src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java b/core/src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java
index 36d6007..f778095 100644
--- a/core/src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java
+++ b/core/src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java
@@ -19,6 +19,7 @@
 import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX;
 
 import android.graphics.Rect;
+import android.graphics.Region;
 import android.os.Build;
 import android.os.Bundle;
 import android.text.InputType;
@@ -31,12 +32,15 @@
 import android.util.SparseArray;
 import android.view.View;
 import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeInfo.TouchDelegateInfo;
 
+import androidx.annotation.IntRange;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
 import androidx.core.R;
 import androidx.core.accessibilityservice.AccessibilityServiceInfoCompat;
+import androidx.core.os.BuildCompat;
 import androidx.core.view.ViewCompat;
 import androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments;
 import androidx.core.view.accessibility.AccessibilityViewCommand.MoveAtGranularityArguments;
@@ -51,6 +55,7 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 
 /**
  * Helper for accessing {@link android.view.accessibility.AccessibilityNodeInfo} in a backwards
@@ -449,6 +454,42 @@
                         android.R.id.accessibilityActionScrollRight, null, null, null);
 
         /**
+         * Action to move to the page above.
+         */
+        @NonNull
+        public static final AccessibilityActionCompat ACTION_PAGE_UP =
+                new AccessibilityActionCompat(Build.VERSION.SDK_INT >= 29
+                        ?  AccessibilityNodeInfo.AccessibilityAction.ACTION_PAGE_UP : null,
+                        android.R.id.accessibilityActionPageUp, null, null, null);
+
+        /**
+         * Action to move to the page below.
+         */
+        @NonNull
+        public static final AccessibilityActionCompat ACTION_PAGE_DOWN =
+                new AccessibilityActionCompat(Build.VERSION.SDK_INT >= 29
+                        ?  AccessibilityNodeInfo.AccessibilityAction.ACTION_PAGE_DOWN : null,
+                        android.R.id.accessibilityActionPageDown, null, null, null);
+
+        /**
+         * Action to move to the page left.
+         */
+        @NonNull
+        public static final AccessibilityActionCompat ACTION_PAGE_LEFT =
+                new AccessibilityActionCompat(Build.VERSION.SDK_INT >= 29
+                        ?  AccessibilityNodeInfo.AccessibilityAction.ACTION_PAGE_LEFT : null,
+                        android.R.id.accessibilityActionPageLeft, null, null, null);
+
+        /**
+         * Action to move to the page right.
+         */
+        @NonNull
+        public static final AccessibilityActionCompat ACTION_PAGE_RIGHT =
+                new AccessibilityActionCompat(Build.VERSION.SDK_INT >= 29
+                        ?  AccessibilityNodeInfo.AccessibilityAction.ACTION_PAGE_RIGHT : null,
+                        android.R.id.accessibilityActionPageRight, null, null, null);
+
+        /**
          * Action that context clicks the node.
          */
         public static final AccessibilityActionCompat ACTION_CONTEXT_CLICK =
@@ -997,6 +1038,97 @@
         }
     }
 
+    /**
+     * Class with information of touch delegated views and regions.
+     */
+    public static final class TouchDelegateInfoCompat {
+        final TouchDelegateInfo mInfo;
+
+        /**
+         * Create a new instance of {@link TouchDelegateInfoCompat}.
+         *
+         * @param targetMap A map from regions (in view coordinates) to delegated views.
+         */
+        public TouchDelegateInfoCompat(@NonNull Map<Region, View> targetMap) {
+            if (BuildCompat.isAtLeastQ()) {
+                mInfo = new TouchDelegateInfo(targetMap);
+            } else {
+                mInfo = null;
+            }
+        }
+
+        TouchDelegateInfoCompat(@NonNull TouchDelegateInfo info) {
+            mInfo = info;
+        }
+
+        /**
+         * Returns the number of touch delegate target region.
+         * <p>
+         * Compatibility:
+         * <ul>
+         *     <li>API &lt; 29: Always returns {@code 0}</li>
+         * </ul>
+         *
+         * @return Number of touch delegate target region.
+         */
+        public @IntRange(from = 0) int getRegionCount() {
+            if (BuildCompat.isAtLeastQ()) {
+                return mInfo.getRegionCount();
+            }
+            return 0;
+        }
+
+        /**
+         * Return the {@link Region} at the given index.
+         * <p>
+         * Compatibility:
+         * <ul>
+         *     <li>API &lt; 29: Always returns {@code null}</li>
+         * </ul>
+         *
+         * @param index The desired index, must be between 0 and {@link #getRegionCount()}-1.
+         * @return Returns the {@link Region} stored at the given index.
+         */
+        @Nullable
+        public Region getRegionAt(@IntRange(from = 0) int index) {
+            if (BuildCompat.isAtLeastQ()) {
+                return mInfo.getRegionAt(index);
+            }
+            return null;
+        }
+
+        /**
+         * Return the target {@link AccessibilityNodeInfoCompat} for the given {@link Region}.
+         * <p>
+         *   <strong>Note:</strong> This api can only be called from
+         *   {@link android.accessibilityservice.AccessibilityService}.
+         * </p>
+         * <p>
+         *   <strong>Note:</strong> It is a client responsibility to recycle the
+         *     received info by calling {@link AccessibilityNodeInfo#recycle()}
+         *     to avoid creating of multiple instances.
+         * </p>
+         * <p>
+         * Compatibility:
+         * <ul>
+         *     <li>API &lt; 29: Always returns {@code null}</li>
+         * </ul>
+         *
+         * @param region The region retrieved from {@link #getRegionAt(int)}.
+         * @return The target node associates with the given region.
+         */
+        @Nullable
+        public AccessibilityNodeInfoCompat getTargetForRegion(@NonNull Region region) {
+            if (BuildCompat.isAtLeastQ()) {
+                AccessibilityNodeInfo info = mInfo.getTargetForRegion(region);
+                if (info != null) {
+                    return AccessibilityNodeInfoCompat.wrap(info);
+                }
+            }
+            return null;
+        }
+    }
+
     private static final String ROLE_DESCRIPTION_KEY =
             "AccessibilityNodeInfo.roleDescription";
 
@@ -1032,6 +1164,7 @@
     private static final int BOOLEAN_PROPERTY_SCREEN_READER_FOCUSABLE = 0x00000001;
     private static final int BOOLEAN_PROPERTY_IS_HEADING = 0x00000002;
     private static final int BOOLEAN_PROPERTY_IS_SHOWING_HINT = 0x00000004;
+    private static final int BOOLEAN_PROPERTY_IS_TEXT_ENTRY_KEY = 0x00000008;
 
     private final AccessibilityNodeInfo mInfo;
 
@@ -1989,16 +2122,28 @@
     }
 
     /**
-     * Gets the node bounds in parent coordinates.
+     * Gets the node bounds in the viewParent's coordinates.
+     * {@link #getParent()} does not represent the source's viewParent.
+     * Instead it represents the result of {@link View#getParentForAccessibility()},
+     * which returns the closest ancestor where {@link View#isImportantForAccessibility()} is true.
+     * So this method is not reliable.
      *
      * @param outBounds The output node bounds.
+     *
+     * @deprecated Use {@link #getBoundsInScreen(Rect)} instead.
      */
+    @Deprecated
     public void getBoundsInParent(Rect outBounds) {
         mInfo.getBoundsInParent(outBounds);
     }
 
     /**
-     * Sets the node bounds in parent coordinates.
+     * Sets the node bounds in the viewParent's coordinates.
+     * {@link #getParent()} does not represent the source's viewParent.
+     * Instead it represents the result of {@link View#getParentForAccessibility()},
+     * which returns the closest ancestor where {@link View#isImportantForAccessibility()} is true.
+     * So this method is not reliable.
+     *
      * <p>
      * <strong>Note:</strong> Cannot be called from an
      * {@link android.accessibilityservice.AccessibilityService}. This class is
@@ -2007,7 +2152,10 @@
      *
      * @param bounds The node bounds.
      * @throws IllegalStateException If called from an AccessibilityService.
+     *
+     * @deprecated Accessibility services should not care about these bounds.
      */
+    @Deprecated
     public void setBoundsInParent(Rect bounds) {
         mInfo.setBoundsInParent(bounds);
     }
@@ -3659,6 +3807,37 @@
     }
 
     /**
+     * Returns whether node represents a text entry key that is part of a keyboard or keypad.
+     *
+     * @return {@code true} if the node is a text entry key, {@code false} otherwise.
+     */
+    public boolean isTextEntryKey() {
+        if (BuildCompat.isAtLeastQ()) {
+            return mInfo.isTextEntryKey();
+        }
+        return getBooleanProperty(BOOLEAN_PROPERTY_IS_TEXT_ENTRY_KEY);
+    }
+
+    /**
+     * Sets whether the node represents a text entry key that is part of a keyboard or keypad.
+     * <p>This method has no effect below API 19</p>
+     * <p>
+     *   <strong>Note:</strong> Cannot be called from an
+     *   {@link android.accessibilityservice.AccessibilityService}.
+     *   This class is made immutable before being delivered to an AccessibilityService.
+     * </p>
+     *
+     * @param isTextEntryKey {@code true} if the node is a text entry key, {@code false} otherwise.
+     */
+    public void setTextEntryKey(boolean isTextEntryKey) {
+        if (BuildCompat.isAtLeastQ()) {
+            mInfo.setTextEntryKey(isTextEntryKey);
+        } else {
+            setBooleanProperty(BOOLEAN_PROPERTY_IS_TEXT_ENTRY_KEY, isTextEntryKey);
+        }
+    }
+
+    /**
      * Refreshes this info with the latest state of the view it represents.
      * <p>
      * <strong>Note:</strong> If this method returns false this info is obsolete
@@ -3717,6 +3896,55 @@
         }
     }
 
+    /**
+     * Get the {@link TouchDelegateInfoCompat} for touch delegate behavior with the represented
+     * view. It is possible for the same node to be pointed to by several regions. Use
+     * {@link TouchDelegateInfoCompat#getRegionAt(int)} to get touch delegate target
+     * {@link Region}, and {@link TouchDelegateInfoCompat#getTargetForRegion(Region)}
+     * for {@link AccessibilityNodeInfoCompat} from the given region.
+     * <p>
+     * Compatibility:
+     * <ul>
+     *     <li>API &lt; 29: Always returns {@code null}</li>
+     * </ul>
+     *
+     * @return {@link TouchDelegateInfoCompat} or {@code null} if there are no touch delegates
+     * in this node.
+     */
+    @Nullable
+    public TouchDelegateInfoCompat getTouchDelegateInfo() {
+        if (BuildCompat.isAtLeastQ()) {
+            TouchDelegateInfo delegateInfo = mInfo.getTouchDelegateInfo();
+            if (delegateInfo != null) {
+                return new TouchDelegateInfoCompat(delegateInfo);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Set touch delegate info if the represented view has a {@link android.view.TouchDelegate}.
+     * <p>
+     *   <strong>Note:</strong> Cannot be called from an
+     *   {@link android.accessibilityservice.AccessibilityService}.
+     *   This class is made immutable before being delivered to an
+     *   AccessibilityService.
+     * </p>
+     * <p>
+     * Compatibility:
+     * <ul>
+     *     <li>API &lt; 29: No-op</li>
+     * </ul>
+     *
+     * @param delegatedInfo {@link TouchDelegateInfoCompat}
+     * @throws IllegalStateException If called from an AccessibilityService.
+     */
+    public void setTouchDelegateInfo(@NonNull TouchDelegateInfoCompat delegatedInfo) {
+        if (BuildCompat.isAtLeastQ()) {
+            mInfo.setTouchDelegateInfo(delegatedInfo.mInfo);
+        }
+    }
+
     @Override
     public int hashCode() {
         return (mInfo == null) ? 0 : mInfo.hashCode();
diff --git a/core/src/main/java/androidx/core/widget/TextViewCompat.java b/core/src/main/java/androidx/core/widget/TextViewCompat.java
index 9597110..bf5da4e 100644
--- a/core/src/main/java/androidx/core/widget/TextViewCompat.java
+++ b/core/src/main/java/androidx/core/widget/TextViewCompat.java
@@ -26,6 +26,7 @@
 
 import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX;
 
+import android.annotation.SuppressLint;
 import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
@@ -60,6 +61,7 @@
 import androidx.annotation.RequiresApi;
 import androidx.annotation.RestrictTo;
 import androidx.annotation.StyleRes;
+import androidx.core.os.BuildCompat;
 import androidx.core.text.PrecomputedTextCompat;
 import androidx.core.util.Preconditions;
 
@@ -878,14 +880,21 @@
      * @param precomputed the precomputed text
      * @throws IllegalArgumentException if precomputed text is not compatible with textView.
      */
+    @SuppressLint("NewApi")  // TODO: Remove once Q SDK is released
     public static void setPrecomputedText(@NonNull TextView textView,
                                           @NonNull PrecomputedTextCompat precomputed) {
 
-        PrecomputedTextCompat.Params param = TextViewCompat.getTextMetricsParams(textView);
-        if (!param.equalsWithoutTextDirection(precomputed.getParams())) {
-            throw new IllegalArgumentException("Given text can not be applied to TextView.");
+        if (BuildCompat.isAtLeastQ()) {
+            // Framework can not understand PrecomptedTextCompat. Pass underlying PrecomputedText.
+            // Parameter check is also done by framework.
+            textView.setText(precomputed.getPrecomputedText());
+        } else {
+            PrecomputedTextCompat.Params param = TextViewCompat.getTextMetricsParams(textView);
+            if (!param.equalsWithoutTextDirection(precomputed.getParams())) {
+                throw new IllegalArgumentException("Given text can not be applied to TextView.");
+            }
+            textView.setText(precomputed);
         }
-        textView.setText(precomputed);
     }
 
     /**
diff --git a/development/studio/idea.properties b/development/studio/idea.properties
index 47930b3..91a1949 100644
--- a/development/studio/idea.properties
+++ b/development/studio/idea.properties
@@ -5,12 +5,12 @@
 #---------------------------------------------------------------------
 # Uncomment this option if you want to customize path to IDE config folder. Make sure you're using forward slashes.
 #---------------------------------------------------------------------
-idea.config.path=${user.home}/.AndroidStudioAndroidX/config
+idea.config.path=${user.home}/.AndroidStudioAndroidXPlatform/config
 
 #---------------------------------------------------------------------
 # Uncomment this option if you want to customize path to IDE system folder. Make sure you're using forward slashes.
 #---------------------------------------------------------------------
-idea.system.path=${user.home}/.AndroidStudioAndroidX/system
+idea.system.path=${user.home}/.AndroidStudioAndroidXPlatform/system
 
 #---------------------------------------------------------------------
 # Uncomment this option if you want to customize path to user installed plugins folder. Make sure you're using forward slashes.
diff --git a/documentfile/src/main/java/androidx/documentfile/provider/DocumentFile.java b/documentfile/src/main/java/androidx/documentfile/provider/DocumentFile.java
index 1ad8df4..93545bc 100644
--- a/documentfile/src/main/java/androidx/documentfile/provider/DocumentFile.java
+++ b/documentfile/src/main/java/androidx/documentfile/provider/DocumentFile.java
@@ -16,8 +16,8 @@
 
 package androidx.documentfile.provider;
 
-import android.content.ContentResolver;
 import android.content.Context;
+import android.content.ContentResolver;
 import android.content.Intent;
 import android.net.Uri;
 import android.os.Build;
diff --git a/documentfile/src/main/java/androidx/documentfile/provider/SingleDocumentFile.java b/documentfile/src/main/java/androidx/documentfile/provider/SingleDocumentFile.java
index 7cd4b8c..94545cd 100644
--- a/documentfile/src/main/java/androidx/documentfile/provider/SingleDocumentFile.java
+++ b/documentfile/src/main/java/androidx/documentfile/provider/SingleDocumentFile.java
@@ -97,6 +97,7 @@
     }
 
     @Override
+    @SuppressWarnings("deprecation")
     public boolean delete() {
         try {
             return DocumentsContract.deleteDocument(mContext.getContentResolver(), mUri);
diff --git a/documentfile/src/main/java/androidx/documentfile/provider/TreeDocumentFile.java b/documentfile/src/main/java/androidx/documentfile/provider/TreeDocumentFile.java
index 9cc20d6..65017b7 100644
--- a/documentfile/src/main/java/androidx/documentfile/provider/TreeDocumentFile.java
+++ b/documentfile/src/main/java/androidx/documentfile/provider/TreeDocumentFile.java
@@ -47,6 +47,7 @@
     }
 
     @Nullable
+    @SuppressWarnings("deprecation")
     private static Uri createFile(Context context, Uri self, String mimeType,
             String displayName) {
         try {
@@ -118,6 +119,7 @@
     }
 
     @Override
+    @SuppressWarnings("deprecation")
     public boolean delete() {
         try {
             return DocumentsContract.deleteDocument(mContext.getContentResolver(), mUri);
@@ -174,6 +176,7 @@
     }
 
     @Override
+    @SuppressWarnings("deprecation")
     public boolean renameTo(String displayName) {
         try {
             final Uri result = DocumentsContract.renameDocument(
diff --git a/drawerlayout/build.gradle b/drawerlayout/build.gradle
index 2d91616..a59a60c 100644
--- a/drawerlayout/build.gradle
+++ b/drawerlayout/build.gradle
@@ -1,6 +1,8 @@
 import androidx.build.LibraryGroups
 import androidx.build.LibraryVersions
 
+import static androidx.build.dependencies.DependenciesKt.*
+
 plugins {
     id("AndroidXPlugin")
     id("com.android.library")
@@ -10,6 +12,18 @@
     api(project(":annotation"))
     api(project(":core"))
     api(project(":customview"))
+
+    androidTestImplementation(TEST_EXT_JUNIT)
+    androidTestImplementation(TEST_CORE)
+    androidTestImplementation(TEST_RUNNER)
+    androidTestImplementation(TEST_RULES)
+    androidTestImplementation(TRUTH)
+    androidTestImplementation(ESPRESSO_CORE, libs.exclude_for_espresso)
+    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(':internal-testutils'), {
+        exclude group: 'androidx.appcompat', module: 'appcompat'
+    }
 }
 
 androidx {
diff --git a/drawerlayout/src/androidTest/AndroidManifest.xml b/drawerlayout/src/androidTest/AndroidManifest.xml
new file mode 100644
index 0000000..2c86c12
--- /dev/null
+++ b/drawerlayout/src/androidTest/AndroidManifest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2019 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.support.v7.appcompat.test">
+    <uses-sdk android:targetSdkVersion="${target-sdk-version}"/>
+
+    <application
+        android:supportsRtl="true">
+        <activity android:name="androidx.drawerlayout.app.DrawerLayoutTestActivity"/>
+    </application>
+</manifest>
diff --git a/drawerlayout/src/androidTest/java/androidx/drawerlayout/app/DrawerLayoutTest.java b/drawerlayout/src/androidTest/java/androidx/drawerlayout/app/DrawerLayoutTest.java
new file mode 100644
index 0000000..c51e4ea
--- /dev/null
+++ b/drawerlayout/src/androidTest/java/androidx/drawerlayout/app/DrawerLayoutTest.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.drawerlayout.app;
+
+
+import static androidx.drawerlayout.testutils.DrawerLayoutActions.closeDrawer;
+import static androidx.drawerlayout.testutils.DrawerLayoutActions.openDrawer;
+import static androidx.test.espresso.Espresso.onView;
+import static androidx.test.espresso.matcher.ViewMatchers.withId;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.graphics.Rect;
+import android.view.View;
+
+import androidx.core.os.BuildCompat;
+import androidx.core.view.GravityCompat;
+import androidx.core.view.ViewCompat;
+import androidx.drawerlayout.test.R;
+import androidx.drawerlayout.widget.DrawerLayout;
+import androidx.test.espresso.NoMatchingViewException;
+import androidx.test.espresso.ViewAssertion;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+import androidx.test.rule.ActivityTestRule;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+
+@RunWith(AndroidJUnit4.class)
+public class DrawerLayoutTest {
+    @Rule
+    public final ActivityTestRule<DrawerLayoutTestActivity> mActivityTestRule =
+            new ActivityTestRule<>(DrawerLayoutTestActivity.class);
+
+    private DrawerLayout mDrawerLayout;
+
+    private View mDrawer;
+
+    private View mContentView;
+
+    @Before
+    public void setUp() {
+        final DrawerLayoutTestActivity activity = mActivityTestRule.getActivity();
+        mDrawerLayout = activity.findViewById(R.id.drawer_layout);
+        mDrawer = mDrawerLayout.findViewById(R.id.drawer);
+        mContentView = mDrawerLayout.findViewById(R.id.content);
+
+        // Close the drawer to reset the state for the next test
+        onView(withId(R.id.drawer_layout)).perform(closeDrawer(GravityCompat.START));
+    }
+
+    @Test
+    @SmallTest
+    public void testSystemGestureExclusionRects() {
+        if (!BuildCompat.isAtLeastQ()) {
+            // Not expected on old device
+            return;
+        }
+
+        onView(withId(R.id.drawer_layout)).check(new ViewAssertion() {
+            @Override
+            public void check(View view, NoMatchingViewException noViewFoundException) {
+                final List<Rect> exclusionRects = ViewCompat.getSystemGestureExclusionRects(view);
+                assertTrue("view is laid out", view.isLaidOut());
+                assertFalse("exclusion rects empty", exclusionRects.isEmpty());
+                for (Rect rect : exclusionRects) {
+                    assertFalse("rect " + rect + " is empty", rect.isEmpty());
+                    assertEquals("rect height (" + rect.height() + ") == view height ("
+                            + view.getHeight() + ")", view.getHeight(), rect.height());
+                }
+            }
+        });
+
+        onView(withId(R.id.drawer_layout)).perform(openDrawer(mDrawer));
+
+        assertTrue("open drawer exclusion rects empty",
+                ViewCompat.getSystemGestureExclusionRects(mDrawerLayout).isEmpty());
+
+        onView(withId(R.id.drawer_layout)).perform(closeDrawer(mDrawer));
+
+        final List<Rect> reclosed = ViewCompat.getSystemGestureExclusionRects(mDrawerLayout);
+        assertFalse("re-closed drawer has exclusion rects", reclosed.isEmpty());
+        for (Rect rect : reclosed) {
+            assertFalse("re-closed drawer exclusion rect should not be empty", rect.isEmpty());
+            assertEquals("re-closed drawer rect correct height",
+                    mDrawerLayout.getHeight(), rect.height());
+        }
+    }
+}
diff --git a/drawerlayout/src/androidTest/java/androidx/drawerlayout/app/DrawerLayoutTestActivity.java b/drawerlayout/src/androidTest/java/androidx/drawerlayout/app/DrawerLayoutTestActivity.java
new file mode 100644
index 0000000..a9cd5eb
--- /dev/null
+++ b/drawerlayout/src/androidTest/java/androidx/drawerlayout/app/DrawerLayoutTestActivity.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.drawerlayout.app;
+
+import android.os.Bundle;
+
+import androidx.core.app.ComponentActivity;
+import androidx.drawerlayout.test.R;
+
+public class DrawerLayoutTestActivity extends ComponentActivity {
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.drawer_layout_test_activity);
+    }
+}
diff --git a/drawerlayout/src/androidTest/java/androidx/drawerlayout/testutils/DrawerLayoutActions.java b/drawerlayout/src/androidTest/java/androidx/drawerlayout/testutils/DrawerLayoutActions.java
new file mode 100644
index 0000000..b9f735a
--- /dev/null
+++ b/drawerlayout/src/androidTest/java/androidx/drawerlayout/testutils/DrawerLayoutActions.java
@@ -0,0 +1,350 @@
+/*
+ * 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.drawerlayout.testutils;
+
+import static androidx.test.espresso.matcher.ViewMatchers.isAssignableFrom;
+
+import android.view.View;
+
+import androidx.annotation.Nullable;
+import androidx.drawerlayout.widget.DrawerLayout;
+import androidx.test.espresso.Espresso;
+import androidx.test.espresso.IdlingResource;
+import androidx.test.espresso.UiController;
+import androidx.test.espresso.ViewAction;
+
+import org.hamcrest.Matcher;
+
+public class DrawerLayoutActions {
+    /**
+     * Drawer listener that serves as Espresso's {@link IdlingResource} and notifies the registered
+     * callback when the drawer gets to STATE_IDLE state.
+     */
+    private static class CustomDrawerListener
+            implements DrawerLayout.DrawerListener, IdlingResource {
+        private int mCurrState = DrawerLayout.STATE_IDLE;
+
+        @Nullable
+        private IdlingResource.ResourceCallback mCallback;
+
+        private boolean mNeedsIdle = false;
+
+        @Override
+        public void registerIdleTransitionCallback(ResourceCallback resourceCallback) {
+            mCallback = resourceCallback;
+        }
+
+        @Override
+        public String getName() {
+            return "Drawer listener";
+        }
+
+        @Override
+        public boolean isIdleNow() {
+            if (!mNeedsIdle) {
+                return true;
+            } else {
+                return mCurrState == DrawerLayout.STATE_IDLE;
+            }
+        }
+
+        @Override
+        public void onDrawerClosed(View drawer) {
+            if (mCurrState == DrawerLayout.STATE_IDLE) {
+                if (mCallback != null) {
+                    mCallback.onTransitionToIdle();
+                }
+            }
+        }
+
+        @Override
+        public void onDrawerOpened(View drawer) {
+            if (mCurrState == DrawerLayout.STATE_IDLE) {
+                if (mCallback != null) {
+                    mCallback.onTransitionToIdle();
+                }
+            }
+        }
+
+        @Override
+        public void onDrawerSlide(View drawer, float slideOffset) {
+        }
+
+        @Override
+        public void onDrawerStateChanged(int state) {
+            mCurrState = state;
+            if (state == DrawerLayout.STATE_IDLE) {
+                if (mCallback != null) {
+                    mCallback.onTransitionToIdle();
+                }
+            }
+        }
+    }
+
+    private abstract static class WrappedViewAction implements ViewAction {
+    }
+
+    public static ViewAction wrap(final ViewAction baseAction) {
+        if (baseAction instanceof WrappedViewAction) {
+            throw new IllegalArgumentException("Don't wrap and already wrapped action");
+        }
+
+        return new WrappedViewAction() {
+            @Override
+            public Matcher<View> getConstraints() {
+                return baseAction.getConstraints();
+            }
+
+            @Override
+            public String getDescription() {
+                return baseAction.getDescription();
+            }
+
+            @Override
+            public void perform(UiController uiController, View view) {
+                final DrawerLayout drawer = (DrawerLayout) view;
+                // Add a custom tracker listener
+                final CustomDrawerListener customListener = new CustomDrawerListener();
+                drawer.addDrawerListener(customListener);
+
+                // Note that we're running the following block in a try-finally construct. This
+                // is needed since some of the wrapped actions are going to throw (expected)
+                // exceptions. If that happens, we still need to clean up after ourselves to
+                // leave the system (Espesso) in a good state.
+                try {
+                    // Register our listener as idling resource so that Espresso waits until the
+                    // wrapped action results in the drawer getting to the STATE_IDLE state
+                    Espresso.registerIdlingResources(customListener);
+                    baseAction.perform(uiController, view);
+                    customListener.mNeedsIdle = true;
+                    uiController.loopMainThreadUntilIdle();
+                    customListener.mNeedsIdle = false;
+                } finally {
+                    // Unregister our idling resource
+                    Espresso.unregisterIdlingResources(customListener);
+                    // And remove our tracker listener from DrawerLayout
+                    drawer.removeDrawerListener(customListener);
+                }
+            }
+        };
+    }
+
+    /**
+     * Opens the drawer at the specified edge gravity.
+     */
+    public static ViewAction openDrawer(final int drawerEdgeGravity, final boolean animate) {
+        return wrap(new ViewAction() {
+            @Override
+            public Matcher<View> getConstraints() {
+                return isAssignableFrom(DrawerLayout.class);
+            }
+
+            @Override
+            public String getDescription() {
+                return "Opens the drawer";
+            }
+
+            @Override
+            public void perform(UiController uiController, View view) {
+                uiController.loopMainThreadUntilIdle();
+
+                DrawerLayout drawerLayout = (DrawerLayout) view;
+                drawerLayout.openDrawer(drawerEdgeGravity, animate);
+            }
+        });
+    }
+
+    /**
+     * Opens the drawer at the specified edge gravity.
+     */
+    public static ViewAction openDrawer(final int drawerEdgeGravity) {
+        return wrap(new ViewAction() {
+            @Override
+            public Matcher<View> getConstraints() {
+                return isAssignableFrom(DrawerLayout.class);
+            }
+
+            @Override
+            public String getDescription() {
+                return "Opens the drawer";
+            }
+
+            @Override
+            public void perform(UiController uiController, View view) {
+                uiController.loopMainThreadUntilIdle();
+
+                DrawerLayout drawerLayout = (DrawerLayout) view;
+                drawerLayout.openDrawer(drawerEdgeGravity);
+            }
+        });
+    }
+
+    /**
+     * Opens the drawer.
+     */
+    public static ViewAction openDrawer(final View drawerView) {
+        return wrap(new ViewAction() {
+            @Override
+            public Matcher<View> getConstraints() {
+                return isAssignableFrom(DrawerLayout.class);
+            }
+
+            @Override
+            public String getDescription() {
+                return "Opens the drawer";
+            }
+
+            @Override
+            public void perform(UiController uiController, View view) {
+                uiController.loopMainThreadUntilIdle();
+
+                DrawerLayout drawerLayout = (DrawerLayout) view;
+                drawerLayout.openDrawer(drawerView);
+            }
+        });
+    }
+
+    /**
+     * Closes the drawer at the specified edge gravity.
+     */
+    public static ViewAction closeDrawer(final int drawerEdgeGravity) {
+        return wrap(new ViewAction() {
+            @Override
+            public Matcher<View> getConstraints() {
+                return isAssignableFrom(DrawerLayout.class);
+            }
+
+            @Override
+            public String getDescription() {
+                return "Closes the drawer";
+            }
+
+            @Override
+            public void perform(UiController uiController, View view) {
+                uiController.loopMainThreadUntilIdle();
+
+                DrawerLayout drawerLayout = (DrawerLayout) view;
+                drawerLayout.closeDrawer(drawerEdgeGravity);
+            }
+        });
+    }
+
+    /**
+     * Closes the drawer at the specified edge gravity.
+     */
+    public static ViewAction closeDrawer(final int drawerEdgeGravity, final boolean animate) {
+        return wrap(new ViewAction() {
+            @Override
+            public Matcher<View> getConstraints() {
+                return isAssignableFrom(DrawerLayout.class);
+            }
+
+            @Override
+            public String getDescription() {
+                return "Closes the drawer";
+            }
+
+            @Override
+            public void perform(UiController uiController, View view) {
+                uiController.loopMainThreadUntilIdle();
+
+                DrawerLayout drawerLayout = (DrawerLayout) view;
+                drawerLayout.closeDrawer(drawerEdgeGravity, animate);
+            }
+        });
+    }
+
+    /**
+     * Closes the drawer.
+     */
+    public static ViewAction closeDrawer(final View drawerView) {
+        return wrap(new ViewAction() {
+            @Override
+            public Matcher<View> getConstraints() {
+                return isAssignableFrom(DrawerLayout.class);
+            }
+
+            @Override
+            public String getDescription() {
+                return "Closes the drawer";
+            }
+
+            @Override
+            public void perform(UiController uiController, View view) {
+                uiController.loopMainThreadUntilIdle();
+
+                DrawerLayout drawerLayout = (DrawerLayout) view;
+                drawerLayout.closeDrawer(drawerView);
+            }
+        });
+    }
+
+    /**
+     * Sets the lock mode for the drawer at the specified edge gravity.
+     */
+    public static ViewAction setDrawerLockMode(final int lockMode, final int drawerEdgeGravity) {
+        return wrap(new ViewAction() {
+            @Override
+            public Matcher<View> getConstraints() {
+                return isAssignableFrom(DrawerLayout.class);
+            }
+
+            @Override
+            public String getDescription() {
+                return "Sets drawer lock mode";
+            }
+
+            @Override
+            public void perform(UiController uiController, View view) {
+                uiController.loopMainThreadUntilIdle();
+
+                DrawerLayout drawerLayout = (DrawerLayout) view;
+                drawerLayout.setDrawerLockMode(lockMode, drawerEdgeGravity);
+
+                uiController.loopMainThreadUntilIdle();
+            }
+        });
+    }
+
+    /**
+     * Sets the lock mode for the drawer.
+     */
+    public static ViewAction setDrawerLockMode(final int lockMode, final View drawerView) {
+        return wrap(new ViewAction() {
+            @Override
+            public Matcher<View> getConstraints() {
+                return isAssignableFrom(DrawerLayout.class);
+            }
+
+            @Override
+            public String getDescription() {
+                return "Sets drawer lock mode";
+            }
+
+            @Override
+            public void perform(UiController uiController, View view) {
+                uiController.loopMainThreadUntilIdle();
+
+                DrawerLayout drawerLayout = (DrawerLayout) view;
+                drawerLayout.setDrawerLockMode(lockMode, drawerView);
+
+                uiController.loopMainThreadUntilIdle();
+            }
+        });
+    }
+}
+
diff --git a/drawerlayout/src/androidTest/res/layout/drawer_layout_test_activity.xml b/drawerlayout/src/androidTest/res/layout/drawer_layout_test_activity.xml
new file mode 100644
index 0000000..b90f445
--- /dev/null
+++ b/drawerlayout/src/androidTest/res/layout/drawer_layout_test_activity.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2019 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<androidx.drawerlayout.widget.DrawerLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/drawer_layout"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <FrameLayout
+        android:id="@+id/content"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent" />
+    <FrameLayout
+        android:id="@+id/drawer"
+        android:layout_width="300dp"
+        android:layout_height="match_parent"
+        android:layout_gravity="left" />
+</androidx.drawerlayout.widget.DrawerLayout>
diff --git a/drawerlayout/src/main/java/androidx/drawerlayout/widget/DrawerLayout.java b/drawerlayout/src/main/java/androidx/drawerlayout/widget/DrawerLayout.java
index 9236c01..abe947d 100644
--- a/drawerlayout/src/main/java/androidx/drawerlayout/widget/DrawerLayout.java
+++ b/drawerlayout/src/main/java/androidx/drawerlayout/widget/DrawerLayout.java
@@ -52,6 +52,7 @@
 import androidx.annotation.RestrictTo;
 import androidx.core.content.ContextCompat;
 import androidx.core.graphics.drawable.DrawableCompat;
+import androidx.core.os.BuildCompat;
 import androidx.core.view.AccessibilityDelegateCompat;
 import androidx.core.view.GravityCompat;
 import androidx.core.view.ViewCompat;
@@ -63,6 +64,7 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -248,6 +250,8 @@
     private Rect mChildHitRect;
     private Matrix mChildInvertedMatrix;
 
+    private static boolean sSupplyGestureExclusion = BuildCompat.isAtLeastQ();
+
     /**
      * Listener for monitoring events about drawers.
      */
@@ -847,6 +851,25 @@
                 }
             }
         }
+
+        if (sSupplyGestureExclusion) {
+            final List<Rect> rects = new ArrayList<>();
+            final int childCount = getChildCount();
+            for (int i = 0; i < childCount; i++) {
+                final View child = getChildAt(i);
+                if (isContentView(child) || isDrawerOpen(child)) {
+                    continue;
+                }
+
+                if (checkDrawerViewAbsoluteGravity(child, Gravity.LEFT)) {
+                    rects.add(new Rect(0, 0, mLeftDragger.getEdgeSize(), getHeight()));
+                } else {
+                    final int width = getWidth();
+                    rects.add(new Rect(width - mRightDragger.getEdgeSize(), 0, width, getHeight()));
+                }
+            }
+            ViewCompat.setSystemGestureExclusionRects(this, rects);
+        }
     }
 
     void dispatchOnDrawerClosed(View drawerView) {
@@ -1027,6 +1050,8 @@
     }
 
     @SuppressLint("WrongConstant")
+    // Remove deprecation suppression once b/120984242 is resolved.
+    @SuppressWarnings("deprecation")
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         int widthMode = MeasureSpec.getMode(widthMeasureSpec);
@@ -1209,7 +1234,9 @@
     protected void onLayout(boolean changed, int l, int t, int r, int b) {
         mInLayout = true;
         final int width = r - l;
+        final int layoutHeight = b - t;
         final int childCount = getChildCount();
+        List<Rect> gestureExclusionRects = null;
         for (int i = 0; i < childCount; i++) {
             final View child = getChildAt(i);
 
@@ -1232,9 +1259,23 @@
                 if (checkDrawerViewAbsoluteGravity(child, Gravity.LEFT)) {
                     childLeft = -childWidth + (int) (childWidth * lp.onScreen);
                     newOffset = (float) (childWidth + childLeft) / childWidth;
+                    if (sSupplyGestureExclusion && !isDrawerOpen(child)) {
+                        if (gestureExclusionRects == null) {
+                            gestureExclusionRects = new ArrayList<>();
+                        }
+                        gestureExclusionRects.add(
+                                new Rect(0, 0, mLeftDragger.getEdgeSize(), layoutHeight));
+                    }
                 } else { // Right; onMeasure checked for us.
                     childLeft = width - (int) (childWidth * lp.onScreen);
                     newOffset = (float) (width - childLeft) / childWidth;
+                    if (sSupplyGestureExclusion && !isDrawerOpen(child)) {
+                        if (gestureExclusionRects == null) {
+                            gestureExclusionRects = new ArrayList<>();
+                        }
+                        gestureExclusionRects.add(new Rect(
+                                width - mRightDragger.getEdgeSize(), 0, width, layoutHeight));
+                    }
                 }
 
                 final boolean changeOffset = newOffset != lp.onScreen;
@@ -1285,6 +1326,12 @@
                 }
             }
         }
+        // Always set exclusion rects; set an empty list if we had no drawer views.
+        if (gestureExclusionRects != null) {
+            ViewCompat.setSystemGestureExclusionRects(this, gestureExclusionRects);
+        } else {
+            ViewCompat.setSystemGestureExclusionRects(this, Collections.<Rect>emptyList());
+        }
         mInLayout = false;
         mFirstLayout = false;
     }
@@ -1313,6 +1360,8 @@
         }
     }
 
+    // Remove deprecation suppression once b/120984242 is resolved.
+    @SuppressWarnings("deprecation")
     private static boolean hasOpaqueBackground(View v) {
         final Drawable bg = v.getBackground();
         if (bg != null) {
diff --git a/emoji/core/src/main/java/androidx/emoji/widget/EmojiExtractTextLayout.java b/emoji/core/src/main/java/androidx/emoji/widget/EmojiExtractTextLayout.java
index b9d6d1b..01c1494 100644
--- a/emoji/core/src/main/java/androidx/emoji/widget/EmojiExtractTextLayout.java
+++ b/emoji/core/src/main/java/androidx/emoji/widget/EmojiExtractTextLayout.java
@@ -32,6 +32,7 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.RequiresApi;
+import androidx.core.os.BuildCompat;
 import androidx.emoji.R;
 import androidx.emoji.text.EmojiCompat;
 import androidx.emoji.text.EmojiSpan;
@@ -114,6 +115,11 @@
             if (attrs != null) {
                 final TypedArray a = context.obtainStyledAttributes(attrs,
                         R.styleable.EmojiExtractTextLayout, defStyleAttr, defStyleRes);
+                if (BuildCompat.isAtLeastQ()) {
+                    saveAttributeDataForStyleable(
+                            context, R.styleable.EmojiExtractTextLayout, attrs, a, defStyleAttr,
+                            defStyleRes);
+                }
                 final int replaceStrategy = a.getInteger(
                         R.styleable.EmojiExtractTextLayout_emojiReplaceStrategy,
                         EmojiCompat.REPLACE_STRATEGY_DEFAULT);
diff --git a/fakeannotations/build.gradle b/fakeannotations/build.gradle
new file mode 100644
index 0000000..3302c21
--- /dev/null
+++ b/fakeannotations/build.gradle
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+apply plugin: 'java-library'
+
+dependencies {
+    implementation fileTree(dir: 'libs', include: ['*.jar'])
+}
+
+sourceCompatibility = "7"
+targetCompatibility = "7"
diff --git a/fakeannotations/src/main/java/androidx/annotation/RecentlyNonNull.java b/fakeannotations/src/main/java/androidx/annotation/RecentlyNonNull.java
new file mode 100644
index 0000000..194aab1
--- /dev/null
+++ b/fakeannotations/src/main/java/androidx/annotation/RecentlyNonNull.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package androidx.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.PACKAGE;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.CLASS;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+@Retention(CLASS)
+@Target({METHOD, PARAMETER, FIELD, LOCAL_VARIABLE, ANNOTATION_TYPE, PACKAGE})
+public @interface RecentlyNonNull {
+}
diff --git a/fakeannotations/src/main/java/androidx/annotation/RecentlyNullable.java b/fakeannotations/src/main/java/androidx/annotation/RecentlyNullable.java
new file mode 100644
index 0000000..4ccdf93
--- /dev/null
+++ b/fakeannotations/src/main/java/androidx/annotation/RecentlyNullable.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package androidx.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.PACKAGE;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.CLASS;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+@Retention(CLASS)
+@Target({METHOD, PARAMETER, FIELD, LOCAL_VARIABLE, ANNOTATION_TYPE, PACKAGE})
+public @interface RecentlyNullable {
+}
diff --git a/fragment/api/1.1.0-alpha03.txt b/fragment/api/1.1.0-alpha03.txt
index 8b5c94f..239fc9e3 100644
--- a/fragment/api/1.1.0-alpha03.txt
+++ b/fragment/api/1.1.0-alpha03.txt
@@ -163,6 +163,7 @@
     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);
diff --git a/fragment/api/1.1.0-alpha04.txt b/fragment/api/1.1.0-alpha04.txt
index 0883047..58f4d6e 100644
--- a/fragment/api/1.1.0-alpha04.txt
+++ b/fragment/api/1.1.0-alpha04.txt
@@ -164,6 +164,7 @@
     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);
diff --git a/fragment/api/1.1.0-alpha05.txt b/fragment/api/1.1.0-alpha05.txt
index e586a2f..47ba5f4 100644
--- a/fragment/api/1.1.0-alpha05.txt
+++ b/fragment/api/1.1.0-alpha05.txt
@@ -164,6 +164,7 @@
     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);
diff --git a/fragment/api/1.1.0-alpha06.txt b/fragment/api/1.1.0-alpha06.txt
index a5c77ae..6e285e8 100644
--- a/fragment/api/1.1.0-alpha06.txt
+++ b/fragment/api/1.1.0-alpha06.txt
@@ -165,6 +165,7 @@
     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);
diff --git a/fragment/api/1.1.0-alpha07.txt b/fragment/api/1.1.0-alpha07.txt
index a5c77ae..6e285e8 100644
--- a/fragment/api/1.1.0-alpha07.txt
+++ b/fragment/api/1.1.0-alpha07.txt
@@ -165,6 +165,7 @@
     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);
diff --git a/fragment/api/current.txt b/fragment/api/current.txt
index a5c77ae..6e285e8 100644
--- a/fragment/api/current.txt
+++ b/fragment/api/current.txt
@@ -165,6 +165,7 @@
     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);
diff --git a/gradle.properties b/gradle.properties
index c788833..5d0e134 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-org.gradle.jvmargs=-Xmx8g
+org.gradle.jvmargs=-Xmx8g -XX:MaxPermSize=8g
 org.gradle.daemon=true
 org.gradle.configureondemand=true
 org.gradle.parallel=true
diff --git a/graphics/drawable/animated/api/1.1.0-alpha01.txt b/graphics/drawable/animated/api/1.1.0-alpha01.txt
index 7542e29..70c9c23 100644
--- a/graphics/drawable/animated/api/1.1.0-alpha01.txt
+++ b/graphics/drawable/animated/api/1.1.0-alpha01.txt
@@ -25,6 +25,7 @@
     method public static void registerAnimationCallback(android.graphics.drawable.Drawable!, androidx.vectordrawable.graphics.drawable.Animatable2Compat.AnimationCallback!);
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter!);
+    method public void setColorFilter(int, android.graphics.PorterDuff.Mode!);
     method public void start();
     method public void stop();
     method public boolean unregisterAnimationCallback(androidx.vectordrawable.graphics.drawable.Animatable2Compat.AnimationCallback);
diff --git a/graphics/drawable/animated/api/1.1.0-alpha02.txt b/graphics/drawable/animated/api/1.1.0-alpha02.txt
index 7542e29..70c9c23 100644
--- a/graphics/drawable/animated/api/1.1.0-alpha02.txt
+++ b/graphics/drawable/animated/api/1.1.0-alpha02.txt
@@ -25,6 +25,7 @@
     method public static void registerAnimationCallback(android.graphics.drawable.Drawable!, androidx.vectordrawable.graphics.drawable.Animatable2Compat.AnimationCallback!);
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter!);
+    method public void setColorFilter(int, android.graphics.PorterDuff.Mode!);
     method public void start();
     method public void stop();
     method public boolean unregisterAnimationCallback(androidx.vectordrawable.graphics.drawable.Animatable2Compat.AnimationCallback);
diff --git a/graphics/drawable/animated/api/current.txt b/graphics/drawable/animated/api/current.txt
index 7542e29..70c9c23 100644
--- a/graphics/drawable/animated/api/current.txt
+++ b/graphics/drawable/animated/api/current.txt
@@ -25,6 +25,7 @@
     method public static void registerAnimationCallback(android.graphics.drawable.Drawable!, androidx.vectordrawable.graphics.drawable.Animatable2Compat.AnimationCallback!);
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter!);
+    method public void setColorFilter(int, android.graphics.PorterDuff.Mode!);
     method public void start();
     method public void stop();
     method public boolean unregisterAnimationCallback(androidx.vectordrawable.graphics.drawable.Animatable2Compat.AnimationCallback);
diff --git a/graphics/drawable/animated/src/main/java/androidx/vectordrawable/graphics/drawable/AnimatedVectorDrawableCompat.java b/graphics/drawable/animated/src/main/java/androidx/vectordrawable/graphics/drawable/AnimatedVectorDrawableCompat.java
index b0c84bd..7dd9e1d 100644
--- a/graphics/drawable/animated/src/main/java/androidx/vectordrawable/graphics/drawable/AnimatedVectorDrawableCompat.java
+++ b/graphics/drawable/animated/src/main/java/androidx/vectordrawable/graphics/drawable/AnimatedVectorDrawableCompat.java
@@ -397,6 +397,8 @@
         return mAnimatedVectorState.mVectorDrawable.isStateful();
     }
 
+    // Remove deprecation suppression once b/120984759 is resolved
+    @SuppressWarnings("deprecation")
     @Override
     public int getOpacity() {
         if (mDelegateDrawable != null) {
diff --git a/graphics/drawable/static/api/1.1.0-alpha01.txt b/graphics/drawable/static/api/1.1.0-alpha01.txt
index 3fda85b..34cf297 100644
--- a/graphics/drawable/static/api/1.1.0-alpha01.txt
+++ b/graphics/drawable/static/api/1.1.0-alpha01.txt
@@ -8,6 +8,7 @@
     method public int getOpacity();
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter!);
+    method public void setColorFilter(int, android.graphics.PorterDuff.Mode!);
   }
 
 }
diff --git a/graphics/drawable/static/api/1.1.0-alpha02.txt b/graphics/drawable/static/api/1.1.0-alpha02.txt
index 3fda85b..34cf297 100644
--- a/graphics/drawable/static/api/1.1.0-alpha02.txt
+++ b/graphics/drawable/static/api/1.1.0-alpha02.txt
@@ -8,6 +8,7 @@
     method public int getOpacity();
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter!);
+    method public void setColorFilter(int, android.graphics.PorterDuff.Mode!);
   }
 
 }
diff --git a/graphics/drawable/static/api/current.txt b/graphics/drawable/static/api/current.txt
index 3fda85b..34cf297 100644
--- a/graphics/drawable/static/api/current.txt
+++ b/graphics/drawable/static/api/current.txt
@@ -8,6 +8,7 @@
     method public int getOpacity();
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter!);
+    method public void setColorFilter(int, android.graphics.PorterDuff.Mode!);
   }
 
 }
diff --git a/gridlayout/src/main/java/androidx/gridlayout/widget/GridLayout.java b/gridlayout/src/main/java/androidx/gridlayout/widget/GridLayout.java
index c99c799..589e490 100644
--- a/gridlayout/src/main/java/androidx/gridlayout/widget/GridLayout.java
+++ b/gridlayout/src/main/java/androidx/gridlayout/widget/GridLayout.java
@@ -43,6 +43,7 @@
 import android.view.ViewGroup;
 import android.widget.LinearLayout;
 
+import androidx.core.os.BuildCompat;
 import androidx.core.view.GravityCompat;
 import androidx.core.view.ViewCompat;
 import androidx.core.view.ViewGroupCompat;
@@ -271,6 +272,9 @@
         super(context, attrs, defStyle);
         mDefaultGap = context.getResources().getDimensionPixelOffset(R.dimen.default_gap);
         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.GridLayout);
+        if (BuildCompat.isAtLeastQ()) {
+            saveAttributeDataForStyleable(context, R.styleable.GridLayout, attrs, a, defStyle, 0);
+        }
         try {
             setRowCount(a.getInt(ROW_COUNT, DEFAULT_COUNT));
             setColumnCount(a.getInt(COLUMN_COUNT, DEFAULT_COUNT));
diff --git a/leanback-preference/api/1.1.0-alpha01.txt b/leanback-preference/api/1.1.0-alpha01.txt
index 79e53fb..2ff4b27 100644
--- a/leanback-preference/api/1.1.0-alpha01.txt
+++ b/leanback-preference/api/1.1.0-alpha01.txt
@@ -21,6 +21,8 @@
     method @Deprecated public static androidx.leanback.preference.LeanbackListPreferenceDialogFragment! newInstanceMulti(String!);
     method @Deprecated public static androidx.leanback.preference.LeanbackListPreferenceDialogFragment! newInstanceSingle(String!);
     method @Deprecated public androidx.recyclerview.widget.RecyclerView.Adapter! onCreateAdapter();
+    method @Deprecated public android.view.View? onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
+    method @Deprecated public void onSaveInstanceState(android.os.Bundle!);
   }
 
   @Deprecated public class LeanbackListPreferenceDialogFragment.AdapterMulti extends androidx.recyclerview.widget.RecyclerView.Adapter<androidx.leanback.preference.LeanbackListPreferenceDialogFragment.ViewHolder> implements androidx.leanback.preference.LeanbackListPreferenceDialogFragment.ViewHolder.OnItemClickListener {
@@ -67,6 +69,7 @@
   @Deprecated public class LeanbackPreferenceDialogFragment extends android.app.Fragment {
     ctor @Deprecated public LeanbackPreferenceDialogFragment();
     method @Deprecated public androidx.preference.DialogPreference! getPreference();
+    method @Deprecated public void onCreate(android.os.Bundle!);
     field @Deprecated public static final String ARG_KEY = "key";
   }
 
@@ -88,8 +91,12 @@
 
   @Deprecated public abstract class LeanbackSettingsFragment extends android.app.Fragment implements androidx.preference.PreferenceFragment.OnPreferenceDisplayDialogCallback androidx.preference.PreferenceFragment.OnPreferenceStartFragmentCallback androidx.preference.PreferenceFragment.OnPreferenceStartScreenCallback {
     ctor @Deprecated public LeanbackSettingsFragment();
+    method @Deprecated public android.view.View! onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
+    method @Deprecated public void onPause();
     method @Deprecated public boolean onPreferenceDisplayDialog(androidx.preference.PreferenceFragment, androidx.preference.Preference!);
     method @Deprecated public abstract void onPreferenceStartInitialScreen();
+    method @Deprecated public void onResume();
+    method @Deprecated public void onViewCreated(android.view.View!, android.os.Bundle!);
     method @Deprecated public void startImmersiveFragment(android.app.Fragment);
     method @Deprecated public void startPreferenceFragment(android.app.Fragment);
   }
diff --git a/leanback-preference/api/1.1.0-alpha02.txt b/leanback-preference/api/1.1.0-alpha02.txt
index 5d40456..7d55268 100644
--- a/leanback-preference/api/1.1.0-alpha02.txt
+++ b/leanback-preference/api/1.1.0-alpha02.txt
@@ -22,6 +22,8 @@
     method @Deprecated public static androidx.leanback.preference.LeanbackListPreferenceDialogFragment! newInstanceMulti(String!);
     method @Deprecated public static androidx.leanback.preference.LeanbackListPreferenceDialogFragment! newInstanceSingle(String!);
     method @Deprecated public androidx.recyclerview.widget.RecyclerView.Adapter! onCreateAdapter();
+    method @Deprecated public android.view.View? onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
+    method @Deprecated public void onSaveInstanceState(android.os.Bundle!);
   }
 
   @Deprecated public class LeanbackListPreferenceDialogFragment.AdapterMulti extends androidx.recyclerview.widget.RecyclerView.Adapter<androidx.leanback.preference.LeanbackListPreferenceDialogFragment.ViewHolder> implements androidx.leanback.preference.LeanbackListPreferenceDialogFragment.ViewHolder.OnItemClickListener {
@@ -68,6 +70,7 @@
   @Deprecated public class LeanbackPreferenceDialogFragment extends android.app.Fragment {
     ctor @Deprecated public LeanbackPreferenceDialogFragment();
     method @Deprecated public androidx.preference.DialogPreference! getPreference();
+    method @Deprecated public void onCreate(android.os.Bundle!);
     field @Deprecated public static final String ARG_KEY = "key";
   }
 
@@ -89,8 +92,12 @@
 
   @Deprecated public abstract class LeanbackSettingsFragment extends android.app.Fragment implements androidx.preference.PreferenceFragment.OnPreferenceDisplayDialogCallback androidx.preference.PreferenceFragment.OnPreferenceStartFragmentCallback androidx.preference.PreferenceFragment.OnPreferenceStartScreenCallback {
     ctor @Deprecated public LeanbackSettingsFragment();
+    method @Deprecated public android.view.View! onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
+    method @Deprecated public void onPause();
     method @Deprecated public boolean onPreferenceDisplayDialog(androidx.preference.PreferenceFragment, androidx.preference.Preference!);
     method @Deprecated public abstract void onPreferenceStartInitialScreen();
+    method @Deprecated public void onResume();
+    method @Deprecated public void onViewCreated(android.view.View!, android.os.Bundle!);
     method @Deprecated public void startImmersiveFragment(android.app.Fragment);
     method @Deprecated public void startPreferenceFragment(android.app.Fragment);
   }
diff --git a/leanback-preference/api/current.txt b/leanback-preference/api/current.txt
index 5d40456..7d55268 100644
--- a/leanback-preference/api/current.txt
+++ b/leanback-preference/api/current.txt
@@ -22,6 +22,8 @@
     method @Deprecated public static androidx.leanback.preference.LeanbackListPreferenceDialogFragment! newInstanceMulti(String!);
     method @Deprecated public static androidx.leanback.preference.LeanbackListPreferenceDialogFragment! newInstanceSingle(String!);
     method @Deprecated public androidx.recyclerview.widget.RecyclerView.Adapter! onCreateAdapter();
+    method @Deprecated public android.view.View? onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
+    method @Deprecated public void onSaveInstanceState(android.os.Bundle!);
   }
 
   @Deprecated public class LeanbackListPreferenceDialogFragment.AdapterMulti extends androidx.recyclerview.widget.RecyclerView.Adapter<androidx.leanback.preference.LeanbackListPreferenceDialogFragment.ViewHolder> implements androidx.leanback.preference.LeanbackListPreferenceDialogFragment.ViewHolder.OnItemClickListener {
@@ -68,6 +70,7 @@
   @Deprecated public class LeanbackPreferenceDialogFragment extends android.app.Fragment {
     ctor @Deprecated public LeanbackPreferenceDialogFragment();
     method @Deprecated public androidx.preference.DialogPreference! getPreference();
+    method @Deprecated public void onCreate(android.os.Bundle!);
     field @Deprecated public static final String ARG_KEY = "key";
   }
 
@@ -89,8 +92,12 @@
 
   @Deprecated public abstract class LeanbackSettingsFragment extends android.app.Fragment implements androidx.preference.PreferenceFragment.OnPreferenceDisplayDialogCallback androidx.preference.PreferenceFragment.OnPreferenceStartFragmentCallback androidx.preference.PreferenceFragment.OnPreferenceStartScreenCallback {
     ctor @Deprecated public LeanbackSettingsFragment();
+    method @Deprecated public android.view.View! onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
+    method @Deprecated public void onPause();
     method @Deprecated public boolean onPreferenceDisplayDialog(androidx.preference.PreferenceFragment, androidx.preference.Preference!);
     method @Deprecated public abstract void onPreferenceStartInitialScreen();
+    method @Deprecated public void onResume();
+    method @Deprecated public void onViewCreated(android.view.View!, android.os.Bundle!);
     method @Deprecated public void startImmersiveFragment(android.app.Fragment);
     method @Deprecated public void startPreferenceFragment(android.app.Fragment);
   }
diff --git a/leanback-preference/api/restricted_1.1.0-alpha02.txt b/leanback-preference/api/restricted_1.1.0-alpha02.txt
index c559029..9e56499 100644
--- a/leanback-preference/api/restricted_1.1.0-alpha02.txt
+++ b/leanback-preference/api/restricted_1.1.0-alpha02.txt
@@ -7,6 +7,7 @@
 
   @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static class LeanbackSettingsFragment.DummyFragment extends android.app.Fragment {
     ctor @Deprecated public LeanbackSettingsFragment.DummyFragment();
+    method @Deprecated public android.view.View? onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
   }
 
   @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class LeanbackSettingsRootView extends android.widget.FrameLayout {
diff --git a/leanback-preference/api/restricted_current.txt b/leanback-preference/api/restricted_current.txt
index c559029..9e56499 100644
--- a/leanback-preference/api/restricted_current.txt
+++ b/leanback-preference/api/restricted_current.txt
@@ -7,6 +7,7 @@
 
   @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static class LeanbackSettingsFragment.DummyFragment extends android.app.Fragment {
     ctor @Deprecated public LeanbackSettingsFragment.DummyFragment();
+    method @Deprecated public android.view.View? onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
   }
 
   @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class LeanbackSettingsRootView extends android.widget.FrameLayout {
diff --git a/leanback/api/1.1.0-alpha01.txt b/leanback/api/1.1.0-alpha01.txt
index 9dab078..6bf9dcc 100644
--- a/leanback/api/1.1.0-alpha01.txt
+++ b/leanback/api/1.1.0-alpha01.txt
@@ -24,6 +24,7 @@
   @Deprecated public class BaseFragment extends androidx.leanback.app.BrandedFragment {
     method @Deprecated protected Object! createEntranceTransition();
     method @Deprecated public final androidx.leanback.app.ProgressBarManager! getProgressBarManager();
+    method @Deprecated public void onCreate(android.os.Bundle!);
     method @Deprecated protected void onEntranceTransitionEnd();
     method @Deprecated protected void onEntranceTransitionPrepare();
     method @Deprecated protected void onEntranceTransitionStart();
@@ -53,7 +54,13 @@
     method @Deprecated public androidx.leanback.widget.TitleViewAdapter! getTitleViewAdapter();
     method @Deprecated public void installTitleView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
     method @Deprecated public final boolean isShowingTitle();
+    method @Deprecated public void onDestroyView();
     method @Deprecated public android.view.View! onInflateTitleView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
+    method @Deprecated public void onPause();
+    method @Deprecated public void onResume();
+    method @Deprecated public void onSaveInstanceState(android.os.Bundle!);
+    method @Deprecated public void onStart();
+    method @Deprecated public void onViewCreated(android.view.View, android.os.Bundle?);
     method @Deprecated public void setBadgeDrawable(android.graphics.drawable.Drawable!);
     method @Deprecated public void setOnSearchClickedListener(android.view.View.OnClickListener!);
     method @Deprecated public void setSearchAffordanceColor(int);
@@ -104,6 +111,9 @@
     method @Deprecated public boolean isInHeadersTransition();
     method @Deprecated public boolean isShowingHeaders();
     method @Deprecated public androidx.leanback.app.HeadersFragment! onCreateHeadersFragment();
+    method @Deprecated public android.view.View! onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
+    method @Deprecated public void onDestroy();
+    method @Deprecated public void onStop();
     method @Deprecated public void setAdapter(androidx.leanback.widget.ObjectAdapter!);
     method @Deprecated public void setBrandColor(@ColorInt int);
     method @Deprecated public void setBrowseTransitionListener(androidx.leanback.app.BrowseFragment.BrowseTransitionListener!);
@@ -289,8 +299,10 @@
     method @Deprecated public androidx.leanback.widget.DetailsParallax! getParallax();
     method @Deprecated public androidx.leanback.app.RowsFragment! getRowsFragment();
     method @Deprecated protected android.view.View! inflateTitle(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
+    method @Deprecated public android.view.View! onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
     method @Deprecated protected void onSetDetailsOverviewRowStatus(androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter!, androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder!, int, int, int);
     method @Deprecated protected void onSetRowStatus(androidx.leanback.widget.RowPresenter!, androidx.leanback.widget.RowPresenter.ViewHolder!, int, int, int);
+    method @Deprecated public void onStop();
     method @Deprecated public void setAdapter(androidx.leanback.widget.ObjectAdapter!);
     method @Deprecated public void setOnItemViewClickedListener(androidx.leanback.widget.BaseOnItemViewClickedListener!);
     method @Deprecated public void setOnItemViewSelectedListener(androidx.leanback.widget.BaseOnItemViewSelectedListener!);
@@ -369,6 +381,7 @@
     method @Deprecated public android.graphics.drawable.Drawable! getImageDrawable();
     method @Deprecated public CharSequence! getMessage();
     method @Deprecated public boolean isBackgroundTranslucent();
+    method @Deprecated public android.view.View! onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
     method @Deprecated public void setBackgroundDrawable(android.graphics.drawable.Drawable!);
     method @Deprecated public void setButtonClickListener(android.view.View.OnClickListener!);
     method @Deprecated public void setButtonText(String!);
@@ -425,6 +438,7 @@
     method @Deprecated public void notifyActionChanged(int);
     method @Deprecated public void notifyButtonActionChanged(int);
     method @Deprecated protected void onAddSharedElementTransition(android.app.FragmentTransaction!, androidx.leanback.app.GuidedStepFragment!);
+    method @Deprecated public void onCreate(android.os.Bundle!);
     method @Deprecated public void onCreateActions(java.util.List<androidx.leanback.widget.GuidedAction>, android.os.Bundle!);
     method @Deprecated public androidx.leanback.widget.GuidedActionsStylist! onCreateActionsStylist();
     method @Deprecated public android.view.View! onCreateBackgroundView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
@@ -432,6 +446,8 @@
     method @Deprecated public androidx.leanback.widget.GuidedActionsStylist! onCreateButtonActionsStylist();
     method @Deprecated public androidx.leanback.widget.GuidanceStylist.Guidance onCreateGuidance(android.os.Bundle!);
     method @Deprecated public androidx.leanback.widget.GuidanceStylist! onCreateGuidanceStylist();
+    method @Deprecated public android.view.View! onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
+    method @Deprecated public void onDestroyView();
     method @Deprecated public void onGuidedActionClicked(androidx.leanback.widget.GuidedAction!);
     method @Deprecated public void onGuidedActionEditCanceled(androidx.leanback.widget.GuidedAction!);
     method @Deprecated public void onGuidedActionEdited(androidx.leanback.widget.GuidedAction!);
@@ -439,6 +455,8 @@
     method @Deprecated public void onGuidedActionFocused(androidx.leanback.widget.GuidedAction!);
     method @Deprecated protected void onProvideFragmentTransitions();
     method @Deprecated public int onProvideTheme();
+    method @Deprecated public void onResume();
+    method @Deprecated public void onSaveInstanceState(android.os.Bundle!);
     method @Deprecated public boolean onSubGuidedActionClicked(androidx.leanback.widget.GuidedAction!);
     method @Deprecated public void openInEditMode(androidx.leanback.widget.GuidedAction!);
     method @Deprecated public void popBackStackToGuidedStepFragment(Class!, int);
@@ -525,9 +543,13 @@
     method @Deprecated public int getSelectedPosition();
     method @Deprecated public final androidx.leanback.widget.VerticalGridView! getVerticalGridView();
     method @Deprecated public boolean isScrolling();
+    method @Deprecated public android.view.View! onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
+    method @Deprecated public void onDestroyView();
+    method @Deprecated public void onSaveInstanceState(android.os.Bundle!);
     method @Deprecated public void onTransitionEnd();
     method @Deprecated public boolean onTransitionPrepare();
     method @Deprecated public void onTransitionStart();
+    method @Deprecated public void onViewCreated(android.view.View, android.os.Bundle?);
     method @Deprecated public final void setAdapter(androidx.leanback.widget.ObjectAdapter!);
     method @Deprecated public void setAlignment(int);
     method @Deprecated public void setOnHeaderClickedListener(androidx.leanback.app.HeadersFragment.OnHeaderClickedListener!);
@@ -597,10 +619,13 @@
     method @Deprecated protected abstract android.view.View? onCreateForegroundView(android.view.LayoutInflater!, android.view.ViewGroup!);
     method @Deprecated protected android.animation.Animator? onCreateLogoAnimation();
     method @Deprecated protected android.animation.Animator! onCreateTitleAnimator();
+    method @Deprecated public android.view.View? onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
     method @Deprecated protected void onFinishFragment();
     method @Deprecated protected void onLogoAnimationFinished();
     method @Deprecated protected void onPageChanged(int, int);
     method @Deprecated public int onProvideTheme();
+    method @Deprecated public void onSaveInstanceState(android.os.Bundle!);
+    method @Deprecated public void onViewCreated(android.view.View, android.os.Bundle?);
     method @Deprecated public void setArrowBackgroundColor(@ColorInt int);
     method @Deprecated public void setArrowColor(@ColorInt int);
     method @Deprecated public void setDescriptionViewTextColor(@ColorInt int);
@@ -664,8 +689,17 @@
     method @Deprecated public boolean isShowOrHideControlsOverlayOnUserInteraction();
     method @Deprecated public void notifyPlaybackRowChanged();
     method @Deprecated protected void onBufferingStateChanged(boolean);
+    method @Deprecated public void onCreate(android.os.Bundle!);
+    method @Deprecated public android.view.View! onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
+    method @Deprecated public void onDestroy();
+    method @Deprecated public void onDestroyView();
     method @Deprecated protected void onError(int, CharSequence!);
+    method @Deprecated public void onPause();
+    method @Deprecated public void onResume();
+    method @Deprecated public void onStart();
+    method @Deprecated public void onStop();
     method @Deprecated protected void onVideoSizeChanged(int, int);
+    method @Deprecated public void onViewCreated(android.view.View, android.os.Bundle?);
     method @Deprecated public void setAdapter(androidx.leanback.widget.ObjectAdapter!);
     method @Deprecated public void setBackgroundType(int);
     method @Deprecated public void setControlsOverlayAutoHideEnabled(boolean);
@@ -765,9 +799,14 @@
     method @Deprecated public int getSelectedPosition();
     method @Deprecated public final androidx.leanback.widget.VerticalGridView! getVerticalGridView();
     method @Deprecated public boolean isScrolling();
+    method @Deprecated public void onCreate(android.os.Bundle!);
+    method @Deprecated public android.view.View! onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
+    method @Deprecated public void onDestroyView();
+    method @Deprecated public void onSaveInstanceState(android.os.Bundle!);
     method @Deprecated public void onTransitionEnd();
     method @Deprecated public boolean onTransitionPrepare();
     method @Deprecated public void onTransitionStart();
+    method @Deprecated public void onViewCreated(android.view.View, android.os.Bundle?);
     method @Deprecated public final void setAdapter(androidx.leanback.widget.ObjectAdapter!);
     method @Deprecated public void setAlignment(int);
     method @Deprecated public void setEntranceTransitionState(boolean);
@@ -838,6 +877,13 @@
     method @Deprecated public androidx.leanback.app.RowsFragment! getRowsFragment();
     method @Deprecated public String! getTitle();
     method @Deprecated public static androidx.leanback.app.SearchFragment! newInstance(String!);
+    method @Deprecated public void onCreate(android.os.Bundle!);
+    method @Deprecated public android.view.View! onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
+    method @Deprecated public void onDestroy();
+    method @Deprecated public void onPause();
+    method @Deprecated public void onRequestPermissionsResult(int, String[]!, int[]!);
+    method @Deprecated public void onResume();
+    method @Deprecated public void onStart();
     method @Deprecated public void setBadgeDrawable(android.graphics.drawable.Drawable!);
     method @Deprecated public void setOnItemViewClickedListener(androidx.leanback.widget.OnItemViewClickedListener!);
     method @Deprecated public void setOnItemViewSelectedListener(androidx.leanback.widget.OnItemViewSelectedListener!);
@@ -891,6 +937,7 @@
     method @Deprecated public androidx.leanback.widget.ObjectAdapter! getAdapter();
     method @Deprecated public androidx.leanback.widget.VerticalGridPresenter! getGridPresenter();
     method @Deprecated public androidx.leanback.widget.OnItemViewClickedListener! getOnItemViewClickedListener();
+    method @Deprecated public android.view.View! onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
     method @Deprecated public void setAdapter(androidx.leanback.widget.ObjectAdapter!);
     method @Deprecated public void setGridPresenter(androidx.leanback.widget.VerticalGridPresenter!);
     method @Deprecated public void setOnItemViewClickedListener(androidx.leanback.widget.OnItemViewClickedListener!);
diff --git a/leanback/api/1.1.0-alpha02.txt b/leanback/api/1.1.0-alpha02.txt
index 9dab078..6bf9dcc 100644
--- a/leanback/api/1.1.0-alpha02.txt
+++ b/leanback/api/1.1.0-alpha02.txt
@@ -24,6 +24,7 @@
   @Deprecated public class BaseFragment extends androidx.leanback.app.BrandedFragment {
     method @Deprecated protected Object! createEntranceTransition();
     method @Deprecated public final androidx.leanback.app.ProgressBarManager! getProgressBarManager();
+    method @Deprecated public void onCreate(android.os.Bundle!);
     method @Deprecated protected void onEntranceTransitionEnd();
     method @Deprecated protected void onEntranceTransitionPrepare();
     method @Deprecated protected void onEntranceTransitionStart();
@@ -53,7 +54,13 @@
     method @Deprecated public androidx.leanback.widget.TitleViewAdapter! getTitleViewAdapter();
     method @Deprecated public void installTitleView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
     method @Deprecated public final boolean isShowingTitle();
+    method @Deprecated public void onDestroyView();
     method @Deprecated public android.view.View! onInflateTitleView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
+    method @Deprecated public void onPause();
+    method @Deprecated public void onResume();
+    method @Deprecated public void onSaveInstanceState(android.os.Bundle!);
+    method @Deprecated public void onStart();
+    method @Deprecated public void onViewCreated(android.view.View, android.os.Bundle?);
     method @Deprecated public void setBadgeDrawable(android.graphics.drawable.Drawable!);
     method @Deprecated public void setOnSearchClickedListener(android.view.View.OnClickListener!);
     method @Deprecated public void setSearchAffordanceColor(int);
@@ -104,6 +111,9 @@
     method @Deprecated public boolean isInHeadersTransition();
     method @Deprecated public boolean isShowingHeaders();
     method @Deprecated public androidx.leanback.app.HeadersFragment! onCreateHeadersFragment();
+    method @Deprecated public android.view.View! onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
+    method @Deprecated public void onDestroy();
+    method @Deprecated public void onStop();
     method @Deprecated public void setAdapter(androidx.leanback.widget.ObjectAdapter!);
     method @Deprecated public void setBrandColor(@ColorInt int);
     method @Deprecated public void setBrowseTransitionListener(androidx.leanback.app.BrowseFragment.BrowseTransitionListener!);
@@ -289,8 +299,10 @@
     method @Deprecated public androidx.leanback.widget.DetailsParallax! getParallax();
     method @Deprecated public androidx.leanback.app.RowsFragment! getRowsFragment();
     method @Deprecated protected android.view.View! inflateTitle(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
+    method @Deprecated public android.view.View! onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
     method @Deprecated protected void onSetDetailsOverviewRowStatus(androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter!, androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder!, int, int, int);
     method @Deprecated protected void onSetRowStatus(androidx.leanback.widget.RowPresenter!, androidx.leanback.widget.RowPresenter.ViewHolder!, int, int, int);
+    method @Deprecated public void onStop();
     method @Deprecated public void setAdapter(androidx.leanback.widget.ObjectAdapter!);
     method @Deprecated public void setOnItemViewClickedListener(androidx.leanback.widget.BaseOnItemViewClickedListener!);
     method @Deprecated public void setOnItemViewSelectedListener(androidx.leanback.widget.BaseOnItemViewSelectedListener!);
@@ -369,6 +381,7 @@
     method @Deprecated public android.graphics.drawable.Drawable! getImageDrawable();
     method @Deprecated public CharSequence! getMessage();
     method @Deprecated public boolean isBackgroundTranslucent();
+    method @Deprecated public android.view.View! onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
     method @Deprecated public void setBackgroundDrawable(android.graphics.drawable.Drawable!);
     method @Deprecated public void setButtonClickListener(android.view.View.OnClickListener!);
     method @Deprecated public void setButtonText(String!);
@@ -425,6 +438,7 @@
     method @Deprecated public void notifyActionChanged(int);
     method @Deprecated public void notifyButtonActionChanged(int);
     method @Deprecated protected void onAddSharedElementTransition(android.app.FragmentTransaction!, androidx.leanback.app.GuidedStepFragment!);
+    method @Deprecated public void onCreate(android.os.Bundle!);
     method @Deprecated public void onCreateActions(java.util.List<androidx.leanback.widget.GuidedAction>, android.os.Bundle!);
     method @Deprecated public androidx.leanback.widget.GuidedActionsStylist! onCreateActionsStylist();
     method @Deprecated public android.view.View! onCreateBackgroundView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
@@ -432,6 +446,8 @@
     method @Deprecated public androidx.leanback.widget.GuidedActionsStylist! onCreateButtonActionsStylist();
     method @Deprecated public androidx.leanback.widget.GuidanceStylist.Guidance onCreateGuidance(android.os.Bundle!);
     method @Deprecated public androidx.leanback.widget.GuidanceStylist! onCreateGuidanceStylist();
+    method @Deprecated public android.view.View! onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
+    method @Deprecated public void onDestroyView();
     method @Deprecated public void onGuidedActionClicked(androidx.leanback.widget.GuidedAction!);
     method @Deprecated public void onGuidedActionEditCanceled(androidx.leanback.widget.GuidedAction!);
     method @Deprecated public void onGuidedActionEdited(androidx.leanback.widget.GuidedAction!);
@@ -439,6 +455,8 @@
     method @Deprecated public void onGuidedActionFocused(androidx.leanback.widget.GuidedAction!);
     method @Deprecated protected void onProvideFragmentTransitions();
     method @Deprecated public int onProvideTheme();
+    method @Deprecated public void onResume();
+    method @Deprecated public void onSaveInstanceState(android.os.Bundle!);
     method @Deprecated public boolean onSubGuidedActionClicked(androidx.leanback.widget.GuidedAction!);
     method @Deprecated public void openInEditMode(androidx.leanback.widget.GuidedAction!);
     method @Deprecated public void popBackStackToGuidedStepFragment(Class!, int);
@@ -525,9 +543,13 @@
     method @Deprecated public int getSelectedPosition();
     method @Deprecated public final androidx.leanback.widget.VerticalGridView! getVerticalGridView();
     method @Deprecated public boolean isScrolling();
+    method @Deprecated public android.view.View! onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
+    method @Deprecated public void onDestroyView();
+    method @Deprecated public void onSaveInstanceState(android.os.Bundle!);
     method @Deprecated public void onTransitionEnd();
     method @Deprecated public boolean onTransitionPrepare();
     method @Deprecated public void onTransitionStart();
+    method @Deprecated public void onViewCreated(android.view.View, android.os.Bundle?);
     method @Deprecated public final void setAdapter(androidx.leanback.widget.ObjectAdapter!);
     method @Deprecated public void setAlignment(int);
     method @Deprecated public void setOnHeaderClickedListener(androidx.leanback.app.HeadersFragment.OnHeaderClickedListener!);
@@ -597,10 +619,13 @@
     method @Deprecated protected abstract android.view.View? onCreateForegroundView(android.view.LayoutInflater!, android.view.ViewGroup!);
     method @Deprecated protected android.animation.Animator? onCreateLogoAnimation();
     method @Deprecated protected android.animation.Animator! onCreateTitleAnimator();
+    method @Deprecated public android.view.View? onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
     method @Deprecated protected void onFinishFragment();
     method @Deprecated protected void onLogoAnimationFinished();
     method @Deprecated protected void onPageChanged(int, int);
     method @Deprecated public int onProvideTheme();
+    method @Deprecated public void onSaveInstanceState(android.os.Bundle!);
+    method @Deprecated public void onViewCreated(android.view.View, android.os.Bundle?);
     method @Deprecated public void setArrowBackgroundColor(@ColorInt int);
     method @Deprecated public void setArrowColor(@ColorInt int);
     method @Deprecated public void setDescriptionViewTextColor(@ColorInt int);
@@ -664,8 +689,17 @@
     method @Deprecated public boolean isShowOrHideControlsOverlayOnUserInteraction();
     method @Deprecated public void notifyPlaybackRowChanged();
     method @Deprecated protected void onBufferingStateChanged(boolean);
+    method @Deprecated public void onCreate(android.os.Bundle!);
+    method @Deprecated public android.view.View! onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
+    method @Deprecated public void onDestroy();
+    method @Deprecated public void onDestroyView();
     method @Deprecated protected void onError(int, CharSequence!);
+    method @Deprecated public void onPause();
+    method @Deprecated public void onResume();
+    method @Deprecated public void onStart();
+    method @Deprecated public void onStop();
     method @Deprecated protected void onVideoSizeChanged(int, int);
+    method @Deprecated public void onViewCreated(android.view.View, android.os.Bundle?);
     method @Deprecated public void setAdapter(androidx.leanback.widget.ObjectAdapter!);
     method @Deprecated public void setBackgroundType(int);
     method @Deprecated public void setControlsOverlayAutoHideEnabled(boolean);
@@ -765,9 +799,14 @@
     method @Deprecated public int getSelectedPosition();
     method @Deprecated public final androidx.leanback.widget.VerticalGridView! getVerticalGridView();
     method @Deprecated public boolean isScrolling();
+    method @Deprecated public void onCreate(android.os.Bundle!);
+    method @Deprecated public android.view.View! onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
+    method @Deprecated public void onDestroyView();
+    method @Deprecated public void onSaveInstanceState(android.os.Bundle!);
     method @Deprecated public void onTransitionEnd();
     method @Deprecated public boolean onTransitionPrepare();
     method @Deprecated public void onTransitionStart();
+    method @Deprecated public void onViewCreated(android.view.View, android.os.Bundle?);
     method @Deprecated public final void setAdapter(androidx.leanback.widget.ObjectAdapter!);
     method @Deprecated public void setAlignment(int);
     method @Deprecated public void setEntranceTransitionState(boolean);
@@ -838,6 +877,13 @@
     method @Deprecated public androidx.leanback.app.RowsFragment! getRowsFragment();
     method @Deprecated public String! getTitle();
     method @Deprecated public static androidx.leanback.app.SearchFragment! newInstance(String!);
+    method @Deprecated public void onCreate(android.os.Bundle!);
+    method @Deprecated public android.view.View! onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
+    method @Deprecated public void onDestroy();
+    method @Deprecated public void onPause();
+    method @Deprecated public void onRequestPermissionsResult(int, String[]!, int[]!);
+    method @Deprecated public void onResume();
+    method @Deprecated public void onStart();
     method @Deprecated public void setBadgeDrawable(android.graphics.drawable.Drawable!);
     method @Deprecated public void setOnItemViewClickedListener(androidx.leanback.widget.OnItemViewClickedListener!);
     method @Deprecated public void setOnItemViewSelectedListener(androidx.leanback.widget.OnItemViewSelectedListener!);
@@ -891,6 +937,7 @@
     method @Deprecated public androidx.leanback.widget.ObjectAdapter! getAdapter();
     method @Deprecated public androidx.leanback.widget.VerticalGridPresenter! getGridPresenter();
     method @Deprecated public androidx.leanback.widget.OnItemViewClickedListener! getOnItemViewClickedListener();
+    method @Deprecated public android.view.View! onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
     method @Deprecated public void setAdapter(androidx.leanback.widget.ObjectAdapter!);
     method @Deprecated public void setGridPresenter(androidx.leanback.widget.VerticalGridPresenter!);
     method @Deprecated public void setOnItemViewClickedListener(androidx.leanback.widget.OnItemViewClickedListener!);
diff --git a/leanback/api/current.txt b/leanback/api/current.txt
index 9dab078..6bf9dcc 100644
--- a/leanback/api/current.txt
+++ b/leanback/api/current.txt
@@ -24,6 +24,7 @@
   @Deprecated public class BaseFragment extends androidx.leanback.app.BrandedFragment {
     method @Deprecated protected Object! createEntranceTransition();
     method @Deprecated public final androidx.leanback.app.ProgressBarManager! getProgressBarManager();
+    method @Deprecated public void onCreate(android.os.Bundle!);
     method @Deprecated protected void onEntranceTransitionEnd();
     method @Deprecated protected void onEntranceTransitionPrepare();
     method @Deprecated protected void onEntranceTransitionStart();
@@ -53,7 +54,13 @@
     method @Deprecated public androidx.leanback.widget.TitleViewAdapter! getTitleViewAdapter();
     method @Deprecated public void installTitleView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
     method @Deprecated public final boolean isShowingTitle();
+    method @Deprecated public void onDestroyView();
     method @Deprecated public android.view.View! onInflateTitleView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
+    method @Deprecated public void onPause();
+    method @Deprecated public void onResume();
+    method @Deprecated public void onSaveInstanceState(android.os.Bundle!);
+    method @Deprecated public void onStart();
+    method @Deprecated public void onViewCreated(android.view.View, android.os.Bundle?);
     method @Deprecated public void setBadgeDrawable(android.graphics.drawable.Drawable!);
     method @Deprecated public void setOnSearchClickedListener(android.view.View.OnClickListener!);
     method @Deprecated public void setSearchAffordanceColor(int);
@@ -104,6 +111,9 @@
     method @Deprecated public boolean isInHeadersTransition();
     method @Deprecated public boolean isShowingHeaders();
     method @Deprecated public androidx.leanback.app.HeadersFragment! onCreateHeadersFragment();
+    method @Deprecated public android.view.View! onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
+    method @Deprecated public void onDestroy();
+    method @Deprecated public void onStop();
     method @Deprecated public void setAdapter(androidx.leanback.widget.ObjectAdapter!);
     method @Deprecated public void setBrandColor(@ColorInt int);
     method @Deprecated public void setBrowseTransitionListener(androidx.leanback.app.BrowseFragment.BrowseTransitionListener!);
@@ -289,8 +299,10 @@
     method @Deprecated public androidx.leanback.widget.DetailsParallax! getParallax();
     method @Deprecated public androidx.leanback.app.RowsFragment! getRowsFragment();
     method @Deprecated protected android.view.View! inflateTitle(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
+    method @Deprecated public android.view.View! onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
     method @Deprecated protected void onSetDetailsOverviewRowStatus(androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter!, androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder!, int, int, int);
     method @Deprecated protected void onSetRowStatus(androidx.leanback.widget.RowPresenter!, androidx.leanback.widget.RowPresenter.ViewHolder!, int, int, int);
+    method @Deprecated public void onStop();
     method @Deprecated public void setAdapter(androidx.leanback.widget.ObjectAdapter!);
     method @Deprecated public void setOnItemViewClickedListener(androidx.leanback.widget.BaseOnItemViewClickedListener!);
     method @Deprecated public void setOnItemViewSelectedListener(androidx.leanback.widget.BaseOnItemViewSelectedListener!);
@@ -369,6 +381,7 @@
     method @Deprecated public android.graphics.drawable.Drawable! getImageDrawable();
     method @Deprecated public CharSequence! getMessage();
     method @Deprecated public boolean isBackgroundTranslucent();
+    method @Deprecated public android.view.View! onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
     method @Deprecated public void setBackgroundDrawable(android.graphics.drawable.Drawable!);
     method @Deprecated public void setButtonClickListener(android.view.View.OnClickListener!);
     method @Deprecated public void setButtonText(String!);
@@ -425,6 +438,7 @@
     method @Deprecated public void notifyActionChanged(int);
     method @Deprecated public void notifyButtonActionChanged(int);
     method @Deprecated protected void onAddSharedElementTransition(android.app.FragmentTransaction!, androidx.leanback.app.GuidedStepFragment!);
+    method @Deprecated public void onCreate(android.os.Bundle!);
     method @Deprecated public void onCreateActions(java.util.List<androidx.leanback.widget.GuidedAction>, android.os.Bundle!);
     method @Deprecated public androidx.leanback.widget.GuidedActionsStylist! onCreateActionsStylist();
     method @Deprecated public android.view.View! onCreateBackgroundView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
@@ -432,6 +446,8 @@
     method @Deprecated public androidx.leanback.widget.GuidedActionsStylist! onCreateButtonActionsStylist();
     method @Deprecated public androidx.leanback.widget.GuidanceStylist.Guidance onCreateGuidance(android.os.Bundle!);
     method @Deprecated public androidx.leanback.widget.GuidanceStylist! onCreateGuidanceStylist();
+    method @Deprecated public android.view.View! onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
+    method @Deprecated public void onDestroyView();
     method @Deprecated public void onGuidedActionClicked(androidx.leanback.widget.GuidedAction!);
     method @Deprecated public void onGuidedActionEditCanceled(androidx.leanback.widget.GuidedAction!);
     method @Deprecated public void onGuidedActionEdited(androidx.leanback.widget.GuidedAction!);
@@ -439,6 +455,8 @@
     method @Deprecated public void onGuidedActionFocused(androidx.leanback.widget.GuidedAction!);
     method @Deprecated protected void onProvideFragmentTransitions();
     method @Deprecated public int onProvideTheme();
+    method @Deprecated public void onResume();
+    method @Deprecated public void onSaveInstanceState(android.os.Bundle!);
     method @Deprecated public boolean onSubGuidedActionClicked(androidx.leanback.widget.GuidedAction!);
     method @Deprecated public void openInEditMode(androidx.leanback.widget.GuidedAction!);
     method @Deprecated public void popBackStackToGuidedStepFragment(Class!, int);
@@ -525,9 +543,13 @@
     method @Deprecated public int getSelectedPosition();
     method @Deprecated public final androidx.leanback.widget.VerticalGridView! getVerticalGridView();
     method @Deprecated public boolean isScrolling();
+    method @Deprecated public android.view.View! onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
+    method @Deprecated public void onDestroyView();
+    method @Deprecated public void onSaveInstanceState(android.os.Bundle!);
     method @Deprecated public void onTransitionEnd();
     method @Deprecated public boolean onTransitionPrepare();
     method @Deprecated public void onTransitionStart();
+    method @Deprecated public void onViewCreated(android.view.View, android.os.Bundle?);
     method @Deprecated public final void setAdapter(androidx.leanback.widget.ObjectAdapter!);
     method @Deprecated public void setAlignment(int);
     method @Deprecated public void setOnHeaderClickedListener(androidx.leanback.app.HeadersFragment.OnHeaderClickedListener!);
@@ -597,10 +619,13 @@
     method @Deprecated protected abstract android.view.View? onCreateForegroundView(android.view.LayoutInflater!, android.view.ViewGroup!);
     method @Deprecated protected android.animation.Animator? onCreateLogoAnimation();
     method @Deprecated protected android.animation.Animator! onCreateTitleAnimator();
+    method @Deprecated public android.view.View? onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
     method @Deprecated protected void onFinishFragment();
     method @Deprecated protected void onLogoAnimationFinished();
     method @Deprecated protected void onPageChanged(int, int);
     method @Deprecated public int onProvideTheme();
+    method @Deprecated public void onSaveInstanceState(android.os.Bundle!);
+    method @Deprecated public void onViewCreated(android.view.View, android.os.Bundle?);
     method @Deprecated public void setArrowBackgroundColor(@ColorInt int);
     method @Deprecated public void setArrowColor(@ColorInt int);
     method @Deprecated public void setDescriptionViewTextColor(@ColorInt int);
@@ -664,8 +689,17 @@
     method @Deprecated public boolean isShowOrHideControlsOverlayOnUserInteraction();
     method @Deprecated public void notifyPlaybackRowChanged();
     method @Deprecated protected void onBufferingStateChanged(boolean);
+    method @Deprecated public void onCreate(android.os.Bundle!);
+    method @Deprecated public android.view.View! onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
+    method @Deprecated public void onDestroy();
+    method @Deprecated public void onDestroyView();
     method @Deprecated protected void onError(int, CharSequence!);
+    method @Deprecated public void onPause();
+    method @Deprecated public void onResume();
+    method @Deprecated public void onStart();
+    method @Deprecated public void onStop();
     method @Deprecated protected void onVideoSizeChanged(int, int);
+    method @Deprecated public void onViewCreated(android.view.View, android.os.Bundle?);
     method @Deprecated public void setAdapter(androidx.leanback.widget.ObjectAdapter!);
     method @Deprecated public void setBackgroundType(int);
     method @Deprecated public void setControlsOverlayAutoHideEnabled(boolean);
@@ -765,9 +799,14 @@
     method @Deprecated public int getSelectedPosition();
     method @Deprecated public final androidx.leanback.widget.VerticalGridView! getVerticalGridView();
     method @Deprecated public boolean isScrolling();
+    method @Deprecated public void onCreate(android.os.Bundle!);
+    method @Deprecated public android.view.View! onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
+    method @Deprecated public void onDestroyView();
+    method @Deprecated public void onSaveInstanceState(android.os.Bundle!);
     method @Deprecated public void onTransitionEnd();
     method @Deprecated public boolean onTransitionPrepare();
     method @Deprecated public void onTransitionStart();
+    method @Deprecated public void onViewCreated(android.view.View, android.os.Bundle?);
     method @Deprecated public final void setAdapter(androidx.leanback.widget.ObjectAdapter!);
     method @Deprecated public void setAlignment(int);
     method @Deprecated public void setEntranceTransitionState(boolean);
@@ -838,6 +877,13 @@
     method @Deprecated public androidx.leanback.app.RowsFragment! getRowsFragment();
     method @Deprecated public String! getTitle();
     method @Deprecated public static androidx.leanback.app.SearchFragment! newInstance(String!);
+    method @Deprecated public void onCreate(android.os.Bundle!);
+    method @Deprecated public android.view.View! onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
+    method @Deprecated public void onDestroy();
+    method @Deprecated public void onPause();
+    method @Deprecated public void onRequestPermissionsResult(int, String[]!, int[]!);
+    method @Deprecated public void onResume();
+    method @Deprecated public void onStart();
     method @Deprecated public void setBadgeDrawable(android.graphics.drawable.Drawable!);
     method @Deprecated public void setOnItemViewClickedListener(androidx.leanback.widget.OnItemViewClickedListener!);
     method @Deprecated public void setOnItemViewSelectedListener(androidx.leanback.widget.OnItemViewSelectedListener!);
@@ -891,6 +937,7 @@
     method @Deprecated public androidx.leanback.widget.ObjectAdapter! getAdapter();
     method @Deprecated public androidx.leanback.widget.VerticalGridPresenter! getGridPresenter();
     method @Deprecated public androidx.leanback.widget.OnItemViewClickedListener! getOnItemViewClickedListener();
+    method @Deprecated public android.view.View! onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
     method @Deprecated public void setAdapter(androidx.leanback.widget.ObjectAdapter!);
     method @Deprecated public void setGridPresenter(androidx.leanback.widget.VerticalGridPresenter!);
     method @Deprecated public void setOnItemViewClickedListener(androidx.leanback.widget.OnItemViewClickedListener!);
diff --git a/leanback/api/restricted_1.1.0-alpha02.txt b/leanback/api/restricted_1.1.0-alpha02.txt
index d54d9cd..b60f71d 100644
--- a/leanback/api/restricted_1.1.0-alpha02.txt
+++ b/leanback/api/restricted_1.1.0-alpha02.txt
@@ -17,6 +17,10 @@
 
   @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final class BackgroundFragment extends android.app.Fragment {
     ctor public BackgroundFragment();
+    method public void onDestroy();
+    method public void onResume();
+    method public void onStart();
+    method public void onStop();
   }
 
   @Deprecated public class GuidedStepFragment extends android.app.Fragment implements androidx.leanback.widget.GuidedActionAdapter.FocusListener {
@@ -28,6 +32,7 @@
 
   @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static class GuidedStepFragment.DummyFragment extends android.app.Fragment {
     ctor @Deprecated public GuidedStepFragment.DummyFragment();
+    method @Deprecated public android.view.View! onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
   }
 
   public class GuidedStepSupportFragment extends androidx.fragment.app.Fragment implements androidx.leanback.widget.GuidedActionAdapter.FocusListener {
diff --git a/leanback/api/restricted_current.txt b/leanback/api/restricted_current.txt
index d54d9cd..b60f71d 100644
--- a/leanback/api/restricted_current.txt
+++ b/leanback/api/restricted_current.txt
@@ -17,6 +17,10 @@
 
   @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final class BackgroundFragment extends android.app.Fragment {
     ctor public BackgroundFragment();
+    method public void onDestroy();
+    method public void onResume();
+    method public void onStart();
+    method public void onStop();
   }
 
   @Deprecated public class GuidedStepFragment extends android.app.Fragment implements androidx.leanback.widget.GuidedActionAdapter.FocusListener {
@@ -28,6 +32,7 @@
 
   @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static class GuidedStepFragment.DummyFragment extends android.app.Fragment {
     ctor @Deprecated public GuidedStepFragment.DummyFragment();
+    method @Deprecated public android.view.View! onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
   }
 
   public class GuidedStepSupportFragment extends androidx.fragment.app.Fragment implements androidx.leanback.widget.GuidedActionAdapter.FocusListener {
diff --git a/leanback/src/main/java/androidx/leanback/widget/HorizontalGridView.java b/leanback/src/main/java/androidx/leanback/widget/HorizontalGridView.java
index 53f77ae..06df8962 100644
--- a/leanback/src/main/java/androidx/leanback/widget/HorizontalGridView.java
+++ b/leanback/src/main/java/androidx/leanback/widget/HorizontalGridView.java
@@ -28,6 +28,7 @@
 import android.util.TypedValue;
 import android.view.View;
 
+import androidx.core.os.BuildCompat;
 import androidx.leanback.R;
 import androidx.recyclerview.widget.RecyclerView;
 
@@ -81,6 +82,10 @@
     protected void initAttributes(Context context, AttributeSet attrs) {
         initBaseGridViewAttributes(context, attrs);
         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.lbHorizontalGridView);
+        if (BuildCompat.isAtLeastQ()) {
+            saveAttributeDataForStyleable(
+                    context, R.styleable.lbHorizontalGridView, attrs, a, 0, 0);
+        }
         setRowHeight(a);
         setNumRows(a.getInt(R.styleable.lbHorizontalGridView_numberOfRows, 1));
         a.recycle();
diff --git a/leanback/src/main/java/androidx/leanback/widget/ImageCardView.java b/leanback/src/main/java/androidx/leanback/widget/ImageCardView.java
index 7286b19..5e2a0c7 100644
--- a/leanback/src/main/java/androidx/leanback/widget/ImageCardView.java
+++ b/leanback/src/main/java/androidx/leanback/widget/ImageCardView.java
@@ -28,6 +28,7 @@
 import android.widget.TextView;
 
 import androidx.annotation.ColorInt;
+import androidx.core.os.BuildCompat;
 import androidx.leanback.R;
 
 /**
@@ -170,6 +171,11 @@
         inflater.inflate(R.layout.lb_image_card_view, this);
         TypedArray cardAttrs = getContext().obtainStyledAttributes(attrs,
                 R.styleable.lbImageCardView, defStyleAttr, defStyle);
+        if (BuildCompat.isAtLeastQ()) {
+            saveAttributeDataForStyleable(
+                    getContext(), R.styleable.lbImageCardView, attrs, cardAttrs, defStyleAttr,
+                    defStyle);
+        }
         int cardType = cardAttrs
                 .getInt(R.styleable.lbImageCardView_lbImageCardViewType, CARD_TYPE_FLAG_IMAGE_ONLY);
 
diff --git a/leanback/src/main/java/androidx/leanback/widget/PagingIndicator.java b/leanback/src/main/java/androidx/leanback/widget/PagingIndicator.java
index dafc41b..22adc74 100644
--- a/leanback/src/main/java/androidx/leanback/widget/PagingIndicator.java
+++ b/leanback/src/main/java/androidx/leanback/widget/PagingIndicator.java
@@ -42,6 +42,7 @@
 import androidx.annotation.ColorInt;
 import androidx.annotation.RestrictTo;
 import androidx.annotation.VisibleForTesting;
+import androidx.core.os.BuildCompat;
 import androidx.leanback.R;
 
 /**
@@ -143,6 +144,10 @@
         Resources res = getResources();
         TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.PagingIndicator,
                 defStyle, 0);
+        if (BuildCompat.isAtLeastQ()) {
+            saveAttributeDataForStyleable(
+                    context, R.styleable.PagingIndicator, attrs, typedArray, defStyle, 0);
+        }
         mDotRadius = getDimensionFromTypedArray(typedArray, R.styleable.PagingIndicator_lbDotRadius,
                 R.dimen.lb_page_indicator_dot_radius);
         mDotDiameter = mDotRadius * 2;
diff --git a/leanback/src/main/java/androidx/leanback/widget/SearchOrbView.java b/leanback/src/main/java/androidx/leanback/widget/SearchOrbView.java
index 6cd17bb..bcbab76 100644
--- a/leanback/src/main/java/androidx/leanback/widget/SearchOrbView.java
+++ b/leanback/src/main/java/androidx/leanback/widget/SearchOrbView.java
@@ -32,6 +32,7 @@
 import android.widget.ImageView;
 
 import androidx.annotation.ColorInt;
+import androidx.core.os.BuildCompat;
 import androidx.core.view.ViewCompat;
 import androidx.leanback.R;
 
@@ -184,6 +185,10 @@
 
         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.lbSearchOrbView,
                 defStyleAttr, 0);
+        if (BuildCompat.isAtLeastQ()) {
+            saveAttributeDataForStyleable(
+                    context, R.styleable.lbSearchOrbView, attrs, a, defStyleAttr, 0);
+        }
 
         Drawable img = a.getDrawable(R.styleable.lbSearchOrbView_searchOrbIcon);
         if (img == null) {
diff --git a/leanback/src/main/java/androidx/leanback/widget/VerticalGridView.java b/leanback/src/main/java/androidx/leanback/widget/VerticalGridView.java
index 844e8a8..0886661 100644
--- a/leanback/src/main/java/androidx/leanback/widget/VerticalGridView.java
+++ b/leanback/src/main/java/androidx/leanback/widget/VerticalGridView.java
@@ -18,6 +18,7 @@
 import android.util.AttributeSet;
 import android.util.TypedValue;
 
+import androidx.core.os.BuildCompat;
 import androidx.leanback.R;
 import androidx.recyclerview.widget.RecyclerView;
 
@@ -57,6 +58,10 @@
     protected void initAttributes(Context context, AttributeSet attrs) {
         initBaseGridViewAttributes(context, attrs);
         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.lbVerticalGridView);
+        if (BuildCompat.isAtLeastQ()) {
+            saveAttributeDataForStyleable(
+                    context, R.styleable.lbVerticalGridView, attrs, a, 0, 0);
+        }
         setColumnWidth(a);
         setNumColumns(a.getInt(R.styleable.lbVerticalGridView_numberOfColumns, 1));
         a.recycle();
diff --git a/leanback/src/main/java/androidx/leanback/widget/picker/DatePicker.java b/leanback/src/main/java/androidx/leanback/widget/picker/DatePicker.java
index 48850f1..91c4207 100644
--- a/leanback/src/main/java/androidx/leanback/widget/picker/DatePicker.java
+++ b/leanback/src/main/java/androidx/leanback/widget/picker/DatePicker.java
@@ -21,6 +21,7 @@
 import android.util.Log;
 
 import androidx.annotation.VisibleForTesting;
+import androidx.core.os.BuildCompat;
 import androidx.leanback.R;
 
 import java.text.DateFormat;
@@ -75,6 +76,10 @@
 
         final TypedArray attributesArray = context.obtainStyledAttributes(attrs,
                 R.styleable.lbDatePicker);
+        if (BuildCompat.isAtLeastQ()) {
+            saveAttributeDataForStyleable(
+                    context, R.styleable.lbDatePicker, attrs, attributesArray, 0, 0);
+        }
         String minDate;
         String maxDate;
         String datePickerFormat;
diff --git a/leanback/src/main/java/androidx/leanback/widget/picker/Picker.java b/leanback/src/main/java/androidx/leanback/widget/picker/Picker.java
index b302f7b..5505aa2 100644
--- a/leanback/src/main/java/androidx/leanback/widget/picker/Picker.java
+++ b/leanback/src/main/java/androidx/leanback/widget/picker/Picker.java
@@ -31,6 +31,7 @@
 
 import androidx.annotation.IdRes;
 import androidx.annotation.LayoutRes;
+import androidx.core.os.BuildCompat;
 import androidx.leanback.R;
 import androidx.leanback.widget.OnChildViewHolderSelectedListener;
 import androidx.leanback.widget.VerticalGridView;
@@ -193,6 +194,10 @@
         super(context, attrs, defStyleAttr);
         final TypedArray a = context.obtainStyledAttributes(
                 attrs, R.styleable.lbPicker, defStyleAttr, 0);
+        if (BuildCompat.isAtLeastQ()) {
+            saveAttributeDataForStyleable(
+                    context, R.styleable.lbPicker, attrs, a, defStyleAttr, 0);
+        }
         mPickerItemLayoutId = a.getResourceId(R.styleable.lbPicker_pickerItemLayout,
                 R.layout.lb_picker_item);
         mPickerItemTextViewId = a.getResourceId(R.styleable.lbPicker_pickerItemTextViewId, 0);
diff --git a/leanback/src/main/java/androidx/leanback/widget/picker/PinPicker.java b/leanback/src/main/java/androidx/leanback/widget/picker/PinPicker.java
index 2c1505d..27c3b4c 100644
--- a/leanback/src/main/java/androidx/leanback/widget/picker/PinPicker.java
+++ b/leanback/src/main/java/androidx/leanback/widget/picker/PinPicker.java
@@ -21,6 +21,7 @@
 import android.util.AttributeSet;
 import android.view.KeyEvent;
 
+import androidx.core.os.BuildCompat;
 import androidx.leanback.R;
 
 import java.util.ArrayList;
@@ -44,6 +45,10 @@
         super(context, attrs, defStyleAttr);
         final TypedArray a = context.obtainStyledAttributes(
                 attrs, R.styleable.lbPinPicker, defStyleAttr, 0);
+        if (BuildCompat.isAtLeastQ()) {
+            saveAttributeDataForStyleable(
+                    context, R.styleable.lbPinPicker, attrs, a, defStyleAttr, 0);
+        }
         try {
             setSeparator(" ");
             setNumberOfColumns(a.getInt(R.styleable.lbPinPicker_columnCount, DEFAULT_COLUMN_COUNT));
diff --git a/leanback/src/main/java/androidx/leanback/widget/picker/TimePicker.java b/leanback/src/main/java/androidx/leanback/widget/picker/TimePicker.java
index ec01225..3e04e7e 100644
--- a/leanback/src/main/java/androidx/leanback/widget/picker/TimePicker.java
+++ b/leanback/src/main/java/androidx/leanback/widget/picker/TimePicker.java
@@ -24,6 +24,7 @@
 import android.view.View;
 
 import androidx.annotation.IntRange;
+import androidx.core.os.BuildCompat;
 import androidx.leanback.R;
 
 import java.text.SimpleDateFormat;
@@ -107,6 +108,10 @@
 
         final TypedArray attributesArray = context.obtainStyledAttributes(attrs,
                 R.styleable.lbTimePicker);
+        if (BuildCompat.isAtLeastQ()) {
+            saveAttributeDataForStyleable(
+                    context, R.styleable.lbTimePicker, attrs, attributesArray, 0, 0);
+        }
         boolean useCurrentTime;
 
         try {
diff --git a/lifecycle/runtime/api/restricted_2.1.0-alpha03.txt b/lifecycle/runtime/api/restricted_2.1.0-alpha03.txt
index c79f82d..49e4512 100644
--- a/lifecycle/runtime/api/restricted_2.1.0-alpha03.txt
+++ b/lifecycle/runtime/api/restricted_2.1.0-alpha03.txt
@@ -4,6 +4,12 @@
   @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class ReportFragment extends android.app.Fragment {
     ctor public ReportFragment();
     method public static void injectIfNeededIn(android.app.Activity!);
+    method public void onActivityCreated(android.os.Bundle!);
+    method public void onDestroy();
+    method public void onPause();
+    method public void onResume();
+    method public void onStart();
+    method public void onStop();
   }
 
 }
diff --git a/lifecycle/runtime/api/restricted_2.1.0-alpha04.txt b/lifecycle/runtime/api/restricted_2.1.0-alpha04.txt
index c79f82d..49e4512 100644
--- a/lifecycle/runtime/api/restricted_2.1.0-alpha04.txt
+++ b/lifecycle/runtime/api/restricted_2.1.0-alpha04.txt
@@ -4,6 +4,12 @@
   @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class ReportFragment extends android.app.Fragment {
     ctor public ReportFragment();
     method public static void injectIfNeededIn(android.app.Activity!);
+    method public void onActivityCreated(android.os.Bundle!);
+    method public void onDestroy();
+    method public void onPause();
+    method public void onResume();
+    method public void onStart();
+    method public void onStop();
   }
 
 }
diff --git a/lifecycle/runtime/api/restricted_2.1.0-alpha05.txt b/lifecycle/runtime/api/restricted_2.1.0-alpha05.txt
index c79f82d..49e4512 100644
--- a/lifecycle/runtime/api/restricted_2.1.0-alpha05.txt
+++ b/lifecycle/runtime/api/restricted_2.1.0-alpha05.txt
@@ -4,6 +4,12 @@
   @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class ReportFragment extends android.app.Fragment {
     ctor public ReportFragment();
     method public static void injectIfNeededIn(android.app.Activity!);
+    method public void onActivityCreated(android.os.Bundle!);
+    method public void onDestroy();
+    method public void onPause();
+    method public void onResume();
+    method public void onStart();
+    method public void onStop();
   }
 
 }
diff --git a/lifecycle/runtime/api/restricted_current.txt b/lifecycle/runtime/api/restricted_current.txt
index c79f82d..49e4512 100644
--- a/lifecycle/runtime/api/restricted_current.txt
+++ b/lifecycle/runtime/api/restricted_current.txt
@@ -4,6 +4,12 @@
   @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class ReportFragment extends android.app.Fragment {
     ctor public ReportFragment();
     method public static void injectIfNeededIn(android.app.Activity!);
+    method public void onActivityCreated(android.os.Bundle!);
+    method public void onDestroy();
+    method public void onPause();
+    method public void onResume();
+    method public void onStart();
+    method public void onStop();
   }
 
 }
diff --git a/mediarouter/src/main/java/androidx/mediarouter/app/MediaRouteButton.java b/mediarouter/src/main/java/androidx/mediarouter/app/MediaRouteButton.java
index fbdc209..8c31071 100644
--- a/mediarouter/src/main/java/androidx/mediarouter/app/MediaRouteButton.java
+++ b/mediarouter/src/main/java/androidx/mediarouter/app/MediaRouteButton.java
@@ -38,6 +38,7 @@
 import androidx.annotation.NonNull;
 import androidx.appcompat.widget.TooltipCompat;
 import androidx.core.graphics.drawable.DrawableCompat;
+import androidx.core.os.BuildCompat;
 import androidx.fragment.app.FragmentActivity;
 import androidx.fragment.app.FragmentManager;
 import androidx.fragment.app.FragmentTransaction;
@@ -150,6 +151,10 @@
         context = getContext();
         TypedArray a = context.obtainStyledAttributes(attrs,
                 R.styleable.MediaRouteButton, defStyleAttr, 0);
+        if (BuildCompat.isAtLeastQ()) {
+            saveAttributeDataForStyleable(
+                    context, R.styleable.MediaRouteButton, attrs, a, defStyleAttr, 0);
+        }
         if (isInEditMode()) {
             mRouter = null;
             mCallback = null;
diff --git a/navigation/safe-args-gradle-plugin/build.gradle b/navigation/safe-args-gradle-plugin/build.gradle
index a68a18a..101ee5d 100644
--- a/navigation/safe-args-gradle-plugin/build.gradle
+++ b/navigation/safe-args-gradle-plugin/build.gradle
@@ -48,7 +48,7 @@
 
 task generateSdkResource() {
     inputs.property("prebuiltsRoot", prebuiltsRoot)
-    inputs.property("compileSdkVersion", SupportConfig.TARGET_SDK_VERSION)
+    inputs.property("compileSdkVersion", SupportConfig.COMPILE_SDK_VERSION)
     inputs.property("buildToolsVersion", SupportConfig.BUILD_TOOLS_VERSION)
     inputs.property("minSdkVersion", SupportConfig.DEFAULT_MIN_SDK_VERSION)
     inputs.property("debugKeystore", debugKeystore)
@@ -60,7 +60,7 @@
         // so we don't use it and write a file manually
         new File(generatedResources, "sdk.prop").withWriter('UTF-8') { writer ->
             writer.write("prebuiltsRepo=$prebuiltsRoot\n")
-            writer.write("compileSdkVersion=$SupportConfig.TARGET_SDK_VERSION\n")
+            writer.write("compileSdkVersion=\"$SupportConfig.COMPILE_SDK_VERSION\"\n")
             writer.write("buildToolsVersion=$SupportConfig.BUILD_TOOLS_VERSION\n")
             writer.write("minSdkVersion=$SupportConfig.DEFAULT_MIN_SDK_VERSION\n")
             writer.write("debugKeystore=$debugKeystore\n")
diff --git a/preference/api/1.1.0-alpha03.txt b/preference/api/1.1.0-alpha03.txt
index d3b0755..611d611 100644
--- a/preference/api/1.1.0-alpha03.txt
+++ b/preference/api/1.1.0-alpha03.txt
@@ -290,9 +290,13 @@
     method @Deprecated public androidx.preference.DialogPreference! getPreference();
     method @Deprecated protected void onBindDialogView(android.view.View!);
     method @Deprecated public void onClick(android.content.DialogInterface!, int);
+    method @Deprecated public void onCreate(android.os.Bundle!);
+    method @Deprecated public android.app.Dialog onCreateDialog(android.os.Bundle!);
     method @Deprecated protected android.view.View! onCreateDialogView(android.content.Context!);
     method @Deprecated public abstract void onDialogClosed(boolean);
+    method @Deprecated public void onDismiss(android.content.DialogInterface!);
     method @Deprecated protected void onPrepareDialogBuilder(android.app.AlertDialog.Builder!);
+    method @Deprecated public void onSaveInstanceState(android.os.Bundle);
     field @Deprecated protected static final String ARG_KEY = "key";
   }
 
@@ -314,13 +318,20 @@
     method @Deprecated public final androidx.recyclerview.widget.RecyclerView! getListView();
     method @Deprecated public androidx.preference.PreferenceManager! getPreferenceManager();
     method @Deprecated public androidx.preference.PreferenceScreen! getPreferenceScreen();
+    method @Deprecated public void onCreate(android.os.Bundle!);
     method @Deprecated protected androidx.recyclerview.widget.RecyclerView.Adapter! onCreateAdapter(androidx.preference.PreferenceScreen!);
     method @Deprecated public androidx.recyclerview.widget.RecyclerView.LayoutManager! onCreateLayoutManager();
     method @Deprecated public abstract void onCreatePreferences(android.os.Bundle!, String!);
     method @Deprecated public androidx.recyclerview.widget.RecyclerView! onCreateRecyclerView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
+    method @Deprecated public android.view.View! onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
+    method @Deprecated public void onDestroyView();
     method @Deprecated public void onDisplayPreferenceDialog(androidx.preference.Preference!);
     method @Deprecated public void onNavigateToScreen(androidx.preference.PreferenceScreen!);
     method @Deprecated public boolean onPreferenceTreeClick(androidx.preference.Preference!);
+    method @Deprecated public void onSaveInstanceState(android.os.Bundle!);
+    method @Deprecated public void onStart();
+    method @Deprecated public void onStop();
+    method @Deprecated public void onViewCreated(android.view.View!, android.os.Bundle!);
     method @Deprecated public void scrollToPreference(String!);
     method @Deprecated public void scrollToPreference(androidx.preference.Preference!);
     method @Deprecated public void setDivider(android.graphics.drawable.Drawable!);
diff --git a/preference/api/1.1.0-alpha04.txt b/preference/api/1.1.0-alpha04.txt
index 0edd4f7b..b23276b 100644
--- a/preference/api/1.1.0-alpha04.txt
+++ b/preference/api/1.1.0-alpha04.txt
@@ -290,9 +290,13 @@
     method @Deprecated public androidx.preference.DialogPreference! getPreference();
     method @Deprecated protected void onBindDialogView(android.view.View!);
     method @Deprecated public void onClick(android.content.DialogInterface!, int);
+    method @Deprecated public void onCreate(android.os.Bundle!);
+    method @Deprecated public android.app.Dialog onCreateDialog(android.os.Bundle!);
     method @Deprecated protected android.view.View! onCreateDialogView(android.content.Context!);
     method @Deprecated public abstract void onDialogClosed(boolean);
+    method @Deprecated public void onDismiss(android.content.DialogInterface!);
     method @Deprecated protected void onPrepareDialogBuilder(android.app.AlertDialog.Builder!);
+    method @Deprecated public void onSaveInstanceState(android.os.Bundle);
     field @Deprecated protected static final String ARG_KEY = "key";
   }
 
@@ -314,13 +318,20 @@
     method @Deprecated public final androidx.recyclerview.widget.RecyclerView! getListView();
     method @Deprecated public androidx.preference.PreferenceManager! getPreferenceManager();
     method @Deprecated public androidx.preference.PreferenceScreen! getPreferenceScreen();
+    method @Deprecated public void onCreate(android.os.Bundle!);
     method @Deprecated protected androidx.recyclerview.widget.RecyclerView.Adapter! onCreateAdapter(androidx.preference.PreferenceScreen!);
     method @Deprecated public androidx.recyclerview.widget.RecyclerView.LayoutManager! onCreateLayoutManager();
     method @Deprecated public abstract void onCreatePreferences(android.os.Bundle!, String!);
     method @Deprecated public androidx.recyclerview.widget.RecyclerView! onCreateRecyclerView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
+    method @Deprecated public android.view.View! onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
+    method @Deprecated public void onDestroyView();
     method @Deprecated public void onDisplayPreferenceDialog(androidx.preference.Preference!);
     method @Deprecated public void onNavigateToScreen(androidx.preference.PreferenceScreen!);
     method @Deprecated public boolean onPreferenceTreeClick(androidx.preference.Preference!);
+    method @Deprecated public void onSaveInstanceState(android.os.Bundle!);
+    method @Deprecated public void onStart();
+    method @Deprecated public void onStop();
+    method @Deprecated public void onViewCreated(android.view.View!, android.os.Bundle!);
     method @Deprecated public void scrollToPreference(String!);
     method @Deprecated public void scrollToPreference(androidx.preference.Preference!);
     method @Deprecated public void setDivider(android.graphics.drawable.Drawable!);
diff --git a/preference/api/1.1.0-alpha05.txt b/preference/api/1.1.0-alpha05.txt
index 0edd4f7b..b23276b 100644
--- a/preference/api/1.1.0-alpha05.txt
+++ b/preference/api/1.1.0-alpha05.txt
@@ -290,9 +290,13 @@
     method @Deprecated public androidx.preference.DialogPreference! getPreference();
     method @Deprecated protected void onBindDialogView(android.view.View!);
     method @Deprecated public void onClick(android.content.DialogInterface!, int);
+    method @Deprecated public void onCreate(android.os.Bundle!);
+    method @Deprecated public android.app.Dialog onCreateDialog(android.os.Bundle!);
     method @Deprecated protected android.view.View! onCreateDialogView(android.content.Context!);
     method @Deprecated public abstract void onDialogClosed(boolean);
+    method @Deprecated public void onDismiss(android.content.DialogInterface!);
     method @Deprecated protected void onPrepareDialogBuilder(android.app.AlertDialog.Builder!);
+    method @Deprecated public void onSaveInstanceState(android.os.Bundle);
     field @Deprecated protected static final String ARG_KEY = "key";
   }
 
@@ -314,13 +318,20 @@
     method @Deprecated public final androidx.recyclerview.widget.RecyclerView! getListView();
     method @Deprecated public androidx.preference.PreferenceManager! getPreferenceManager();
     method @Deprecated public androidx.preference.PreferenceScreen! getPreferenceScreen();
+    method @Deprecated public void onCreate(android.os.Bundle!);
     method @Deprecated protected androidx.recyclerview.widget.RecyclerView.Adapter! onCreateAdapter(androidx.preference.PreferenceScreen!);
     method @Deprecated public androidx.recyclerview.widget.RecyclerView.LayoutManager! onCreateLayoutManager();
     method @Deprecated public abstract void onCreatePreferences(android.os.Bundle!, String!);
     method @Deprecated public androidx.recyclerview.widget.RecyclerView! onCreateRecyclerView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
+    method @Deprecated public android.view.View! onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
+    method @Deprecated public void onDestroyView();
     method @Deprecated public void onDisplayPreferenceDialog(androidx.preference.Preference!);
     method @Deprecated public void onNavigateToScreen(androidx.preference.PreferenceScreen!);
     method @Deprecated public boolean onPreferenceTreeClick(androidx.preference.Preference!);
+    method @Deprecated public void onSaveInstanceState(android.os.Bundle!);
+    method @Deprecated public void onStart();
+    method @Deprecated public void onStop();
+    method @Deprecated public void onViewCreated(android.view.View!, android.os.Bundle!);
     method @Deprecated public void scrollToPreference(String!);
     method @Deprecated public void scrollToPreference(androidx.preference.Preference!);
     method @Deprecated public void setDivider(android.graphics.drawable.Drawable!);
diff --git a/preference/api/current.txt b/preference/api/current.txt
index 0edd4f7b..b23276b 100644
--- a/preference/api/current.txt
+++ b/preference/api/current.txt
@@ -290,9 +290,13 @@
     method @Deprecated public androidx.preference.DialogPreference! getPreference();
     method @Deprecated protected void onBindDialogView(android.view.View!);
     method @Deprecated public void onClick(android.content.DialogInterface!, int);
+    method @Deprecated public void onCreate(android.os.Bundle!);
+    method @Deprecated public android.app.Dialog onCreateDialog(android.os.Bundle!);
     method @Deprecated protected android.view.View! onCreateDialogView(android.content.Context!);
     method @Deprecated public abstract void onDialogClosed(boolean);
+    method @Deprecated public void onDismiss(android.content.DialogInterface!);
     method @Deprecated protected void onPrepareDialogBuilder(android.app.AlertDialog.Builder!);
+    method @Deprecated public void onSaveInstanceState(android.os.Bundle);
     field @Deprecated protected static final String ARG_KEY = "key";
   }
 
@@ -314,13 +318,20 @@
     method @Deprecated public final androidx.recyclerview.widget.RecyclerView! getListView();
     method @Deprecated public androidx.preference.PreferenceManager! getPreferenceManager();
     method @Deprecated public androidx.preference.PreferenceScreen! getPreferenceScreen();
+    method @Deprecated public void onCreate(android.os.Bundle!);
     method @Deprecated protected androidx.recyclerview.widget.RecyclerView.Adapter! onCreateAdapter(androidx.preference.PreferenceScreen!);
     method @Deprecated public androidx.recyclerview.widget.RecyclerView.LayoutManager! onCreateLayoutManager();
     method @Deprecated public abstract void onCreatePreferences(android.os.Bundle!, String!);
     method @Deprecated public androidx.recyclerview.widget.RecyclerView! onCreateRecyclerView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
+    method @Deprecated public android.view.View! onCreateView(android.view.LayoutInflater!, android.view.ViewGroup!, android.os.Bundle!);
+    method @Deprecated public void onDestroyView();
     method @Deprecated public void onDisplayPreferenceDialog(androidx.preference.Preference!);
     method @Deprecated public void onNavigateToScreen(androidx.preference.PreferenceScreen!);
     method @Deprecated public boolean onPreferenceTreeClick(androidx.preference.Preference!);
+    method @Deprecated public void onSaveInstanceState(android.os.Bundle!);
+    method @Deprecated public void onStart();
+    method @Deprecated public void onStop();
+    method @Deprecated public void onViewCreated(android.view.View!, android.os.Bundle!);
     method @Deprecated public void scrollToPreference(String!);
     method @Deprecated public void scrollToPreference(androidx.preference.Preference!);
     method @Deprecated public void setDivider(android.graphics.drawable.Drawable!);
diff --git a/preference/res/values-en-rCA/strings.xml b/preference/res/values-en-rCA/strings.xml
index c8d1681..16cf6b7 100644
--- a/preference/res/values-en-rCA/strings.xml
+++ b/preference/res/values-en-rCA/strings.xml
@@ -5,4 +5,6 @@
     <string name="v7_preference_off" msgid="5138405918326871307">"OFF"</string>
     <string name="expand_button_title" msgid="1234962710353108940">"Advanced"</string>
     <string name="summary_collapsed_preference_list" msgid="5190123168583152844">"<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>, <xliff:g id="ADDED_ITEMS">%2$s</xliff:g>"</string>
+    <string name="copy" msgid="3209159573327985035">"Copy"</string>
+    <string name="preference_copied" msgid="7961817945132860002">"\'<xliff:g id="SUMMARY">%1$s</xliff:g>\' copied to clipboard."</string>
 </resources>
diff --git a/preference/res/values-en-rXC/strings.xml b/preference/res/values-en-rXC/strings.xml
index 96219e7..cb60d80 100644
--- a/preference/res/values-en-rXC/strings.xml
+++ b/preference/res/values-en-rXC/strings.xml
@@ -5,4 +5,6 @@
     <string name="v7_preference_off" msgid="5138405918326871307">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‏‎‎‏‏‏‏‎‏‎‎‏‎‎‎‏‏‏‏‎‏‎‏‎‏‎‏‎‎‎‏‏‎‏‎‎‎‏‏‎‏‎‏‎‏‎‏‎‎‎‎‏‎‏‏‎OFF‎‏‎‎‏‎"</string>
     <string name="expand_button_title" msgid="1234962710353108940">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‎‎‏‎‎‎‏‏‎‏‏‏‏‎‎‎‎‎‎‎‏‎‏‎‏‎‏‏‏‏‎‏‎‏‏‏‎‎‏‏‎‏‎‏‏‏‏‏‏‏‎‎‏‏‎‎‎Advanced‎‏‎‎‏‎"</string>
     <string name="summary_collapsed_preference_list" msgid="5190123168583152844">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‎‎‎‎‏‏‏‎‎‎‎‎‏‎‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‎‎‎‏‏‏‎‏‎‎‏‏‎‎‏‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="CURRENT_ITEMS">%1$s</xliff:g>‎‏‎‎‏‏‏‎, ‎‏‎‎‏‏‎<xliff:g id="ADDED_ITEMS">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="copy" msgid="3209159573327985035">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‏‎‎‎‏‎‎‏‎‎‏‏‏‎‎‏‏‎‏‎‎‎‎‏‎‎‎‎‏‎‏‏‏‏‎‎‎‎‏‎‎‎‏‏‏‎‎‏‏‎‎‎‏‎‏‏‎Copy‎‏‎‎‏‎"</string>
+    <string name="preference_copied" msgid="7961817945132860002">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‎‎‏‏‏‏‎‎‏‏‎‏‎‎‎‏‏‏‏‏‏‎‎‏‏‎‎‎‎‎‏‎‎‏‏‎‎‎‏‎‎\"‎‏‎‎‏‏‎<xliff:g id="SUMMARY">%1$s</xliff:g>‎‏‎‎‏‏‏‎\" copied to clipboard.‎‏‎‎‏‎"</string>
 </resources>
diff --git a/recyclerview/recyclerview/src/main/java/androidx/recyclerview/widget/RecyclerView.java b/recyclerview/recyclerview/src/main/java/androidx/recyclerview/widget/RecyclerView.java
index 51374b5..bad5210 100644
--- a/recyclerview/recyclerview/src/main/java/androidx/recyclerview/widget/RecyclerView.java
+++ b/recyclerview/recyclerview/src/main/java/androidx/recyclerview/widget/RecyclerView.java
@@ -65,6 +65,7 @@
 import androidx.annotation.Px;
 import androidx.annotation.RestrictTo;
 import androidx.annotation.VisibleForTesting;
+import androidx.core.os.BuildCompat;
 import androidx.core.os.TraceCompat;
 import androidx.core.util.Preconditions;
 import androidx.core.view.AccessibilityDelegateCompat;
@@ -691,6 +692,10 @@
             int defStyleRes = 0;
             TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RecyclerView,
                     defStyle, defStyleRes);
+            if (BuildCompat.isAtLeastQ()) {
+                saveAttributeDataForStyleable(
+                        context, R.styleable.RecyclerView, attrs, a, defStyle, defStyleRes);
+            }
             String layoutManagerName = a.getString(R.styleable.RecyclerView_layoutManager);
             int descendantFocusability = a.getInt(
                     R.styleable.RecyclerView_android_descendantFocusability, -1);
@@ -716,6 +721,10 @@
             if (Build.VERSION.SDK_INT >= 21) {
                 a = context.obtainStyledAttributes(attrs, NESTED_SCROLLING_ATTRS,
                         defStyle, defStyleRes);
+                if (BuildCompat.isAtLeastQ()) {
+                    saveAttributeDataForStyleable(
+                            context, NESTED_SCROLLING_ATTRS, attrs, a, defStyle, defStyleRes);
+                }
                 nestedScrollingEnabled = a.getBoolean(0, true);
                 a.recycle();
             }
diff --git a/samples/BiometricDemos/src/main/java/com/example/android/biometric/BiometricPromptDemo.java b/samples/BiometricDemos/src/main/java/com/example/android/biometric/BiometricPromptDemo.java
index 0a30f48..95d1206 100644
--- a/samples/BiometricDemos/src/main/java/com/example/android/biometric/BiometricPromptDemo.java
+++ b/samples/BiometricDemos/src/main/java/com/example/android/biometric/BiometricPromptDemo.java
@@ -16,6 +16,7 @@
 
 package com.example.android.biometric;
 
+import android.hardware.biometrics.BiometricManager;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
@@ -28,11 +29,13 @@
 import android.view.View;
 import android.widget.Button;
 import android.widget.CheckBox;
+import android.widget.RadioGroup;
 import android.widget.Toast;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.RequiresApi;
 import androidx.biometric.BiometricPrompt;
+import androidx.core.os.BuildCompat;
 import androidx.fragment.app.FragmentActivity;
 
 import java.io.IOException;
@@ -66,25 +69,30 @@
 
     private static final String TAG = "BiometricPromptDemo";
 
-    private static final String KEY_SAVED_USE_CRYPTO = "saved_use_crypto_state";
-    private static final String KEY_SAVED_RADIO = "saved_radio_state";
-    private static final String KEY_SAVED_FAILURES = "saved_failures_state";
     private static final String KEY_COUNTER = "saved_counter";
 
     private static final String DEFAULT_KEY_NAME = "default_key";
 
+    private static final String BIOMETRIC_SUCCESS_MESSAGE = "BIOMETRIC_SUCCESS_MESSAGE";
+    private static final String BIOMETRIC_ERROR_HW_UNAVAILABLE_MESSAGE =
+            "BIOMETRIC_ERROR_HW_UNAVAILABLE";
+    private static final String BIOMETRIC_ERROR_NONE_ENROLLED_MESSAGE =
+            "BIOMETRIC_ERROR_NONE_ENROLLED";
+    private static final String BIOMETRIC_ERROR_UNKNOWN = "Error unknown return result";
+
     private static final int MODE_NONE = 0;
     private static final int MODE_PERSIST_ACROSS_CONFIGURATION_CHANGES = 1;
     private static final int MODE_CANCEL_ON_CONFIGURATION_CHANGE = 2;
     private static final int MODE_CANCEL_AFTER_THREE_FAILURES = 3;
 
-    private int mMode = MODE_NONE;
-    private boolean mUseCrypto;
-
     private Handler mHandler = new Handler(Looper.getMainLooper());
     private KeyStore mKeyStore;
     private BiometricPrompt mBiometricPrompt;
 
+    private CheckBox mUseCryptoCheckbox;
+    private CheckBox mConfirmationRequiredCheckbox;
+    private CheckBox mDeviceCredentialAllowedCheckbox;
+
     private int mCounter;
     private int mNumberFailedAttempts;
 
@@ -128,7 +136,7 @@
             mNumberFailedAttempts++;
 
             // Cancel authentication after 3 failed attempts to test the cancel() method.
-            if (mMode == MODE_CANCEL_AFTER_THREE_FAILURES && mNumberFailedAttempts == 3) {
+            if (getMode() == MODE_CANCEL_AFTER_THREE_FAILURES && mNumberFailedAttempts == 3) {
                 mBiometricPrompt.cancelAuthentication();
             }
         }
@@ -139,9 +147,6 @@
         super.onCreate(savedInstanceState);
 
         if (savedInstanceState != null) {
-            mUseCrypto = savedInstanceState.getBoolean(KEY_SAVED_USE_CRYPTO);
-            mMode = savedInstanceState.getInt(KEY_SAVED_RADIO);
-            mNumberFailedAttempts = savedInstanceState.getInt(KEY_SAVED_FAILURES);
             mCounter = savedInstanceState.getInt(KEY_COUNTER);
         }
 
@@ -150,7 +155,12 @@
         final Button buttonCreateKeys;
         buttonCreateKeys = findViewById(R.id.button_enable_biometric_with_crypto);
         final Button buttonAuthenticate;
+        final Button canAuthenticate;
         buttonAuthenticate = findViewById(R.id.button_authenticate);
+        canAuthenticate = findViewById(R.id.can_authenticate);
+        mUseCryptoCheckbox = findViewById(R.id.checkbox_use_crypto);
+        mConfirmationRequiredCheckbox = findViewById(R.id.checkbox_require_confirmation);
+        mDeviceCredentialAllowedCheckbox = findViewById(R.id.checkbox_enable_fallback);
 
         try {
             mKeyStore = KeyStore.getInstance("AndroidKeyStore");
@@ -158,7 +168,7 @@
             throw new RuntimeException("Failed to get an instance of KeyStore", e);
         }
 
-        if (!mUseCrypto) {
+        if (!useCrypto()) {
             buttonCreateKeys.setVisibility(View.GONE);
         } else {
             buttonCreateKeys.setVisibility(View.VISIBLE);
@@ -168,11 +178,43 @@
             buttonCreateKeys.setOnClickListener(v -> enableBiometricWithCrypto());
         }
         buttonAuthenticate.setOnClickListener(v -> startAuthentication());
+
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
+            mConfirmationRequiredCheckbox.setEnabled(false);
+            mConfirmationRequiredCheckbox.setChecked(false);
+        }
+        if (BuildCompat.isAtLeastQ()) {
+            canAuthenticate.setOnClickListener(v -> {
+                BiometricManager bm = getApplicationContext().getSystemService(
+                        BiometricManager.class);
+                String message;
+                switch (bm.canAuthenticate()) {
+                    case BiometricManager.BIOMETRIC_SUCCESS:
+                        message = BIOMETRIC_SUCCESS_MESSAGE;
+                        break;
+                    case BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE:
+                        message = BIOMETRIC_ERROR_HW_UNAVAILABLE_MESSAGE;
+                        break;
+                    case BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED:
+                        message = BIOMETRIC_ERROR_NONE_ENROLLED_MESSAGE;
+                        break;
+                    default:
+                        message = BIOMETRIC_ERROR_UNKNOWN;
+                }
+                Toast.makeText(getApplicationContext(), "canAuthenticate : " + message,
+                        Toast.LENGTH_SHORT).show();
+            });
+        } else {
+            mDeviceCredentialAllowedCheckbox.setEnabled(false);
+            mDeviceCredentialAllowedCheckbox.setChecked(false);
+            canAuthenticate.setVisibility(View.GONE);
+        }
+
     }
 
     @Override
     protected void onPause() {
-        if (mMode == MODE_CANCEL_ON_CONFIGURATION_CHANGE) {
+        if (getMode() == MODE_CANCEL_ON_CONFIGURATION_CHANGE) {
             mBiometricPrompt.cancelAuthentication();
         }
         super.onPause();
@@ -192,53 +234,9 @@
     @Override
     public void onSaveInstanceState(Bundle outState) {
         super.onSaveInstanceState(outState);
-        outState.putBoolean(KEY_SAVED_USE_CRYPTO, mUseCrypto);
-        outState.putInt(KEY_SAVED_RADIO, mMode);
-        outState.putInt(KEY_SAVED_FAILURES, mNumberFailedAttempts);
         outState.putInt(KEY_COUNTER, mCounter);
     }
 
-    /**
-     * Callback when the radio buttons are clicked.
-     * @param view
-     */
-    public void onRadioButtonClicked(View view) {
-        mNumberFailedAttempts = 0;
-
-        switch(view.getId()) {
-            case R.id.radio_persist_across_configuration_changes:
-                mMode = MODE_PERSIST_ACROSS_CONFIGURATION_CHANGES;
-                break;
-            case R.id.radio_cancel_on_configuration_change:
-                mMode = MODE_CANCEL_ON_CONFIGURATION_CHANGE;
-                break;
-            case R.id.radio_cancel_after_three_failures:
-                mMode = MODE_CANCEL_AFTER_THREE_FAILURES;
-                break;
-        }
-    }
-
-    /**
-     * Callback when the checkbox is clicked.
-     * @param view
-     */
-    public void onCheckboxClicked(View view) {
-        boolean checked = ((CheckBox) view).isChecked();
-
-        switch(view.getId()) {
-            case R.id.checkbox_use_crypto:
-                if (checked) {
-                    findViewById(R.id.button_enable_biometric_with_crypto)
-                            .setVisibility(View.VISIBLE);
-                } else {
-                    findViewById(R.id.button_enable_biometric_with_crypto)
-                            .setVisibility(View.GONE);
-                }
-                mUseCrypto = checked;
-                break;
-        }
-    }
-
     @RequiresApi(Build.VERSION_CODES.M)
     private void enableBiometricWithCrypto() {
         // Create the key, this is usually done when the user allows Biometric
@@ -252,25 +250,34 @@
     }
 
     private void startAuthentication() {
-        if (mMode == MODE_NONE) {
+        if (getMode() == MODE_NONE) {
             Toast.makeText(getApplicationContext(), "Select a test first", Toast.LENGTH_SHORT)
                     .show();
             return;
         }
 
         // Build the biometric prompt info
-        BiometricPrompt.PromptInfo info =
-                new BiometricPrompt.PromptInfo.Builder()
-                        .setTitle("Title " + mCounter)
-                        .setSubtitle("Subtitle " + mCounter)
-                        .setDescription(
-                                "Lorem ipsum dolor sit amet, consecte etur adipisicing elit. "
-                                        + mCounter)
-                        .setNegativeButtonText("Negative Button " + mCounter)
-                        .build();
+        BiometricPrompt.PromptInfo.Builder builder = new BiometricPrompt.PromptInfo.Builder()
+                .setTitle("Title " + mCounter)
+                .setSubtitle("Subtitle " + mCounter)
+                .setDescription(
+                        "Lorem ipsum dolor sit amet, consecte etur adipisicing elit. "
+                                + mCounter)
+                .setConfirmationRequired(mConfirmationRequiredCheckbox.isChecked());
+
+        if (BuildCompat.isAtLeastQ()) {
+            if (mDeviceCredentialAllowedCheckbox.isChecked()) {
+                builder.setDeviceCredentialAllowed(true);
+            } else {
+                builder.setNegativeButtonText("Negative Button " + mCounter);
+            }
+        } else {
+            builder.setNegativeButtonText("Negative Button " + mCounter);
+        }
+        BiometricPrompt.PromptInfo info = builder.build();
         mCounter++;
 
-        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M && mUseCrypto) {
+        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M && useCrypto()) {
             try {
                 // Initialize the cipher. The cipher will be unlocked by KeyStore after the user has
                 // authenticated via biometrics.
@@ -357,4 +364,26 @@
             throw new RuntimeException(e);
         }
     }
+
+    private boolean useCrypto() {
+        return mUseCryptoCheckbox.isChecked();
+    }
+
+    /**
+     * @return The currently selected configuration.
+     */
+    private int getMode() {
+        int id = ((RadioGroup) findViewById(R.id.radio_group)).getCheckedRadioButtonId();
+        switch (id) {
+            case R.id.radio_persist_across_configuration_changes:
+                return MODE_PERSIST_ACROSS_CONFIGURATION_CHANGES;
+            case R.id.radio_cancel_on_configuration_change:
+                return MODE_CANCEL_ON_CONFIGURATION_CHANGE;
+            case R.id.radio_cancel_after_three_failures:
+                return MODE_CANCEL_AFTER_THREE_FAILURES;
+            default:
+                return MODE_NONE;
+        }
+    }
+
 }
diff --git a/samples/BiometricDemos/src/main/res/layout/fragment_activity.xml b/samples/BiometricDemos/src/main/res/layout/fragment_activity.xml
index 6d2c318..4853e972 100644
--- a/samples/BiometricDemos/src/main/res/layout/fragment_activity.xml
+++ b/samples/BiometricDemos/src/main/res/layout/fragment_activity.xml
@@ -28,19 +28,44 @@
         android:text="@string/button_enable_biometric_with_crypto"/>
 
     <Button
+        android:id="@+id/can_authenticate"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/button_can_authenticate"/>
+
+    <Button
         android:id="@+id/button_authenticate"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:text="@string/button_authenticate"/>
 
-    <CheckBox
-        android:id="@+id/checkbox_use_crypto"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:text="@string/checkbox_text_use_crypto"
-        android:onClick="onCheckboxClicked"/>
+    <LinearLayout android:layout_width="match_parent"
+                  android:layout_height="wrap_content"
+                  android:orientation="vertical">
+        <CheckBox
+                android:id="@+id/checkbox_use_crypto"
+                android:layout_weight="1"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/checkbox_text_use_crypto"/>
+        <CheckBox
+                android:id="@+id/checkbox_require_confirmation"
+                android:layout_weight="1"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/checkbox_text_require_confirmation"
+                android:checked="true"/>
+        <CheckBox
+                android:id="@+id/checkbox_enable_fallback"
+                android:layout_weight="1"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/checkbox_text_allow_device_credential"/>
+    </LinearLayout>
+
 
     <RadioGroup
+        android:id="@+id/radio_group"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content">
 
@@ -48,22 +73,19 @@
             android:id="@+id/radio_persist_across_configuration_changes"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:text="@string/radio_text_persist_across_configuration_changes"
-            android:onClick="onRadioButtonClicked"/>
+            android:text="@string/radio_text_persist_across_configuration_changes" />
 
         <RadioButton
             android:id="@+id/radio_cancel_on_configuration_change"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:text="@string/radio_text_cancel_on_configuration_change"
-            android:onClick="onRadioButtonClicked"/>
+            android:text="@string/radio_text_cancel_on_configuration_change" />
 
         <RadioButton
             android:id="@+id/radio_cancel_after_three_failures"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:text="@string/radio_text_cancel_after_three_failures"
-            android:onClick="onRadioButtonClicked"/>
+            android:text="@string/radio_text_cancel_after_three_failures" />
 
     </RadioGroup>
 
diff --git a/samples/BiometricDemos/src/main/res/values/strings.xml b/samples/BiometricDemos/src/main/res/values/strings.xml
index e945842..5d0f03e 100644
--- a/samples/BiometricDemos/src/main/res/values/strings.xml
+++ b/samples/BiometricDemos/src/main/res/values/strings.xml
@@ -20,8 +20,11 @@
 
     <string name="button_enable_biometric_with_crypto">Create keys (for crypto)</string>
     <string name="button_authenticate">Authenticate</string>
+    <string name="button_can_authenticate">Can Authenticate</string>
 
     <string name="checkbox_text_use_crypto">Use crypto</string>
+    <string name="checkbox_text_require_confirmation">Require confirmation</string>
+    <string name="checkbox_text_allow_device_credential">Allow Device Credential</string>
 
     <string name="radio_text_persist_across_configuration_changes">Persist across configuration changes</string>
     <string name="radio_text_cancel_on_configuration_change">Cancel when configuration changes</string>
diff --git a/settings.gradle b/settings.gradle
index 15004af..3a615f1 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -75,6 +75,7 @@
 includeProject(":fragment", "fragment")
 includeProject(":fragment-ktx", "fragment/ktx")
 includeProject(":fragment-testing", "fragment/testing")
+includeProject(":fakeannotations", "fakeannotations")
 includeProject(":gridlayout", "gridlayout")
 includeProject(":heifwriter", "heifwriter")
 includeProject(":interpolator", "interpolator")
diff --git a/slidingpanelayout/src/main/java/androidx/slidingpanelayout/widget/SlidingPaneLayout.java b/slidingpanelayout/src/main/java/androidx/slidingpanelayout/widget/SlidingPaneLayout.java
index 88df164..50429c5 100644
--- a/slidingpanelayout/src/main/java/androidx/slidingpanelayout/widget/SlidingPaneLayout.java
+++ b/slidingpanelayout/src/main/java/androidx/slidingpanelayout/widget/SlidingPaneLayout.java
@@ -22,7 +22,6 @@
 import android.graphics.Paint;
 import android.graphics.PixelFormat;
 import android.graphics.PorterDuff;
-import android.graphics.PorterDuffColorFilter;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.os.Build;
@@ -400,6 +399,8 @@
         }
     }
 
+    @SuppressWarnings("deprecation")
+    // Remove suppression once b/120984816 is addressed.
     private static boolean viewIsOpaque(View v) {
         if (v.isOpaque()) {
             return true;
@@ -962,6 +963,7 @@
         dispatchOnPanelSlide(mSlideableView);
     }
 
+    @SuppressWarnings("deprecation")
     private void dimChildView(View v, float mag, int fadeColor) {
         final LayoutParams lp = (LayoutParams) v.getLayoutParams();
 
@@ -972,7 +974,8 @@
             if (lp.dimPaint == null) {
                 lp.dimPaint = new Paint();
             }
-            lp.dimPaint.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_OVER));
+            lp.dimPaint.setColorFilter(new android.graphics.PorterDuffColorFilter(
+                    color, PorterDuff.Mode.SRC_OVER));
             if (v.getLayerType() != View.LAYER_TYPE_HARDWARE) {
                 v.setLayerType(View.LAYER_TYPE_HARDWARE, lp.dimPaint);
             }
diff --git a/swiperefreshlayout/src/main/java/androidx/swiperefreshlayout/widget/CircularProgressDrawable.java b/swiperefreshlayout/src/main/java/androidx/swiperefreshlayout/widget/CircularProgressDrawable.java
index d397f84..1aeeeb9 100644
--- a/swiperefreshlayout/src/main/java/androidx/swiperefreshlayout/widget/CircularProgressDrawable.java
+++ b/swiperefreshlayout/src/main/java/androidx/swiperefreshlayout/widget/CircularProgressDrawable.java
@@ -429,6 +429,8 @@
     }
 
     @Override
+    @SuppressWarnings("deprecation")
+    // Remove suppression was b/120985527 is addressed.
     public int getOpacity() {
         return PixelFormat.TRANSLUCENT;
     }
diff --git a/transition/src/main/java/androidx/transition/CanvasUtils.java b/transition/src/main/java/androidx/transition/CanvasUtils.java
index 4e6ac36..d3f872b 100644
--- a/transition/src/main/java/androidx/transition/CanvasUtils.java
+++ b/transition/src/main/java/androidx/transition/CanvasUtils.java
@@ -16,10 +16,12 @@
 
 package androidx.transition;
 
+import android.annotation.SuppressLint;
 import android.graphics.Canvas;
 import android.os.Build;
 
 import androidx.annotation.NonNull;
+import androidx.core.os.BuildCompat;
 
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
@@ -35,10 +37,18 @@
      *
      * IMPORTANT: This method doesn't work on Pie! It will thrown an exception instead
      */
+    @SuppressLint("NewApi") // TODO: Remove this suppression once Q SDK is released.
     static void enableZ(@NonNull Canvas canvas, boolean enable) {
         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
             // no shadows yet added into a platform
-        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
+        } else if (BuildCompat.isAtLeastQ()) {
+            if (enable) {
+                canvas.enableZ();
+            } else {
+                canvas.disableZ();
+            }
+        } else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.P) {
+            // not on P's greylist, can't use reflection
             throw new IllegalStateException("This method doesn't work on Pie!");
         } else {
             if (!sOrderMethodsFetched) {
diff --git a/transition/src/main/java/androidx/transition/GhostViewUtils.java b/transition/src/main/java/androidx/transition/GhostViewUtils.java
index ed202ec..422517a 100644
--- a/transition/src/main/java/androidx/transition/GhostViewUtils.java
+++ b/transition/src/main/java/androidx/transition/GhostViewUtils.java
@@ -23,13 +23,16 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.core.os.BuildCompat;
 
 class GhostViewUtils {
 
     @Nullable
     static GhostView addGhost(@NonNull View view, @NonNull ViewGroup viewGroup,
             @Nullable Matrix matrix) {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
+        if (!BuildCompat.isAtLeastQ() && // TODO we need this check as Q has the same number as P
+                Build.VERSION.SDK_INT == Build.VERSION_CODES.P) {
+            // Use the platform implementation on P as we can't backport the shadows drawing.
             return GhostViewPlatform.addGhost(view, viewGroup, matrix);
         } else {
             return GhostViewPort.addGhost(view, viewGroup, matrix);
@@ -37,7 +40,9 @@
     }
 
     static void removeGhost(View view) {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
+        if (!BuildCompat.isAtLeastQ() && // TODO we need this check as Q has the same number as P
+                Build.VERSION.SDK_INT == Build.VERSION_CODES.P) {
+            // Use the platform implementation on P as we can't backport the shadows drawing.
             GhostViewPlatform.removeGhost(view);
         } else {
             GhostViewPort.removeGhost(view);
diff --git a/transition/src/main/java/androidx/transition/ImageViewUtils.java b/transition/src/main/java/androidx/transition/ImageViewUtils.java
index 9559c75..f21acc3 100644
--- a/transition/src/main/java/androidx/transition/ImageViewUtils.java
+++ b/transition/src/main/java/androidx/transition/ImageViewUtils.java
@@ -16,21 +16,25 @@
 
 package androidx.transition;
 
+import android.annotation.SuppressLint;
 import android.graphics.Matrix;
 import android.graphics.drawable.Drawable;
 import android.os.Build;
-import android.util.Log;
 import android.widget.ImageView;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
+import androidx.core.os.BuildCompat;
+
 import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
 
 class ImageViewUtils {
-    private static final String TAG = "ImageViewUtils";
 
-    private static Method sAnimateTransformMethod;
-    private static boolean sAnimateTransformMethodFetched;
+    /**
+     * False when linking of the hidden animateTransform method has previously failed.
+     */
+    private static boolean sTryHiddenAnimateTransform = true;
 
     private static Field sDrawMatrixField;
     private static boolean sDrawMatrixFieldFetched;
@@ -38,10 +42,13 @@
     /**
      * Sets the matrix to animate the content of the image view.
      */
-    static void animateTransform(ImageView view, Matrix matrix) {
-        if (matrix == null) {
-            // There is a bug in ImageView.animateTransform() prior to the current development
-            // version of Android so paddings are ignored when matrix is null.
+    @SuppressLint("NewApi") // TODO: Remove this suppression once Q SDK is released.
+    static void animateTransform(@NonNull ImageView view, @Nullable Matrix matrix) {
+        if (BuildCompat.isAtLeastQ()) {
+            view.animateTransform(matrix);
+        } else if (matrix == null) {
+            // There is a bug in ImageView.animateTransform() prior to Q so paddings are
+            // ignored when matrix is null.
             Drawable drawable = view.getDrawable();
             if (drawable != null) {
                 int vwidth = view.getWidth() - view.getPaddingLeft() - view.getPaddingRight();
@@ -50,16 +57,7 @@
                 view.invalidate();
             }
         } else if (Build.VERSION.SDK_INT >= 21) {
-            fetchAnimateTransformMethod();
-            if (sAnimateTransformMethod != null) {
-                try {
-                    sAnimateTransformMethod.invoke(view, matrix);
-                } catch (IllegalAccessException e) {
-                    // Do nothing
-                } catch (InvocationTargetException e) {
-                    throw new RuntimeException(e.getCause());
-                }
-            }
+            hiddenAnimateTransform(view, matrix);
         } else {
             Drawable drawable = view.getDrawable();
             if (drawable != null) {
@@ -86,16 +84,17 @@
         }
     }
 
-    private static void fetchAnimateTransformMethod() {
-        if (!sAnimateTransformMethodFetched) {
+    @RequiresApi(21)
+    @SuppressLint("NewApi") // Lint doesn't know about the hidden method.
+    private static void hiddenAnimateTransform(@NonNull ImageView view, @Nullable Matrix matrix) {
+        if (sTryHiddenAnimateTransform) {
+            // Since this was an @hide method made public, we can link directly against it with
+            // a try/catch for its absence instead of doing the same through reflection.
             try {
-                sAnimateTransformMethod = ImageView.class.getDeclaredMethod("animateTransform",
-                        Matrix.class);
-                sAnimateTransformMethod.setAccessible(true);
-            } catch (NoSuchMethodException e) {
-                Log.i(TAG, "Failed to retrieve animateTransform method", e);
+                view.animateTransform(matrix);
+            } catch (NoSuchMethodError e) {
+                sTryHiddenAnimateTransform = false;
             }
-            sAnimateTransformMethodFetched = true;
         }
     }
 
diff --git a/transition/src/main/java/androidx/transition/ViewGroupUtils.java b/transition/src/main/java/androidx/transition/ViewGroupUtils.java
index 566c0cb..f27b1f8a 100644
--- a/transition/src/main/java/androidx/transition/ViewGroupUtils.java
+++ b/transition/src/main/java/androidx/transition/ViewGroupUtils.java
@@ -16,10 +16,13 @@
 
 package androidx.transition;
 
+import android.annotation.SuppressLint;
 import android.os.Build;
 import android.view.ViewGroup;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
+import androidx.core.os.BuildCompat;
 
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
@@ -29,6 +32,11 @@
  */
 class ViewGroupUtils {
 
+    /**
+     * False when linking of the hidden suppressLayout method has previously failed.
+     */
+    private static boolean sTryHiddenSuppressLayout = true;
+
     private static Method sGetChildDrawingOrderMethod;
     private static boolean sGetChildDrawingOrderMethodFetched;
 
@@ -45,38 +53,60 @@
     /**
      * Provides access to the hidden ViewGroup#suppressLayout method.
      */
+    @SuppressLint("NewApi") // TODO: Remove this suppression once Q SDK is released.
     static void suppressLayout(@NonNull ViewGroup group, boolean suppress) {
-        if (Build.VERSION.SDK_INT >= 18) {
-            ViewGroupUtilsApi18.suppressLayout(group, suppress);
+        if (BuildCompat.isAtLeastQ()) {
+            group.suppressLayout(suppress);
+        } else if (Build.VERSION.SDK_INT >= 18) {
+            hiddenSuppressLayout(group, suppress);
         } else {
             ViewGroupUtilsApi14.suppressLayout(group, suppress);
         }
     }
 
+    @RequiresApi(18)
+    @SuppressLint("NewApi") // Lint doesn't know about the hidden method.
+    private static void hiddenSuppressLayout(@NonNull ViewGroup group, boolean suppress) {
+        if (sTryHiddenSuppressLayout) {
+            // Since this was an @hide method made public, we can link directly against it with
+            // a try/catch for its absence instead of doing the same through reflection.
+            try {
+                group.suppressLayout(suppress);
+            } catch (NoSuchMethodError e) {
+                sTryHiddenSuppressLayout = false;
+            }
+        }
+    }
+
     /**
      * Returns the index of the child to draw for this iteration.
      */
+    @SuppressLint("NewApi") // TODO: Remove this suppression once Q SDK is released.
     static int getChildDrawingOrder(@NonNull ViewGroup viewGroup, int i) {
-        if (!sGetChildDrawingOrderMethodFetched) {
-            try {
-                sGetChildDrawingOrderMethod = ViewGroup.class.getDeclaredMethod(
-                        "getChildDrawingOrder", int.class, int.class);
-                sGetChildDrawingOrderMethod.setAccessible(true);
-            } catch (NoSuchMethodException ignore) {
+        if (BuildCompat.isAtLeastQ()) {
+            return viewGroup.getChildDrawingOrder(i);
+        } else {
+            if (!sGetChildDrawingOrderMethodFetched) {
+                try {
+                    sGetChildDrawingOrderMethod = ViewGroup.class.getDeclaredMethod(
+                            "getChildDrawingOrder", int.class, int.class);
+                    sGetChildDrawingOrderMethod.setAccessible(true);
+                } catch (NoSuchMethodException ignore) {
 
+                }
+                sGetChildDrawingOrderMethodFetched = true;
             }
-            sGetChildDrawingOrderMethodFetched = true;
-        }
-        if (sGetChildDrawingOrderMethod != null) {
-            try {
-                return (Integer) sGetChildDrawingOrderMethod.invoke(viewGroup,
-                        viewGroup.getChildCount(), i);
-            } catch (IllegalAccessException ignore) {
-            } catch (InvocationTargetException ignore) {
+            if (sGetChildDrawingOrderMethod != null) {
+                try {
+                    return (Integer) sGetChildDrawingOrderMethod.invoke(viewGroup,
+                            viewGroup.getChildCount(), i);
+                } catch (IllegalAccessException ignore) {
+                } catch (InvocationTargetException ignore) {
+                }
             }
+            // fallback implementation
+            return i;
         }
-        // fallback implementation
-        return i;
     }
 
 
diff --git a/transition/src/main/java/androidx/transition/ViewGroupUtilsApi18.java b/transition/src/main/java/androidx/transition/ViewGroupUtilsApi18.java
deleted file mode 100644
index e4d4ffa..0000000
--- a/transition/src/main/java/androidx/transition/ViewGroupUtilsApi18.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.transition;
-
-import android.util.Log;
-import android.view.ViewGroup;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.RequiresApi;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-@RequiresApi(18)
-class ViewGroupUtilsApi18 {
-
-    private static final String TAG = "ViewUtilsApi18";
-
-    private static Method sSuppressLayoutMethod;
-    private static boolean sSuppressLayoutMethodFetched;
-
-    static void suppressLayout(@NonNull ViewGroup group, boolean suppress) {
-        fetchSuppressLayoutMethod();
-        if (sSuppressLayoutMethod != null) {
-            try {
-                sSuppressLayoutMethod.invoke(group, suppress);
-            } catch (IllegalAccessException e) {
-                Log.i(TAG, "Failed to invoke suppressLayout method", e);
-            } catch (InvocationTargetException e) {
-                Log.i(TAG, "Error invoking suppressLayout method", e);
-            }
-        }
-    }
-
-    private static void fetchSuppressLayoutMethod() {
-        if (!sSuppressLayoutMethodFetched) {
-            try {
-                sSuppressLayoutMethod = ViewGroup.class.getDeclaredMethod("suppressLayout",
-                        boolean.class);
-                sSuppressLayoutMethod.setAccessible(true);
-            } catch (NoSuchMethodException e) {
-                Log.i(TAG, "Failed to retrieve suppressLayout method", e);
-            }
-            sSuppressLayoutMethodFetched = true;
-        }
-    }
-
-    private ViewGroupUtilsApi18() {
-    }
-}
diff --git a/transition/src/main/java/androidx/transition/ViewUtils.java b/transition/src/main/java/androidx/transition/ViewUtils.java
index d770ab6..df3f919 100644
--- a/transition/src/main/java/androidx/transition/ViewUtils.java
+++ b/transition/src/main/java/androidx/transition/ViewUtils.java
@@ -16,19 +16,18 @@
 
 package androidx.transition;
 
+import android.annotation.SuppressLint;
 import android.graphics.Matrix;
 import android.graphics.Rect;
 import android.os.Build;
-import android.util.Log;
 import android.util.Property;
 import android.view.View;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.core.os.BuildCompat;
 import androidx.core.view.ViewCompat;
 
-import java.lang.reflect.Field;
-
 /**
  * Compatibility utilities for platform features of {@link View}.
  */
@@ -37,16 +36,18 @@
     private static final ViewUtilsBase IMPL;
     private static final String TAG = "ViewUtils";
 
-    private static Field sViewFlagsField;
-    private static boolean sViewFlagsFieldFetched;
-    private static final int VISIBILITY_MASK = 0x0000000C;
-
     static {
-        if (Build.VERSION.SDK_INT >= 22) {
+        if (BuildCompat.isAtLeastQ()) {
+            // TODO: replace with 'new ViewUtilsApi29()' when we can use an SDK_INT check as lint
+            //       doesn't understand BuildCompat API checks
+            IMPL = createViewUtilsApi29();
+        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+            IMPL = new ViewUtilsApi23();
+        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
             IMPL = new ViewUtilsApi22();
-        } else if (Build.VERSION.SDK_INT >= 21) {
+        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
             IMPL = new ViewUtilsApi21();
-        } else if (Build.VERSION.SDK_INT >= 19) {
+        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
             IMPL = new ViewUtilsApi19();
         } else {
             IMPL = new ViewUtilsBase();
@@ -145,15 +146,7 @@
      *                   {@link View#GONE}.
      */
     static void setTransitionVisibility(@NonNull View view, int visibility) {
-        fetchViewFlagsField();
-        if (sViewFlagsField != null) {
-            try {
-                int viewFlags = sViewFlagsField.getInt(view);
-                sViewFlagsField.setInt(view, (viewFlags & ~VISIBILITY_MASK) | visibility);
-            } catch (IllegalAccessException e) {
-                // Do nothing
-            }
-        }
+        IMPL.setTransitionVisibility(view, visibility);
     }
 
     /**
@@ -210,16 +203,10 @@
         IMPL.setLeftTopRightBottom(v, left, top, right, bottom);
     }
 
-    private static void fetchViewFlagsField() {
-        if (!sViewFlagsFieldFetched) {
-            try {
-                sViewFlagsField = View.class.getDeclaredField("mViewFlags");
-                sViewFlagsField.setAccessible(true);
-            } catch (NoSuchFieldException e) {
-                Log.i(TAG, "fetchViewFlagsField: ");
-            }
-            sViewFlagsFieldFetched = true;
-        }
+    // TODO: delete when we use an SDK_INT check as lint doesn't understand BuildCompat API checks
+    @SuppressLint("NewApi")
+    private static ViewUtilsApi29 createViewUtilsApi29() {
+        return new ViewUtilsApi29();
     }
 
     private ViewUtils() {
diff --git a/transition/src/main/java/androidx/transition/ViewUtilsApi19.java b/transition/src/main/java/androidx/transition/ViewUtilsApi19.java
index ff604319..b5a2547 100644
--- a/transition/src/main/java/androidx/transition/ViewUtilsApi19.java
+++ b/transition/src/main/java/androidx/transition/ViewUtilsApi19.java
@@ -16,54 +16,49 @@
 
 package androidx.transition;
 
-import android.util.Log;
+import android.annotation.SuppressLint;
 import android.view.View;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.RequiresApi;
 
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
 @RequiresApi(19)
 class ViewUtilsApi19 extends ViewUtilsBase {
 
-    private static final String TAG = "ViewUtilsApi19";
-
-    private static Method sSetTransitionAlphaMethod;
-    private static boolean sSetTransitionAlphaMethodFetched;
-    private static Method sGetTransitionAlphaMethod;
-    private static boolean sGetTransitionAlphaMethodFetched;
+    /**
+     * False when linking of the hidden set[get]TransitionAlpha method has previously failed.
+     */
+    private static boolean sTryHiddenTransitionAlpha = true;
 
     @Override
+    @SuppressLint("NewApi") // Lint doesn't know about the hidden method.
     public void setTransitionAlpha(@NonNull View view, float alpha) {
-        fetchSetTransitionAlphaMethod();
-        if (sSetTransitionAlphaMethod != null) {
+        if (sTryHiddenTransitionAlpha) {
+            // Since this was an @hide method made public, we can link directly against it with
+            // a try/catch for its absence instead of doing the same through reflection.
             try {
-                sSetTransitionAlphaMethod.invoke(view, alpha);
-            } catch (IllegalAccessException e) {
-                // Do nothing
-            } catch (InvocationTargetException e) {
-                throw new RuntimeException(e.getCause());
+                view.setTransitionAlpha(alpha);
+                return;
+            } catch (NoSuchMethodError e) {
+                sTryHiddenTransitionAlpha = false;
             }
-        } else {
-            view.setAlpha(alpha);
         }
+        view.setAlpha(alpha);
     }
 
     @Override
+    @SuppressLint("NewApi") // Lint doesn't know about the hidden method.
     public float getTransitionAlpha(@NonNull View view) {
-        fetchGetTransitionAlphaMethod();
-        if (sGetTransitionAlphaMethod != null) {
+        if (sTryHiddenTransitionAlpha) {
+            // Since this was an @hide method made public, we can link directly against it with
+            // a try/catch for its absence instead of doing the same through reflection.
             try {
-                return (Float) sGetTransitionAlphaMethod.invoke(view);
-            } catch (IllegalAccessException e) {
-                // Do nothing
-            } catch (InvocationTargetException e) {
-                throw new RuntimeException(e.getCause());
+                return view.getTransitionAlpha();
+            } catch (NoSuchMethodError e) {
+                sTryHiddenTransitionAlpha = false;
             }
         }
-        return super.getTransitionAlpha(view);
+        return view.getAlpha();
     }
 
     @Override
@@ -76,29 +71,4 @@
         // Do nothing
     }
 
-    private void fetchSetTransitionAlphaMethod() {
-        if (!sSetTransitionAlphaMethodFetched) {
-            try {
-                sSetTransitionAlphaMethod = View.class.getDeclaredMethod("setTransitionAlpha",
-                        float.class);
-                sSetTransitionAlphaMethod.setAccessible(true);
-            } catch (NoSuchMethodException e) {
-                Log.i(TAG, "Failed to retrieve setTransitionAlpha method", e);
-            }
-            sSetTransitionAlphaMethodFetched = true;
-        }
-    }
-
-    private void fetchGetTransitionAlphaMethod() {
-        if (!sGetTransitionAlphaMethodFetched) {
-            try {
-                sGetTransitionAlphaMethod = View.class.getDeclaredMethod("getTransitionAlpha");
-                sGetTransitionAlphaMethod.setAccessible(true);
-            } catch (NoSuchMethodException e) {
-                Log.i(TAG, "Failed to retrieve getTransitionAlpha method", e);
-            }
-            sGetTransitionAlphaMethodFetched = true;
-        }
-    }
-
 }
diff --git a/transition/src/main/java/androidx/transition/ViewUtilsApi21.java b/transition/src/main/java/androidx/transition/ViewUtilsApi21.java
index 14301d2..c5a8900 100644
--- a/transition/src/main/java/androidx/transition/ViewUtilsApi21.java
+++ b/transition/src/main/java/androidx/transition/ViewUtilsApi21.java
@@ -16,107 +16,70 @@
 
 package androidx.transition;
 
+import android.annotation.SuppressLint;
 import android.graphics.Matrix;
-import android.util.Log;
 import android.view.View;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.annotation.RequiresApi;
 
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
 @RequiresApi(21)
 class ViewUtilsApi21 extends ViewUtilsApi19 {
 
-    private static final String TAG = "ViewUtilsApi21";
-
-    private static Method sTransformMatrixToGlobalMethod;
-    private static boolean sTransformMatrixToGlobalMethodFetched;
-    private static Method sTransformMatrixToLocalMethod;
-    private static boolean sTransformMatrixToLocalMethodFetched;
-    private static Method sSetAnimationMatrixMethod;
-    private static boolean sSetAnimationMatrixMethodFetched;
+    /**
+     * False when linking of the hidden setAnimationMatrix method has previously failed.
+     */
+    private static boolean sTryHiddenSetAnimationMatrix = true;
+    /**
+     * False when linking of the hidden transformMatrixToGlobal method has previously failed.
+     */
+    private static boolean sTryHiddenTransformMatrixToGlobal = true;
+    /**
+     * False when linking of the hidden transformMatrixToLocal method has previously failed.
+     */
+    private static boolean sTryHiddenTransformMatrixToLocal = true;
 
     @Override
+    @SuppressLint("NewApi") // Lint doesn't know about the hidden method.
     public void transformMatrixToGlobal(@NonNull View view, @NonNull Matrix matrix) {
-        fetchTransformMatrixToGlobalMethod();
-        if (sTransformMatrixToGlobalMethod != null) {
+        if (sTryHiddenTransformMatrixToGlobal) {
+            // Since this was an @hide method made public, we can link directly against it with
+            // a try/catch for its absence instead of doing the same through reflection.
             try {
-                sTransformMatrixToGlobalMethod.invoke(view, matrix);
-            } catch (IllegalAccessException e) {
-                // Do nothing
-            } catch (InvocationTargetException e) {
-                throw new RuntimeException(e.getCause());
+                view.transformMatrixToGlobal(matrix);
+            } catch (NoSuchMethodError e) {
+                sTryHiddenTransformMatrixToGlobal = false;
             }
         }
     }
 
     @Override
+    @SuppressLint("NewApi") // Lint doesn't know about the hidden method.
     public void transformMatrixToLocal(@NonNull View view, @NonNull Matrix matrix) {
-        fetchTransformMatrixToLocalMethod();
-        if (sTransformMatrixToLocalMethod != null) {
+        if (sTryHiddenTransformMatrixToLocal) {
+            // Since this was an @hide method made public, we can link directly against it with
+            // a try/catch for its absence instead of doing the same through reflection.
             try {
-                sTransformMatrixToLocalMethod.invoke(view, matrix);
-            } catch (IllegalAccessException e) {
-                // Do nothing
-            } catch (InvocationTargetException e) {
-                throw new RuntimeException(e.getCause());
+                view.transformMatrixToLocal(matrix);
+            } catch (NoSuchMethodError e) {
+                sTryHiddenTransformMatrixToLocal = false;
             }
         }
     }
 
     @Override
-    public void setAnimationMatrix(@NonNull View view, Matrix matrix) {
-        fetchSetAnimationMatrix();
-        if (sSetAnimationMatrixMethod != null) {
+    @SuppressLint("NewApi") // Lint doesn't know about the hidden method.
+    public void setAnimationMatrix(@NonNull View view, @Nullable Matrix matrix) {
+        if (sTryHiddenSetAnimationMatrix) {
+            // Since this was an @hide method made public, we can link directly against it with
+            // a try/catch for its absence instead of doing the same through reflection.
             try {
-                sSetAnimationMatrixMethod.invoke(view, matrix);
-            } catch (InvocationTargetException e) {
-                // Do nothing
-            } catch (IllegalAccessException e) {
-                throw new RuntimeException(e.getCause());
+                view.setAnimationMatrix(matrix);
+            } catch (NoSuchMethodError e) {
+                sTryHiddenSetAnimationMatrix = false;
             }
         }
     }
 
-    private void fetchTransformMatrixToGlobalMethod() {
-        if (!sTransformMatrixToGlobalMethodFetched) {
-            try {
-                sTransformMatrixToGlobalMethod = View.class.getDeclaredMethod(
-                        "transformMatrixToGlobal", Matrix.class);
-                sTransformMatrixToGlobalMethod.setAccessible(true);
-            } catch (NoSuchMethodException e) {
-                Log.i(TAG, "Failed to retrieve transformMatrixToGlobal method", e);
-            }
-            sTransformMatrixToGlobalMethodFetched = true;
-        }
-    }
-
-    private void fetchTransformMatrixToLocalMethod() {
-        if (!sTransformMatrixToLocalMethodFetched) {
-            try {
-                sTransformMatrixToLocalMethod = View.class.getDeclaredMethod(
-                        "transformMatrixToLocal", Matrix.class);
-                sTransformMatrixToLocalMethod.setAccessible(true);
-            } catch (NoSuchMethodException e) {
-                Log.i(TAG, "Failed to retrieve transformMatrixToLocal method", e);
-            }
-            sTransformMatrixToLocalMethodFetched = true;
-        }
-    }
-
-    private void fetchSetAnimationMatrix() {
-        if (!sSetAnimationMatrixMethodFetched) {
-            try {
-                sSetAnimationMatrixMethod = View.class.getDeclaredMethod(
-                        "setAnimationMatrix", Matrix.class);
-                sSetAnimationMatrixMethod.setAccessible(true);
-            } catch (NoSuchMethodException e) {
-                Log.i(TAG, "Failed to retrieve setAnimationMatrix method", e);
-            }
-            sSetAnimationMatrixMethodFetched = true;
-        }
-    }
-
 }
diff --git a/transition/src/main/java/androidx/transition/ViewUtilsApi22.java b/transition/src/main/java/androidx/transition/ViewUtilsApi22.java
index f8dd2a0..a251bbe 100644
--- a/transition/src/main/java/androidx/transition/ViewUtilsApi22.java
+++ b/transition/src/main/java/androidx/transition/ViewUtilsApi22.java
@@ -17,49 +17,31 @@
 package androidx.transition;
 
 import android.annotation.SuppressLint;
-import android.util.Log;
 import android.view.View;
 
+import androidx.annotation.NonNull;
 import androidx.annotation.RequiresApi;
 
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
 @RequiresApi(22)
 class ViewUtilsApi22 extends ViewUtilsApi21 {
 
-    private static final String TAG = "ViewUtilsApi22";
-
-    private static Method sSetLeftTopRightBottomMethod;
-    private static boolean sSetLeftTopRightBottomMethodFetched;
+    /**
+     * False when linking of the hidden setLeftTopRightBottom method has previously failed.
+     */
+    private static boolean sTryHiddenSetLeftTopRightBottom = true;
 
     @Override
-    public void setLeftTopRightBottom(View v, int left, int top, int right, int bottom) {
-        fetchSetLeftTopRightBottomMethod();
-        if (sSetLeftTopRightBottomMethod != null) {
+    @SuppressLint("NewApi") // Lint doesn't know about the hidden method.
+    public void setLeftTopRightBottom(@NonNull View v, int left, int top, int right, int bottom) {
+        if (sTryHiddenSetLeftTopRightBottom) {
+            // Since this was an @hide method made public, we can link directly against it with
+            // a try/catch for its absence instead of doing the same through reflection.
             try {
-                sSetLeftTopRightBottomMethod.invoke(v, left, top, right, bottom);
-            } catch (IllegalAccessException e) {
-                // Do nothing
-            } catch (InvocationTargetException e) {
-                throw new RuntimeException(e.getCause());
+                v.setLeftTopRightBottom(left, top, right, bottom);
+            } catch (NoSuchMethodError e) {
+                sTryHiddenSetLeftTopRightBottom = false;
             }
         }
     }
-
-    @SuppressLint("PrivateApi")
-    private void fetchSetLeftTopRightBottomMethod() {
-        if (!sSetLeftTopRightBottomMethodFetched) {
-            try {
-                sSetLeftTopRightBottomMethod = View.class.getDeclaredMethod("setLeftTopRightBottom",
-                        int.class, int.class, int.class, int.class);
-                sSetLeftTopRightBottomMethod.setAccessible(true);
-            } catch (NoSuchMethodException e) {
-                Log.i(TAG, "Failed to retrieve setLeftTopRightBottom method", e);
-            }
-            sSetLeftTopRightBottomMethodFetched = true;
-        }
-    }
-
 }
 
diff --git a/transition/src/main/java/androidx/transition/ViewUtilsApi23.java b/transition/src/main/java/androidx/transition/ViewUtilsApi23.java
new file mode 100644
index 0000000..a089f2f
--- /dev/null
+++ b/transition/src/main/java/androidx/transition/ViewUtilsApi23.java
@@ -0,0 +1,53 @@
+/*
+ * 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.transition;
+
+import android.annotation.SuppressLint;
+import android.os.Build;
+import android.view.View;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
+
+@RequiresApi(23)
+class ViewUtilsApi23 extends ViewUtilsApi22 {
+
+    /**
+     * False when linking of the hidden setLeftTopRightBottom method has previously failed.
+     */
+    private static boolean sTryHiddenSetTransitionVisibility = true;
+
+    @Override
+    @SuppressLint("NewApi") // Lint doesn't know about the hidden method.
+    public void setTransitionVisibility(@NonNull View view, int visibility) {
+        // on P this method is blacklisted, so we have to resort to reflecting on mViewFlags
+        if (Build.VERSION.SDK_INT == Build.VERSION_CODES.P) {
+            super.setTransitionVisibility(view, visibility);
+        } else {
+            if (sTryHiddenSetTransitionVisibility) {
+                // Since this was an @hide method made public, we can link directly against it with
+                // a try/catch for its absence instead of doing the same through reflection.
+                try {
+                    view.setTransitionVisibility(visibility);
+                } catch (NoSuchMethodError e) {
+                    sTryHiddenSetTransitionVisibility = false;
+                }
+            }
+        }
+    }
+}
+
diff --git a/transition/src/main/java/androidx/transition/ViewUtilsApi29.java b/transition/src/main/java/androidx/transition/ViewUtilsApi29.java
new file mode 100644
index 0000000..be835de5
--- /dev/null
+++ b/transition/src/main/java/androidx/transition/ViewUtilsApi29.java
@@ -0,0 +1,64 @@
+/*
+ * 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.transition;
+
+import android.graphics.Matrix;
+import android.view.View;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
+
+@RequiresApi(29)
+class ViewUtilsApi29 extends ViewUtilsApi23 {
+
+    @Override
+    public void setTransitionAlpha(@NonNull View view, float alpha) {
+        view.setTransitionAlpha(alpha);
+    }
+
+    @Override
+    public float getTransitionAlpha(@NonNull View view) {
+        return view.getTransitionAlpha();
+    }
+
+    @Override
+    public void setTransitionVisibility(@NonNull View view, int visibility) {
+        view.setTransitionVisibility(visibility);
+    }
+
+    @Override
+    public void setLeftTopRightBottom(@NonNull View v, int left, int top, int right, int bottom) {
+        v.setLeftTopRightBottom(left, top, right, bottom);
+    }
+
+    @Override
+    public void transformMatrixToGlobal(@NonNull View view, @NonNull Matrix matrix) {
+        view.transformMatrixToGlobal(matrix);
+    }
+
+    @Override
+    public void transformMatrixToLocal(@NonNull View view, @NonNull Matrix matrix) {
+        view.transformMatrixToLocal(matrix);
+    }
+
+    @Override
+    public void setAnimationMatrix(@NonNull View view, @Nullable Matrix matrix) {
+        view.setAnimationMatrix(matrix);
+    }
+}
+
diff --git a/transition/src/main/java/androidx/transition/ViewUtilsBase.java b/transition/src/main/java/androidx/transition/ViewUtilsBase.java
index 87917dd..3c43422 100644
--- a/transition/src/main/java/androidx/transition/ViewUtilsBase.java
+++ b/transition/src/main/java/androidx/transition/ViewUtilsBase.java
@@ -23,7 +23,9 @@
 import android.view.ViewParent;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 
+import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 
@@ -34,6 +36,10 @@
     private static Method sSetFrameMethod;
     private static boolean sSetFrameFetched;
 
+    private static Field sViewFlagsField;
+    private static boolean sViewFlagsFieldFetched;
+    private static final int VISIBILITY_MASK = 0x0000000C;
+
     private float[] mMatrixValues;
 
     public void setTransitionAlpha(@NonNull View view, float alpha) {
@@ -99,7 +105,7 @@
         }
     }
 
-    public void setAnimationMatrix(@NonNull View view, Matrix matrix) {
+    public void setAnimationMatrix(@NonNull View view, @Nullable Matrix matrix) {
         if (matrix == null || matrix.isIdentity()) {
             view.setPivotX(view.getWidth() / 2);
             view.setPivotY(view.getHeight() / 2);
@@ -132,7 +138,7 @@
         }
     }
 
-    public void setLeftTopRightBottom(View v, int left, int top, int right, int bottom) {
+    public void setLeftTopRightBottom(@NonNull View v, int left, int top, int right, int bottom) {
         fetchSetFrame();
         if (sSetFrameMethod != null) {
             try {
@@ -145,6 +151,26 @@
         }
     }
 
+    public void setTransitionVisibility(@NonNull View view, int visibility) {
+        if (!sViewFlagsFieldFetched) {
+            try {
+                sViewFlagsField = View.class.getDeclaredField("mViewFlags");
+                sViewFlagsField.setAccessible(true);
+            } catch (NoSuchFieldException e) {
+                Log.i(TAG, "fetchViewFlagsField: ");
+            }
+            sViewFlagsFieldFetched = true;
+        }
+        if (sViewFlagsField != null) {
+            try {
+                int viewFlags = sViewFlagsField.getInt(view);
+                sViewFlagsField.setInt(view, (viewFlags & ~VISIBILITY_MASK) | visibility);
+            } catch (IllegalAccessException e) {
+                // Do nothing
+            }
+        }
+    }
+
     @SuppressLint("PrivateApi")
     private void fetchSetFrame() {
         if (!sSetFrameFetched) {
diff --git a/viewpager/src/main/java/androidx/viewpager/widget/PagerTitleStrip.java b/viewpager/src/main/java/androidx/viewpager/widget/PagerTitleStrip.java
index d94fc09..fb050e7 100644
--- a/viewpager/src/main/java/androidx/viewpager/widget/PagerTitleStrip.java
+++ b/viewpager/src/main/java/androidx/viewpager/widget/PagerTitleStrip.java
@@ -34,6 +34,7 @@
 import androidx.annotation.FloatRange;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.core.os.BuildCompat;
 import androidx.core.widget.TextViewCompat;
 
 import java.lang.ref.WeakReference;
@@ -117,6 +118,9 @@
         addView(mNextText = new TextView(context));
 
         final TypedArray a = context.obtainStyledAttributes(attrs, ATTRS);
+        if (BuildCompat.isAtLeastQ()) {
+            saveAttributeDataForStyleable(context, ATTRS, attrs, a, 0, 0);
+        }
         final int textAppearance = a.getResourceId(0, 0);
         if (textAppearance != 0) {
             TextViewCompat.setTextAppearance(mPrevText, textAppearance);
diff --git a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/AccessibilityTest.kt b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/AccessibilityTest.kt
new file mode 100644
index 0000000..02cd523
--- /dev/null
+++ b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/AccessibilityTest.kt
@@ -0,0 +1,173 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.viewpager2.widget
+
+import android.os.Build
+import android.view.accessibility.AccessibilityNodeInfo
+import androidx.core.view.ViewCompat
+import androidx.core.view.accessibility.AccessibilityNodeInfoCompat
+import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_PAGE_DOWN
+import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_PAGE_LEFT
+import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_PAGE_RIGHT
+import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_PAGE_UP
+import androidx.test.filters.LargeTest
+import androidx.viewpager2.LocaleTestUtils
+import androidx.viewpager2.widget.ViewPager2.ORIENTATION_HORIZONTAL
+import androidx.viewpager2.widget.ViewPager2.ORIENTATION_VERTICAL
+import org.hamcrest.CoreMatchers.equalTo
+import org.junit.Assert.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+import java.util.concurrent.TimeUnit
+
+@RunWith(Parameterized::class)
+@LargeTest
+class AccessibilityTest(private val config: TestConfig) : BaseTest() {
+    data class TestConfig(
+        @ViewPager2.Orientation val orientation: Int,
+        val rtl: Boolean
+    )
+
+    companion object {
+        @JvmStatic
+        @Parameterized.Parameters(name = "{0}")
+        fun spec(): List<TestConfig> = createTestSet()
+    }
+
+    override fun setUp() {
+        super.setUp()
+        if (config.rtl) {
+            localeUtil.resetLocale()
+            localeUtil.setLocale(LocaleTestUtils.RTL_LANGUAGE)
+        }
+    }
+
+    @Test
+    fun test_onPerformPageAction() {
+        setUpTest(config.orientation).apply {
+            setAdapterSync(viewAdapterProvider(stringSequence(6)))
+
+            val initialPage = viewPager.currentItem
+            assertBasicState(initialPage)
+
+            listOf(1, 2, 3, 2, 3, 2, 3, 4, 5, 4, 5, 4, 3, 2, 1, 0, 1).forEach {
+                    targetPage ->
+                val currentPage = viewPager.currentItem
+                val latch = viewPager.addWaitForScrolledLatch(targetPage)
+                if (targetPage - currentPage == 1) {
+                    ViewCompat.performAccessibilityAction(viewPager,
+                        getNextPageAction(config.orientation, isRtl), null)
+                } else {
+                    ViewCompat.performAccessibilityAction(viewPager,
+                        getPreviousPageAction(config.orientation, isRtl), null)
+                }
+                latch.await(1, TimeUnit.SECONDS)
+                assertBasicState(targetPage)
+            }
+        }
+    }
+
+    @Test
+    fun test_collectionInfo() {
+        setUpTest(config.orientation).apply {
+            setAdapterSync(viewAdapterProvider(stringSequence(6)))
+
+            val initialPage = viewPager.currentItem
+            assertBasicState(initialPage)
+
+            var node = AccessibilityNodeInfo.obtain()
+            activityTestRule.runOnUiThread { viewPager.onInitializeAccessibilityNodeInfo(node) }
+            var collectionInfo = node.collectionInfo
+
+            if (config.orientation == ORIENTATION_VERTICAL) {
+                assertThat(collectionInfo.rowCount, equalTo(6))
+                assertThat(collectionInfo.columnCount, equalTo(0))
+            } else {
+                assertThat(collectionInfo.columnCount, equalTo(6))
+                assertThat(collectionInfo.rowCount, equalTo(0))
+            }
+            assertThat(collectionInfo.isHierarchical, equalTo(false))
+            if (Build.VERSION.SDK_INT >= 21) {
+                assertThat(collectionInfo.selectionMode, equalTo(0))
+            }
+        }
+    }
+
+    @Test
+    fun test_onOrientationChange() {
+        setUpTest(config.orientation).apply {
+            setAdapterSync(viewAdapterProvider(stringSequence(2)))
+
+            val initialPage = viewPager.currentItem
+            assertBasicState(initialPage)
+
+            activityTestRule.runOnUiThread {
+                viewPager.setOrientation(getOppositeOrientation(config.orientation))
+            }
+            assertBasicState(initialPage)
+        }
+    }
+
+    private fun getNextPageAction(orientation: Int, isRtl: Boolean): Int {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+            if (orientation == ViewPager2.ORIENTATION_HORIZONTAL) {
+                if (isRtl) {
+                    return ACTION_PAGE_LEFT.id
+                } else {
+                    return ACTION_PAGE_RIGHT.id
+                }
+            }
+            return ACTION_PAGE_DOWN.id
+        }
+        return AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD
+    }
+
+    private fun getPreviousPageAction(orientation: Int, isRtl: Boolean): Int {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+            if (orientation == ViewPager2.ORIENTATION_HORIZONTAL) {
+                if (isRtl) {
+                    return ACTION_PAGE_RIGHT.id
+                } else {
+                    return ACTION_PAGE_LEFT.id
+                }
+            }
+            return ACTION_PAGE_UP.id
+        }
+        return AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD
+    }
+
+    private fun getOppositeOrientation(orientation: Int): Int {
+        if (orientation == ViewPager2.ORIENTATION_HORIZONTAL) {
+            return ViewPager2.ORIENTATION_VERTICAL
+        } else {
+            return ViewPager2.ORIENTATION_HORIZONTAL
+        }
+    }
+}
+
+// region Test Suite creation
+
+private fun createTestSet(): List<AccessibilityTest.TestConfig> {
+    return listOf(ORIENTATION_HORIZONTAL, ORIENTATION_VERTICAL).flatMap { orientation ->
+        listOf(true, false).map { rtl ->
+            AccessibilityTest.TestConfig(orientation, rtl)
+        }
+    }
+}
+
+// endregion
diff --git a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/BaseTest.kt b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/BaseTest.kt
index 899c341..7ce0c84 100644
--- a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/BaseTest.kt
+++ b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/BaseTest.kt
@@ -20,7 +20,15 @@
 import android.os.Build
 import android.view.View
 import android.view.View.OVER_SCROLL_NEVER
+import android.view.accessibility.AccessibilityNodeInfo
 import androidx.core.view.ViewCompat
+import androidx.core.view.accessibility.AccessibilityNodeInfoCompat
+import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_PAGE_RIGHT
+import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_PAGE_LEFT
+import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_PAGE_UP
+import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_PAGE_DOWN
+import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD
+import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD
 import androidx.recyclerview.widget.LinearLayoutManager
 import androidx.recyclerview.widget.RecyclerView
 import androidx.test.core.app.ApplicationProvider
@@ -229,6 +237,91 @@
                     )
                 )
         }
+
+        fun assertPageActions() {
+            var customActions = getActionList(viewPager)
+            var currentPage = viewPager.currentItem
+            var numPages = viewPager.adapter!!.itemCount
+            var isUserInputEnabled = viewPager.isUserInputEnabled
+            var isHorizontalOrientation = viewPager.orientation == ViewPager2.ORIENTATION_HORIZONTAL
+            var isVerticalOrientation = viewPager.orientation == ViewPager2.ORIENTATION_VERTICAL
+
+            val expectPageLeftAction = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP &&
+                    isUserInputEnabled && isHorizontalOrientation &&
+                    (if (isRtl) currentPage < numPages - 1 else currentPage > 0)
+
+            val expectPageRightAction = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP &&
+                    isUserInputEnabled && isHorizontalOrientation &&
+                    (if (isRtl) currentPage > 0 else currentPage < numPages - 1)
+
+            val expectPageUpAction = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP &&
+                    isUserInputEnabled && isVerticalOrientation &&
+                    currentPage > 0
+
+            val expectPageDownAction = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP &&
+                    isUserInputEnabled && isVerticalOrientation &&
+                    currentPage < numPages - 1
+
+            val expectScrollBackwardAction = Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP &&
+                    Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN &&
+                    isUserInputEnabled && currentPage > 0
+
+            val expectScrollForwardAction = Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP &&
+                    Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN &&
+                    isUserInputEnabled && currentPage < numPages - 1
+
+            assertThat("Left action expected: $expectPageLeftAction",
+                hasPageAction(customActions, ACTION_PAGE_LEFT.id),
+                equalTo(expectPageLeftAction)
+            )
+
+            assertThat("Right action expected: $expectPageRightAction",
+                hasPageAction(customActions, ACTION_PAGE_RIGHT.id),
+                equalTo(expectPageRightAction)
+            )
+            assertThat("Up action expected: $expectPageUpAction",
+                hasPageAction(customActions, ACTION_PAGE_UP.id),
+                equalTo(expectPageUpAction)
+            )
+            assertThat("Down action expected: $expectPageDownAction",
+                hasPageAction(customActions, ACTION_PAGE_DOWN.id),
+                equalTo(expectPageDownAction)
+            )
+
+            var node = AccessibilityNodeInfo.obtain()
+            activityTestRule.runOnUiThread { viewPager.onInitializeAccessibilityNodeInfo(node) }
+            var standardActions = node.actions
+
+            assertThat("scroll backward action expected: $expectScrollBackwardAction",
+                hasScrollAction(standardActions, ACTION_SCROLL_BACKWARD),
+                equalTo(expectScrollBackwardAction)
+            )
+
+            assertThat("Scroll forward action expected: $expectScrollForwardAction",
+                hasScrollAction(standardActions, ACTION_SCROLL_FORWARD),
+                equalTo(expectScrollForwardAction)
+            )
+        }
+
+        private fun hasScrollAction(
+            actions: Int,
+            accessibilityActionId: Int
+        ): Boolean {
+            return actions and accessibilityActionId != 0
+        }
+
+        private fun hasPageAction(
+            actions: List<AccessibilityNodeInfoCompat.AccessibilityActionCompat>,
+            accessibilityActionId: Int
+        ): Boolean {
+            return actions.any { it.id == accessibilityActionId }
+        }
+
+        private fun getActionList(view: View):
+                List<AccessibilityNodeInfoCompat.AccessibilityActionCompat> {
+            return view.getTag(R.id.tag_accessibility_actions) as?
+                    ArrayList<AccessibilityNodeInfoCompat.AccessibilityActionCompat> ?: ArrayList()
+        }
     }
 
     /**
@@ -360,6 +453,7 @@
         if (viewPager.adapter is SelfChecking) {
             (viewPager.adapter as SelfChecking).selfCheck()
         }
+        assertPageActions()
     }
 
     fun ViewPager2.setCurrentItemSync(
diff --git a/viewpager2/src/main/java/androidx/viewpager2/widget/ScrollEventAdapter.java b/viewpager2/src/main/java/androidx/viewpager2/widget/ScrollEventAdapter.java
index 3e2b758..3ed699c 100644
--- a/viewpager2/src/main/java/androidx/viewpager2/widget/ScrollEventAdapter.java
+++ b/viewpager2/src/main/java/androidx/viewpager2/widget/ScrollEventAdapter.java
@@ -272,10 +272,7 @@
      * Let the adapter know that mCurrentItem was restored in onRestoreInstanceState.
      */
     void notifyRestoreCurrentItem(int currentItem) {
-        // Don't send page selected event for page 0 for consistency with ViewPager
-        if (currentItem != 0) {
-            dispatchSelected(currentItem);
-        }
+        dispatchSelected(currentItem);
     }
 
     /**
diff --git a/viewpager2/src/main/java/androidx/viewpager2/widget/ViewPager2.java b/viewpager2/src/main/java/androidx/viewpager2/widget/ViewPager2.java
index a42d6aa..0b9bc04 100644
--- a/viewpager2/src/main/java/androidx/viewpager2/widget/ViewPager2.java
+++ b/viewpager2/src/main/java/androidx/viewpager2/widget/ViewPager2.java
@@ -16,6 +16,11 @@
 
 package androidx.viewpager2.widget;
 
+import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_PAGE_DOWN;
+import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_PAGE_LEFT;
+import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_PAGE_RIGHT;
+import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_PAGE_UP;
+
 import static java.lang.annotation.RetentionPolicy.SOURCE;
 
 import android.annotation.SuppressLint;
@@ -33,15 +38,17 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
 
 import androidx.annotation.IntDef;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.Px;
 import androidx.annotation.RequiresApi;
+import androidx.core.os.BuildCompat;
 import androidx.core.view.ViewCompat;
 import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
-import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat;
+import androidx.core.view.accessibility.AccessibilityViewCommand;
 import androidx.recyclerview.widget.LinearLayoutManager;
 import androidx.recyclerview.widget.PagerSnapHelper;
 import androidx.recyclerview.widget.RecyclerView;
@@ -76,6 +83,26 @@
     public static final int SCROLL_STATE_DRAGGING = 1;
     public static final int SCROLL_STATE_SETTLING = 2;
 
+    private static final AccessibilityViewCommand ACTION_PAGE_FORWARD =
+            new AccessibilityViewCommand() {
+        @Override
+        public boolean perform(@NonNull View view, @Nullable CommandArguments arguments) {
+            ViewPager2 viewPager = (ViewPager2) view;
+            viewPager.setCurrentItem(viewPager.getCurrentItem() + 1, true);
+            return true;
+        }
+    };
+
+    private static final AccessibilityViewCommand ACTION_PAGE_BACKWARD =
+            new AccessibilityViewCommand() {
+        @Override
+        public boolean perform(@NonNull View view, @Nullable CommandArguments arguments) {
+            ViewPager2 viewPager = (ViewPager2) view;
+            viewPager.setCurrentItem(viewPager.getCurrentItem() - 1, true);
+            return true;
+        }
+    };
+
     // reused in layout(...)
     private final Rect mTmpContainerRect = new Rect();
     private final Rect mTmpChildRect = new Rect();
@@ -92,6 +119,7 @@
     private PageTransformerAdapter mPageTransformerAdapter;
     private CompositeOnPageChangeCallback mPageChangeEventDispatcher;
     private boolean mUserInputEnabled = true;
+    private RecyclerView.AdapterDataObserver mAdapterDataObserver;
 
     public ViewPager2(@NonNull Context context) {
         super(context);
@@ -118,8 +146,10 @@
     private void initialize(Context context, AttributeSet attrs) {
         mRecyclerView = new RecyclerViewImpl(context);
         mRecyclerView.setId(ViewCompat.generateViewId());
+        ViewCompat.setImportantForAccessibility(mRecyclerView,
+                ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_NO);
 
-        mLayoutManager = new LinearLayoutManagerImpl(context);
+        mLayoutManager = new LinearLayoutManager(context);
         mRecyclerView.setLayoutManager(mLayoutManager);
         setOrientation(context, attrs);
 
@@ -141,12 +171,23 @@
         mPageChangeEventDispatcher = new CompositeOnPageChangeCallback(3);
         mScrollEventAdapter.setOnPageChangeCallback(mPageChangeEventDispatcher);
 
+        mAdapterDataObserver = new RecyclerView.AdapterDataObserver() {
+            @Override
+            public void onChanged() {
+                super.onChanged();
+                updatePageAccessibilityActions();
+            }
+        };
+
         // Callback that updates mCurrentItem after swipes. Also triggered in other cases, but in
         // all those cases mCurrentItem will only be overwritten with the same value.
         final OnPageChangeCallback currentItemUpdater = new OnPageChangeCallback() {
             @Override
             public void onPageSelected(int position) {
-                mCurrentItem = position;
+                if (mCurrentItem != position) {
+                    mCurrentItem = position;
+                    updatePageAccessibilityActions();
+                }
             }
         };
 
@@ -161,6 +202,12 @@
         mPageChangeEventDispatcher.addOnPageChangeCallback(mPageTransformerAdapter);
 
         attachViewToParent(mRecyclerView, 0, mRecyclerView.getLayoutParams());
+
+        if (ViewCompat.getImportantForAccessibility(this)
+                == ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
+            ViewCompat.setImportantForAccessibility(this,
+                    ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_YES);
+        }
     }
 
     /**
@@ -188,8 +235,70 @@
         };
     }
 
+    @Override
+    public CharSequence getAccessibilityClassName() {
+        return "androidx.viewpager.widget.ViewPager";
+    }
+
+    /**
+     * Update the ViewPager2's available page accessibility actions. These are updated in response
+     * to page, adapter, and orientation changes. Compatible with API >= 21.
+     */
+    void updatePageAccessibilityActions() {
+        ViewCompat.removeAccessibilityAction(this, ACTION_PAGE_LEFT.getId());
+        ViewCompat.removeAccessibilityAction(this, ACTION_PAGE_RIGHT.getId());
+        ViewCompat.removeAccessibilityAction(this, ACTION_PAGE_UP.getId());
+        ViewCompat.removeAccessibilityAction(this, ACTION_PAGE_DOWN.getId());
+
+        if (getAdapter() == null) {
+            return;
+        }
+
+        int itemCount = getAdapter().getItemCount();
+        if (itemCount == 0) {
+            return;
+        }
+
+        if (!isUserInputEnabled()) {
+            return;
+        }
+
+        if (getOrientation() == ORIENTATION_HORIZONTAL) {
+            boolean isLayoutRtl = isLayoutRtl();
+            AccessibilityNodeInfoCompat.AccessibilityActionCompat actionPageForward =
+                    isLayoutRtl ? ACTION_PAGE_LEFT : ACTION_PAGE_RIGHT;
+            AccessibilityNodeInfoCompat.AccessibilityActionCompat actionPageBackward =
+                    isLayoutRtl ? ACTION_PAGE_RIGHT : ACTION_PAGE_LEFT;
+
+            if (mCurrentItem < itemCount - 1) {
+                ViewCompat.replaceAccessibilityAction(this, actionPageForward, null,
+                        ACTION_PAGE_FORWARD);
+            }
+            if (mCurrentItem > 0) {
+                ViewCompat.replaceAccessibilityAction(this, actionPageBackward, null,
+                        ACTION_PAGE_BACKWARD);
+            }
+        } else {
+            if (mCurrentItem < itemCount - 1) {
+                ViewCompat.replaceAccessibilityAction(this, ACTION_PAGE_DOWN, null,
+                        ACTION_PAGE_FORWARD);
+            }
+            if (mCurrentItem > 0) {
+                ViewCompat.replaceAccessibilityAction(this, ACTION_PAGE_UP, null,
+                        ACTION_PAGE_BACKWARD);
+            }
+        }
+    }
+
+    private boolean isLayoutRtl() {
+        return ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_RTL;
+    }
+
     private void setOrientation(Context context, AttributeSet attrs) {
         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ViewPager2);
+        if (BuildCompat.isAtLeastQ()) {
+            saveAttributeDataForStyleable(context, R.styleable.ViewPager2, attrs, a, 0, 0);
+        }
         try {
             setOrientation(
                     a.getInt(R.styleable.ViewPager2_android_orientation, ORIENTATION_HORIZONTAL));
@@ -333,7 +442,14 @@
      * @see RecyclerView#setAdapter(Adapter)
      */
     public void setAdapter(@Nullable Adapter adapter) {
+        Adapter oldAdapter = mRecyclerView.getAdapter();
+        if (oldAdapter != null) {
+            oldAdapter.unregisterAdapterDataObserver(mAdapterDataObserver);
+        }
+
         mRecyclerView.setAdapter(adapter);
+        updatePageAccessibilityActions();
+        adapter.registerAdapterDataObserver(mAdapterDataObserver);
     }
 
     public @Nullable Adapter getAdapter() {
@@ -391,6 +507,7 @@
      */
     public void setOrientation(@Orientation int orientation) {
         mLayoutManager.setOrientation(orientation);
+        updatePageAccessibilityActions();
     }
 
     public @Orientation int getOrientation() {
@@ -443,6 +560,7 @@
 
         float previousItem = mCurrentItem;
         mCurrentItem = item;
+        updatePageAccessibilityActions();
 
         if (!mScrollEventAdapter.isIdle()) {
             // Scroll in progress, overwrite previousItem with actual current position
@@ -590,6 +708,10 @@
      */
     public void setUserInputEnabled(boolean enabled) {
         mUserInputEnabled = enabled;
+        updatePageAccessibilityActions();
+        if (Build.VERSION.SDK_INT < 21) {
+            sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
+        }
     }
 
     /**
@@ -637,6 +759,72 @@
         mPageTransformerAdapter.setPageTransformer(transformer);
     }
 
+    @Override
+    @RequiresApi(17)
+    public void setLayoutDirection(int layoutDirection) {
+        super.setLayoutDirection(layoutDirection);
+        updatePageAccessibilityActions();
+    }
+
+    @Override
+    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+        super.onInitializeAccessibilityNodeInfo(info);
+        addCollectionInfo(info);
+        addScrollActions(info);
+    }
+
+    private void addCollectionInfo(AccessibilityNodeInfo info) {
+        int rowCount = 0;
+        int colCount = 0;
+        if (getAdapter() != null) {
+            if (getOrientation() == ORIENTATION_VERTICAL) {
+                rowCount = getAdapter().getItemCount();
+            } else {
+                colCount = getAdapter().getItemCount();
+            }
+        }
+        AccessibilityNodeInfoCompat nodeInfoCompat = AccessibilityNodeInfoCompat.wrap(info);
+        AccessibilityNodeInfoCompat.CollectionInfoCompat collectionInfo =
+                AccessibilityNodeInfoCompat.CollectionInfoCompat.obtain(rowCount, colCount,
+                        /* hierarchical= */false,
+                        AccessibilityNodeInfoCompat.CollectionInfoCompat.SELECTION_MODE_NONE);
+        nodeInfoCompat.setCollectionInfo(collectionInfo);
+    }
+
+    private void addScrollActions(AccessibilityNodeInfo info) {
+        if (Build.VERSION.SDK_INT < 21) {
+            if (getAdapter() == null) {
+                return;
+            }
+            int itemCount = mRecyclerView.getAdapter().getItemCount();
+            if (itemCount == 0 || !mUserInputEnabled) {
+                return;
+            }
+            if (mCurrentItem > 0) {
+                info.addAction(AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD);
+            }
+            if (mCurrentItem < itemCount - 1) {
+                info.addAction(AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD);
+            }
+            info.setScrollable(true);
+        }
+    }
+
+    @Override
+    public boolean performAccessibilityAction(int action, Bundle arguments) {
+        switch (action) {
+            case AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD:
+            case AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD:
+                int nextItem = (action == AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD)
+                        ? getCurrentItem() - 1
+                        : getCurrentItem() + 1;
+
+                setCurrentItem(nextItem, true);
+                return true;
+        }
+        return super.performAccessibilityAction(action, arguments);
+    }
+
     /**
      * Slightly modified RecyclerView to get ViewPager behavior in accessibility and to
      * enable/disable user scrolling.
@@ -647,15 +835,12 @@
         }
 
         @Override
-        public CharSequence getAccessibilityClassName() {
-            return "androidx.viewpager.widget.ViewPager";
-        }
-
-        @Override
         public void onInitializeAccessibilityEvent(@NonNull AccessibilityEvent event) {
             super.onInitializeAccessibilityEvent(event);
             event.setFromIndex(mCurrentItem);
             event.setToIndex(mCurrentItem);
+            event.setSource(ViewPager2.this);
+            event.setClassName(ViewPager2.this.getAccessibilityClassName());
         }
 
         @SuppressLint("ClickableViewAccessibility")
@@ -670,41 +855,6 @@
         }
     }
 
-    /**
-     * Slightly modified LinearLayoutManager to adjust accessibility when user scrolling is
-     * disabled.
-     */
-    private class LinearLayoutManagerImpl extends LinearLayoutManager {
-        LinearLayoutManagerImpl(Context context) {
-            super(context);
-        }
-
-        @Override
-        public boolean performAccessibilityAction(@NonNull RecyclerView.Recycler recycler,
-                @NonNull RecyclerView.State state, int action, @Nullable Bundle args) {
-            switch (action) {
-                case AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD:
-                case AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD:
-                    if (!isUserInputEnabled()) {
-                        return false;
-                    }
-                    break;
-            }
-            return super.performAccessibilityAction(recycler, state, action, args);
-        }
-
-        @Override
-        public void onInitializeAccessibilityNodeInfo(@NonNull RecyclerView.Recycler recycler,
-                @NonNull RecyclerView.State state, @NonNull AccessibilityNodeInfoCompat info) {
-            super.onInitializeAccessibilityNodeInfo(recycler, state, info);
-            if (!isUserInputEnabled()) {
-                info.removeAction(AccessibilityActionCompat.ACTION_SCROLL_BACKWARD);
-                info.removeAction(AccessibilityActionCompat.ACTION_SCROLL_FORWARD);
-                info.setScrollable(false);
-            }
-        }
-    }
-
     private class PagerSnapHelperImpl extends PagerSnapHelper {
         PagerSnapHelperImpl() {
         }
diff --git a/wear/api/1.1.0-alpha01.txt b/wear/api/1.1.0-alpha01.txt
index 6609d67..325310e 100644
--- a/wear/api/1.1.0-alpha01.txt
+++ b/wear/api/1.1.0-alpha01.txt
@@ -19,6 +19,14 @@
   @Deprecated public final class AmbientMode extends android.app.Fragment {
     ctor @Deprecated public AmbientMode();
     method @Deprecated public static <T extends android.app.Activity> androidx.wear.ambient.AmbientMode.AmbientController! attachAmbientSupport(T!);
+    method @Deprecated public void dump(String!, java.io.FileDescriptor!, java.io.PrintWriter!, String[]!);
+    method @Deprecated @CallSuper public void onAttach(android.content.Context!);
+    method @Deprecated @CallSuper public void onCreate(android.os.Bundle!);
+    method @Deprecated @CallSuper public void onDestroy();
+    method @Deprecated @CallSuper public void onDetach();
+    method @Deprecated @CallSuper public void onPause();
+    method @Deprecated @CallSuper public void onResume();
+    method @Deprecated @CallSuper public void onStop();
     field @Deprecated public static final String EXTRA_BURN_IN_PROTECTION = "com.google.android.wearable.compat.extra.BURN_IN_PROTECTION";
     field @Deprecated public static final String EXTRA_LOWBIT_AMBIENT = "com.google.android.wearable.compat.extra.LOWBIT_AMBIENT";
     field @Deprecated public static final String FRAGMENT_TAG = "android.support.wearable.ambient.AmbientMode";
diff --git a/wear/api/current.txt b/wear/api/current.txt
index 6609d67..325310e 100644
--- a/wear/api/current.txt
+++ b/wear/api/current.txt
@@ -19,6 +19,14 @@
   @Deprecated public final class AmbientMode extends android.app.Fragment {
     ctor @Deprecated public AmbientMode();
     method @Deprecated public static <T extends android.app.Activity> androidx.wear.ambient.AmbientMode.AmbientController! attachAmbientSupport(T!);
+    method @Deprecated public void dump(String!, java.io.FileDescriptor!, java.io.PrintWriter!, String[]!);
+    method @Deprecated @CallSuper public void onAttach(android.content.Context!);
+    method @Deprecated @CallSuper public void onCreate(android.os.Bundle!);
+    method @Deprecated @CallSuper public void onDestroy();
+    method @Deprecated @CallSuper public void onDetach();
+    method @Deprecated @CallSuper public void onPause();
+    method @Deprecated @CallSuper public void onResume();
+    method @Deprecated @CallSuper public void onStop();
     field @Deprecated public static final String EXTRA_BURN_IN_PROTECTION = "com.google.android.wearable.compat.extra.BURN_IN_PROTECTION";
     field @Deprecated public static final String EXTRA_LOWBIT_AMBIENT = "com.google.android.wearable.compat.extra.LOWBIT_AMBIENT";
     field @Deprecated public static final String FRAGMENT_TAG = "android.support.wearable.ambient.AmbientMode";
diff --git a/wear/src/main/java/androidx/wear/widget/CircledImageView.java b/wear/src/main/java/androidx/wear/widget/CircledImageView.java
index 43ed817..c858f2f 100644
--- a/wear/src/main/java/androidx/wear/widget/CircledImageView.java
+++ b/wear/src/main/java/androidx/wear/widget/CircledImageView.java
@@ -37,6 +37,7 @@
 import androidx.annotation.Px;
 import androidx.annotation.RestrictTo;
 import androidx.annotation.RestrictTo.Scope;
+import androidx.core.os.BuildCompat;
 import androidx.wear.R;
 
 import java.util.Objects;
@@ -127,6 +128,9 @@
         super(context, attrs, defStyle);
 
         TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.CircledImageView);
+        if (BuildCompat.isAtLeastQ()) {
+            saveAttributeDataForStyleable(context, R.styleable.CircledImageView, attrs, a, 0, 0);
+        }
         mDrawable = a.getDrawable(R.styleable.CircledImageView_android_src);
         if (mDrawable != null && mDrawable.getConstantState() != null) {
             // The provided Drawable may be used elsewhere, so make a mutable clone before setTint()
diff --git a/wear/src/main/java/androidx/wear/widget/WearableRecyclerView.java b/wear/src/main/java/androidx/wear/widget/WearableRecyclerView.java
index a538479..037bfbc 100644
--- a/wear/src/main/java/androidx/wear/widget/WearableRecyclerView.java
+++ b/wear/src/main/java/androidx/wear/widget/WearableRecyclerView.java
@@ -25,6 +25,7 @@
 import android.view.ViewTreeObserver;
 
 import androidx.annotation.Nullable;
+import androidx.core.os.BuildCompat;
 import androidx.recyclerview.widget.RecyclerView;
 import androidx.wear.R;
 
@@ -84,6 +85,10 @@
         if (attrs != null) {
             TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.WearableRecyclerView,
                     defStyle, defStyleRes);
+            if (BuildCompat.isAtLeastQ()) {
+                saveAttributeDataForStyleable(
+                        context, R.styleable.WearableRecyclerView, attrs, a, defStyle, defStyleRes);
+            }
 
             setCircularScrollingGestureEnabled(
                     a.getBoolean(
diff --git a/wear/src/main/java/androidx/wear/widget/drawer/WearableActionDrawerView.java b/wear/src/main/java/androidx/wear/widget/drawer/WearableActionDrawerView.java
index 8674247..f78d6a2 100644
--- a/wear/src/main/java/androidx/wear/widget/drawer/WearableActionDrawerView.java
+++ b/wear/src/main/java/androidx/wear/widget/drawer/WearableActionDrawerView.java
@@ -37,6 +37,7 @@
 import android.widget.TextView;
 
 import androidx.annotation.Nullable;
+import androidx.core.os.BuildCompat;
 import androidx.recyclerview.widget.LinearLayoutManager;
 import androidx.recyclerview.widget.RecyclerView;
 import androidx.wear.R;
@@ -119,6 +120,12 @@
             TypedArray typedArray = context.obtainStyledAttributes(
                     attrs, R.styleable.WearableActionDrawerView, defStyleAttr, 0 /* defStyleRes */);
 
+            if (BuildCompat.isAtLeastQ()) {
+                saveAttributeDataForStyleable(
+                        context, R.styleable.WearableActionDrawerView, attrs, typedArray,
+                        defStyleAttr, 0);
+            }
+
             try {
                 mTitle = typedArray.getString(R.styleable.WearableActionDrawerView_drawerTitle);
                 showOverflowInPeek = typedArray.getBoolean(
diff --git a/wear/src/main/java/androidx/wear/widget/drawer/WearableDrawerView.java b/wear/src/main/java/androidx/wear/widget/drawer/WearableDrawerView.java
index 87b43b8..6ec2902 100644
--- a/wear/src/main/java/androidx/wear/widget/drawer/WearableDrawerView.java
+++ b/wear/src/main/java/androidx/wear/widget/drawer/WearableDrawerView.java
@@ -33,6 +33,7 @@
 import androidx.annotation.RestrictTo;
 import androidx.annotation.RestrictTo.Scope;
 import androidx.annotation.StyleableRes;
+import androidx.core.os.BuildCompat;
 import androidx.customview.widget.ViewDragHelper;
 import androidx.wear.R;
 
@@ -466,6 +467,11 @@
                 context.obtainStyledAttributes(
                         attrs, R.styleable.WearableDrawerView, defStyleAttr,
                         R.style.Widget_Wear_WearableDrawerView);
+        if (BuildCompat.isAtLeastQ()) {
+            saveAttributeDataForStyleable(
+                    context, R.styleable.WearableDrawerView, attrs, typedArray, defStyleAttr,
+                    R.style.Widget_Wear_WearableDrawerView);
+        }
 
         Drawable background =
                 getDrawable(context, typedArray, R.styleable.WearableDrawerView_android_background);
diff --git a/wear/src/main/java/androidx/wear/widget/drawer/WearableNavigationDrawerView.java b/wear/src/main/java/androidx/wear/widget/drawer/WearableNavigationDrawerView.java
index 667d177..e015ba7 100644
--- a/wear/src/main/java/androidx/wear/widget/drawer/WearableNavigationDrawerView.java
+++ b/wear/src/main/java/androidx/wear/widget/drawer/WearableNavigationDrawerView.java
@@ -33,6 +33,7 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
 import androidx.annotation.RestrictTo.Scope;
+import androidx.core.os.BuildCompat;
 import androidx.wear.R;
 import androidx.wear.internal.widget.drawer.MultiPagePresenter;
 import androidx.wear.internal.widget.drawer.MultiPageUi;
@@ -143,6 +144,12 @@
                     defStyleAttr,
                     0 /* defStyleRes */);
 
+            if (BuildCompat.isAtLeastQ()) {
+                saveAttributeDataForStyleable(
+                        context, R.styleable.WearableNavigationDrawerView, attrs, typedArray,
+                        defStyleAttr, 0);
+            }
+
             //noinspection WrongConstant
             navStyle = typedArray.getInt(
                     R.styleable.WearableNavigationDrawerView_navigationStyle, DEFAULT_STYLE);