diff options
15 files changed, 212 insertions, 52 deletions
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index a55484b89177..00abc759278f 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -2242,6 +2242,21 @@ public final class Settings { public static final String ACTION_TETHER_SETTINGS = "android.settings.TETHER_SETTINGS"; /** + * Activity Action: Show screen that lets user configure wifi tethering. + * <p> + * In some cases, a matching Activity may not exist, so ensure you safeguard against this. + * <p> + * Input: Nothing + * <p> + * Output: Nothing + * + * @hide + */ + @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) + public static final String ACTION_WIFI_TETHER_SETTING = + "com.android.settings.WIFI_TETHER_SETTINGS"; + + /** * Broadcast to trigger notification of asking user to enable MMS. * Need to specify {@link #EXTRA_ENABLE_MMS_DATA_REQUEST_REASON} and {@link #EXTRA_SUB_ID}. * diff --git a/packages/SystemUI/res/drawable/notif_footer_btn_background.xml b/packages/SystemUI/res/drawable/notif_footer_btn_background.xml index 6725a26c102c..e6266754c0af 100644 --- a/packages/SystemUI/res/drawable/notif_footer_btn_background.xml +++ b/packages/SystemUI/res/drawable/notif_footer_btn_background.xml @@ -14,19 +14,20 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> - - -<shape xmlns:android="http://schemas.android.com/apk/res/android" +<ripple xmlns:android="http://schemas.android.com/apk/res/android" xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" - android:shape="rectangle"> - <solid - android:color="?androidprv:attr/colorSurface" - /> - <corners android:radius="20dp" /> - - <padding - android:left="20dp" - android:right="20dp"> - </padding> - -</shape>
\ No newline at end of file + android:color="?android:attr/colorControlHighlight"> + <item> + <inset + android:insetBottom="4dp" + android:insetTop="4dp"> + <shape android:shape="rectangle"> + <corners android:radius="20dp" /> + <padding + android:left="20dp" + android:right="20dp" /> + <solid android:color="?androidprv:attr/colorSurface" /> + </shape> + </inset> + </item> +</ripple> diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml index d8346aba4a8f..8b787323ccb6 100644 --- a/packages/SystemUI/res/layout/status_bar_expanded.xml +++ b/packages/SystemUI/res/layout/status_bar_expanded.xml @@ -70,6 +70,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 diff --git a/packages/SystemUI/res/layout/status_bar_notification_footer.xml b/packages/SystemUI/res/layout/status_bar_notification_footer.xml index 412276d05ea3..bbb8df1c5a4a 100644 --- a/packages/SystemUI/res/layout/status_bar_notification_footer.xml +++ b/packages/SystemUI/res/layout/status_bar_notification_footer.xml @@ -30,8 +30,8 @@ style="@style/TextAppearance.NotificationSectionHeaderButton" android:id="@+id/manage_text" android:layout_width="wrap_content" - android:layout_height="40dp" - android:layout_marginTop="16dp" + android:layout_height="48dp" + android:layout_marginTop="12dp" android:layout_gravity="start" android:background="@drawable/notif_footer_btn_background" android:focusable="true" @@ -43,8 +43,8 @@ style="@style/TextAppearance.NotificationSectionHeaderButton" android:id="@+id/dismiss_text" android:layout_width="wrap_content" - android:layout_height="40dp" - android:layout_marginTop="16dp" + android:layout_height="48dp" + android:layout_marginTop="12dp" android:layout_gravity="end" android:background="@drawable/notif_footer_btn_background" android:focusable="true" diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconView.java b/packages/SystemUI/src/com/android/keyguard/LockIconView.java index dd3bb8990599..371564a98aad 100644 --- a/packages/SystemUI/src/com/android/keyguard/LockIconView.java +++ b/packages/SystemUI/src/com/android/keyguard/LockIconView.java @@ -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); + } } /** diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java index 2a4022ca57b6..aa79504ae7ca 100644 --- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java @@ -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; @@ -32,6 +34,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; @@ -59,6 +62,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; @@ -94,6 +99,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; @@ -112,6 +119,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; @@ -121,6 +129,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(); @@ -155,6 +169,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()); @@ -173,19 +193,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(); @@ -193,15 +213,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); @@ -231,7 +254,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme mCancelDelayedUpdateVisibilityRunnable = null; } - if (!mIsKeyguardShowing) { + if (!mIsKeyguardShowing && !mIsDozing) { mView.setVisibility(View.INVISIBLE); return; } @@ -242,6 +265,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) { @@ -264,10 +288,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()); @@ -344,10 +380,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); @@ -355,17 +393,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(); } @@ -439,7 +517,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme mKeyguardUpdateMonitor.getUserUnlockedWithBiometric( KeyguardUpdateMonitor.getCurrentUser()); } - mUdfpsEnrolled = mKeyguardUpdateMonitor.isUdfpsEnrolled(); + updateIsUdfpsEnrolled(); updateVisibility(); } @@ -485,8 +563,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(), @@ -494,6 +571,8 @@ public class LockIconViewController extends ViewController<LockIconView> impleme "lockIcon-onDown", VIBRATION_SONIFICATION_ATTRIBUTES); } + + mDownDetected = true; return true; } @@ -551,6 +630,9 @@ public class LockIconViewController extends ViewController<LockIconView> impleme mAuthRippleController.showRipple(FINGERPRINT); } updateVisibility(); + if (mOnGestureDetectedRunnable != null) { + mOnGestureDetectedRunnable.run(); + } mKeyguardViewController.showBouncer(/* scrim */ true); return true; } @@ -561,16 +643,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; @@ -594,7 +678,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(); } }; diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java index 9ba0583d9ca6..9f8990f87d1e 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java @@ -876,6 +876,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 diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java index 838b9c8adadb..c128e5e2ab30 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java @@ -40,7 +40,6 @@ import com.android.systemui.util.time.SystemClock; import java.io.FileDescriptor; import java.io.PrintWriter; - /** * Class that coordinates non-HBM animations during keyguard authentication. */ diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java index 2d215e0f1f62..a424674ed252 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java @@ -100,8 +100,7 @@ public class KeyguardIndicationRotateTextViewController extends */ public void updateIndication(@IndicationType int type, KeyguardIndication newIndication, boolean updateImmediately) { - if (type == INDICATION_TYPE_NOW_PLAYING - || type == INDICATION_TYPE_REVERSE_CHARGING) { + if (type == INDICATION_TYPE_REVERSE_CHARGING) { // temporarily don't show here, instead use AmbientContainer b/181049781 return; } @@ -303,7 +302,6 @@ public class KeyguardIndicationRotateTextViewController extends public static final int INDICATION_TYPE_TRUST = 6; public static final int INDICATION_TYPE_RESTING = 7; public static final int INDICATION_TYPE_USER_LOCKED = 8; - public static final int INDICATION_TYPE_NOW_PLAYING = 9; public static final int INDICATION_TYPE_REVERSE_CHARGING = 10; @IntDef({ @@ -317,7 +315,6 @@ public class KeyguardIndicationRotateTextViewController extends INDICATION_TYPE_TRUST, INDICATION_TYPE_RESTING, INDICATION_TYPE_USER_LOCKED, - INDICATION_TYPE_NOW_PLAYING, INDICATION_TYPE_REVERSE_CHARGING, }) @Retention(RetentionPolicy.SOURCE) diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java index 34f2b6331678..87edc2cf8bac 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java @@ -47,6 +47,7 @@ import javax.inject.Inject; /** Quick settings tile: Hotspot **/ public class HotspotTile extends QSTileImpl<BooleanState> { + private final Icon mEnabledStatic = ResourceIcon.get(R.drawable.ic_hotspot); private final HotspotController mHotspotController; @@ -98,7 +99,7 @@ public class HotspotTile extends QSTileImpl<BooleanState> { @Override public Intent getLongClickIntent() { - return new Intent(Settings.ACTION_TETHER_SETTINGS); + return new Intent(Settings.ACTION_WIFI_TETHER_SETTING); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java index 963bf7b7fb00..733f83c60e4f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java @@ -3671,6 +3671,7 @@ public class NotificationPanelViewController extends PanelViewController { } public void dozeTimeTick() { + mLockIconViewController.dozeTimeTick(); mKeyguardBottomArea.dozeTimeTick(); mKeyguardStatusViewController.dozeTimeTick(); if (mInterpolatedDarkAmount > 0) { @@ -3974,10 +3975,6 @@ public class NotificationPanelViewController extends PanelViewController { mStatusBarKeyguardViewManager.updateKeyguardPosition(event.getX()); } - if (mLockIconViewController.onTouchEvent(event)) { - return true; - } - handled |= super.onTouch(v, event); return !mDozing || mPulsing || handled; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java index e57e2005e3b5..3807b4647fe1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java @@ -35,6 +35,7 @@ import android.view.View; import android.view.ViewGroup; import com.android.internal.annotations.VisibleForTesting; +import com.android.keyguard.LockIconViewController; import com.android.systemui.R; import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.dock.DockManager; @@ -88,6 +89,7 @@ public class NotificationShadeWindowViewController { private final NotificationShadeDepthController mDepthController; private final NotificationStackScrollLayoutController mNotificationStackScrollLayoutController; private final LockscreenShadeTransitionController mLockscreenShadeTransitionController; + private final LockIconViewController mLockIconViewController; private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; private GestureDetector mGestureDetector; @@ -138,7 +140,8 @@ public class NotificationShadeWindowViewController { NotificationPanelViewController notificationPanelViewController, SuperStatusBarViewFactory statusBarViewFactory, NotificationStackScrollLayoutController notificationStackScrollLayoutController, - StatusBarKeyguardViewManager statusBarKeyguardViewManager) { + StatusBarKeyguardViewManager statusBarKeyguardViewManager, + LockIconViewController lockIconViewController) { mInjectionInflationController = injectionInflationController; mCoordinator = coordinator; mPulseExpansionHandler = pulseExpansionHandler; @@ -163,6 +166,7 @@ public class NotificationShadeWindowViewController { mStatusBarViewFactory = statusBarViewFactory; mNotificationStackScrollLayoutController = notificationStackScrollLayoutController; mStatusBarKeyguardViewManager = statusBarKeyguardViewManager; + mLockIconViewController = lockIconViewController; // This view is not part of the newly inflated expanded status bar. mBrightnessMirror = mView.findViewById(R.id.brightness_mirror_container); @@ -235,6 +239,7 @@ public class NotificationShadeWindowViewController { if (!isCancel && mService.shouldIgnoreTouch()) { return false; } + if (isDown) { setTouchActive(true); mTouchCancelled = false; @@ -245,6 +250,7 @@ public class NotificationShadeWindowViewController { if (mTouchCancelled || mExpandAnimationRunning) { return false; } + mFalsingCollector.onTouchEvent(ev); mGestureDetector.onTouchEvent(ev); mStatusBarKeyguardViewManager.onTouch(ev); @@ -260,9 +266,17 @@ public class NotificationShadeWindowViewController { if (isDown) { mNotificationStackScrollLayoutController.closeControlsIfOutsideTouch(ev); } + if (mStatusBarStateController.isDozing()) { mService.mDozeScrimController.extendPulse(); } + mLockIconViewController.onTouchEvent( + ev, + () -> mService.wakeUpIfDozing( + SystemClock.uptimeMillis(), + mView, + "LOCK_ICON_TOUCH")); + // In case we start outside of the view bounds (below the status bar), we need to // dispatch // the touch manually as the view system can't accommodate for touches outside of diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java index 063d4183032d..04ebee8913c0 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java @@ -478,11 +478,12 @@ public class UdfpsControllerTest extends SysuiTestCase { @Test public void aodInterrupt() throws RemoteException { - // GIVEN that the overlay is showing and screen is on + // GIVEN that the overlay is showing and screen is on and fp is running mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID, IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback); mScreenObserver.onScreenTurnedOn(); mFgExecutor.runAllReady(); + when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true); // WHEN fingerprint is requested because of AOD interrupt mUdfpsController.onAodInterrupt(0, 0, 2f, 3f); // THEN illumination begins @@ -500,6 +501,7 @@ public class UdfpsControllerTest extends SysuiTestCase { IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback); mScreenObserver.onScreenTurnedOn(); mFgExecutor.runAllReady(); + when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true); mUdfpsController.onAodInterrupt(0, 0, 0f, 0f); when(mUdfpsView.isIlluminationRequested()).thenReturn(true); // WHEN it is cancelled @@ -515,6 +517,7 @@ public class UdfpsControllerTest extends SysuiTestCase { IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback); mScreenObserver.onScreenTurnedOn(); mFgExecutor.runAllReady(); + when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true); mUdfpsController.onAodInterrupt(0, 0, 0f, 0f); when(mUdfpsView.isIlluminationRequested()).thenReturn(true); // WHEN it times out @@ -533,6 +536,23 @@ public class UdfpsControllerTest extends SysuiTestCase { mFgExecutor.runAllReady(); // WHEN aod interrupt is received + when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true); + mUdfpsController.onAodInterrupt(0, 0, 0f, 0f); + + // THEN no illumination because screen is off + verify(mUdfpsView, never()).startIllumination(any()); + } + + @Test + public void aodInterrupt_fingerprintNotRunning() throws RemoteException { + // GIVEN showing overlay + mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID, + IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback); + mScreenObserver.onScreenTurnedOn(); + mFgExecutor.runAllReady(); + + // WHEN aod interrupt is received when the fingerprint service isn't running + when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(false); mUdfpsController.onAodInterrupt(0, 0, 0f, 0f); // THEN no illumination because screen is off diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/LockIconViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/LockIconViewControllerTest.java index d279bbb02cee..a2af9b2dc35d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/LockIconViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/LockIconViewControllerTest.java @@ -18,6 +18,7 @@ package com.android.systemui.keyguard; import static junit.framework.Assert.assertEquals; +import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -49,6 +50,8 @@ import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.util.concurrency.DelayableExecutor; +import com.airbnb.lottie.LottieAnimationView; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -80,6 +83,7 @@ public class LockIconViewControllerTest extends SysuiTestCase { private @Mock DelayableExecutor mDelayableExecutor; private @Mock Vibrator mVibrator; private @Mock AuthRippleController mAuthRippleController; + private @Mock LottieAnimationView mAodFp; private LockIconViewController mLockIconViewController; @@ -101,6 +105,7 @@ public class LockIconViewControllerTest extends SysuiTestCase { when(mLockIconView.getContext()).thenReturn(mContext); when(mContext.getResources()).thenReturn(mResources); when(mResources.getDisplayMetrics()).thenReturn(mDisplayMetrics); + when(mLockIconView.findViewById(anyInt())).thenReturn(mAodFp); mLockIconViewController = new LockIconViewController( mLockIconView, @@ -121,7 +126,7 @@ public class LockIconViewControllerTest extends SysuiTestCase { @Test public void testUpdateFingerprintLocationOnInit() { - // GIVEN fp sensor location is available pre-init + // GIVEN fp sensor location is available pre-attached final PointF udfpsLocation = new PointF(50, 75); final int radius = 33; final FingerprintSensorPropertiesInternal fpProps = @@ -139,7 +144,7 @@ public class LockIconViewControllerTest extends SysuiTestCase { // WHEN lock icon view controller is initialized and attached mLockIconViewController.init(); captureAttachListener(); - mAttachListener.onViewAttachedToWindow(null); + mAttachListener.onViewAttachedToWindow(mLockIconView); // THEN lock icon view location is updated with the same coordinates as fpProps verify(mLockIconView).setCenterLocation(mPointCaptor.capture(), eq(radius)); @@ -152,8 +157,10 @@ public class LockIconViewControllerTest extends SysuiTestCase { when(mAuthController.getFingerprintSensorLocation()).thenReturn(null); when(mAuthController.getUdfpsProps()).thenReturn(null); mLockIconViewController.init(); + captureAttachListener(); + mAttachListener.onViewAttachedToWindow(mLockIconView); - // GIVEN fp sensor location is available post-init + // GIVEN fp sensor location is available post-atttached captureAuthControllerCallback(); final PointF udfpsLocation = new PointF(50, 75); final int radius = 33; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java index bcc257dfa3d9..aafaebd959f0 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java @@ -32,6 +32,7 @@ import android.view.MotionEvent; import androidx.test.filters.SmallTest; +import com.android.keyguard.LockIconViewController; import com.android.systemui.R; import com.android.systemui.SystemUIFactory; import com.android.systemui.SysuiTestCase; @@ -97,6 +98,7 @@ public class NotificationShadeWindowViewTest extends SysuiTestCase { @Mock private NotificationStackScrollLayoutController mNotificationStackScrollLayoutController; @Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; @Mock private LockscreenShadeTransitionController mLockscreenShadeTransitionController; + @Mock private LockIconViewController mLockIconViewController; @Captor private ArgumentCaptor<NotificationShadeWindowView.InteractionEventHandler> mInteractionEventHandlerCaptor; @@ -142,7 +144,8 @@ public class NotificationShadeWindowViewTest extends SysuiTestCase { mNotificationPanelViewController, mStatusBarViewFactory, mNotificationStackScrollLayoutController, - mStatusBarKeyguardViewManager); + mStatusBarKeyguardViewManager, + mLockIconViewController); mController.setupExpandedStatusBar(); mController.setService(mStatusBar, mNotificationShadeWindowController); mController.setDragDownHelper(mDragDownHelper); |