Merge "Bump all versions for March 13th Release" into androidx-master-dev
am: b83b3330d8
Change-Id: Id45dc42fe759e7a9f40818c751e4e4601f9a4b4c
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 58b1d10..89bb5dc 100644
--- a/appcompat/resources/src/main/java/androidx/appcompat/widget/DrawableUtils.java
+++ b/appcompat/resources/src/main/java/androidx/appcompat/widget/DrawableUtils.java
@@ -33,6 +33,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;
@@ -68,6 +69,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/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..576a1e5 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
@@ -41,8 +42,10 @@
}
public static class BiometricPrompt.PromptInfo {
+ method public boolean getAllowDeviceCredential();
method public CharSequence? getDescription();
method public CharSequence getNegativeButtonText();
+ method public boolean getRequireConfirmation();
method public CharSequence? getSubtitle();
method public CharSequence getTitle();
}
@@ -50,8 +53,10 @@
public static class BiometricPrompt.PromptInfo.Builder {
ctor public BiometricPrompt.PromptInfo.Builder();
method public androidx.biometric.BiometricPrompt.PromptInfo build();
+ method @RequiresApi(29) public androidx.biometric.BiometricPrompt.PromptInfo.Builder setAllowDeviceCredential(boolean);
method public androidx.biometric.BiometricPrompt.PromptInfo.Builder setDescription(CharSequence?);
method public androidx.biometric.BiometricPrompt.PromptInfo.Builder setNegativeButtonText(CharSequence);
+ method public androidx.biometric.BiometricPrompt.PromptInfo.Builder setRequireConfirmation(boolean);
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..576a1e5 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
@@ -41,8 +42,10 @@
}
public static class BiometricPrompt.PromptInfo {
+ method public boolean getAllowDeviceCredential();
method public CharSequence? getDescription();
method public CharSequence getNegativeButtonText();
+ method public boolean getRequireConfirmation();
method public CharSequence? getSubtitle();
method public CharSequence getTitle();
}
@@ -50,8 +53,10 @@
public static class BiometricPrompt.PromptInfo.Builder {
ctor public BiometricPrompt.PromptInfo.Builder();
method public androidx.biometric.BiometricPrompt.PromptInfo build();
+ method @RequiresApi(29) public androidx.biometric.BiometricPrompt.PromptInfo.Builder setAllowDeviceCredential(boolean);
method public androidx.biometric.BiometricPrompt.PromptInfo.Builder setDescription(CharSequence?);
method public androidx.biometric.BiometricPrompt.PromptInfo.Builder setNegativeButtonText(CharSequence);
+ method public androidx.biometric.BiometricPrompt.PromptInfo.Builder setRequireConfirmation(boolean);
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..1d9da37 100644
--- a/biometric/src/main/java/androidx/biometric/BiometricFragment.java
+++ b/biometric/src/main/java/androidx/biometric/BiometricFragment.java
@@ -22,12 +22,14 @@
import android.os.CancellationSignal;
import android.os.Handler;
import android.os.Looper;
+import android.text.TextUtils;
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;
@@ -207,13 +209,25 @@
// 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 setAllowDeviceCredential 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.setRequireConfirmation(
+ mBundle.getBoolean((BiometricPrompt.KEY_REQUIRE_CONFIRMATION), true));
+ builder.setAllowDeviceCredential(
+ mBundle.getBoolean(BiometricPrompt.KEY_ALLOW_DEVICE_CREDENTIAL));
+ }
+ 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 da6bf70..b59c10e 100644
--- a/biometric/src/main/java/androidx/biometric/BiometricPrompt.java
+++ b/biometric/src/main/java/androidx/biometric/BiometricPrompt.java
@@ -27,6 +27,7 @@
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.Lifecycle;
@@ -60,6 +61,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,
@@ -73,7 +76,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 {}
/**
@@ -237,6 +241,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 setRequireConfirmation(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 setAllowDeviceCredential(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.
@@ -245,12 +295,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);
}
@@ -297,6 +352,22 @@
public CharSequence getNegativeButtonText() {
return mBundle.getCharSequence(KEY_NEGATIVE_TEXT);
}
+
+ /**
+ * @return See {@link Builder#setRequireConfirmation(boolean)}.
+ */
+ @Nullable
+ public boolean getRequireConfirmation() {
+ return mBundle.getBoolean(KEY_REQUIRE_CONFIRMATION);
+ }
+
+ /**
+ * @return See {@link Builder#setAllowDeviceCredential(boolean)}.
+ */
+ @Nullable
+ public boolean getAllowDeviceCredential() {
+ return mBundle.getBoolean(KEY_ALLOW_DEVICE_CREDENTIAL);
+ }
}
// Passed in from the client.
@@ -444,6 +515,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);
}
diff --git a/buildSrc/src/main/kotlin/androidx/build/DiffAndDocs.kt b/buildSrc/src/main/kotlin/androidx/build/DiffAndDocs.kt
index 224130c..3573279 100644
--- a/buildSrc/src/main/kotlin/androidx/build/DiffAndDocs.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/DiffAndDocs.kt
@@ -82,6 +82,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(
@@ -90,7 +96,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
@@ -560,13 +567,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 7f7d4dc..9b587e7 100644
--- a/buildSrc/src/main/kotlin/androidx/build/PublishDocsRules.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/PublishDocsRules.kt
@@ -46,7 +46,7 @@
prebuilts(LibraryGroups.CORE, "core-ktx", "1.1.0-alpha04")
prebuilts(LibraryGroups.CURSORADAPTER, "1.0.0")
prebuilts(LibraryGroups.CUSTOMVIEW, "1.0.0")
- prebuilts(LibraryGroups.DOCUMENTFILE, "1.0.0")
+ ignore(LibraryGroups.DOCUMENTFILE)
prebuilts(LibraryGroups.DRAWERLAYOUT, "1.0.0")
prebuilts(LibraryGroups.DYNAMICANIMATION, "dynamicanimation-ktx", "1.0.0-alpha01")
prebuilts(LibraryGroups.DYNAMICANIMATION, "1.0.0")
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/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/current.txt b/core/api/current.txt
index 0ece2e3..5855002 100644
--- a/core/api/current.txt
+++ b/core/api/current.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/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_current.txt b/core/api/restricted_current.txt
index 5baf105..87a5dd5 100644
--- a/core/api/restricted_current.txt
+++ b/core/api/restricted_current.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/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/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..87e003bd
--- /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.getFileDescriptor())
+ .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..b6ab58b 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;
@@ -906,6 +907,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.
}
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/accessibility/AccessibilityNodeInfoCompat.java b/core/src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java
index 2f784ae..7d9d140 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 < 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 < 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 < 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;
@@ -3673,6 +3806,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
@@ -3731,6 +3895,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 < 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 < 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..130cb5b 100644
--- a/documentfile/src/main/java/androidx/documentfile/provider/DocumentFile.java
+++ b/documentfile/src/main/java/androidx/documentfile/provider/DocumentFile.java
@@ -16,7 +16,6 @@
package androidx.documentfile.provider;
-import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
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/src/main/java/androidx/drawerlayout/widget/DrawerLayout.java b/drawerlayout/src/main/java/androidx/drawerlayout/widget/DrawerLayout.java
index 7bbaf62..bbd6ec03 100644
--- a/drawerlayout/src/main/java/androidx/drawerlayout/widget/DrawerLayout.java
+++ b/drawerlayout/src/main/java/androidx/drawerlayout/widget/DrawerLayout.java
@@ -1027,6 +1027,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);
@@ -1313,6 +1315,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/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/current.txt b/fragment/api/current.txt
index e586a2f..47ba5f4 100644
--- a/fragment/api/current.txt
+++ b/fragment/api/current.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/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/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/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_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/navigation/safe-args-gradle-plugin/build.gradle b/navigation/safe-args-gradle-plugin/build.gradle
index 67d3153..c9f08d3 100644
--- a/navigation/safe-args-gradle-plugin/build.gradle
+++ b/navigation/safe-args-gradle-plugin/build.gradle
@@ -45,7 +45,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)
@@ -57,7 +57,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 0edd4f7..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/current.txt b/preference/api/current.txt
index 0edd4f7..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/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..298874c 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
@@ -28,11 +28,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,9 +68,6 @@
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";
@@ -78,13 +77,14 @@
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 mRequireConfirmationCheckbox;
+ private CheckBox mAllowDeviceCredential;
+
private int mCounter;
private int mNumberFailedAttempts;
@@ -128,7 +128,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 +139,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);
}
@@ -151,6 +148,9 @@
buttonCreateKeys = findViewById(R.id.button_enable_biometric_with_crypto);
final Button buttonAuthenticate;
buttonAuthenticate = findViewById(R.id.button_authenticate);
+ mUseCryptoCheckbox = findViewById(R.id.checkbox_use_crypto);
+ mRequireConfirmationCheckbox = findViewById(R.id.checkbox_require_confirmation);
+ mAllowDeviceCredential = findViewById(R.id.checkbox_enable_fallback);
try {
mKeyStore = KeyStore.getInstance("AndroidKeyStore");
@@ -158,7 +158,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 +168,21 @@
buttonCreateKeys.setOnClickListener(v -> enableBiometricWithCrypto());
}
buttonAuthenticate.setOnClickListener(v -> startAuthentication());
+
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
+ mRequireConfirmationCheckbox.setEnabled(false);
+ mRequireConfirmationCheckbox.setChecked(false);
+ }
+ if (!BuildCompat.isAtLeastQ()) {
+ mAllowDeviceCredential.setEnabled(false);
+ mAllowDeviceCredential.setChecked(false);
+ }
+
}
@Override
protected void onPause() {
- if (mMode == MODE_CANCEL_ON_CONFIGURATION_CHANGE) {
+ if (getMode() == MODE_CANCEL_ON_CONFIGURATION_CHANGE) {
mBiometricPrompt.cancelAuthentication();
}
super.onPause();
@@ -192,53 +202,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 +218,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)
+ .setRequireConfirmation(mRequireConfirmationCheckbox.isChecked());
+
+ if (BuildCompat.isAtLeastQ()) {
+ if (mAllowDeviceCredential.isChecked()) {
+ builder.setAllowDeviceCredential(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 +332,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..ed02990 100644
--- a/samples/BiometricDemos/src/main/res/layout/fragment_activity.xml
+++ b/samples/BiometricDemos/src/main/res/layout/fragment_activity.xml
@@ -33,14 +33,33 @@
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:>
+ <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 +67,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:>
+ 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:>
+ 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:>
+ 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..d570e1b 100644
--- a/samples/BiometricDemos/src/main/res/values/strings.xml
+++ b/samples/BiometricDemos/src/main/res/values/strings.xml
@@ -22,6 +22,8 @@
<string name="button_authenticate">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 31e96e2..753208f 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -74,6 +74,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/slices/core/src/main/java/androidx/slice/SliceProvider.java b/slices/core/src/main/java/androidx/slice/SliceProvider.java
index 397db68..e5144cc 100644
--- a/slices/core/src/main/java/androidx/slice/SliceProvider.java
+++ b/slices/core/src/main/java/androidx/slice/SliceProvider.java
@@ -143,6 +143,7 @@
private SliceProviderCompat mCompat;
+ private final Object mPinnedSliceUrisLock = new Object();
private List<Uri> mPinnedSliceUris;
/**
@@ -200,8 +201,6 @@
@Override
public final boolean onCreate() {
if (Build.VERSION.SDK_INT < 19) return false;
- mPinnedSliceUris = new ArrayList<>(SliceManager.getInstance(
- getContext()).getPinnedSlices());
if (Build.VERSION.SDK_INT < 28) {
mCompat = new SliceProviderCompat(this,
onCreatePermissionManager(mAutoGrantPermissions), getContext());
@@ -361,8 +360,9 @@
@RestrictTo(RestrictTo.Scope.LIBRARY)
@RequiresApi(19)
public void handleSlicePinned(Uri sliceUri) {
- if (!mPinnedSliceUris.contains(sliceUri)) {
- mPinnedSliceUris.add(sliceUri);
+ List<Uri> pinnedSlices = getPinnedSlices();
+ if (!pinnedSlices.contains(sliceUri)) {
+ pinnedSlices.add(sliceUri);
}
}
@@ -372,8 +372,9 @@
@RestrictTo(RestrictTo.Scope.LIBRARY)
@RequiresApi(19)
public void handleSliceUnpinned(Uri sliceUri) {
- if (mPinnedSliceUris.contains(sliceUri)) {
- mPinnedSliceUris.remove(sliceUri);
+ List<Uri> pinnedSlices = getPinnedSlices();
+ if (pinnedSlices.contains(sliceUri)) {
+ pinnedSlices.remove(sliceUri);
}
}
@@ -413,6 +414,12 @@
*/
@RequiresApi(19)
@NonNull public List<Uri> getPinnedSlices() {
+ synchronized (mPinnedSliceUrisLock) {
+ if (mPinnedSliceUris == null) {
+ mPinnedSliceUris = new ArrayList<>(SliceManager.getInstance(getContext())
+ .getPinnedSlices());
+ }
+ }
return mPinnedSliceUris;
}
diff --git a/slidingpanelayout/src/main/java/androidx/slidingpanelayout/widget/SlidingPaneLayout.java b/slidingpanelayout/src/main/java/androidx/slidingpanelayout/widget/SlidingPaneLayout.java
index 282d377..6ac1cb0 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/viewpager2/src/androidTest/java/androidx/viewpager2/widget/BaseTest.kt b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/BaseTest.kt
index 9b308b1..2d6fb72 100644
--- a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/BaseTest.kt
+++ b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/BaseTest.kt
@@ -21,6 +21,11 @@
import android.view.View
import android.view.View.OVER_SCROLL_NEVER
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.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.test.core.app.ApplicationProvider
@@ -221,6 +226,58 @@
)
)
}
+
+ fun assertPageActions() {
+ var actions = 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 = isUserInputEnabled && isHorizontalOrientation &&
+ (if (isRtl) currentPage < numPages - 1 else currentPage > 0)
+
+ val expectPageRightAction = isUserInputEnabled && isHorizontalOrientation &&
+ (if (isRtl) currentPage > 0 else currentPage < numPages - 1)
+
+ val expectPageUpAction = isUserInputEnabled && isVerticalOrientation &&
+ currentPage > 0
+
+ val expectPageDownAction = isUserInputEnabled && isVerticalOrientation &&
+ currentPage < numPages - 1
+
+ assertThat("Left action expected: $expectPageLeftAction",
+ hasPageAction(actions, ACTION_PAGE_LEFT.id),
+ equalTo(expectPageLeftAction)
+ )
+
+ assertThat("Right action expected: $expectPageRightAction",
+ hasPageAction(actions, ACTION_PAGE_RIGHT.id),
+ equalTo(expectPageRightAction)
+ )
+ assertThat("Up action expected: $expectPageUpAction",
+ hasPageAction(actions, ACTION_PAGE_UP.id),
+ equalTo(expectPageUpAction)
+ )
+ assertThat("Down action expected: $expectPageDownAction",
+ hasPageAction(actions, ACTION_PAGE_DOWN.id),
+ equalTo(expectPageDownAction)
+ )
+ }
+
+ 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()
+ }
}
/**
@@ -346,6 +403,7 @@
if (viewPager.adapter is SelfChecking) {
(viewPager.adapter as SelfChecking).selfCheck()
}
+ assertPageActions()
}
fun ViewPager2.setCurrentItemSync(
diff --git a/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PageAccessibilityActionsTest.kt b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PageAccessibilityActionsTest.kt
new file mode 100644
index 0000000..cb3115b
--- /dev/null
+++ b/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PageAccessibilityActionsTest.kt
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.viewpager2.widget
+
+import androidx.core.view.ViewCompat
+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.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+import java.util.concurrent.TimeUnit
+
+@RunWith(Parameterized::class)
+@LargeTest
+class PageAccessibilityActionsTest(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_onHorizontalOrientation() {
+ 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_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 (orientation == ViewPager2.ORIENTATION_HORIZONTAL) {
+ if (isRtl) {
+ return ACTION_PAGE_LEFT.id
+ } else {
+ return ACTION_PAGE_RIGHT.id
+ }
+ }
+ return ACTION_PAGE_DOWN.id
+ }
+
+ private fun getPreviousPageAction(orientation: Int, isRtl: Boolean): Int {
+ if (orientation == ViewPager2.ORIENTATION_HORIZONTAL) {
+ if (isRtl) {
+ return ACTION_PAGE_RIGHT.id
+ } else {
+ return ACTION_PAGE_LEFT.id
+ }
+ }
+ return ACTION_PAGE_UP.id
+ }
+
+ 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<PageAccessibilityActionsTest.TestConfig> {
+ return listOf(ORIENTATION_HORIZONTAL, ORIENTATION_VERTICAL).flatMap { orientation ->
+ listOf(true, false).map { rtl ->
+ PageAccessibilityActionsTest.TestConfig(orientation, rtl)
+ }
+ }
+}
+
+// endregion
diff --git a/viewpager2/src/main/java/androidx/viewpager2/widget/ScrollEventAdapter.java b/viewpager2/src/main/java/androidx/viewpager2/widget/ScrollEventAdapter.java
index 5eadede..04a5d6b 100644
--- a/viewpager2/src/main/java/androidx/viewpager2/widget/ScrollEventAdapter.java
+++ b/viewpager2/src/main/java/androidx/viewpager2/widget/ScrollEventAdapter.java
@@ -271,10 +271,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);
}
private boolean isLayoutRTL() {
diff --git a/viewpager2/src/main/java/androidx/viewpager2/widget/ViewPager2.java b/viewpager2/src/main/java/androidx/viewpager2/widget/ViewPager2.java
index 5c7fb00..89a237f 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;
@@ -23,7 +28,6 @@
import android.content.res.TypedArray;
import android.graphics.Rect;
import android.os.Build;
-import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.AttributeSet;
@@ -41,7 +45,7 @@
import androidx.annotation.RequiresApi;
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 +80,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();
@@ -90,6 +114,7 @@
private PageTransformerAdapter mPageTransformerAdapter;
private CompositeOnPageChangeCallback mPageChangeEventDispatcher;
private boolean mUserInputEnabled = true;
+ private RecyclerView.AdapterDataObserver mAdapterDataObserver;
public ViewPager2(@NonNull Context context) {
super(context);
@@ -116,8 +141,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);
@@ -132,12 +159,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();
+ }
}
};
@@ -152,6 +190,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);
+ }
}
/**
@@ -179,6 +223,65 @@
};
}
+ @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.
+ */
+ 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);
try {
@@ -221,7 +324,7 @@
super.onRestoreInstanceState(ss.getSuperState());
setOrientation(ss.mOrientation);
mCurrentItem = ss.mCurrentItem;
- mUserInputEnabled = ss.mUserScrollable;
+ setUserInputEnabled(ss.mUserScrollable);
if (ss.mScrollInProgress) {
// A scroll was in progress, so the RecyclerView is not at mCurrentItem right now. Move
// it to mCurrentItem instantly in the _next_ frame, as RecyclerView is not yet fired up
@@ -334,7 +437,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() {
@@ -392,6 +502,7 @@
*/
public void setOrientation(@Orientation int orientation) {
mLayoutManager.setOrientation(orientation);
+ updatePageAccessibilityActions();
}
public @Orientation int getOrientation() {
@@ -440,6 +551,7 @@
float previousItem = mCurrentItem;
mCurrentItem = item;
+ updatePageAccessibilityActions();
if (!mScrollEventAdapter.isIdle()) {
// Scroll in progress, overwrite previousItem with actual current position
@@ -484,6 +596,7 @@
*/
public void setUserInputEnabled(boolean enabled) {
mUserInputEnabled = enabled;
+ updatePageAccessibilityActions();
}
/**
@@ -531,6 +644,13 @@
mPageTransformerAdapter.setPageTransformer(transformer);
}
+ @Override
+ @RequiresApi(17)
+ public void setLayoutDirection(int layoutDirection) {
+ super.setLayoutDirection(layoutDirection);
+ updatePageAccessibilityActions();
+ }
+
/**
* Slightly modified RecyclerView to get ViewPager behavior in accessibility and to
* enable/disable user scrolling.
@@ -541,15 +661,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")
@@ -564,41 +681,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 static class SmoothScrollToPosition implements Runnable {
private final int mPosition;
private final RecyclerView mRecyclerView;
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";