Merge "Added lottie animations for udfps side/tip" into sc-v2-dev
diff --git a/res/layout/udfps_enroll_enrolling.xml b/res/layout/udfps_enroll_enrolling.xml
index 67c127b..e933753 100644
--- a/res/layout/udfps_enroll_enrolling.xml
+++ b/res/layout/udfps_enroll_enrolling.xml
@@ -17,6 +17,7 @@
<com.google.android.setupdesign.GlifLayout
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/setup_wizard_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -30,15 +31,45 @@
android:clipChildren="false"
android:orientation="vertical">
- <TextView
- android:id="@+id/error_text"
- style="@style/TextAppearance.ErrorText"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal|bottom"
- android:accessibilityLiveRegion="polite"
- android:gravity="center_horizontal"
- android:visibility="invisible" />
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:gravity="center|bottom"
+ android:orientation="vertical">
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:layout_gravity="center_horizontal|bottom">
+
+ <!-- Animation res MUST be set in code -->
+ <com.airbnb.lottie.LottieAnimationView
+ android:id="@+id/illustration_lottie"
+ android:layout_width="match_parent"
+ android:layout_height="200dp"
+ android:layout_marginTop="@dimen/udfps_lottie_translate_y"
+ android:scaleType="centerInside"
+ android:visibility="gone"
+ app:lottie_autoPlay="true"
+ app:lottie_loop="true"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ app:lottie_speed=".85" />
+ </FrameLayout>
+
+ <TextView
+ android:id="@+id/error_text"
+ style="@style/TextAppearance.ErrorText"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal|bottom"
+ android:accessibilityLiveRegion="polite"
+ android:gravity="center_horizontal"
+ android:visibility="invisible" />
+ </LinearLayout>
</LinearLayout>
</com.google.android.setupdesign.GlifLayout>
diff --git a/res/raw/udfps_edge_hint_lottie.json b/res/raw/udfps_edge_hint_lottie.json
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/res/raw/udfps_edge_hint_lottie.json
diff --git a/res/raw/udfps_tip_hint_lottie.json b/res/raw/udfps_tip_hint_lottie.json
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/res/raw/udfps_tip_hint_lottie.json
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 2468db6..a5753df 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -235,6 +235,7 @@
fingerprint_finish_max_size = fingerprint_progress_bar_max_size
+ (fingerprint_enrolling_content_margin_vertical x 2) -->
<dimen name="fingerprint_finish_max_size">288dp</dimen>
+ <dimen name="udfps_lottie_translate_y">0dp</dimen>
<!-- Face -->
<item name="face_preview_translate_y" format="float" type="dimen">0</item>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 300b3a4..f7be31c 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1084,6 +1084,10 @@
<string name="security_settings_fingerprint_enroll_finish_message">Now you can use your fingerprint to unlock your phone or verify it\u2019s you, like when you sign in to apps</string>
<!-- Button text to skip enrollment of fingerprint [CHAR LIMIT=40] -->
<string name="security_settings_fingerprint_enroll_enrolling_skip">Do it later</string>
+ <!-- Accessibility message for fingerprint enrollment asking the user to place the tip of their finger on the fingerprint sensor [CHAR LIMIT=NONE] -->
+ <string name="security_settings_udfps_tip_fingerprint_help">Lift, then touch again</string>
+ <!-- Accessibility message for fingerprint enrollment asking the user to place the sides of their finger on the fingerprint sensor [CHAR LIMIT=NONE] -->
+ <string name="security_settings_udfps_side_fingerprint_help">Place the side of your fingerprint on the sensor and hold, then switch to the other side</string>
<!-- Title of the dialog shown when the user tries to skip fingerprint setup, asking them to confirm the action [CHAR LIMIT=40] -->
<string name="setup_fingerprint_enroll_enrolling_skip_title">Skip fingerprint setup?</string>
<!-- Content of the dialog shown when the user tries to skip fingerprint setup, asking them to confirm the action [CHAR LIMIT=NONE] -->
diff --git a/src/com/android/settings/biometrics/BiometricUtils.java b/src/com/android/settings/biometrics/BiometricUtils.java
index 5ee7880..febe3c6 100644
--- a/src/com/android/settings/biometrics/BiometricUtils.java
+++ b/src/com/android/settings/biometrics/BiometricUtils.java
@@ -289,4 +289,14 @@
}
return false;
}
+
+ /**
+ * Returns {@code true} if the screen is going into a landscape mode and the angle is equal to
+ * 90.
+ * @param context Context that we use to get the display this context is associated with
+ * @return True if the angle of the rotation is equal to 90.
+ */
+ public static boolean isLandscape(@NonNull Context context) {
+ return context.getDisplay().getRotation() == Surface.ROTATION_90;
+ }
}
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java
index c2bcee3..84519f8 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java
@@ -19,11 +19,13 @@
import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.annotation.IntDef;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Dialog;
import android.app.settings.SettingsEnums;
import android.content.DialogInterface;
import android.content.Intent;
+import android.content.res.Configuration;
import android.graphics.drawable.Animatable2;
import android.graphics.drawable.AnimatedVectorDrawable;
import android.graphics.drawable.Drawable;
@@ -54,7 +56,9 @@
import com.android.settings.biometrics.BiometricUtils;
import com.android.settings.biometrics.BiometricsEnrollEnrolling;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+import com.android.settingslib.display.DisplayDensityUtils;
+import com.airbnb.lottie.LottieAnimationView;
import com.google.android.setupcompat.template.FooterBarMixin;
import com.google.android.setupcompat.template.FooterButton;
import com.google.android.setupcompat.util.WizardManagerHelper;
@@ -126,10 +130,16 @@
private boolean mIsSetupWizard;
private AccessibilityManager mAccessibilityManager;
private boolean mIsAccessibilityEnabled;
+ private LottieAnimationView mIllustrationLottie;
+ private boolean mHaveShownUdfpsTipLottie;
+ private boolean mHaveShownUdfpsSideLottie;
+ private boolean mShouldShowLottie;
private OrientationEventListener mOrientationEventListener;
private int mPreviousRotation = 0;
+ private boolean mShowingNewUdfpsEnroll = false;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -163,6 +173,25 @@
setHeaderText(R.string.security_settings_fingerprint_enroll_repeat_title);
}
+ DisplayDensityUtils displayDensity =
+ new DisplayDensityUtils(getApplicationContext());
+ int currentDensityIndex = displayDensity.getCurrentIndex();
+ final int currentDensity = displayDensity.getValues()[currentDensityIndex];
+ final int defaultDensity = displayDensity.getDefaultDensity();
+ mShouldShowLottie = defaultDensity == currentDensity;
+
+ mShowingNewUdfpsEnroll = getApplicationContext().getResources().getBoolean(
+ com.android.internal.R.bool.config_udfpsSupportsNewUi);
+ // Only show the lottie if the current display density is the default density.
+ // Otherwise, the lottie will overlap with the settings header text.
+ boolean isLandscape = BiometricUtils.isReverseLandscape(getApplicationContext())
+ || BiometricUtils.isLandscape(getApplicationContext());
+
+ if (mShowingNewUdfpsEnroll) {
+ updateOrientation((isLandscape
+ ? Configuration.ORIENTATION_LANDSCAPE : Configuration.ORIENTATION_PORTRAIT));
+ }
+
mErrorText = findViewById(R.id.error_text);
mProgressBar = findViewById(R.id.fingerprint_progress_bar);
mVibrator = getSystemService(Vibrator.class);
@@ -339,20 +368,53 @@
case STAGE_FINGERTIP:
setHeaderText(R.string.security_settings_udfps_enroll_fingertip_title);
- if (isStageHalfCompleted()) {
- setDescriptionText(R.string.security_settings_fingerprint_enroll_repeat_title);
+ if (mShowingNewUdfpsEnroll) {
+ if (!mHaveShownUdfpsTipLottie && mIllustrationLottie != null) {
+ mHaveShownUdfpsTipLottie = true;
+ setDescriptionText("");
+ mIllustrationLottie.setAnimation(R.raw.udfps_tip_hint_lottie);
+ mIllustrationLottie.setVisibility(View.VISIBLE);
+ mIllustrationLottie.playAnimation();
+ mIllustrationLottie.setContentDescription(
+ getString(R.string.security_settings_udfps_tip_fingerprint_help));
+ }
} else {
- setDescriptionText("");
+ if (isStageHalfCompleted()) {
+ setDescriptionText(
+ R.string.security_settings_fingerprint_enroll_repeat_title);
+ } else {
+ setDescriptionText("");
+ }
}
break;
case STAGE_EDGES:
setHeaderText(R.string.security_settings_udfps_enroll_edge_title);
- if (isStageHalfCompleted()) {
- setDescriptionText(
- R.string.security_settings_fingerprint_enroll_repeat_message);
+ if (mShowingNewUdfpsEnroll) {
+ if (!mHaveShownUdfpsSideLottie && mIllustrationLottie != null) {
+ mHaveShownUdfpsSideLottie = true;
+ setDescriptionText("");
+ mIllustrationLottie.setAnimation(R.raw.udfps_edge_hint_lottie);
+ mIllustrationLottie.setVisibility(View.VISIBLE);
+ mIllustrationLottie.playAnimation();
+ mIllustrationLottie.setContentDescription(
+ getString(R.string.security_settings_udfps_side_fingerprint_help));
+ } else if (mIllustrationLottie == null) {
+ if (isStageHalfCompleted()) {
+ setDescriptionText(
+ R.string.security_settings_fingerprint_enroll_repeat_message);
+ } else {
+ setDescriptionText(
+ R.string.security_settings_udfps_enroll_edge_message);
+ }
+ }
} else {
- setDescriptionText(R.string.security_settings_udfps_enroll_edge_message);
+ if (isStageHalfCompleted()) {
+ setDescriptionText(
+ R.string.security_settings_fingerprint_enroll_repeat_message);
+ } else {
+ setDescriptionText(R.string.security_settings_udfps_enroll_edge_message);
+ }
}
break;
@@ -634,6 +696,45 @@
return SettingsEnums.FINGERPRINT_ENROLLING;
}
+ private void updateOrientation(int orientation) {
+ switch(orientation) {
+ case Configuration.ORIENTATION_LANDSCAPE: {
+ mIllustrationLottie = null;
+ break;
+ }
+ case Configuration.ORIENTATION_PORTRAIT: {
+ if (mShouldShowLottie) {
+ mIllustrationLottie = findViewById(R.id.illustration_lottie);
+ }
+ break;
+ }
+ default:
+ Log.e(TAG, "Error unhandled configuration change");
+ break;
+ }
+ }
+
+ @Override
+ public void onConfigurationChanged(@NonNull Configuration newConfig) {
+ if (!mShowingNewUdfpsEnroll) {
+ return;
+ }
+
+ switch(newConfig.orientation) {
+ case Configuration.ORIENTATION_LANDSCAPE: {
+ updateOrientation(Configuration.ORIENTATION_LANDSCAPE);
+ break;
+ }
+ case Configuration.ORIENTATION_PORTRAIT: {
+ updateOrientation(Configuration.ORIENTATION_PORTRAIT);
+ break;
+ }
+ default:
+ Log.e(TAG, "Error unhandled configuration change");
+ break;
+ }
+ }
+
public static class IconTouchDialog extends InstrumentedDialogFragment {
@Override