Merge "Add alt auth affordance for keyguard notif-taps" into sc-dev
This commit is contained in:
25
packages/SystemUI/res/drawable/fingerprint_bg.xml
Normal file
25
packages/SystemUI/res/drawable/fingerprint_bg.xml
Normal file
@@ -0,0 +1,25 @@
|
||||
<!-- Copyright (C) 2021 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.
|
||||
-->
|
||||
<shape
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="oval">
|
||||
|
||||
<solid
|
||||
android:color="?android:attr/colorBackground"/>
|
||||
|
||||
<size
|
||||
android:width="64dp"
|
||||
android:height="64dp"/>
|
||||
</shape>
|
||||
@@ -20,7 +20,13 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<!-- TODO: add background protection -->
|
||||
<!-- Background protection -->
|
||||
<ImageView
|
||||
android:id="@+id/udfps_keyguard_fp_bg"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/fingerprint_bg"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<!-- Fingerprint -->
|
||||
<ImageView
|
||||
|
||||
@@ -79,6 +79,10 @@ abstract class UdfpsAnimationView extends FrameLayout {
|
||||
return mPauseAuth ? mAlpha : 255;
|
||||
}
|
||||
|
||||
boolean isPauseAuth() {
|
||||
return mPauseAuth;
|
||||
}
|
||||
|
||||
private int expansionToAlpha(float expansion) {
|
||||
// Fade to 0 opacity when reaching this expansion amount
|
||||
final float maxExpansion = 0.4f;
|
||||
|
||||
@@ -24,10 +24,16 @@ import android.annotation.NonNull;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.RectF;
|
||||
|
||||
import com.android.systemui.Dumpable;
|
||||
import com.android.systemui.dump.DumpManager;
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||
import com.android.systemui.statusbar.StatusBarState;
|
||||
import com.android.systemui.statusbar.phone.StatusBar;
|
||||
import com.android.systemui.util.ViewController;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
* Handles:
|
||||
* 1. registering for listeners when its view is attached and unregistering on view detached
|
||||
@@ -39,33 +45,50 @@ import com.android.systemui.util.ViewController;
|
||||
* - doze time event
|
||||
*/
|
||||
abstract class UdfpsAnimationViewController<T extends UdfpsAnimationView>
|
||||
extends ViewController<T> {
|
||||
extends ViewController<T> implements Dumpable {
|
||||
@NonNull final StatusBarStateController mStatusBarStateController;
|
||||
@NonNull final StatusBar mStatusBar;
|
||||
@NonNull final DumpManager mDumpManger;
|
||||
|
||||
private boolean mNotificationShadeExpanded;
|
||||
private int mStatusBarState;
|
||||
|
||||
protected UdfpsAnimationViewController(
|
||||
T view,
|
||||
StatusBarStateController statusBarStateController,
|
||||
StatusBar statusBar) {
|
||||
@NonNull StatusBarStateController statusBarStateController,
|
||||
@NonNull StatusBar statusBar,
|
||||
@NonNull DumpManager dumpManager) {
|
||||
super(view);
|
||||
mStatusBarStateController = statusBarStateController;
|
||||
mStatusBar = statusBar;
|
||||
mDumpManger = dumpManager;
|
||||
}
|
||||
|
||||
abstract @NonNull String getTag();
|
||||
|
||||
@Override
|
||||
protected void onViewAttached() {
|
||||
mStatusBarStateController.addCallback(mStateListener);
|
||||
mStateListener.onStateChanged(mStatusBarStateController.getState());
|
||||
mStatusBar.addExpansionChangedListener(mStatusBarExpansionChangedListener);
|
||||
|
||||
mDumpManger.registerDumpable(getTag(), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onViewDetached() {
|
||||
mStatusBarStateController.removeCallback(mStateListener);
|
||||
mStatusBar.removeExpansionChangedListener(mStatusBarExpansionChangedListener);
|
||||
|
||||
mDumpManger.unregisterDumpable(getTag());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
||||
pw.println("mStatusBarState=" + StatusBarState.toShortString(mStatusBarState));
|
||||
pw.println("mNotificationShadeExpanded=" + mNotificationShadeExpanded);
|
||||
pw.println("shouldPauseAuth()=" + shouldPauseAuth());
|
||||
pw.println("isPauseAuth=" + mView.isPauseAuth());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
package com.android.systemui.biometrics;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
|
||||
import com.android.systemui.dump.DumpManager;
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||
import com.android.systemui.statusbar.phone.StatusBar;
|
||||
|
||||
@@ -24,9 +27,15 @@ import com.android.systemui.statusbar.phone.StatusBar;
|
||||
*/
|
||||
class UdfpsBpViewController extends UdfpsAnimationViewController<UdfpsBpView> {
|
||||
protected UdfpsBpViewController(
|
||||
UdfpsBpView view,
|
||||
StatusBarStateController statusBarStateController,
|
||||
StatusBar statusBar) {
|
||||
super(view, statusBarStateController, statusBar);
|
||||
@NonNull UdfpsBpView view,
|
||||
@NonNull StatusBarStateController statusBarStateController,
|
||||
@NonNull StatusBar statusBar,
|
||||
@NonNull DumpManager dumpManager) {
|
||||
super(view, statusBarStateController, statusBar, dumpManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull String getTag() {
|
||||
return "UdfpsBpViewController";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,8 +50,10 @@ import com.android.systemui.R;
|
||||
import com.android.systemui.dagger.SysUISingleton;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
import com.android.systemui.doze.DozeReceiver;
|
||||
import com.android.systemui.dump.DumpManager;
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||
import com.android.systemui.statusbar.phone.StatusBar;
|
||||
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
|
||||
import com.android.systemui.util.concurrency.DelayableExecutor;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@@ -83,6 +85,8 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
|
||||
private final DelayableExecutor mFgExecutor;
|
||||
@NonNull private final StatusBar mStatusBar;
|
||||
@NonNull private final StatusBarStateController mStatusBarStateController;
|
||||
@NonNull private final StatusBarKeyguardViewManager mKeyguardViewManager;
|
||||
@NonNull private final DumpManager mDumpManager;
|
||||
// Currently the UdfpsController supports a single UDFPS sensor. If devices have multiple
|
||||
// sensors, this, in addition to a lot of the code here, will be updated.
|
||||
@VisibleForTesting final FingerprintSensorPropertiesInternal mSensorProps;
|
||||
@@ -299,7 +303,9 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
|
||||
WindowManager windowManager,
|
||||
@NonNull StatusBarStateController statusBarStateController,
|
||||
@Main DelayableExecutor fgExecutor,
|
||||
@NonNull StatusBar statusBar) {
|
||||
@NonNull StatusBar statusBar,
|
||||
@NonNull StatusBarKeyguardViewManager statusBarKeyguardViewManager,
|
||||
@NonNull DumpManager dumpManager) {
|
||||
mContext = context;
|
||||
mInflater = inflater;
|
||||
// The fingerprint manager is queried for UDFPS before this class is constructed, so the
|
||||
@@ -309,6 +315,8 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
|
||||
mFgExecutor = fgExecutor;
|
||||
mStatusBar = statusBar;
|
||||
mStatusBarStateController = statusBarStateController;
|
||||
mKeyguardViewManager = statusBarKeyguardViewManager;
|
||||
mDumpManager = dumpManager;
|
||||
|
||||
mSensorProps = findFirstUdfps();
|
||||
// At least one UDFPS sensor exists
|
||||
@@ -457,7 +465,8 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
|
||||
enrollView,
|
||||
mServerRequest.mEnrollHelper,
|
||||
mStatusBarStateController,
|
||||
mStatusBar
|
||||
mStatusBar,
|
||||
mDumpManager
|
||||
);
|
||||
case IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD:
|
||||
UdfpsKeyguardView keyguardView = (UdfpsKeyguardView)
|
||||
@@ -466,7 +475,9 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
|
||||
return new UdfpsKeyguardViewController(
|
||||
keyguardView,
|
||||
mStatusBarStateController,
|
||||
mStatusBar
|
||||
mStatusBar,
|
||||
mKeyguardViewManager,
|
||||
mDumpManager
|
||||
);
|
||||
case IUdfpsOverlayController.REASON_AUTH_BP:
|
||||
// note: empty controller, currently shows no visual affordance
|
||||
@@ -475,7 +486,8 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
|
||||
return new UdfpsBpViewController(
|
||||
bpView,
|
||||
mStatusBarStateController,
|
||||
mStatusBar
|
||||
mStatusBar,
|
||||
mDumpManager
|
||||
);
|
||||
case IUdfpsOverlayController.REASON_AUTH_FPM_OTHER:
|
||||
UdfpsFpmOtherView authOtherView = (UdfpsFpmOtherView)
|
||||
@@ -484,7 +496,8 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
|
||||
return new UdfpsFpmOtherViewController(
|
||||
authOtherView,
|
||||
mStatusBarStateController,
|
||||
mStatusBar
|
||||
mStatusBar,
|
||||
mDumpManager
|
||||
);
|
||||
default:
|
||||
Log.d(TAG, "Animation for reason " + reason + " not supported yet");
|
||||
|
||||
@@ -61,12 +61,14 @@ public abstract class UdfpsDrawable extends Drawable {
|
||||
*/
|
||||
protected void updateFingerprintIconBounds(@NonNull Rect bounds) {
|
||||
mFingerprintDrawable.setBounds(bounds);
|
||||
invalidateSelf();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlpha(int alpha) {
|
||||
mAlpha = alpha;
|
||||
mFingerprintDrawable.setAlpha(mAlpha);
|
||||
invalidateSelf();
|
||||
}
|
||||
|
||||
boolean isIlluminationShowing() {
|
||||
@@ -74,7 +76,11 @@ public abstract class UdfpsDrawable extends Drawable {
|
||||
}
|
||||
|
||||
void setIlluminationShowing(boolean showing) {
|
||||
if (mIlluminationShowing == showing) {
|
||||
return;
|
||||
}
|
||||
mIlluminationShowing = showing;
|
||||
invalidateSelf();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -21,6 +21,7 @@ import android.graphics.PointF;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.dump.DumpManager;
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||
import com.android.systemui.statusbar.phone.StatusBar;
|
||||
|
||||
@@ -32,16 +33,22 @@ public class UdfpsEnrollViewController extends UdfpsAnimationViewController<Udfp
|
||||
@NonNull private final UdfpsEnrollHelper mEnrollHelper;
|
||||
|
||||
protected UdfpsEnrollViewController(
|
||||
UdfpsEnrollView view,
|
||||
@NonNull UdfpsEnrollView view,
|
||||
@NonNull UdfpsEnrollHelper enrollHelper,
|
||||
StatusBarStateController statusBarStateController,
|
||||
StatusBar statusBar) {
|
||||
super(view, statusBarStateController, statusBar);
|
||||
@NonNull StatusBarStateController statusBarStateController,
|
||||
@NonNull StatusBar statusBar,
|
||||
@NonNull DumpManager dumpManager) {
|
||||
super(view, statusBarStateController, statusBar, dumpManager);
|
||||
mEnrollHelper = enrollHelper;
|
||||
mProgressBar = mView.findViewById(R.id.progress_bar);
|
||||
mView.setEnrollHelper(mEnrollHelper);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull String getTag() {
|
||||
return "UdfpsEnrollViewController";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onViewAttached() {
|
||||
super.onViewAttached();
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
package com.android.systemui.biometrics;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
|
||||
import com.android.systemui.dump.DumpManager;
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||
import com.android.systemui.statusbar.phone.StatusBar;
|
||||
|
||||
@@ -27,9 +30,15 @@ import com.android.systemui.statusbar.phone.StatusBar;
|
||||
*/
|
||||
class UdfpsFpmOtherViewController extends UdfpsAnimationViewController<UdfpsFpmOtherView> {
|
||||
protected UdfpsFpmOtherViewController(
|
||||
UdfpsFpmOtherView view,
|
||||
StatusBarStateController statusBarStateController,
|
||||
StatusBar statusBar) {
|
||||
super(view, statusBarStateController, statusBar);
|
||||
@NonNull UdfpsFpmOtherView view,
|
||||
@NonNull StatusBarStateController statusBarStateController,
|
||||
@NonNull StatusBar statusBar,
|
||||
@NonNull DumpManager dumpManager) {
|
||||
super(view, statusBarStateController, statusBar, dumpManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull String getTag() {
|
||||
return "UdfpsFpmOtherViewController";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,14 +36,14 @@ import com.android.systemui.doze.DozeReceiver;
|
||||
public class UdfpsKeyguardDrawable extends UdfpsDrawable implements DozeReceiver {
|
||||
|
||||
private static final String TAG = "UdfpsAnimationKeyguard";
|
||||
private final int mLockScreenColor;
|
||||
private final int mAmbientDisplayColor;
|
||||
|
||||
@NonNull private final Context mContext;
|
||||
private final int mMaxBurnInOffsetX;
|
||||
private final int mMaxBurnInOffsetY;
|
||||
private int mLockScreenColor;
|
||||
|
||||
// AOD anti-burn-in offsets
|
||||
private final int mMaxBurnInOffsetX;
|
||||
private final int mMaxBurnInOffsetY;
|
||||
private float mInterpolatedDarkAmount;
|
||||
private float mBurnInOffsetX;
|
||||
private float mBurnInOffsetY;
|
||||
@@ -95,4 +95,10 @@ public class UdfpsKeyguardDrawable extends UdfpsDrawable implements DozeReceiver
|
||||
mInterpolatedDarkAmount = eased;
|
||||
updateAodPositionAndColor();
|
||||
}
|
||||
|
||||
void setLockScreenColor(int color) {
|
||||
if (mLockScreenColor == color) return;
|
||||
mLockScreenColor = color;
|
||||
updateAodPositionAndColor();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,13 +16,23 @@
|
||||
|
||||
package com.android.systemui.biometrics;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ArgbEvaluator;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.settingslib.Utils;
|
||||
import com.android.systemui.Interpolators;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.statusbar.StatusBarState;
|
||||
|
||||
/**
|
||||
* View corresponding with udfps_keyguard_view.xml
|
||||
@@ -30,6 +40,14 @@ import com.android.systemui.R;
|
||||
public class UdfpsKeyguardView extends UdfpsAnimationView {
|
||||
private final UdfpsKeyguardDrawable mFingerprintDrawable;
|
||||
private ImageView mFingerprintView;
|
||||
private int mWallpaperTexColor;
|
||||
private int mStatusBarState;
|
||||
|
||||
// used when highlighting fp icon:
|
||||
private int mTextColorPrimary;
|
||||
private ImageView mBgProtection;
|
||||
|
||||
private AnimatorSet mAnimatorSet;
|
||||
|
||||
public UdfpsKeyguardView(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
@@ -38,8 +56,15 @@ public class UdfpsKeyguardView extends UdfpsAnimationView {
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
mFingerprintView = findViewById(R.id.udfps_keyguard_animation_fp_view);
|
||||
mFingerprintView.setImageDrawable(mFingerprintDrawable);
|
||||
mFingerprintView.setForeground(mFingerprintDrawable);
|
||||
|
||||
mBgProtection = findViewById(R.id.udfps_keyguard_fp_bg);
|
||||
|
||||
mWallpaperTexColor = Utils.getColorAttrDefaultColor(mContext, R.attr.wallpaperTextColor);
|
||||
mTextColorPrimary = Utils.getColorAttrDefaultColor(mContext,
|
||||
android.R.attr.textColorPrimary);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -54,7 +79,114 @@ public class UdfpsKeyguardView extends UdfpsAnimationView {
|
||||
return true;
|
||||
}
|
||||
|
||||
void setStatusBarState(int statusBarState) {
|
||||
mStatusBarState = statusBarState;
|
||||
if (!isShadeLocked()) {
|
||||
mFingerprintView.setAlpha(1f);
|
||||
mFingerprintDrawable.setLockScreenColor(mWallpaperTexColor);
|
||||
}
|
||||
}
|
||||
|
||||
void onDozeAmountChanged(float linear, float eased) {
|
||||
mFingerprintDrawable.onDozeAmountChanged(linear, eased);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Animates in the bg protection circle behind the fp icon to highlight the icon.
|
||||
*/
|
||||
void animateHighlightFp() {
|
||||
if (mBgProtection.getVisibility() == View.VISIBLE && mBgProtection.getAlpha() == 1f) {
|
||||
// already fully highlighted, don't re-animate
|
||||
return;
|
||||
}
|
||||
|
||||
if (mAnimatorSet != null) {
|
||||
mAnimatorSet.cancel();
|
||||
}
|
||||
ValueAnimator fpIconAnim;
|
||||
if (isShadeLocked()) {
|
||||
// set color and fade in since we weren't showing before
|
||||
mFingerprintDrawable.setLockScreenColor(mTextColorPrimary);
|
||||
fpIconAnim = ObjectAnimator.ofFloat(mFingerprintView, View.ALPHA, 0f, 1f);
|
||||
} else {
|
||||
// update icon color
|
||||
fpIconAnim = new ValueAnimator();
|
||||
fpIconAnim.setIntValues(mWallpaperTexColor, mTextColorPrimary);
|
||||
fpIconAnim.setEvaluator(new ArgbEvaluator());
|
||||
fpIconAnim.addUpdateListener(valueAnimator -> mFingerprintDrawable.setLockScreenColor(
|
||||
(Integer) valueAnimator.getAnimatedValue()));
|
||||
}
|
||||
|
||||
mAnimatorSet = new AnimatorSet();
|
||||
mAnimatorSet.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
|
||||
mAnimatorSet.setDuration(500);
|
||||
mAnimatorSet.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
mBgProtection.setVisibility(View.VISIBLE);
|
||||
}
|
||||
});
|
||||
|
||||
mAnimatorSet.playTogether(
|
||||
ObjectAnimator.ofFloat(mBgProtection, View.ALPHA, 0f, 1f),
|
||||
ObjectAnimator.ofFloat(mBgProtection, View.SCALE_X, 0f, 1f),
|
||||
ObjectAnimator.ofFloat(mBgProtection, View.SCALE_Y, 0f, 1f),
|
||||
fpIconAnim);
|
||||
mAnimatorSet.start();
|
||||
}
|
||||
|
||||
private boolean isShadeLocked() {
|
||||
return mStatusBarState == StatusBarState.SHADE_LOCKED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Animates out the bg protection circle behind the fp icon to unhighlight the icon.
|
||||
*/
|
||||
void animateUnhighlightFp(@Nullable Runnable onEndAnimation) {
|
||||
if (mBgProtection.getVisibility() == View.GONE) {
|
||||
// already hidden
|
||||
return;
|
||||
}
|
||||
|
||||
if (mAnimatorSet != null) {
|
||||
mAnimatorSet.cancel();
|
||||
}
|
||||
ValueAnimator fpIconAnim;
|
||||
if (isShadeLocked()) {
|
||||
// fade out
|
||||
fpIconAnim = ObjectAnimator.ofFloat(mFingerprintView, View.ALPHA, 1f, 0f);
|
||||
} else {
|
||||
// update icon color
|
||||
fpIconAnim = new ValueAnimator();
|
||||
fpIconAnim.setIntValues(mTextColorPrimary, mWallpaperTexColor);
|
||||
fpIconAnim.setEvaluator(new ArgbEvaluator());
|
||||
fpIconAnim.addUpdateListener(valueAnimator -> mFingerprintDrawable.setLockScreenColor(
|
||||
(Integer) valueAnimator.getAnimatedValue()));
|
||||
}
|
||||
|
||||
mAnimatorSet = new AnimatorSet();
|
||||
mAnimatorSet.playTogether(
|
||||
ObjectAnimator.ofFloat(mBgProtection, View.ALPHA, 1f, 0f),
|
||||
ObjectAnimator.ofFloat(mBgProtection, View.SCALE_X, 1f, 0f),
|
||||
ObjectAnimator.ofFloat(mBgProtection, View.SCALE_Y, 1f, 0f),
|
||||
fpIconAnim);
|
||||
mAnimatorSet.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
|
||||
mAnimatorSet.setDuration(500);
|
||||
|
||||
mAnimatorSet.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
mBgProtection.setVisibility(View.GONE);
|
||||
if (onEndAnimation != null) {
|
||||
onEndAnimation.run();
|
||||
}
|
||||
}
|
||||
});
|
||||
mAnimatorSet.start();
|
||||
}
|
||||
|
||||
boolean isAnimating() {
|
||||
return mAnimatorSet != null && mAnimatorSet.isRunning();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,34 +16,62 @@
|
||||
|
||||
package com.android.systemui.biometrics;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
|
||||
import com.android.systemui.dump.DumpManager;
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||
import com.android.systemui.statusbar.phone.StatusBar;
|
||||
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
* Class that coordinates non-HBM animations during keyguard authentication.
|
||||
*/
|
||||
public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<UdfpsKeyguardView> {
|
||||
@NonNull private final StatusBarKeyguardViewManager mKeyguardViewManager;
|
||||
|
||||
private boolean mForceShow;
|
||||
|
||||
protected UdfpsKeyguardViewController(
|
||||
UdfpsKeyguardView view,
|
||||
StatusBarStateController statusBarStateController,
|
||||
StatusBar statusBar) {
|
||||
super(view, statusBarStateController, statusBar);
|
||||
@NonNull UdfpsKeyguardView view,
|
||||
@NonNull StatusBarStateController statusBarStateController,
|
||||
@NonNull StatusBar statusBar,
|
||||
@NonNull StatusBarKeyguardViewManager statusBarKeyguardViewManager,
|
||||
@NonNull DumpManager dumpManager) {
|
||||
super(view, statusBarStateController, statusBar, dumpManager);
|
||||
mKeyguardViewManager = statusBarKeyguardViewManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull String getTag() {
|
||||
return "UdfpsKeyguardViewController";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onViewAttached() {
|
||||
super.onViewAttached();
|
||||
mStatusBarStateController.addCallback(mStateListener);
|
||||
|
||||
final float dozeAmount = mStatusBarStateController.getDozeAmount();
|
||||
mStatusBarStateController.addCallback(mStateListener);
|
||||
mStateListener.onDozeAmountChanged(dozeAmount, dozeAmount);
|
||||
mStateListener.onStateChanged(mStatusBarStateController.getState());
|
||||
mKeyguardViewManager.setAlternateAuthInterceptor(mAlternateAuthInterceptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onViewDetached() {
|
||||
super.onViewDetached();
|
||||
mStatusBarStateController.removeCallback(mStateListener);
|
||||
mAlternateAuthInterceptor.reset();
|
||||
mKeyguardViewManager.setAlternateAuthInterceptor(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
||||
super.dump(fd, pw, args);
|
||||
pw.println("mForceShow=" + mForceShow);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,7 +84,11 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
|
||||
|
||||
mForceShow = forceShow;
|
||||
updatePauseAuth();
|
||||
// TODO: animate show/hide background protection
|
||||
if (mForceShow) {
|
||||
mView.animateHighlightFp();
|
||||
} else {
|
||||
mView.animateUnhighlightFp(() -> mKeyguardViewManager.cancelPostAuthActions());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -76,6 +108,50 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
|
||||
@Override
|
||||
public void onDozeAmountChanged(float linear, float eased) {
|
||||
mView.onDozeAmountChanged(linear, eased);
|
||||
if (linear != 0) forceShow(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateChanged(int statusBarState) {
|
||||
mView.setStatusBarState(statusBarState);
|
||||
}
|
||||
};
|
||||
|
||||
private final StatusBarKeyguardViewManager.AlternateAuthInterceptor mAlternateAuthInterceptor =
|
||||
new StatusBarKeyguardViewManager.AlternateAuthInterceptor() {
|
||||
@Override
|
||||
public boolean showAlternativeAuthMethod() {
|
||||
if (mForceShow) {
|
||||
return false;
|
||||
}
|
||||
|
||||
forceShow(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean reset() {
|
||||
if (!mForceShow) {
|
||||
return false;
|
||||
}
|
||||
|
||||
forceShow(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShowingAlternativeAuth() {
|
||||
return mForceShow;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAnimating() {
|
||||
return mView.isAnimating();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(PrintWriter pw) {
|
||||
pw.print(getTag());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3386,6 +3386,9 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
return new TouchHandler() {
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent event) {
|
||||
if (mStatusBarKeyguardViewManager.isShowingAlternativeAuthOrAnimating()) {
|
||||
return true;
|
||||
}
|
||||
if (mBlockTouches || mQsFullyExpanded && mQs.disallowPanelTouches()) {
|
||||
return false;
|
||||
}
|
||||
@@ -3413,6 +3416,12 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
final boolean showingOrAnimatingAltAuth =
|
||||
mStatusBarKeyguardViewManager.isShowingAlternativeAuthOrAnimating();
|
||||
if (showingOrAnimatingAltAuth) {
|
||||
mStatusBarKeyguardViewManager.resetAlternateAuth();
|
||||
}
|
||||
|
||||
if (mBlockTouches || (mQsFullyExpanded && mQs != null
|
||||
&& mQs.disallowPanelTouches())) {
|
||||
return false;
|
||||
@@ -3464,7 +3473,7 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
handled = true;
|
||||
}
|
||||
handled |= super.onTouch(v, event);
|
||||
return !mDozing || mPulsing || handled;
|
||||
return !mDozing || mPulsing || handled || showingOrAnimatingAltAuth;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -453,7 +453,8 @@ public abstract class PanelViewController {
|
||||
// We need to collapse the panel since we peeked to the small height.
|
||||
mView.postOnAnimation(mPostCollapseRunnable);
|
||||
}
|
||||
} else if (!mStatusBar.isBouncerShowing()) {
|
||||
} else if (!mStatusBar.isBouncerShowing()
|
||||
&& !mStatusBarKeyguardViewManager.isShowingAlternativeAuthOrAnimating()) {
|
||||
boolean expands = onEmptySpaceClick(mInitialTouchX);
|
||||
onTrackingStopped(expands);
|
||||
}
|
||||
|
||||
@@ -88,6 +88,17 @@ public enum ScrimState {
|
||||
}
|
||||
},
|
||||
|
||||
AUTH_SCRIMMED {
|
||||
@Override
|
||||
public void prepare(ScrimState previousState) {
|
||||
mFrontTint = Color.BLACK;
|
||||
|
||||
mBehindAlpha = 0f;
|
||||
mFrontAlpha = .66f;
|
||||
mBubbleAlpha = 0f;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Showing password challenge on the keyguard.
|
||||
*/
|
||||
|
||||
@@ -4147,7 +4147,7 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void updateScrimController() {
|
||||
public void updateScrimController() {
|
||||
Trace.beginSection("StatusBar#updateScrimController");
|
||||
|
||||
// We don't want to end up in KEYGUARD state when we're unlocking with
|
||||
@@ -4163,7 +4163,9 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
mNotificationPanelViewController.isLaunchingAffordanceWithPreview();
|
||||
mScrimController.setLaunchingAffordanceWithPreview(launchingAffordanceWithPreview);
|
||||
|
||||
if (mBouncerShowing) {
|
||||
if (mStatusBarKeyguardViewManager.isShowingAlternativeAuth()) {
|
||||
mScrimController.transitionTo(ScrimState.AUTH_SCRIMMED);
|
||||
} else if (mBouncerShowing) {
|
||||
// Bouncer needs the front scrim when it's on top of an activity,
|
||||
// tapping on a notification, editing QS or being dismissed by
|
||||
// FLAG_DISMISS_KEYGUARD_ACTIVITY.
|
||||
|
||||
@@ -38,6 +38,7 @@ import android.view.ViewRootImpl;
|
||||
import android.view.WindowManagerGlobal;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.internal.util.LatencyTracker;
|
||||
@@ -199,6 +200,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
||||
private final DockManager mDockManager;
|
||||
private final KeyguardUpdateMonitor mKeyguardUpdateManager;
|
||||
private KeyguardBypassController mBypassController;
|
||||
@Nullable private AlternateAuthInterceptor mAlternateAuthInterceptor;
|
||||
|
||||
private final KeyguardUpdateMonitorCallback mUpdateMonitorCallback =
|
||||
new KeyguardUpdateMonitorCallback() {
|
||||
@@ -271,6 +273,10 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
||||
registerListeners();
|
||||
}
|
||||
|
||||
public void setAlternateAuthInterceptor(@Nullable AlternateAuthInterceptor authInterceptor) {
|
||||
mAlternateAuthInterceptor = authInterceptor;
|
||||
}
|
||||
|
||||
private void registerListeners() {
|
||||
mKeyguardUpdateManager.registerCallback(mUpdateMonitorCallback);
|
||||
mStatusBarStateController.addCallback(this);
|
||||
@@ -434,11 +440,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
||||
if (mShowing) {
|
||||
// If we were showing the bouncer and then aborting, we need to also clear out any
|
||||
// potential actions unless we actually unlocked.
|
||||
mAfterKeyguardGoneAction = null;
|
||||
if (mKeyguardGoneCancelAction != null) {
|
||||
mKeyguardGoneCancelAction.run();
|
||||
mKeyguardGoneCancelAction = null;
|
||||
}
|
||||
cancelPostAuthActions();
|
||||
}
|
||||
mBouncer.hide(destroyView);
|
||||
cancelPendingWakeupAction();
|
||||
@@ -474,6 +476,14 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
||||
return;
|
||||
}
|
||||
|
||||
if (mAlternateAuthInterceptor != null
|
||||
&& mAlternateAuthInterceptor.showAlternativeAuthMethod()) {
|
||||
mStatusBar.updateScrimController();
|
||||
mAfterKeyguardGoneAction = r;
|
||||
mKeyguardGoneCancelAction = cancelAction;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!afterKeyguardGone) {
|
||||
mBouncer.showWithDismissAction(r, cancelAction);
|
||||
} else {
|
||||
@@ -508,11 +518,21 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
||||
} else {
|
||||
showBouncerOrKeyguard(hideBouncerWhenShowing);
|
||||
}
|
||||
resetAlternateAuth();
|
||||
mKeyguardUpdateManager.sendKeyguardReset();
|
||||
updateStates();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop showing any alternate auth methods
|
||||
*/
|
||||
public void resetAlternateAuth() {
|
||||
if (mAlternateAuthInterceptor != null && mAlternateAuthInterceptor.reset()) {
|
||||
mStatusBar.updateScrimController();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartedWakingUp() {
|
||||
mStatusBar.getNotificationShadeWindowView().getWindowInsetsController()
|
||||
@@ -834,6 +854,20 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
||||
return mBouncer.isFullscreenBouncer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear out any potential actions that were saved to run when the device is unlocked
|
||||
*/
|
||||
public void cancelPostAuthActions() {
|
||||
if (bouncerIsOrWillBeShowing()) {
|
||||
return; // allow bouncer to trigger saved actions
|
||||
}
|
||||
mAfterKeyguardGoneAction = null;
|
||||
if (mKeyguardGoneCancelAction != null) {
|
||||
mKeyguardGoneCancelAction.run();
|
||||
mKeyguardGoneCancelAction = null;
|
||||
}
|
||||
}
|
||||
|
||||
private long getNavBarShowDelay() {
|
||||
if (mKeyguardStateController.isKeyguardFadingAway()) {
|
||||
return mKeyguardStateController.getKeyguardFadingAwayDelay();
|
||||
@@ -1063,6 +1097,11 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
||||
if (mBouncer != null) {
|
||||
mBouncer.dump(pw);
|
||||
}
|
||||
|
||||
if (mAlternateAuthInterceptor != null) {
|
||||
pw.println("AltAuthInterceptor: ");
|
||||
mAlternateAuthInterceptor.dump(pw);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1079,6 +1118,17 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
||||
return mBouncer;
|
||||
}
|
||||
|
||||
public boolean isShowingAlternativeAuth() {
|
||||
return mAlternateAuthInterceptor != null
|
||||
&& mAlternateAuthInterceptor.isShowingAlternativeAuth();
|
||||
}
|
||||
|
||||
public boolean isShowingAlternativeAuthOrAnimating() {
|
||||
return mAlternateAuthInterceptor != null
|
||||
&& (mAlternateAuthInterceptor.isShowingAlternativeAuth()
|
||||
|| mAlternateAuthInterceptor.isAnimating());
|
||||
}
|
||||
|
||||
private static class DismissWithActionRequest {
|
||||
final OnDismissAction dismissAction;
|
||||
final Runnable cancelAction;
|
||||
@@ -1093,4 +1143,36 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegate used to send show/reset events to an alternate authentication method instead of the
|
||||
* bouncer.
|
||||
*/
|
||||
public interface AlternateAuthInterceptor {
|
||||
/**
|
||||
* @return whether alternative auth method was newly shown
|
||||
*/
|
||||
boolean showAlternativeAuthMethod();
|
||||
|
||||
/**
|
||||
* reset the state to the default (only keyguard showing, no auth methods showing)
|
||||
* @return whether alternative auth method was newly hidden
|
||||
*/
|
||||
boolean reset();
|
||||
|
||||
/**
|
||||
* @return true if alternative auth method is showing
|
||||
*/
|
||||
boolean isShowingAlternativeAuth();
|
||||
|
||||
/**
|
||||
* print information for the alternate auth interceptor registered
|
||||
*/
|
||||
void dump(PrintWriter pw);
|
||||
|
||||
/**
|
||||
* @return true if the new auth method is currently animating in or out.
|
||||
*/
|
||||
boolean isAnimating();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,8 +44,10 @@ import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.dump.DumpManager;
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||
import com.android.systemui.statusbar.phone.StatusBar;
|
||||
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
|
||||
import com.android.systemui.util.concurrency.FakeExecutor;
|
||||
import com.android.systemui.util.time.FakeSystemClock;
|
||||
|
||||
@@ -91,6 +93,10 @@ public class UdfpsControllerTest extends SysuiTestCase {
|
||||
@Mock
|
||||
private StatusBar mStatusBar;
|
||||
@Mock
|
||||
private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
|
||||
@Mock
|
||||
private DumpManager mDumpManager;
|
||||
@Mock
|
||||
private IUdfpsOverlayControllerCallback mUdfpsOverlayControllerCallback;
|
||||
|
||||
private FakeExecutor mFgExecutor;
|
||||
@@ -129,7 +135,9 @@ public class UdfpsControllerTest extends SysuiTestCase {
|
||||
mWindowManager,
|
||||
mStatusBarStateController,
|
||||
mFgExecutor,
|
||||
mStatusBar);
|
||||
mStatusBar,
|
||||
mStatusBarKeyguardViewManager,
|
||||
mDumpManager);
|
||||
verify(mFingerprintManager).setUdfpsOverlayController(mOverlayCaptor.capture());
|
||||
mOverlayController = mOverlayCaptor.getValue();
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.systemui.biometrics;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
@@ -26,9 +28,11 @@ import android.testing.TestableLooper.RunWithLooper;
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.dump.DumpManager;
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||
import com.android.systemui.statusbar.StatusBarState;
|
||||
import com.android.systemui.statusbar.phone.StatusBar;
|
||||
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -51,24 +55,34 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase {
|
||||
private StatusBarStateController mStatusBarStateController;
|
||||
@Mock
|
||||
private StatusBar mStatusBar;
|
||||
@Mock
|
||||
private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
|
||||
@Mock
|
||||
private DumpManager mDumpManager;
|
||||
|
||||
private UdfpsKeyguardViewController mController;
|
||||
|
||||
// Capture listeners so that they can be used to send events
|
||||
@Captor private ArgumentCaptor<StatusBarStateController.StateListener> mStateListenerCaptor;
|
||||
private StatusBarStateController.StateListener mParentListener;
|
||||
private StatusBarStateController.StateListener mDozeListener;
|
||||
private StatusBarStateController.StateListener mParentStatusBarStateListener;
|
||||
private StatusBarStateController.StateListener mStatusBarStateListener;
|
||||
|
||||
@Captor private ArgumentCaptor<StatusBar.ExpansionChangedListener> mExpansionListenerCaptor;
|
||||
private StatusBar.ExpansionChangedListener mExpansionListener;
|
||||
|
||||
@Captor private ArgumentCaptor<StatusBarKeyguardViewManager.AlternateAuthInterceptor>
|
||||
mAltAuthInterceptorCaptor;
|
||||
private StatusBarKeyguardViewManager.AlternateAuthInterceptor mAltAuthInterceptor;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mController = new UdfpsKeyguardViewController(
|
||||
mView,
|
||||
mStatusBarStateController,
|
||||
mStatusBar);
|
||||
mStatusBar,
|
||||
mStatusBarKeyguardViewManager,
|
||||
mDumpManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -86,7 +100,7 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase {
|
||||
@Test
|
||||
public void testViewControllerQueriesSBStateOnAttached() {
|
||||
mController.onViewAttached();
|
||||
verify(mStatusBarStateController).getState();
|
||||
verify(mStatusBarStateController, times(2)).getState();
|
||||
verify(mStatusBarStateController).getDozeAmount();
|
||||
|
||||
final float dozeAmount = .88f;
|
||||
@@ -106,8 +120,8 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase {
|
||||
captureExpansionListener();
|
||||
mController.onViewDetached();
|
||||
|
||||
verify(mStatusBarStateController).removeCallback(mParentListener);
|
||||
verify(mStatusBarStateController).removeCallback(mDozeListener);
|
||||
verify(mStatusBarStateController).removeCallback(mParentStatusBarStateListener);
|
||||
verify(mStatusBarStateController).removeCallback(mStatusBarStateListener);
|
||||
verify(mStatusBar).removeExpansionChangedListener(mExpansionListener);
|
||||
}
|
||||
|
||||
@@ -118,21 +132,88 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase {
|
||||
|
||||
final float linear = .55f;
|
||||
final float eased = .65f;
|
||||
mDozeListener.onDozeAmountChanged(linear, eased);
|
||||
mStatusBarStateListener.onDozeAmountChanged(linear, eased);
|
||||
|
||||
verify(mView).onDozeAmountChanged(linear, eased);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldNotPauseAuthOnKeyguard() {
|
||||
mController.onViewAttached();
|
||||
captureStatusBarStateListeners();
|
||||
captureExpansionListener();
|
||||
|
||||
sendStatusBarStateChanged(StatusBarState.KEYGUARD);
|
||||
|
||||
assertFalse(mController.shouldPauseAuth());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldPauseAuthOnShadeLocked() {
|
||||
mController.onViewAttached();
|
||||
captureStatusBarStateListeners();
|
||||
captureExpansionListener();
|
||||
|
||||
sendStatusBarStateChanged(StatusBarState.SHADE_LOCKED);
|
||||
|
||||
assertTrue(mController.shouldPauseAuth());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOverrideShouldPauseAuthOnShadeLocked() {
|
||||
mController.onViewAttached();
|
||||
captureStatusBarStateListeners();
|
||||
captureAltAuthInterceptor();
|
||||
|
||||
sendStatusBarStateChanged(StatusBarState.SHADE_LOCKED);
|
||||
assertTrue(mController.shouldPauseAuth());
|
||||
|
||||
mAltAuthInterceptor.showAlternativeAuthMethod(); // force show
|
||||
assertFalse(mController.shouldPauseAuth());
|
||||
assertTrue(mAltAuthInterceptor.isShowingAlternativeAuth());
|
||||
|
||||
mAltAuthInterceptor.reset(); // stop force show
|
||||
assertTrue(mController.shouldPauseAuth());
|
||||
assertFalse(mAltAuthInterceptor.isShowingAlternativeAuth());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnDetachedStateReset() {
|
||||
// GIVEN view is attached, alt auth is force being shown
|
||||
mController.onViewAttached();
|
||||
captureStatusBarStateListeners();
|
||||
captureAltAuthInterceptor();
|
||||
|
||||
mAltAuthInterceptor.showAlternativeAuthMethod(); // alt auth force show
|
||||
|
||||
// WHEN view is detached
|
||||
mController.onViewDetached();
|
||||
|
||||
// THEN alt auth state reports not showing
|
||||
assertFalse(mAltAuthInterceptor.isShowingAlternativeAuth());
|
||||
}
|
||||
|
||||
private void sendStatusBarStateChanged(int statusBarState) {
|
||||
mStatusBarStateListener.onStateChanged(statusBarState);
|
||||
mParentStatusBarStateListener.onStateChanged(statusBarState);
|
||||
}
|
||||
|
||||
private void captureStatusBarStateListeners() {
|
||||
verify(mStatusBarStateController, times(2)).addCallback(mStateListenerCaptor.capture());
|
||||
List<StatusBarStateController.StateListener> stateListeners =
|
||||
mStateListenerCaptor.getAllValues();
|
||||
mParentListener = stateListeners.get(0);
|
||||
mDozeListener = stateListeners.get(1);
|
||||
mParentStatusBarStateListener = stateListeners.get(0);
|
||||
mStatusBarStateListener = stateListeners.get(1);
|
||||
}
|
||||
|
||||
private void captureExpansionListener() {
|
||||
verify(mStatusBar).addExpansionChangedListener(mExpansionListenerCaptor.capture());
|
||||
mExpansionListener = mExpansionListenerCaptor.getValue();
|
||||
}
|
||||
|
||||
private void captureAltAuthInterceptor() {
|
||||
verify(mStatusBarKeyguardViewManager).setAlternateAuthInterceptor(
|
||||
mAltAuthInterceptorCaptor.capture());
|
||||
mAltAuthInterceptor = mAltAuthInterceptorCaptor.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user