Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7981c1a5 authored by Kevin Chyn's avatar Kevin Chyn Committed by Android (Google) Code Review
Browse files

Merge changes I50af022a,I82b77ec1 into qt-dev

* changes:
  Do not vibrate if last acquire message was NOT_DETECTED
  Persist dialog state across configuration change
parents 0a751bba 0ce70856
Loading
Loading
Loading
Loading
+276 −0
Original line number Diff line number Diff line
<!--
  ~ Copyright (C) 2019 The Android Open Source Project
  ~
  ~ Licensed under the Apache License, Version 2.0 (the "License");
  ~ you may not use this file except in compliance with the License.
  ~ You may obtain a copy of the License at
  ~
  ~      http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing, software
  ~ distributed under the License is distributed on an "AS IS" BASIS,
  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License
  -->

<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:aapt="http://schemas.android.com/aapt">
    <aapt:attr name="android:drawable">
        <vector
            android:width="60dp"
            android:height="60dp"
            android:viewportWidth="60"
            android:viewportHeight="60">
            <group android:name="_R_G">
                <group
                    android:name="_R_G_L_0_G"
                    android:pivotX="30"
                    android:pivotY="30"
                    android:scaleX="1.03"
                    android:scaleY="1.03">
                    <path
                        android:name="_R_G_L_0_G_D_0_P_0"
                        android:pathData=" M30 6.2 C16.9,6.2 6.3,16.8 6.3,30 C6.3,43.2 16.9,53.8 30,53.8 C43.1,53.8 53.8,43.2 53.8,30 C53.8,16.8 43.1,6.2 30,6.2c "
                        android:strokeWidth="2.5"
                        android:strokeAlpha="1.0"
                        android:strokeColor="@color/biometric_dialog_gray"
                        android:trimPathStart="0"
                        android:trimPathEnd="1"
                        android:trimPathOffset="0" />
                    <path
                        android:name="_R_G_L_0_G_D_1_P_0"
                        android:pathData=" M33.75 42.75 C32.75,43.77 31.37,44.39 29.83,44.39 C26.8,44.39 24.34,41.93 24.34,38.9 "
                        android:strokeWidth="2"
                        android:strokeAlpha="1.0"
                        android:strokeColor="@color/biometric_dialog_gray"
                        android:trimPathStart="0"
                        android:trimPathEnd="1"
                        android:trimPathOffset="0" />
                    <path
                        android:name="_R_G_L_0_G_D_2_P_0"
                        android:fillAlpha="1.0"
                        android:fillColor="@color/biometric_dialog_gray"
                        android:fillType="nonZero"
                        android:pathData=" M39 23.8 C39,25 39.9,25.9 41.1,25.9 C42.2,25.9 43.2,25 43.2,23.8 C43.2,22.6 42.3,21.7 41.1,21.7 C39.9,21.7 39,22.6 39,23.8c " />
                    <path
                        android:name="_R_G_L_0_G_D_3_P_0"
                        android:fillAlpha="1.0"
                        android:fillColor="@color/biometric_dialog_gray"
                        android:fillType="nonZero"
                        android:pathData=" M16.5 23.8 C16.5,25 17.4,25.9 18.6,25.9 C19.8,25.9 20.7,25 20.7,23.8 C20.7,22.6 19.8,21.7 18.6,21.7 C17.4,21.7 16.5,22.6 16.5,23.8c " />
                    <path
                        android:name="_R_G_L_0_G_D_4_P_0"
                        android:fillAlpha="1.0"
                        android:fillColor="@color/biometric_dialog_gray"
                        android:fillType="nonZero"
                        android:pathData=" M33.33 34.95 C33.33,34.95 28.13,34.95 28.13,34.95 C28.13,34.95 28.13,32.95 28.13,32.95 C28.13,32.95 31.33,32.95 31.33,32.95 C31.33,32.95 31.33,28.45 31.33,28.45 C31.33,28.45 33.33,28.45 33.33,28.45 C33.33,28.45 33.33,34.95 33.33,34.95c " />
                </group>
            </group>
            <group android:name="time_group" />
        </vector>
    </aapt:attr>
    <target android:name="_R_G_L_0_G_D_0_P_0">
        <aapt:attr name="android:animation">
            <set android:ordering="together">
                <objectAnimator
                    android:duration="500"
                    android:propertyName="strokeAlpha"
                    android:startOffset="0"
                    android:valueFrom="1.0"
                    android:valueTo="1.0"
                    android:valueType="floatType">
                    <aapt:attr name="android:interpolator">
                        <pathInterpolator android:pathData="M 0.0,0.0 c0.118,1.266 0.419,1 1.0,1.0" />
                    </aapt:attr>
                </objectAnimator>
                <objectAnimator
                    android:duration="500"
                    android:propertyName="strokeAlpha"
                    android:startOffset="500"
                    android:valueFrom="1.0"
                    android:valueTo="1.0"
                    android:valueType="floatType">
                    <aapt:attr name="android:interpolator">
                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0" />
                    </aapt:attr>
                </objectAnimator>
            </set>
        </aapt:attr>
    </target>
    <target android:name="_R_G_L_0_G_D_1_P_0">
        <aapt:attr name="android:animation">
            <set android:ordering="together">
                <objectAnimator
                    android:duration="500"
                    android:propertyName="strokeAlpha"
                    android:startOffset="0"
                    android:valueFrom="1.0"
                    android:valueTo="1.0"
                    android:valueType="floatType">
                    <aapt:attr name="android:interpolator">
                        <pathInterpolator android:pathData="M 0.0,0.0 c0.118,1.266 0.419,1 1.0,1.0" />
                    </aapt:attr>
                </objectAnimator>
                <objectAnimator
                    android:duration="500"
                    android:propertyName="strokeAlpha"
                    android:startOffset="500"
                    android:valueFrom="1.0"
                    android:valueTo="1.0"
                    android:valueType="floatType">
                    <aapt:attr name="android:interpolator">
                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0" />
                    </aapt:attr>
                </objectAnimator>
            </set>
        </aapt:attr>
    </target>
    <target android:name="_R_G_L_0_G_D_2_P_0">
        <aapt:attr name="android:animation">
            <set android:ordering="together">
                <objectAnimator
                    android:duration="500"
                    android:propertyName="fillAlpha"
                    android:startOffset="0"
                    android:valueFrom="1.0"
                    android:valueTo="1.0"
                    android:valueType="floatType">
                    <aapt:attr name="android:interpolator">
                        <pathInterpolator android:pathData="M 0.0,0.0 c0.118,1.266 0.419,1 1.0,1.0" />
                    </aapt:attr>
                </objectAnimator>
                <objectAnimator
                    android:duration="500"
                    android:propertyName="fillAlpha"
                    android:startOffset="500"
                    android:valueFrom="1.0"
                    android:valueTo="1.0"
                    android:valueType="floatType">
                    <aapt:attr name="android:interpolator">
                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0" />
                    </aapt:attr>
                </objectAnimator>
            </set>
        </aapt:attr>
    </target>
    <target android:name="_R_G_L_0_G_D_3_P_0">
        <aapt:attr name="android:animation">
            <set android:ordering="together">
                <objectAnimator
                    android:duration="500"
                    android:propertyName="fillAlpha"
                    android:startOffset="0"
                    android:valueFrom="1.0"
                    android:valueTo="1.0"
                    android:valueType="floatType">
                    <aapt:attr name="android:interpolator">
                        <pathInterpolator android:pathData="M 0.0,0.0 c0.118,1.266 0.419,1 1.0,1.0" />
                    </aapt:attr>
                </objectAnimator>
                <objectAnimator
                    android:duration="500"
                    android:propertyName="fillAlpha"
                    android:startOffset="500"
                    android:valueFrom="1.0"
                    android:valueTo="1.0"
                    android:valueType="floatType">
                    <aapt:attr name="android:interpolator">
                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0" />
                    </aapt:attr>
                </objectAnimator>
            </set>
        </aapt:attr>
    </target>
    <target android:name="_R_G_L_0_G_D_4_P_0">
        <aapt:attr name="android:animation">
            <set android:ordering="together">
                <objectAnimator
                    android:duration="500"
                    android:propertyName="fillAlpha"
                    android:startOffset="0"
                    android:valueFrom="1.0"
                    android:valueTo="1.0"
                    android:valueType="floatType">
                    <aapt:attr name="android:interpolator">
                        <pathInterpolator android:pathData="M 0.0,0.0 c0.118,1.266 0.419,1 1.0,1.0" />
                    </aapt:attr>
                </objectAnimator>
                <objectAnimator
                    android:duration="500"
                    android:propertyName="fillAlpha"
                    android:startOffset="500"
                    android:valueFrom="1.0"
                    android:valueTo="1.0"
                    android:valueType="floatType">
                    <aapt:attr name="android:interpolator">
                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0" />
                    </aapt:attr>
                </objectAnimator>
            </set>
        </aapt:attr>
    </target>
    <target android:name="_R_G_L_0_G">
        <aapt:attr name="android:animation">
            <set android:ordering="together">
                <objectAnimator
                    android:duration="500"
                    android:propertyName="scaleX"
                    android:startOffset="0"
                    android:valueFrom="1.03"
                    android:valueTo="1"
                    android:valueType="floatType">
                    <aapt:attr name="android:interpolator">
                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
                    </aapt:attr>
                </objectAnimator>
                <objectAnimator
                    android:duration="500"
                    android:propertyName="scaleY"
                    android:startOffset="0"
                    android:valueFrom="1.03"
                    android:valueTo="1"
                    android:valueType="floatType">
                    <aapt:attr name="android:interpolator">
                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
                    </aapt:attr>
                </objectAnimator>
                <objectAnimator
                    android:duration="500"
                    android:propertyName="scaleX"
                    android:startOffset="500"
                    android:valueFrom="1"
                    android:valueTo="1.03"
                    android:valueType="floatType">
                    <aapt:attr name="android:interpolator">
                        <pathInterpolator android:pathData="M 0.0,0.0 c0.204,0.46 0.568,1 1.0,1.0" />
                    </aapt:attr>
                </objectAnimator>
                <objectAnimator
                    android:duration="500"
                    android:propertyName="scaleY"
                    android:startOffset="500"
                    android:valueFrom="1"
                    android:valueTo="1.03"
                    android:valueType="floatType">
                    <aapt:attr name="android:interpolator">
                        <pathInterpolator android:pathData="M 0.0,0.0 c0.204,0.46 0.568,1 1.0,1.0" />
                    </aapt:attr>
                </objectAnimator>
            </set>
        </aapt:attr>
    </target>
    <target android:name="time_group">
        <aapt:attr name="android:animation">
            <set android:ordering="together">
                <objectAnimator
                    android:duration="1017"
                    android:propertyName="translateX"
                    android:startOffset="0"
                    android:valueFrom="0"
                    android:valueTo="1"
                    android:valueType="floatType" />
            </set>
        </aapt:attr>
    </target>
</animated-vector>
 No newline at end of file
+41 −16
Original line number Diff line number Diff line
@@ -56,11 +56,16 @@ public abstract class BiometricDialogView extends LinearLayout {

    private static final String KEY_TRY_AGAIN_VISIBILITY = "key_try_again_visibility";
    private static final String KEY_CONFIRM_VISIBILITY = "key_confirm_visibility";
    private static final String KEY_STATE = "key_state";
    private static final String KEY_ERROR_TEXT_VISIBILITY = "key_error_text_visibility";
    private static final String KEY_ERROR_TEXT_STRING = "key_error_text_string";
    private static final String KEY_ERROR_TEXT_IS_TEMPORARY = "key_error_text_is_temporary";
    private static final String KEY_ERROR_TEXT_COLOR = "key_error_text_color";

    private static final int ANIMATION_DURATION_SHOW = 250; // ms
    private static final int ANIMATION_DURATION_AWAY = 350; // ms

    protected static final int MSG_CLEAR_MESSAGE = 1;
    protected static final int MSG_RESET_MESSAGE = 1;

    protected static final int STATE_IDLE = 0;
    protected static final int STATE_AUTHENTICATING = 1;
@@ -94,7 +99,7 @@ public abstract class BiometricDialogView extends LinearLayout {
    private Bundle mBundle;
    private Bundle mRestoredState;

    private int mState;
    private int mState = STATE_IDLE;
    private boolean mAnimatingAway;
    private boolean mWasForceRemoved;
    private boolean mSkipIntro;
@@ -106,7 +111,7 @@ public abstract class BiometricDialogView extends LinearLayout {
    protected abstract int getIconDescriptionResourceId();
    protected abstract int getDelayAfterAuthenticatedDurationMs();
    protected abstract boolean shouldGrayAreaDismissDialog();
    protected abstract void handleClearMessage();
    protected abstract void handleResetMessage();
    protected abstract void updateIcon(int oldState, int newState);

    private final Runnable mShowAnimationRunnable = new Runnable() {
@@ -132,8 +137,8 @@ public abstract class BiometricDialogView extends LinearLayout {
        @Override
        public void handleMessage(Message msg) {
            switch(msg.what) {
                case MSG_CLEAR_MESSAGE:
                    handleClearMessage();
                case MSG_RESET_MESSAGE:
                    handleResetMessage();
                    break;
                default:
                    Log.e(TAG, "Unhandled message: " + msg.what);
@@ -231,14 +236,17 @@ public abstract class BiometricDialogView extends LinearLayout {
    public void onSaveState(Bundle bundle) {
        bundle.putInt(KEY_TRY_AGAIN_VISIBILITY, mTryAgainButton.getVisibility());
        bundle.putInt(KEY_CONFIRM_VISIBILITY, mPositiveButton.getVisibility());
        bundle.putInt(KEY_STATE, mState);
        bundle.putInt(KEY_ERROR_TEXT_VISIBILITY, mErrorText.getVisibility());
        bundle.putCharSequence(KEY_ERROR_TEXT_STRING, mErrorText.getText());
        bundle.putBoolean(KEY_ERROR_TEXT_IS_TEMPORARY, mHandler.hasMessages(MSG_RESET_MESSAGE));
        bundle.putInt(KEY_ERROR_TEXT_COLOR, mErrorText.getCurrentTextColor());
    }

    @Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();

        mErrorText.setText(getHintStringResourceId());

        final ImageView backgroundView = mLayout.findViewById(R.id.background);

        if (mUserManager.isManagedProfile(mUserId)) {
@@ -253,14 +261,18 @@ public abstract class BiometricDialogView extends LinearLayout {
        }

        mNegativeButton.setVisibility(View.VISIBLE);
        mErrorText.setVisibility(View.VISIBLE);

        if (RotationUtils.getRotation(mContext) != RotationUtils.ROTATION_NONE) {
            mDialog.getLayoutParams().width = (int) mDialogWidth;
        }

        mState = STATE_IDLE;
        if (mRestoredState == null) {
            updateState(STATE_AUTHENTICATING);
            mErrorText.setText(getHintStringResourceId());
            mErrorText.setVisibility(View.VISIBLE);
        } else {
            updateState(mState);
        }

        CharSequence titleText = mBundle.getCharSequence(BiometricPrompt.KEY_TITLE);

@@ -329,7 +341,7 @@ public abstract class BiometricDialogView extends LinearLayout {
                mWindowManager.removeView(BiometricDialogView.this);
                mAnimatingAway = false;
                // Set the icons / text back to normal state
                handleClearMessage();
                handleResetMessage();
                showTryAgainButton(false /* show */);
                updateState(STATE_IDLE);
            }
@@ -401,17 +413,17 @@ public abstract class BiometricDialogView extends LinearLayout {

    // Shows an error/help message
    protected void showTemporaryMessage(String message) {
        mHandler.removeMessages(MSG_CLEAR_MESSAGE);
        mHandler.removeMessages(MSG_RESET_MESSAGE);
        mErrorText.setText(message);
        mErrorText.setTextColor(mErrorColor);
        mErrorText.setContentDescription(message);
        mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_CLEAR_MESSAGE),
        mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_RESET_MESSAGE),
                BiometricPrompt.HIDE_DIALOG_DELAY);
    }

    public void clearTemporaryMessage() {
        mHandler.removeMessages(MSG_CLEAR_MESSAGE);
        mHandler.obtainMessage(MSG_CLEAR_MESSAGE).sendToTarget();
        mHandler.removeMessages(MSG_RESET_MESSAGE);
        mHandler.obtainMessage(MSG_RESET_MESSAGE).sendToTarget();
    }

    /**
@@ -442,7 +454,7 @@ public abstract class BiometricDialogView extends LinearLayout {

    public void updateState(int newState) {
        if (newState == STATE_PENDING_CONFIRMATION) {
            mHandler.removeMessages(MSG_CLEAR_MESSAGE);
            mHandler.removeMessages(MSG_RESET_MESSAGE);
            mErrorText.setVisibility(View.INVISIBLE);
            mPositiveButton.setVisibility(View.VISIBLE);
            mPositiveButton.setEnabled(true);
@@ -470,6 +482,19 @@ public abstract class BiometricDialogView extends LinearLayout {
        mRestoredState = bundle;
        mTryAgainButton.setVisibility(bundle.getInt(KEY_TRY_AGAIN_VISIBILITY));
        mPositiveButton.setVisibility(bundle.getInt(KEY_CONFIRM_VISIBILITY));
        mState = bundle.getInt(KEY_STATE);
        mErrorText.setText(bundle.getCharSequence(KEY_ERROR_TEXT_STRING));
        mErrorText.setVisibility(bundle.getInt(KEY_ERROR_TEXT_VISIBILITY));
        mErrorText.setTextColor(bundle.getInt(KEY_ERROR_TEXT_COLOR));

        if (bundle.getBoolean(KEY_ERROR_TEXT_IS_TEMPORARY)) {
            mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_RESET_MESSAGE),
                    BiometricPrompt.HIDE_DIALOG_DELAY);
        }
    }

    protected int getState() {
        return mState;
    }

    public WindowManager.LayoutParams getLayoutParams() {
+39 −12
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ public class FaceDialogView extends BiometricDialogView {

    private static final String TAG = "FaceDialogView";
    private static final String KEY_DIALOG_SIZE = "key_dialog_size";
    private static final String KEY_DIALOG_ANIMATED_IN = "key_dialog_animated_in";

    private static final int HIDE_DIALOG_DELAY = 500; // ms
    private static final int IMPLICIT_Y_PADDING = 16; // dp
@@ -78,6 +79,10 @@ public class FaceDialogView extends BiometricDialogView {
            animateIcon(iconRes, false);
        }

        public void showStatic(int iconRes) {
            mBiometricIcon.setImageDrawable(mContext.getDrawable(iconRes));
        }

        public void startPulsing() {
            mLastPulseDirection = false;
            animateIcon(R.drawable.face_dialog_pulse_dark_to_light, true);
@@ -276,13 +281,19 @@ public class FaceDialogView extends BiometricDialogView {
    public void onSaveState(Bundle bundle) {
        super.onSaveState(bundle);
        bundle.putInt(KEY_DIALOG_SIZE, mSize);
        bundle.putBoolean(KEY_DIALOG_ANIMATED_IN, mDialogAnimatedIn);
    }


    @Override
    protected void handleClearMessage() {
    protected void handleResetMessage() {
        mErrorText.setText(getHintStringResourceId());
        mErrorText.setTextColor(mTextColor);
        if (getState() == STATE_AUTHENTICATING) {
            mErrorText.setVisibility(View.VISIBLE);
        } else {
            mErrorText.setVisibility(View.INVISIBLE);
        }
    }

    @Override
@@ -290,6 +301,7 @@ public class FaceDialogView extends BiometricDialogView {
        super.restoreState(bundle);
        // Keep in mind that this happens before onAttachedToWindow()
        mSize = bundle.getInt(KEY_DIALOG_SIZE);
        mDialogAnimatedIn = bundle.getBoolean(KEY_DIALOG_ANIMATED_IN);
    }

    /**
@@ -386,7 +398,8 @@ public class FaceDialogView extends BiometricDialogView {
    protected void updateIcon(int oldState, int newState) {
        mIconController.mState = newState;

        if (oldState == STATE_IDLE && newState == STATE_AUTHENTICATING) {
        if (newState == STATE_AUTHENTICATING) {
            mHandler.removeCallbacks(mErrorToIdleAnimationRunnable);
            if (mDialogAnimatedIn) {
                mIconController.startPulsing();
                mErrorText.setVisibility(View.VISIBLE);
@@ -397,25 +410,39 @@ public class FaceDialogView extends BiometricDialogView {
            mIconController.animateOnce(R.drawable.face_dialog_dark_to_checkmark);
        } else if (oldState == STATE_ERROR && newState == STATE_IDLE) {
            mIconController.animateOnce(R.drawable.face_dialog_error_to_idle);
        } else if (oldState == STATE_ERROR && newState == STATE_AUTHENTICATING) {
            mHandler.removeCallbacks(mErrorToIdleAnimationRunnable);
            mIconController.startPulsing();
        } else if (oldState == STATE_ERROR && newState == STATE_PENDING_CONFIRMATION) {
            mHandler.removeCallbacks(mErrorToIdleAnimationRunnable);
            mIconController.animateOnce(R.drawable.face_dialog_wink_from_dark);
        } else if (oldState == STATE_ERROR && newState == STATE_AUTHENTICATED) {
            mHandler.removeCallbacks(mErrorToIdleAnimationRunnable);
            mIconController.animateOnce(R.drawable.face_dialog_dark_to_checkmark);
        } else if (oldState == STATE_AUTHENTICATING && newState == STATE_ERROR) {
        } else if (newState == STATE_ERROR) {
            // It's easier to only check newState and gate showing the animation on the
            // mErrorToIdleAnimationRunnable as a proxy, than add a ton of extra state. For example,
            // we may go from error -> error due to configuration change which is valid and we
            // should show the animation, or we can go from error -> error by receiving repeated
            // acquire messages in which case we do not want to repeatedly start the animation.
            if (!mHandler.hasCallbacks(mErrorToIdleAnimationRunnable)) {
                mIconController.animateOnce(R.drawable.face_dialog_dark_to_error);
            mHandler.postDelayed(mErrorToIdleAnimationRunnable, BiometricPrompt.HIDE_DIALOG_DELAY);
                mHandler.postDelayed(mErrorToIdleAnimationRunnable,
                        BiometricPrompt.HIDE_DIALOG_DELAY);
            }
        } else if (oldState == STATE_AUTHENTICATING && newState == STATE_AUTHENTICATED) {
            mIconController.animateOnce(R.drawable.face_dialog_dark_to_checkmark);
        } else if (oldState == STATE_AUTHENTICATING && newState == STATE_PENDING_CONFIRMATION) {
        } else if (newState == STATE_PENDING_CONFIRMATION) {
            mHandler.removeCallbacks(mErrorToIdleAnimationRunnable);
            mIconController.animateOnce(R.drawable.face_dialog_wink_from_dark);
        } else if (newState == STATE_IDLE) {
            mIconController.showStatic(R.drawable.face_dialog_idle_static);
        } else {
            Log.w(TAG, "Unknown animation from " + oldState + " -> " + newState);
        }

        // Note that this must be after the newState == STATE_ERROR check above since this affects
        // the logic.
        if (oldState == STATE_ERROR && newState == STATE_ERROR) {
            // Keep the error icon and text around for a while longer if we keep receiving
            // STATE_ERROR
            mHandler.removeCallbacks(mErrorToIdleAnimationRunnable);
            mHandler.postDelayed(mErrorToIdleAnimationRunnable, BiometricPrompt.HIDE_DIALOG_DELAY);
        }
    }

    @Override
+8 −8

File changed.

Preview size limit exceeded, changes collapsed.

+6 −0
Original line number Diff line number Diff line
@@ -63,6 +63,8 @@ public abstract class AuthenticationClient extends ClientMonitor {
     */
    public abstract boolean shouldFrameworkHandleLockout();

    public abstract boolean wasUserDetected();

    public AuthenticationClient(Context context, Constants constants,
            BiometricServiceBase.DaemonWrapper daemon, long halDeviceId, IBinder token,
            BiometricServiceBase.ServiceListener listener, int targetUserId, int groupId, long opId,
@@ -105,6 +107,10 @@ public abstract class AuthenticationClient extends ClientMonitor {
        if (!shouldFrameworkHandleLockout()) {
            switch (error) {
                case BiometricConstants.BIOMETRIC_ERROR_TIMEOUT:
                    if (!wasUserDetected() && !isBiometricPrompt()) {
                        // No vibration if user was not detected on keyguard
                        break;
                    }
                case BiometricConstants.BIOMETRIC_ERROR_LOCKOUT:
                case BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT:
                    if (mStarted) {
Loading