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

Commit a03bdc4e authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Show UDFPS icon on AOD even if fp auth isn't running" into sc-v2-dev...

Merge "Show UDFPS icon on AOD even if fp auth isn't running" into sc-v2-dev am: f1851c9a am: 3e0bee34

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15853609

Change-Id: Iebc35b4bd629705b9f77f1cb3b7b576ded484171
parents 93e3b482 3e0bee34
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -74,6 +74,19 @@
            android:padding="@dimen/lock_icon_padding"
            android:layout_gravity="center"
            android:scaleType="centerCrop"/>

        <!-- Fingerprint -->
        <!-- AOD dashed fingerprint icon with moving dashes -->
        <com.airbnb.lottie.LottieAnimationView
            android:id="@+id/lock_udfps_aod_fp"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:padding="@dimen/lock_icon_padding"
            android:layout_gravity="center"
            android:scaleType="centerCrop"
            systemui:lottie_autoPlay="false"
            systemui:lottie_loop="true"
            systemui:lottie_rawRes="@raw/udfps_aod_fp"/>
    </com.android.keyguard.LockIconView>

    <com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer
+11 −6
Original line number Diff line number Diff line
@@ -45,7 +45,7 @@ public class LockIconView extends FrameLayout implements Dumpable {
    private int mRadius;

    private ImageView mLockIcon;
    private ImageView mUnlockBgView;
    private ImageView mBgView;

    private int mLockIconColor;

@@ -58,19 +58,19 @@ public class LockIconView extends FrameLayout implements Dumpable {
    public void onFinishInflate() {
        super.onFinishInflate();
        mLockIcon = findViewById(R.id.lock_icon);
        mUnlockBgView = findViewById(R.id.lock_icon_bg);
        mBgView = findViewById(R.id.lock_icon_bg);
    }

    void updateColorAndBackgroundVisibility(boolean useBackground) {
        if (useBackground) {
        if (useBackground && mLockIcon.getDrawable() != null) {
            mLockIconColor = Utils.getColorAttrDefaultColor(getContext(),
                    android.R.attr.textColorPrimary);
            mUnlockBgView.setBackground(getContext().getDrawable(R.drawable.fingerprint_bg));
            mUnlockBgView.setVisibility(View.VISIBLE);
            mBgView.setBackground(getContext().getDrawable(R.drawable.fingerprint_bg));
            mBgView.setVisibility(View.VISIBLE);
        } else {
            mLockIconColor = Utils.getColorAttrDefaultColor(getContext(),
                    R.attr.wallpaperTextColorAccent);
            mUnlockBgView.setVisibility(View.GONE);
            mBgView.setVisibility(View.GONE);
        }

        mLockIcon.setImageTintList(ColorStateList.valueOf(mLockIconColor));
@@ -78,6 +78,11 @@ public class LockIconView extends FrameLayout implements Dumpable {

    void setImageDrawable(Drawable drawable) {
        mLockIcon.setImageDrawable(drawable);
        if (drawable == null) {
            mBgView.setVisibility(View.INVISIBLE);
        } else {
            mBgView.setVisibility(View.VISIBLE);
        }
    }

    /**
+95 −11
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@ package com.android.keyguard;
import static android.hardware.biometrics.BiometricSourceType.FINGERPRINT;

import static com.android.systemui.classifier.Classifier.LOCK_ICON;
import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset;
import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInProgressOffset;

import android.content.Context;
import android.content.res.Configuration;
@@ -33,6 +35,7 @@ import android.media.AudioAttributes;
import android.os.Process;
import android.os.Vibrator;
import android.util.DisplayMetrics;
import android.util.MathUtils;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
@@ -60,6 +63,8 @@ import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.ViewController;
import com.android.systemui.util.concurrency.DelayableExecutor;

import com.airbnb.lottie.LottieAnimationView;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Objects;
@@ -95,6 +100,8 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
    @NonNull private final DelayableExecutor mExecutor;
    private boolean mUdfpsEnrolled;

    @NonNull private LottieAnimationView mAodFp;

    @NonNull private final AnimatedVectorDrawable mFpToUnlockIcon;
    @NonNull private final AnimatedVectorDrawable mLockToUnlockIcon;
    @NonNull private final Drawable mLockIcon;
@@ -113,6 +120,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
    private boolean mIsKeyguardShowing;
    private boolean mUserUnlockedWithBiometric;
    private Runnable mCancelDelayedUpdateVisibilityRunnable;
    private Runnable mOnGestureDetectedRunnable;

    private boolean mUdfpsSupported;
    private float mHeightPixels;
@@ -122,6 +130,12 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
    private boolean mShowUnlockIcon;
    private boolean mShowLockIcon;

    // for udfps when strong auth is required or unlocked on AOD
    private boolean mShowAODFpIcon;
    private final int mMaxBurnInOffsetX;
    private final int mMaxBurnInOffsetY;
    private float mInterpolatedDarkAmount;

    private boolean mDownDetected;
    private boolean mDetectedLongPress;
    private final Rect mSensorTouchLocation = new Rect();
@@ -156,6 +170,12 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
        mAuthRippleController = authRippleController;

        final Context context = view.getContext();
        mAodFp = mView.findViewById(R.id.lock_udfps_aod_fp);
        mMaxBurnInOffsetX = context.getResources()
                .getDimensionPixelSize(R.dimen.udfps_burn_in_offset_x);
        mMaxBurnInOffsetY = context.getResources()
                .getDimensionPixelSize(R.dimen.udfps_burn_in_offset_y);

        mUnlockIcon = mView.getContext().getResources().getDrawable(
            R.drawable.ic_unlock,
            mView.getContext().getTheme());
@@ -174,19 +194,19 @@ public class LockIconViewController extends ViewController<LockIconView> impleme

    @Override
    protected void onInit() {
        mAuthController.addCallback(mAuthControllerCallback);
        mUdfpsSupported = mAuthController.getUdfpsSensorLocation() != null;

        mView.setAccessibilityDelegate(mAccessibilityDelegate);
    }

    @Override
    protected void onViewAttached() {
        updateIsUdfpsEnrolled();
        updateConfiguration();
        updateKeyguardShowing();
        mUserUnlockedWithBiometric = false;

        mIsBouncerShowing = mKeyguardViewController.isBouncerShowing();
        mIsDozing = mStatusBarStateController.isDozing();
        mInterpolatedDarkAmount = mStatusBarStateController.getDozeAmount();
        mRunningFPS = mKeyguardUpdateMonitor.isFingerprintDetectionRunning();
        mCanDismissLockScreen = mKeyguardStateController.canDismissLockScreen();
        mStatusBarState = mStatusBarStateController.getState();
@@ -194,15 +214,18 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
        updateColors();
        mConfigurationController.addCallback(mConfigurationListener);

        mAuthController.addCallback(mAuthControllerCallback);
        mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateMonitorCallback);
        mStatusBarStateController.addCallback(mStatusBarStateListener);
        mKeyguardStateController.addCallback(mKeyguardStateCallback);
        mDownDetected = false;
        updateBurnInOffsets();
        updateVisibility();
    }

    @Override
    protected void onViewDetached() {
        mAuthController.removeCallback(mAuthControllerCallback);
        mConfigurationController.removeCallback(mConfigurationListener);
        mKeyguardUpdateMonitor.removeCallback(mKeyguardUpdateMonitorCallback);
        mStatusBarStateController.removeCallback(mStatusBarStateListener);
@@ -232,7 +255,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
            mCancelDelayedUpdateVisibilityRunnable = null;
        }

        if (!mIsKeyguardShowing) {
        if (!mIsKeyguardShowing && !mIsDozing) {
            mView.setVisibility(View.INVISIBLE);
            return;
        }
@@ -243,6 +266,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
        mShowLockIcon = !mCanDismissLockScreen && !mUserUnlockedWithBiometric && isLockScreen()
            && (!mUdfpsEnrolled || !mRunningFPS);
        mShowUnlockIcon = mCanDismissLockScreen && isLockScreen();
        mShowAODFpIcon = mIsDozing && mUdfpsEnrolled && !mRunningFPS;

        final CharSequence prevContentDescription = mView.getContentDescription();
        if (mShowLockIcon) {
@@ -265,10 +289,22 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
            }
            mView.setVisibility(View.VISIBLE);
            mView.setContentDescription(mUnlockedLabel);
        } else if (mShowAODFpIcon) {
            mView.setImageDrawable(null);
            mView.setContentDescription(null);
            mAodFp.setVisibility(View.VISIBLE);
            mAodFp.setContentDescription(mCanDismissLockScreen ? mUnlockedLabel : mLockedLabel);
            mView.setVisibility(View.VISIBLE);
        } else {
            mView.setVisibility(View.INVISIBLE);
            mView.setContentDescription(null);
        }

        if (!mShowAODFpIcon) {
            mAodFp.setVisibility(View.INVISIBLE);
            mAodFp.setContentDescription(null);
        }

        if (!Objects.equals(prevContentDescription, mView.getContentDescription())
                && mView.getContentDescription() != null) {
            mView.announceForAccessibility(mView.getContentDescription());
@@ -346,10 +382,12 @@ public class LockIconViewController extends ViewController<LockIconView> impleme

    @Override
    public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) {
        pw.println("mUdfpsSupported: " + mUdfpsSupported);
        pw.println("mUdfpsEnrolled: " + mUdfpsEnrolled);
        pw.println("mIsKeyguardShowing: " + mIsKeyguardShowing);
        pw.println(" mShowUnlockIcon: " + mShowUnlockIcon);
        pw.println(" mShowLockIcon: " + mShowLockIcon);
        pw.println(" mShowAODFpIcon: " + mShowAODFpIcon);
        pw.println("  mIsDozing: " + mIsDozing);
        pw.println("  mIsBouncerShowing: " + mIsBouncerShowing);
        pw.println("  mUserUnlockedWithBiometric: " + mUserUnlockedWithBiometric);
@@ -357,17 +395,57 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
        pw.println("  mCanDismissLockScreen: " + mCanDismissLockScreen);
        pw.println("  mStatusBarState: " + StatusBarState.toShortString(mStatusBarState));
        pw.println("  mQsExpanded: " + mQsExpanded);
        pw.println("  mInterpolatedDarkAmount: " + mInterpolatedDarkAmount);

        if (mView != null) {
            mView.dump(fd, pw, args);
        }
    }

    /** Every minute, update the aod icon's burn in offset */
    public void dozeTimeTick() {
        updateBurnInOffsets();
    }

    private void updateBurnInOffsets() {
        float offsetX = MathUtils.lerp(0f,
                getBurnInOffset(mMaxBurnInOffsetX * 2, true /* xAxis */)
                        - mMaxBurnInOffsetX, mInterpolatedDarkAmount);
        float offsetY = MathUtils.lerp(0f,
                getBurnInOffset(mMaxBurnInOffsetY * 2, false /* xAxis */)
                        - mMaxBurnInOffsetY, mInterpolatedDarkAmount);
        float progress = MathUtils.lerp(0f, getBurnInProgressOffset(), mInterpolatedDarkAmount);

        mAodFp.setTranslationX(offsetX);
        mAodFp.setTranslationY(offsetY);
        mAodFp.setProgress(progress);
        mAodFp.setAlpha(255 * mInterpolatedDarkAmount);
    }

    private void updateIsUdfpsEnrolled() {
        boolean wasUdfpsSupported = mUdfpsSupported;
        boolean wasUdfpsEnrolled = mUdfpsEnrolled;

        mUdfpsSupported = mAuthController.getUdfpsSensorLocation() != null;
        mUdfpsEnrolled = mKeyguardUpdateMonitor.isUdfpsEnrolled();
        if (wasUdfpsSupported != mUdfpsSupported || wasUdfpsEnrolled != mUdfpsEnrolled) {
            updateVisibility();
        }
    }

    private StatusBarStateController.StateListener mStatusBarStateListener =
            new StatusBarStateController.StateListener() {
                @Override
                public void onDozeAmountChanged(float linear, float eased) {
                    mInterpolatedDarkAmount = eased;
                    updateBurnInOffsets();
                }

                @Override
                public void onDozingChanged(boolean isDozing) {
                    mIsDozing = isDozing;
                    updateBurnInOffsets();
                    updateIsUdfpsEnrolled();
                    updateVisibility();
                }

@@ -441,7 +519,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
                    mKeyguardUpdateMonitor.getUserUnlockedWithBiometric(
                        KeyguardUpdateMonitor.getCurrentUser());
            }
            mUdfpsEnrolled = mKeyguardUpdateMonitor.isUdfpsEnrolled();
            updateIsUdfpsEnrolled();
            updateVisibility();
        }

@@ -487,8 +565,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme

                    // intercept all following touches until we see MotionEvent.ACTION_CANCEL UP or
                    // MotionEvent.ACTION_UP (see #onTouchEvent)
                    mDownDetected = true;
                    if (mVibrator != null) {
                    if (mVibrator != null && !mDownDetected) {
                        mVibrator.vibrate(
                                Process.myUid(),
                                getContext().getOpPackageName(),
@@ -496,6 +573,8 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
                                "lockIcon-onDown",
                                VIBRATION_SONIFICATION_ATTRIBUTES);
                    }

                    mDownDetected = true;
                    return true;
                }

@@ -553,6 +632,9 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
                        mAuthRippleController.showRipple(FINGERPRINT);
                    }
                    updateVisibility();
                    if (mOnGestureDetectedRunnable != null) {
                        mOnGestureDetectedRunnable.run();
                    }
                    mKeyguardViewController.showBouncer(/* scrim */ true);
                    return true;
                }
@@ -563,16 +645,18 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
     * in a 'clickable' state
     * @return whether to intercept the touch event
     */
    public boolean onTouchEvent(MotionEvent event) {
    public boolean onTouchEvent(MotionEvent event, Runnable onGestureDetectedRunnable) {
        if (mSensorTouchLocation.contains((int) event.getX(), (int) event.getY())
                && mView.getVisibility() == View.VISIBLE) {
                && (mView.getVisibility() == View.VISIBLE
                || mAodFp.getVisibility() == View.VISIBLE)) {
            mOnGestureDetectedRunnable = onGestureDetectedRunnable;
            mGestureDetector.onTouchEvent(event);
        }

        // we continue to intercept all following touches until we see MotionEvent.ACTION_CANCEL UP
        // or MotionEvent.ACTION_UP. this is to avoid passing the touch to NPV
        // after the lock icon disappears on device entry
        if (mDownDetected && mDetectedLongPress) {
        if (mDownDetected) {
            if (event.getAction() == MotionEvent.ACTION_CANCEL
                    || event.getAction() == MotionEvent.ACTION_UP) {
                mDownDetected = false;
@@ -596,7 +680,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
    private final AuthController.Callback mAuthControllerCallback = new AuthController.Callback() {
        @Override
        public void onAllAuthenticatorsRegistered() {
            mUdfpsSupported = mAuthController.getUdfpsSensorLocation() != null;
            updateIsUdfpsEnrolled();
            updateConfiguration();
        }
    };
+4 −0
Original line number Diff line number Diff line
@@ -881,6 +881,10 @@ public class UdfpsController implements DozeReceiver {
            return;
        }

        if (!mKeyguardUpdateMonitor.isFingerprintDetectionRunning()) {
            return;
        }

        mAodInterruptRunnable = () -> {
            mIsAodInterruptActive = true;
            // Since the sensor that triggers the AOD interrupt doesn't provide
+0 −1
Original line number Diff line number Diff line
@@ -41,7 +41,6 @@ import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Optional;


/**
 * Class that coordinates non-HBM animations during keyguard authentication.
 */
Loading