diff options
20 files changed, 36 insertions, 2677 deletions
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp index 28635318236d..9c8ff80bc30f 100644 --- a/packages/SystemUI/Android.bp +++ b/packages/SystemUI/Android.bp @@ -318,9 +318,6 @@ filegroup { "tests/src/**/systemui/stylus/StylusUsiPowerStartableTest.kt", "tests/src/**/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt", "tests/src/**/keyguard/ClockEventControllerTest.kt", - "tests/src/**/keyguard/LegacyLockIconViewControllerWithCoroutinesTest.kt", - "tests/src/**/keyguard/LegacyLockIconViewControllerBaseTest.kt", - "tests/src/**/keyguard/LegacyLockIconViewControllerTest.java", "tests/src/**/systemui/animation/TransitionAnimatorTest.kt", "tests/src/**/systemui/bluetooth/qsdialog/BluetoothAutoOnRepositoryTest.kt", "tests/src/**/systemui/bluetooth/qsdialog/BluetoothStateInteractorTest.kt", @@ -417,7 +414,6 @@ filegroup { "tests/src/**/systemui/stylus/StylusUsiPowerUiTest.kt", "tests/src/**/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt", "tests/src/**/keyguard/KeyguardUpdateMonitorTest.java", - "tests/src/**/keyguard/LegacyLockIconViewControllerBaseTest.java", "tests/src/**/keyguard/CarrierTextManagerTest.java", "tests/src/**/systemui/ScreenDecorationsTest.java", "tests/src/**/systemui/temporarydisplay/chipbar/SwipeChipbarAwayGestureHandlerTest.kt", diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml index e21466671363..77fbb642f664 100644 --- a/packages/SystemUI/res/layout/status_bar_expanded.xml +++ b/packages/SystemUI/res/layout/status_bar_expanded.xml @@ -128,12 +128,6 @@ <include layout="@layout/dock_info_bottom_area_overlay" /> - <com.android.keyguard.LockIconView - android:id="@+id/lock_icon_view" - android:layout_width="wrap_content" - android:layout_height="wrap_content"> - </com.android.keyguard.LockIconView> - <include layout="@layout/keyguard_bottom_area" android:visibility="gone" /> diff --git a/packages/SystemUI/res/layout/udfps_keyguard_view_legacy.xml b/packages/SystemUI/res/layout/udfps_keyguard_view_legacy.xml deleted file mode 100644 index 530d752732c1..000000000000 --- a/packages/SystemUI/res/layout/udfps_keyguard_view_legacy.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - ~ 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. - --> -<com.android.systemui.biometrics.UdfpsKeyguardViewLegacy - xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/udfps_animation_view_legacy" - android:layout_width="match_parent" - android:layout_height="match_parent"> - - <!-- Add fingerprint views here. See udfps_keyguard_view_internal.xml. --> - -</com.android.systemui.biometrics.UdfpsKeyguardViewLegacy> diff --git a/packages/SystemUI/res/layout/udfps_view.xml b/packages/SystemUI/res/layout/udfps_view.xml deleted file mode 100644 index 257d238f5c54..000000000000 --- a/packages/SystemUI/res/layout/udfps_view.xml +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - ~ Copyright (C) 2020 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. - --> -<com.android.systemui.biometrics.UdfpsView - xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:systemui="http://schemas.android.com/apk/res-auto" - android:id="@+id/udfps_view" - android:layout_width="match_parent" - android:layout_height="match_parent" - systemui:sensorTouchAreaCoefficient="1.0" - android:contentDescription="@string/accessibility_fingerprint_label"> - - <ViewStub - android:id="@+id/animation_view" - android:layout_width="match_parent" - android:layout_height="match_parent"/> - -</com.android.systemui.biometrics.UdfpsView> diff --git a/packages/SystemUI/src/com/android/keyguard/EmptyLockIconViewController.kt b/packages/SystemUI/src/com/android/keyguard/EmptyLockIconViewController.kt index b792db354b36..306d68217e50 100644 --- a/packages/SystemUI/src/com/android/keyguard/EmptyLockIconViewController.kt +++ b/packages/SystemUI/src/com/android/keyguard/EmptyLockIconViewController.kt @@ -17,6 +17,7 @@ package com.android.keyguard import android.view.MotionEvent +import android.view.View import com.android.systemui.dagger.SysUISingleton import com.android.systemui.keyguard.ui.view.KeyguardRootView import com.android.systemui.res.R @@ -34,11 +35,10 @@ import javax.inject.Inject @SysUISingleton class EmptyLockIconViewController @Inject -constructor( - private val keyguardRootView: Lazy<KeyguardRootView>, -) : LockIconViewController { +constructor(private val keyguardRootView: Lazy<KeyguardRootView>) : LockIconViewController { private val deviceEntryIconViewId = R.id.device_entry_icon_view - override fun setLockIconView(lockIconView: LockIconView) { + + override fun setLockIconView(lockIconView: View) { // no-op } diff --git a/packages/SystemUI/src/com/android/keyguard/LegacyLockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LegacyLockIconViewController.java deleted file mode 100644 index 03b13fe47c10..000000000000 --- a/packages/SystemUI/src/com/android/keyguard/LegacyLockIconViewController.java +++ /dev/null @@ -1,843 +0,0 @@ -/* - * Copyright (C) 2020 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. - */ - -package com.android.keyguard; - -import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT; -import static android.hardware.biometrics.BiometricSourceType.FINGERPRINT; - -import static com.android.keyguard.LockIconView.ICON_FINGERPRINT; -import static com.android.keyguard.LockIconView.ICON_LOCK; -import static com.android.keyguard.LockIconView.ICON_UNLOCK; -import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset; -import static com.android.systemui.flags.Flags.DOZING_MIGRATION_1; -import static com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED; -import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.graphics.Point; -import android.graphics.Rect; -import android.hardware.biometrics.BiometricAuthenticator; -import android.hardware.biometrics.BiometricSourceType; -import android.os.VibrationAttributes; -import android.util.DisplayMetrics; -import android.util.Log; -import android.util.MathUtils; -import android.view.HapticFeedbackConstants; -import android.view.MotionEvent; -import android.view.VelocityTracker; -import android.view.View; -import android.view.WindowInsets; -import android.view.WindowManager; -import android.view.accessibility.AccessibilityManager; -import android.view.accessibility.AccessibilityNodeInfo; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.annotation.VisibleForTesting; -import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; - -import com.android.systemui.Dumpable; -import com.android.systemui.biometrics.AuthController; -import com.android.systemui.biometrics.AuthRippleController; -import com.android.systemui.biometrics.UdfpsController; -import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams; -import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor; -import com.android.systemui.dagger.SysUISingleton; -import com.android.systemui.dagger.qualifiers.Main; -import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor; -import com.android.systemui.deviceentry.shared.DeviceEntryUdfpsRefactor; -import com.android.systemui.dump.DumpManager; -import com.android.systemui.flags.FeatureFlags; -import com.android.systemui.flags.Flags; -import com.android.systemui.keyguard.KeyguardBottomAreaRefactor; -import com.android.systemui.keyguard.MigrateClocksToBlueprint; -import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor; -import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor; -import com.android.systemui.keyguard.shared.model.KeyguardState; -import com.android.systemui.plugins.FalsingManager; -import com.android.systemui.plugins.statusbar.StatusBarStateController; -import com.android.systemui.res.R; -import com.android.systemui.scene.shared.flag.SceneContainerFlag; -import com.android.systemui.statusbar.StatusBarState; -import com.android.systemui.statusbar.VibratorHelper; -import com.android.systemui.statusbar.policy.ConfigurationController; -import com.android.systemui.statusbar.policy.KeyguardStateController; -import com.android.systemui.util.concurrency.DelayableExecutor; - -import dagger.Lazy; - -import kotlinx.coroutines.ExperimentalCoroutinesApi; - -import java.io.PrintWriter; -import java.util.Objects; -import java.util.function.Consumer; - -import javax.inject.Inject; - -/** - * Controls when to show the LockIcon affordance (lock/unlocked icon or circle) on lock screen. - * - * For devices with UDFPS, the lock icon will show at the sensor location. Else, the lock - * icon will show a set distance from the bottom of the device. - */ -@SysUISingleton -public class LegacyLockIconViewController implements Dumpable, LockIconViewController { - private static final String TAG = "LockIconViewController"; - private static final float sDefaultDensity = - (float) DisplayMetrics.DENSITY_DEVICE_STABLE / (float) DisplayMetrics.DENSITY_DEFAULT; - private static final int sLockIconRadiusPx = (int) (sDefaultDensity * 36); - private static final VibrationAttributes TOUCH_VIBRATION_ATTRIBUTES = - VibrationAttributes.createForUsage(VibrationAttributes.USAGE_TOUCH); - - private static final long FADE_OUT_DURATION_MS = 250L; - - private final long mLongPressTimeout; - @NonNull private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; - @NonNull private final KeyguardViewController mKeyguardViewController; - @NonNull private final StatusBarStateController mStatusBarStateController; - @NonNull private final KeyguardStateController mKeyguardStateController; - @NonNull private final FalsingManager mFalsingManager; - @NonNull private final AuthController mAuthController; - @NonNull private final AccessibilityManager mAccessibilityManager; - @NonNull private final ConfigurationController mConfigurationController; - @NonNull private final DelayableExecutor mExecutor; - private boolean mUdfpsEnrolled; - private Resources mResources; - private Context mContext; - @NonNull private CharSequence mUnlockedLabel; - @NonNull private CharSequence mLockedLabel; - @NonNull private final VibratorHelper mVibrator; - @Nullable private final AuthRippleController mAuthRippleController; - @NonNull private final FeatureFlags mFeatureFlags; - @NonNull private final PrimaryBouncerInteractor mPrimaryBouncerInteractor; - @NonNull private final KeyguardTransitionInteractor mTransitionInteractor; - @NonNull private final KeyguardInteractor mKeyguardInteractor; - @NonNull private final View.AccessibilityDelegate mAccessibilityDelegate; - @NonNull private final Lazy<DeviceEntryInteractor> mDeviceEntryInteractor; - - // Tracks the velocity of a touch to help filter out the touches that move too fast. - private VelocityTracker mVelocityTracker; - // The ID of the pointer for which ACTION_DOWN has occurred. -1 means no pointer is active. - private int mActivePointerId = -1; - - private boolean mIsDozing; - private boolean mIsActiveDreamLockscreenHosted; - private boolean mIsBouncerShowing; - private boolean mRunningFPS; - private boolean mCanDismissLockScreen; - private int mStatusBarState; - private boolean mIsKeyguardShowing; - private Runnable mLongPressCancelRunnable; - - private boolean mUdfpsSupported; - private float mHeightPixels; - private float mWidthPixels; - private int mBottomPaddingPx; - private int mDefaultPaddingPx; - - private boolean mShowUnlockIcon; - private boolean mShowLockIcon; - - // for udfps when strong auth is required or unlocked on AOD - private boolean mShowAodLockIcon; - private boolean mShowAodUnlockedIcon; - private final int mMaxBurnInOffsetX; - private final int mMaxBurnInOffsetY; - private float mInterpolatedDarkAmount; - - private boolean mDownDetected; - private final Rect mSensorTouchLocation = new Rect(); - private LockIconView mView; - - @VisibleForTesting - final Consumer<Float> mDozeTransitionCallback = (Float value) -> { - mInterpolatedDarkAmount = value; - mView.setDozeAmount(value); - updateBurnInOffsets(); - }; - - @VisibleForTesting - final Consumer<Boolean> mIsDozingCallback = (Boolean isDozing) -> { - mIsDozing = isDozing; - updateBurnInOffsets(); - updateVisibility(); - }; - - @VisibleForTesting - final Consumer<Boolean> mIsActiveDreamLockscreenHostedCallback = - (Boolean isLockscreenHosted) -> { - mIsActiveDreamLockscreenHosted = isLockscreenHosted; - updateVisibility(); - }; - - @Inject - public LegacyLockIconViewController( - @NonNull StatusBarStateController statusBarStateController, - @NonNull KeyguardUpdateMonitor keyguardUpdateMonitor, - @NonNull KeyguardViewController keyguardViewController, - @NonNull KeyguardStateController keyguardStateController, - @NonNull FalsingManager falsingManager, - @NonNull AuthController authController, - @NonNull DumpManager dumpManager, - @NonNull AccessibilityManager accessibilityManager, - @NonNull ConfigurationController configurationController, - @NonNull @Main DelayableExecutor executor, - @NonNull VibratorHelper vibrator, - @Nullable AuthRippleController authRippleController, - @NonNull @Main Resources resources, - @NonNull KeyguardTransitionInteractor transitionInteractor, - @NonNull KeyguardInteractor keyguardInteractor, - @NonNull FeatureFlags featureFlags, - PrimaryBouncerInteractor primaryBouncerInteractor, - Context context, - Lazy<DeviceEntryInteractor> deviceEntryInteractor - ) { - mStatusBarStateController = statusBarStateController; - mKeyguardUpdateMonitor = keyguardUpdateMonitor; - mAuthController = authController; - mKeyguardViewController = keyguardViewController; - mKeyguardStateController = keyguardStateController; - mFalsingManager = falsingManager; - mAccessibilityManager = accessibilityManager; - mConfigurationController = configurationController; - mExecutor = executor; - mVibrator = vibrator; - mAuthRippleController = authRippleController; - mTransitionInteractor = transitionInteractor; - mKeyguardInteractor = keyguardInteractor; - mFeatureFlags = featureFlags; - mPrimaryBouncerInteractor = primaryBouncerInteractor; - - mMaxBurnInOffsetX = resources.getDimensionPixelSize(R.dimen.udfps_burn_in_offset_x); - mMaxBurnInOffsetY = resources.getDimensionPixelSize(R.dimen.udfps_burn_in_offset_y); - mUnlockedLabel = resources.getString(R.string.accessibility_unlock_button); - mLockedLabel = resources.getString(R.string.accessibility_lock_icon); - mLongPressTimeout = resources.getInteger(R.integer.config_lockIconLongPress); - dumpManager.registerDumpable(TAG, this); - mResources = resources; - mContext = context; - mDeviceEntryInteractor = deviceEntryInteractor; - - mAccessibilityDelegate = new View.AccessibilityDelegate() { - private final AccessibilityNodeInfo.AccessibilityAction mAccessibilityAuthenticateHint = - new AccessibilityNodeInfo.AccessibilityAction( - AccessibilityNodeInfoCompat.ACTION_CLICK, - mResources.getString(R.string.accessibility_authenticate_hint)); - private final AccessibilityNodeInfo.AccessibilityAction mAccessibilityEnterHint = - new AccessibilityNodeInfo.AccessibilityAction( - AccessibilityNodeInfoCompat.ACTION_CLICK, - mResources.getString(R.string.accessibility_enter_hint)); - public void onInitializeAccessibilityNodeInfo(View v, AccessibilityNodeInfo info) { - super.onInitializeAccessibilityNodeInfo(v, info); - if (isActionable()) { - if (mShowLockIcon) { - info.addAction(mAccessibilityAuthenticateHint); - } else if (mShowUnlockIcon) { - info.addAction(mAccessibilityEnterHint); - } - } - } - }; - } - - /** Sets the LockIconView to the controller and rebinds any that depend on it. */ - @SuppressLint("ClickableViewAccessibility") - @Override - public void setLockIconView(LockIconView lockIconView) { - mView = lockIconView; - mView.setAccessibilityDelegate(mAccessibilityDelegate); - - if (mFeatureFlags.isEnabled(DOZING_MIGRATION_1)) { - collectFlow(mView, mTransitionInteractor.transitionValue(KeyguardState.AOD), - mDozeTransitionCallback); - collectFlow(mView, mKeyguardInteractor.isDozing(), mIsDozingCallback); - } - - if (mFeatureFlags.isEnabled(LOCKSCREEN_WALLPAPER_DREAM_ENABLED)) { - collectFlow(mView, mKeyguardInteractor.isActiveDreamLockscreenHosted(), - mIsActiveDreamLockscreenHostedCallback); - } - - updateIsUdfpsEnrolled(); - updateConfiguration(); - updateKeyguardShowing(); - - mIsBouncerShowing = mKeyguardViewController.isBouncerShowing(); - mIsDozing = mStatusBarStateController.isDozing(); - mInterpolatedDarkAmount = mStatusBarStateController.getDozeAmount(); - mRunningFPS = mKeyguardUpdateMonitor.isFingerprintDetectionRunning(); - mCanDismissLockScreen = mKeyguardStateController.canDismissLockScreen(); - mStatusBarState = mStatusBarStateController.getState(); - - updateColors(); - mDownDetected = false; - updateBurnInOffsets(); - updateVisibility(); - - updateAccessibility(); - - lockIconView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() { - @Override - public void onViewAttachedToWindow(View view) { - registerCallbacks(); - } - - @Override - public void onViewDetachedFromWindow(View view) { - unregisterCallbacks(); - } - }); - - if (lockIconView.isAttachedToWindow()) { - registerCallbacks(); - } - - lockIconView.setOnTouchListener((view, motionEvent) -> onTouchEvent(motionEvent)); - } - - private void registerCallbacks() { - mConfigurationController.addCallback(mConfigurationListener); - mAuthController.addCallback(mAuthControllerCallback); - mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateMonitorCallback); - mStatusBarStateController.addCallback(mStatusBarStateListener); - mKeyguardStateController.addCallback(mKeyguardStateCallback); - mAccessibilityManager.addAccessibilityStateChangeListener( - mAccessibilityStateChangeListener); - - } - - private void unregisterCallbacks() { - mAuthController.removeCallback(mAuthControllerCallback); - mConfigurationController.removeCallback(mConfigurationListener); - mKeyguardUpdateMonitor.removeCallback(mKeyguardUpdateMonitorCallback); - mStatusBarStateController.removeCallback(mStatusBarStateListener); - mKeyguardStateController.removeCallback(mKeyguardStateCallback); - mAccessibilityManager.removeAccessibilityStateChangeListener( - mAccessibilityStateChangeListener); - - } - - private void updateAccessibility() { - if (mAccessibilityManager.isEnabled()) { - mView.setOnClickListener(mA11yClickListener); - } else { - mView.setOnClickListener(null); - } - } - - @Override - public float getTop() { - return mView.getLocationTop(); - } - - @Override - public float getBottom() { - return mView.getLocationBottom(); - } - - private void updateVisibility() { - if (!mIsKeyguardShowing && !mIsDozing) { - mView.setVisibility(View.INVISIBLE); - return; - } - - if (mIsKeyguardShowing && mIsActiveDreamLockscreenHosted) { - mView.setVisibility(View.INVISIBLE); - return; - } - - boolean wasShowingFpIcon = mUdfpsEnrolled && !mShowUnlockIcon && !mShowLockIcon - && !mShowAodUnlockedIcon && !mShowAodLockIcon; - mShowLockIcon = !mCanDismissLockScreen && isLockScreen() - && (!mUdfpsEnrolled || !mRunningFPS); - mShowUnlockIcon = mCanDismissLockScreen && isLockScreen(); - mShowAodUnlockedIcon = mIsDozing && mUdfpsEnrolled && !mRunningFPS && mCanDismissLockScreen; - mShowAodLockIcon = mIsDozing && mUdfpsEnrolled && !mRunningFPS && !mCanDismissLockScreen; - - final CharSequence prevContentDescription = mView.getContentDescription(); - if (mShowLockIcon) { - if (wasShowingFpIcon) { - // fp icon was shown by UdfpsView, and now we still want to animate the transition - // in this drawable - mView.updateIcon(ICON_FINGERPRINT, false); - } - mView.updateIcon(ICON_LOCK, false); - mView.setContentDescription(mLockedLabel); - mView.setVisibility(View.VISIBLE); - } else if (mShowUnlockIcon) { - if (wasShowingFpIcon) { - // fp icon was shown by UdfpsView, and now we still want to animate the transition - // in this drawable - mView.updateIcon(ICON_FINGERPRINT, false); - } - mView.updateIcon(ICON_UNLOCK, false); - mView.setContentDescription(mUnlockedLabel); - mView.setVisibility(View.VISIBLE); - } else if (mShowAodUnlockedIcon) { - mView.updateIcon(ICON_UNLOCK, true); - mView.setContentDescription(mUnlockedLabel); - mView.setVisibility(View.VISIBLE); - } else if (mShowAodLockIcon) { - mView.updateIcon(ICON_LOCK, true); - mView.setContentDescription(mLockedLabel); - mView.setVisibility(View.VISIBLE); - } else { - mView.clearIcon(); - mView.setVisibility(View.INVISIBLE); - mView.setContentDescription(null); - } - - boolean accessibilityEnabled = - !mPrimaryBouncerInteractor.isAnimatingAway() && mView.isVisibleToUser(); - mView.setImportantForAccessibility( - accessibilityEnabled ? View.IMPORTANT_FOR_ACCESSIBILITY_YES - : View.IMPORTANT_FOR_ACCESSIBILITY_NO); - - if (!Objects.equals(prevContentDescription, mView.getContentDescription()) - && mView.getContentDescription() != null && accessibilityEnabled) { - mView.announceForAccessibility(mView.getContentDescription()); - } - } - - private boolean isLockScreen() { - return !mIsDozing - && !mIsBouncerShowing - && mStatusBarState == StatusBarState.KEYGUARD; - } - - private void updateKeyguardShowing() { - mIsKeyguardShowing = mKeyguardStateController.isShowing() - && !mKeyguardStateController.isKeyguardGoingAway(); - } - - private void updateColors() { - mView.updateColorAndBackgroundVisibility(); - } - - private void updateConfiguration() { - WindowManager windowManager = mContext.getSystemService(WindowManager.class); - Rect bounds = windowManager.getCurrentWindowMetrics().getBounds(); - mWidthPixels = bounds.right; - if (mFeatureFlags.isEnabled(Flags.LOCKSCREEN_ENABLE_LANDSCAPE)) { - // Assumed to be initially neglected as there are no left or right insets in portrait - // However, on landscape, these insets need to included when calculating the midpoint - WindowInsets insets = windowManager.getCurrentWindowMetrics().getWindowInsets(); - mWidthPixels -= insets.getSystemWindowInsetLeft() + insets.getSystemWindowInsetRight(); - } - mHeightPixels = bounds.bottom; - mBottomPaddingPx = mResources.getDimensionPixelSize(R.dimen.lock_icon_margin_bottom); - mDefaultPaddingPx = mResources.getDimensionPixelSize(R.dimen.lock_icon_padding); - mUnlockedLabel = mResources.getString( - R.string.accessibility_unlock_button); - mLockedLabel = mResources.getString(R.string.accessibility_lock_icon); - updateLockIconLocation(); - } - - private void updateLockIconLocation() { - final float scaleFactor = mAuthController.getScaleFactor(); - final int scaledPadding = (int) (mDefaultPaddingPx * scaleFactor); - if (KeyguardBottomAreaRefactor.isEnabled() || MigrateClocksToBlueprint.isEnabled()) { - // positioning in this case is handled by [DefaultDeviceEntrySection] - mView.getLockIcon().setPadding(scaledPadding, scaledPadding, scaledPadding, - scaledPadding); - } else { - if (mUdfpsSupported) { - mView.setCenterLocation(mAuthController.getUdfpsLocation(), - mAuthController.getUdfpsRadius(), scaledPadding); - } else { - mView.setCenterLocation( - new Point((int) mWidthPixels / 2, - (int) (mHeightPixels - - ((mBottomPaddingPx + sLockIconRadiusPx) * scaleFactor))), - sLockIconRadiusPx * scaleFactor, scaledPadding); - } - } - } - - @Override - public void dump(@NonNull PrintWriter pw, @NonNull String[] args) { - pw.println("mUdfpsSupported: " + mUdfpsSupported); - pw.println("mUdfpsEnrolled: " + mUdfpsEnrolled); - pw.println("mIsKeyguardShowing: " + mIsKeyguardShowing); - pw.println(); - pw.println(" mShowUnlockIcon: " + mShowUnlockIcon); - pw.println(" mShowLockIcon: " + mShowLockIcon); - pw.println(" mShowAodUnlockedIcon: " + mShowAodUnlockedIcon); - pw.println(); - pw.println(" mIsDozing: " + mIsDozing); - pw.println(" isFlagEnabled(DOZING_MIGRATION_1): " - + mFeatureFlags.isEnabled(DOZING_MIGRATION_1)); - pw.println(" mIsBouncerShowing: " + mIsBouncerShowing); - pw.println(" mRunningFPS: " + mRunningFPS); - pw.println(" mCanDismissLockScreen: " + mCanDismissLockScreen); - pw.println(" mStatusBarState: " + StatusBarState.toString(mStatusBarState)); - pw.println(" mInterpolatedDarkAmount: " + mInterpolatedDarkAmount); - pw.println(" mSensorTouchLocation: " + mSensorTouchLocation); - pw.println(" mDefaultPaddingPx: " + mDefaultPaddingPx); - pw.println(" mIsActiveDreamLockscreenHosted: " + mIsActiveDreamLockscreenHosted); - - if (mView != null) { - mView.dump(pw, args); - } - } - - /** Every minute, update the aod icon's burn in offset */ - @Override - 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); - - mView.setTranslationX(offsetX); - mView.setTranslationY(offsetY); - } - - private void updateIsUdfpsEnrolled() { - boolean wasUdfpsSupported = mUdfpsSupported; - boolean wasUdfpsEnrolled = mUdfpsEnrolled; - - mUdfpsSupported = mKeyguardUpdateMonitor.isUdfpsSupported(); - mView.setUseBackground(mUdfpsSupported); - - mUdfpsEnrolled = mKeyguardUpdateMonitor.isUdfpsEnrolled(); - if (wasUdfpsSupported != mUdfpsSupported || wasUdfpsEnrolled != mUdfpsEnrolled) { - updateVisibility(); - } - } - - private StatusBarStateController.StateListener mStatusBarStateListener = - new StatusBarStateController.StateListener() { - @Override - public void onDozeAmountChanged(float linear, float eased) { - if (!mFeatureFlags.isEnabled(DOZING_MIGRATION_1)) { - mInterpolatedDarkAmount = eased; - mView.setDozeAmount(eased); - updateBurnInOffsets(); - } - } - - @Override - public void onDozingChanged(boolean isDozing) { - if (!mFeatureFlags.isEnabled(DOZING_MIGRATION_1)) { - mIsDozing = isDozing; - updateBurnInOffsets(); - updateVisibility(); - } - } - - @Override - public void onStateChanged(int statusBarState) { - mStatusBarState = statusBarState; - updateVisibility(); - } - }; - - private final KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback = - new KeyguardUpdateMonitorCallback() { - @Override - public void onKeyguardBouncerStateChanged(boolean bouncer) { - mIsBouncerShowing = bouncer; - updateVisibility(); - } - - @Override - public void onBiometricRunningStateChanged(boolean running, - BiometricSourceType biometricSourceType) { - final boolean wasRunningFps = mRunningFPS; - - if (biometricSourceType == FINGERPRINT) { - mRunningFPS = running; - } - - if (wasRunningFps != mRunningFPS) { - updateVisibility(); - } - } - }; - - private final KeyguardStateController.Callback mKeyguardStateCallback = - new KeyguardStateController.Callback() { - @Override - public void onUnlockedChanged() { - mCanDismissLockScreen = mKeyguardStateController.canDismissLockScreen(); - updateKeyguardShowing(); - updateVisibility(); - } - - @Override - public void onKeyguardShowingChanged() { - // Reset values in case biometrics were removed (ie: pin/pattern/password => swipe). - // If biometrics were removed, local vars mCanDismissLockScreen and - // mUserUnlockedWithBiometric may not be updated. - mCanDismissLockScreen = mKeyguardStateController.canDismissLockScreen(); - - // reset mIsBouncerShowing state in case it was preemptively set - // onLongPress - mIsBouncerShowing = mKeyguardViewController.isBouncerShowing(); - - updateKeyguardShowing(); - updateVisibility(); - } - - @Override - public void onKeyguardFadingAwayChanged() { - updateKeyguardShowing(); - updateVisibility(); - } - }; - - private final ConfigurationController.ConfigurationListener mConfigurationListener = - new ConfigurationController.ConfigurationListener() { - @Override - public void onUiModeChanged() { - updateColors(); - } - - @Override - public void onThemeChanged() { - updateColors(); - } - - @Override - public void onConfigChanged(Configuration newConfig) { - updateConfiguration(); - updateColors(); - } - }; - - /** - * Handles the touch if {@link #isActionable()} is true. - * Subsequently, will trigger {@link #onLongPress()} if a touch is continuously in the lock icon - * area for {@link #mLongPressTimeout} ms. - * - * Touch speed debouncing mimics logic from the velocity tracker in {@link UdfpsController}. - */ - private boolean onTouchEvent(MotionEvent event) { - if (!actionableDownEventStartedOnView(event)) { - cancelTouches(); - return false; - } - - switch(event.getActionMasked()) { - case MotionEvent.ACTION_DOWN: - case MotionEvent.ACTION_HOVER_ENTER: - if (!mDownDetected && mAccessibilityManager.isTouchExplorationEnabled()) { - vibrateOnTouchExploration(); - } - - // The pointer that causes ACTION_DOWN is always at index 0. - // We need to persist its ID to track it during ACTION_MOVE that could include - // data for many other pointers because of multi-touch support. - mActivePointerId = event.getPointerId(0); - if (mVelocityTracker == null) { - // To simplify the lifecycle of the velocity tracker, make sure it's never null - // after ACTION_DOWN, and always null after ACTION_CANCEL or ACTION_UP. - mVelocityTracker = VelocityTracker.obtain(); - } else { - // ACTION_UP or ACTION_CANCEL is not guaranteed to be called before a new - // ACTION_DOWN, in that case we should just reuse the old instance. - mVelocityTracker.clear(); - } - mVelocityTracker.addMovement(event); - - mDownDetected = true; - mLongPressCancelRunnable = mExecutor.executeDelayed( - this::onLongPress, mLongPressTimeout); - break; - case MotionEvent.ACTION_MOVE: - case MotionEvent.ACTION_HOVER_MOVE: - mVelocityTracker.addMovement(event); - // Compute pointer velocity in pixels per second. - mVelocityTracker.computeCurrentVelocity(1000); - float velocity = computePointerSpeed(mVelocityTracker, - mActivePointerId); - if (event.getClassification() != MotionEvent.CLASSIFICATION_DEEP_PRESS - && exceedsVelocityThreshold(velocity)) { - Log.v(TAG, "lock icon long-press rescheduled due to " - + "high pointer velocity=" + velocity); - mLongPressCancelRunnable.run(); - mLongPressCancelRunnable = mExecutor.executeDelayed( - this::onLongPress, mLongPressTimeout); - } - break; - case MotionEvent.ACTION_UP: - case MotionEvent.ACTION_CANCEL: - case MotionEvent.ACTION_HOVER_EXIT: - cancelTouches(); - break; - } - - return true; - } - - /** - * Calculate the pointer speed given a velocity tracker and the pointer id. - * This assumes that the velocity tracker has already been passed all relevant motion events. - */ - private static float computePointerSpeed(@NonNull VelocityTracker tracker, int pointerId) { - final float vx = tracker.getXVelocity(pointerId); - final float vy = tracker.getYVelocity(pointerId); - return (float) Math.sqrt(Math.pow(vx, 2.0) + Math.pow(vy, 2.0)); - } - - /** - * Whether the velocity exceeds the acceptable UDFPS debouncing threshold. - */ - private static boolean exceedsVelocityThreshold(float velocity) { - return velocity > 750f; - } - - private boolean actionableDownEventStartedOnView(MotionEvent event) { - if (!isActionable()) { - return false; - } - - if (event.getActionMasked() == MotionEvent.ACTION_DOWN) { - return true; - } - - return mDownDetected; - } - - @ExperimentalCoroutinesApi - @VisibleForTesting - protected void onLongPress() { - cancelTouches(); - if (mFalsingManager.isFalseLongTap(FalsingManager.LOW_PENALTY)) { - Log.v(TAG, "lock icon long-press rejected by the falsing manager."); - return; - } - - // pre-emptively set to true to hide view - mIsBouncerShowing = true; - if (!DeviceEntryUdfpsRefactor.isEnabled() - && mUdfpsSupported && mShowUnlockIcon && mAuthRippleController != null) { - mAuthRippleController.showUnlockRipple(FINGERPRINT); - } - updateVisibility(); - - // play device entry haptic (consistent with UDFPS controller longpress) - vibrateOnLongPress(); - - if (SceneContainerFlag.isEnabled()) { - mDeviceEntryInteractor.get().attemptDeviceEntry(); - } else { - mKeyguardViewController.showPrimaryBouncer(/* scrim */ true); - } - } - - - private void cancelTouches() { - mDownDetected = false; - if (mLongPressCancelRunnable != null) { - mLongPressCancelRunnable.run(); - } - if (mVelocityTracker != null) { - mVelocityTracker.recycle(); - mVelocityTracker = null; - } - } - - private boolean isActionable() { - if (mIsBouncerShowing) { - Log.v(TAG, "lock icon long-press ignored, bouncer already showing."); - // a long press gestures from AOD may have already triggered the bouncer to show, - // so this touch is no longer actionable - return false; - } - return mUdfpsSupported || mShowUnlockIcon; - } - - /** - * Set the alpha of this view. - */ - @Override - public void setAlpha(float alpha) { - mView.setAlpha(alpha); - } - - private void updateUdfpsConfig() { - // must be called from the main thread since it may update the views - mExecutor.execute(() -> { - updateIsUdfpsEnrolled(); - updateConfiguration(); - }); - } - - @VisibleForTesting - void vibrateOnTouchExploration() { - mVibrator.performHapticFeedback( - mView, - HapticFeedbackConstants.CONTEXT_CLICK - ); - } - - @VisibleForTesting - void vibrateOnLongPress() { - mVibrator.performHapticFeedback(mView, UdfpsController.LONG_PRESS); - } - - private final AuthController.Callback mAuthControllerCallback = new AuthController.Callback() { - @Override - public void onAllAuthenticatorsRegistered(@BiometricAuthenticator.Modality int modality) { - if (modality == TYPE_FINGERPRINT) { - updateUdfpsConfig(); - } - } - - @Override - public void onEnrollmentsChanged(@BiometricAuthenticator.Modality int modality) { - if (modality == TYPE_FINGERPRINT) { - updateUdfpsConfig(); - } - } - - @Override - public void onUdfpsLocationChanged(UdfpsOverlayParams udfpsOverlayParams) { - updateUdfpsConfig(); - } - }; - - /** - * Whether the lock icon will handle a touch while dozing. - */ - @Override - public boolean willHandleTouchWhileDozing(MotionEvent event) { - // is in lock icon area - mView.getHitRect(mSensorTouchLocation); - final boolean inLockIconArea = - mSensorTouchLocation.contains((int) event.getX(), (int) event.getY()) - && mView.getVisibility() == View.VISIBLE; - - return inLockIconArea && actionableDownEventStartedOnView(event); - } - - private final View.OnClickListener mA11yClickListener = v -> onLongPress(); - - private final AccessibilityManager.AccessibilityStateChangeListener - mAccessibilityStateChangeListener = enabled -> updateAccessibility(); -} diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconView.java b/packages/SystemUI/src/com/android/keyguard/LockIconView.java deleted file mode 100644 index ff6a3d0cc6f0..000000000000 --- a/packages/SystemUI/src/com/android/keyguard/LockIconView.java +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright (C) 2020 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. - */ - -package com.android.keyguard; - -import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.content.res.ColorStateList; -import android.graphics.Color; -import android.graphics.Point; -import android.graphics.Rect; -import android.graphics.RectF; -import android.util.AttributeSet; -import android.view.Gravity; -import android.view.View; -import android.widget.FrameLayout; -import android.widget.ImageView; - -import androidx.annotation.IntDef; -import androidx.annotation.NonNull; - -import com.android.internal.graphics.ColorUtils; -import com.android.settingslib.Utils; -import com.android.systemui.Dumpable; -import com.android.systemui.res.R; - -import java.io.PrintWriter; - -/** - * A view positioned under the notification shade. - */ -public class LockIconView extends FrameLayout implements Dumpable { - @IntDef({ICON_NONE, ICON_LOCK, ICON_FINGERPRINT, ICON_UNLOCK}) - public @interface IconType {} - - public static final int ICON_NONE = -1; - public static final int ICON_LOCK = 0; - public static final int ICON_FINGERPRINT = 1; - public static final int ICON_UNLOCK = 2; - - private @IconType int mIconType; - private boolean mAod; - - @NonNull private final RectF mSensorRect; - @NonNull private Point mLockIconCenter = new Point(0, 0); - private float mRadius; - private int mLockIconPadding; - - private ImageView mLockIcon; - private ImageView mBgView; - - private int mLockIconColor; - private boolean mUseBackground = false; - private float mDozeAmount = 0f; - - @SuppressLint("ClickableViewAccessibility") - public LockIconView(Context context, AttributeSet attrs) { - super(context, attrs); - mSensorRect = new RectF(); - - addBgImageView(context, attrs); - addLockIconImageView(context, attrs); - } - - void setDozeAmount(float dozeAmount) { - mDozeAmount = dozeAmount; - updateColorAndBackgroundVisibility(); - } - - void updateColorAndBackgroundVisibility() { - if (mUseBackground && mLockIcon.getDrawable() != null) { - mLockIconColor = ColorUtils.blendARGB( - Utils.getColorAttrDefaultColor(getContext(), android.R.attr.textColorPrimary), - Color.WHITE, - mDozeAmount); - int backgroundColor = Utils.getColorAttrDefaultColor(getContext(), - com.android.internal.R.attr.colorSurface); - mBgView.setImageTintList(ColorStateList.valueOf(backgroundColor)); - mBgView.setAlpha(1f - mDozeAmount); - mBgView.setVisibility(View.VISIBLE); - } else { - mLockIconColor = ColorUtils.blendARGB( - Utils.getColorAttrDefaultColor(getContext(), R.attr.wallpaperTextColorAccent), - Color.WHITE, - mDozeAmount); - mBgView.setVisibility(View.GONE); - } - - mLockIcon.setImageTintList(ColorStateList.valueOf(mLockIconColor)); - } - - /** - * Whether or not to render the lock icon background. Mainly used for UDPFS. - */ - public void setUseBackground(boolean useBackground) { - mUseBackground = useBackground; - updateColorAndBackgroundVisibility(); - } - - /** - * Set the location of the lock icon. - */ - public void setCenterLocation(@NonNull Point center, float radius, int drawablePadding) { - mLockIconCenter = center; - mRadius = radius; - mLockIconPadding = drawablePadding; - - mLockIcon.setPadding(mLockIconPadding, mLockIconPadding, mLockIconPadding, - mLockIconPadding); - - mSensorRect.set(mLockIconCenter.x - mRadius, - mLockIconCenter.y - mRadius, - mLockIconCenter.x + mRadius, - mLockIconCenter.y + mRadius); - - final FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams(); - if (lp != null) { - lp.width = (int) (mSensorRect.right - mSensorRect.left); - lp.height = (int) (mSensorRect.bottom - mSensorRect.top); - lp.topMargin = (int) mSensorRect.top; - lp.setMarginStart((int) mSensorRect.left); - setLayoutParams(lp); - } - } - - @Override - public boolean hasOverlappingRendering() { - return false; - } - - float getLocationTop() { - Rect r = new Rect(); - mLockIcon.getGlobalVisibleRect(r); - return r.top; - } - - float getLocationBottom() { - Rect r = new Rect(); - mLockIcon.getGlobalVisibleRect(r); - return r.bottom; - - } - - /** - * Updates the icon its default state where no visual is shown. - */ - public void clearIcon() { - updateIcon(ICON_NONE, false); - } - - /** - * Transition the current icon to a new state - * @param icon type (ie: lock icon, unlock icon, fingerprint icon) - * @param aod whether to use the aod icon variant (some icons don't have aod variants and will - * therefore show no icon) - */ - public void updateIcon(@IconType int icon, boolean aod) { - mIconType = icon; - mAod = aod; - - mLockIcon.setImageState(getLockIconState(mIconType, mAod), true); - } - - public ImageView getLockIcon() { - return mLockIcon; - } - - private void addLockIconImageView(Context context, AttributeSet attrs) { - mLockIcon = new ImageView(context, attrs); - mLockIcon.setId(R.id.lock_icon); - mLockIcon.setScaleType(ImageView.ScaleType.CENTER_CROP); - mLockIcon.setImageDrawable(context.getDrawable(R.drawable.super_lock_icon)); - addView(mLockIcon); - LayoutParams lp = (LayoutParams) mLockIcon.getLayoutParams(); - lp.height = MATCH_PARENT; - lp.width = MATCH_PARENT; - lp.gravity = Gravity.CENTER; - mLockIcon.setLayoutParams(lp); - } - - private void addBgImageView(Context context, AttributeSet attrs) { - mBgView = new ImageView(context, attrs); - mBgView.setId(R.id.lock_icon_bg); - mBgView.setImageDrawable(context.getDrawable(R.drawable.fingerprint_bg)); - mBgView.setVisibility(View.INVISIBLE); - addView(mBgView); - LayoutParams lp = (LayoutParams) mBgView.getLayoutParams(); - lp.height = MATCH_PARENT; - lp.width = MATCH_PARENT; - mBgView.setLayoutParams(lp); - } - - private static int[] getLockIconState(@IconType int icon, boolean aod) { - if (icon == ICON_NONE) { - return new int[0]; - } - - int[] lockIconState = new int[2]; - switch (icon) { - case ICON_LOCK: - lockIconState[0] = android.R.attr.state_first; - break; - case ICON_FINGERPRINT: - lockIconState[0] = android.R.attr.state_middle; - break; - case ICON_UNLOCK: - lockIconState[0] = android.R.attr.state_last; - break; - } - - if (aod) { - lockIconState[1] = android.R.attr.state_single; - } else { - lockIconState[1] = -android.R.attr.state_single; - } - - return lockIconState; - } - - private String typeToString(@IconType int type) { - switch (type) { - case ICON_NONE: - return "none"; - case ICON_LOCK: - return "lock"; - case ICON_FINGERPRINT: - return "fingerprint"; - case ICON_UNLOCK: - return "unlock"; - } - - return "invalid"; - } - - @Override - public void dump(@NonNull PrintWriter pw, @NonNull String[] args) { - pw.println("Lock Icon View Parameters:"); - pw.println(" Center in px (x, y)= (" - + mLockIconCenter.x + ", " + mLockIconCenter.y + ")"); - pw.println(" Radius in pixels: " + mRadius); - pw.println(" Drawable padding: " + mLockIconPadding); - pw.println(" mIconType=" + typeToString(mIconType)); - pw.println(" mAod=" + mAod); - pw.println("Lock Icon View actual measurements:"); - pw.println(" topLeft= (" + getX() + ", " + getY() + ")"); - pw.println(" width=" + getWidth() + " height=" + getHeight()); - } -} diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.kt b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.kt index 10d5a0cc3dd5..c5012b01dd3e 100644 --- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.kt +++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.kt @@ -17,13 +17,19 @@ package com.android.keyguard import android.view.MotionEvent +import android.view.View /** Controls the [LockIconView]. */ interface LockIconViewController { - fun setLockIconView(lockIconView: LockIconView) + fun setLockIconView(lockIconView: View) + fun getTop(): Float + fun getBottom(): Float + fun dozeTimeTick() + fun setAlpha(alpha: Float) + fun willHandleTouchWhileDozing(event: MotionEvent): Boolean } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt index c95a94e5e388..f6cc72431db0 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt @@ -37,11 +37,9 @@ import com.android.systemui.biometrics.data.repository.FacePropertyRepository import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams import com.android.systemui.dagger.SysUISingleton import com.android.systemui.deviceentry.domain.interactor.AuthRippleInteractor -import com.android.systemui.deviceentry.shared.DeviceEntryUdfpsRefactor import com.android.systemui.keyguard.WakefulnessLifecycle import com.android.systemui.keyguard.shared.model.BiometricUnlockSource import com.android.systemui.lifecycle.repeatWhenAttached -import com.android.systemui.log.core.LogLevel import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.res.R import com.android.systemui.statusbar.CircleReveal @@ -87,7 +85,7 @@ constructor( private val lightRevealScrim: LightRevealScrim, private val authRippleInteractor: AuthRippleInteractor, private val facePropertyRepository: FacePropertyRepository, - rippleView: AuthRippleView? + rippleView: AuthRippleView?, ) : ViewController<AuthRippleView>(rippleView), CoreStartable, @@ -108,15 +106,13 @@ constructor( } init { - if (DeviceEntryUdfpsRefactor.isEnabled) { - rippleView?.repeatWhenAttached { - repeatOnLifecycle(androidx.lifecycle.Lifecycle.State.CREATED) { - authRippleInteractor.showUnlockRipple.collect { biometricUnlockSource -> - if (biometricUnlockSource == BiometricUnlockSource.FINGERPRINT_SENSOR) { - showUnlockRippleInternal(BiometricSourceType.FINGERPRINT) - } else { - showUnlockRippleInternal(BiometricSourceType.FACE) - } + rippleView?.repeatWhenAttached { + repeatOnLifecycle(androidx.lifecycle.Lifecycle.State.CREATED) { + authRippleInteractor.showUnlockRipple.collect { biometricUnlockSource -> + if (biometricUnlockSource == BiometricUnlockSource.FINGERPRINT_SENSOR) { + showUnlockRippleInternal(BiometricSourceType.FINGERPRINT) + } else { + showUnlockRippleInternal(BiometricSourceType.FACE) } } } @@ -134,29 +130,8 @@ constructor( keyguardStateController.addCallback(this) wakefulnessLifecycle.addObserver(this) commandRegistry.registerCommand("auth-ripple") { AuthRippleCommand() } - if (!DeviceEntryUdfpsRefactor.isEnabled) { - biometricUnlockController.addListener(biometricModeListener) - } } - private val biometricModeListener = - object : BiometricUnlockController.BiometricUnlockEventsListener { - override fun onBiometricUnlockedWithKeyguardDismissal( - biometricSourceType: BiometricSourceType? - ) { - DeviceEntryUdfpsRefactor.assertInLegacyMode() - if (biometricSourceType != null) { - showUnlockRippleInternal(biometricSourceType) - } else { - logger.log( - TAG, - LogLevel.ERROR, - "Unexpected scenario where biometricSourceType is null" - ) - } - } - } - @VisibleForTesting public override fun onViewDetached() { udfpsController?.removeCallback(udfpsControllerCallback) @@ -166,17 +141,10 @@ constructor( keyguardStateController.removeCallback(this) wakefulnessLifecycle.removeObserver(this) commandRegistry.unregisterCommand("auth-ripple") - biometricUnlockController.removeListener(biometricModeListener) notificationShadeWindowController.setForcePluginOpen(false, this) } - @Deprecated("Update authRippleInteractor.showUnlockRipple instead of calling this.") - fun showUnlockRipple(biometricSourceType: BiometricSourceType) { - DeviceEntryUdfpsRefactor.assertInLegacyMode() - showUnlockRippleInternal(biometricSourceType) - } - private fun showUnlockRippleInternal(biometricSourceType: BiometricSourceType) { val keyguardNotShowing = !keyguardStateController.isShowing val unlockNotAllowed = @@ -197,8 +165,8 @@ constructor( 0, Math.max( Math.max(it.x, displayMetrics.widthPixels - it.x), - Math.max(it.y, displayMetrics.heightPixels - it.y) - ) + Math.max(it.y, displayMetrics.heightPixels - it.y), + ), ) logger.showingUnlockRippleAt(it.x, it.y, "FP sensor radius: $udfpsRadius") showUnlockedRipple() @@ -213,8 +181,8 @@ constructor( 0, Math.max( Math.max(it.x, displayMetrics.widthPixels - it.x), - Math.max(it.y, displayMetrics.heightPixels - it.y) - ) + Math.max(it.y, displayMetrics.heightPixels - it.y), + ), ) logger.showingUnlockRippleAt(it.x, it.y, "Face unlock ripple") showUnlockedRipple() @@ -322,7 +290,7 @@ constructor( override fun onBiometricAuthenticated( userId: Int, biometricSourceType: BiometricSourceType, - isStrongBiometric: Boolean + isStrongBiometric: Boolean, ) { if (biometricSourceType == BiometricSourceType.FINGERPRINT) { mView.fadeDwellRipple() @@ -337,7 +305,7 @@ constructor( override fun onBiometricAcquired( biometricSourceType: BiometricSourceType, - acquireInfo: Int + acquireInfo: Int, ) { if ( biometricSourceType == BiometricSourceType.FINGERPRINT && diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt deleted file mode 100644 index 76bcd6e2863b..000000000000 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (C) 2020 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. - */ -package com.android.systemui.biometrics - -import android.content.Context -import android.graphics.Canvas -import android.graphics.Color -import android.graphics.Paint -import android.graphics.Rect -import android.graphics.RectF -import android.util.AttributeSet -import android.util.Log -import android.view.MotionEvent -import android.widget.FrameLayout -import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams -import com.android.systemui.doze.DozeReceiver - -private const val TAG = "UdfpsView" - -/** - * The main view group containing all UDFPS animations. - */ -class UdfpsView( - context: Context, - attrs: AttributeSet? -) : FrameLayout(context, attrs), DozeReceiver { - // sensorRect may be bigger than the sensor. True sensor dimensions are defined in - // overlayParams.sensorBounds - var sensorRect = Rect() - private var mUdfpsDisplayMode: UdfpsDisplayModeProvider? = null - private val debugTextPaint = Paint().apply { - isAntiAlias = true - color = Color.BLUE - textSize = 32f - } - - /** View controller (can be different for enrollment, BiometricPrompt, Keyguard, etc.). */ - var animationViewController: UdfpsAnimationViewController<*>? = null - - /** Parameters that affect the position and size of the overlay. */ - var overlayParams = UdfpsOverlayParams() - - /** Debug message. */ - var debugMessage: String? = null - set(value) { - field = value - postInvalidate() - } - - /** True after the call to [configureDisplay] and before the call to [unconfigureDisplay]. */ - var isDisplayConfigured: Boolean = false - private set - - fun setUdfpsDisplayModeProvider(udfpsDisplayModeProvider: UdfpsDisplayModeProvider?) { - mUdfpsDisplayMode = udfpsDisplayModeProvider - } - - // Don't propagate any touch events to the child views. - override fun onInterceptTouchEvent(ev: MotionEvent): Boolean { - return (animationViewController == null || !animationViewController!!.shouldPauseAuth()) - } - - override fun dozeTimeTick() { - animationViewController?.dozeTimeTick() - } - - override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) { - super.onLayout(changed, left, top, right, bottom) - - // Updates sensor rect in relation to the overlay view - animationViewController?.onSensorRectUpdated(RectF(sensorRect)) - } - - override fun onAttachedToWindow() { - super.onAttachedToWindow() - Log.v(TAG, "onAttachedToWindow") - } - - override fun onDetachedFromWindow() { - super.onDetachedFromWindow() - Log.v(TAG, "onDetachedFromWindow") - } - - override fun onDraw(canvas: Canvas) { - super.onDraw(canvas) - if (!isDisplayConfigured) { - if (!debugMessage.isNullOrEmpty()) { - canvas.drawText(debugMessage!!, 0f, 160f, debugTextPaint) - } - } - } - - fun configureDisplay(onDisplayConfigured: Runnable) { - isDisplayConfigured = true - animationViewController?.onDisplayConfiguring() - mUdfpsDisplayMode?.enable(onDisplayConfigured) - } - - fun unconfigureDisplay() { - isDisplayConfigured = false - animationViewController?.onDisplayUnconfigured() - mUdfpsDisplayMode?.disable(null /* onDisabled */) - } -} diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/FaceHelpMessageDeferralInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/FaceHelpMessageDeferralInteractor.kt index ffe392a52c9f..88daa5de8816 100644 --- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/FaceHelpMessageDeferralInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/FaceHelpMessageDeferralInteractor.kt @@ -21,7 +21,6 @@ import android.hardware.face.FaceManager import com.android.systemui.biometrics.FaceHelpMessageDeferralFactory import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application -import com.android.systemui.deviceentry.shared.DeviceEntryUdfpsRefactor import com.android.systemui.deviceentry.shared.model.AcquiredFaceAuthenticationStatus import com.android.systemui.deviceentry.shared.model.HelpFaceAuthenticationStatus import javax.inject.Inject @@ -55,9 +54,7 @@ constructor( faceAuthInteractor.authenticationStatus.filterIsInstance<HelpFaceAuthenticationStatus>() init { - if (DeviceEntryUdfpsRefactor.isEnabled) { - startUpdatingFaceHelpMessageDeferral() - } + startUpdatingFaceHelpMessageDeferral() } /** diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/shared/DeviceEntryUdfpsRefactor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/shared/DeviceEntryUdfpsRefactor.kt deleted file mode 100644 index b5d5803ca6fb..000000000000 --- a/packages/SystemUI/src/com/android/systemui/deviceentry/shared/DeviceEntryUdfpsRefactor.kt +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2023 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. - */ - -package com.android.systemui.deviceentry.shared - -import com.android.systemui.Flags -import com.android.systemui.flags.FlagToken -import com.android.systemui.flags.RefactorFlagUtils - -/** Helper for reading or using the device entry udfps refactor flag state. */ -@Suppress("NOTHING_TO_INLINE") -object DeviceEntryUdfpsRefactor { - /** The aconfig flag name */ - const val FLAG_NAME = Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR - - /** A token used for dependency declaration */ - val token: FlagToken - get() = FlagToken(FLAG_NAME, isEnabled) - - /** Is the refactor enabled */ - @JvmStatic - inline val isEnabled - get() = Flags.deviceEntryUdfpsRefactor() - - /** - * Called to ensure code is only run when the flag is enabled. This protects users from the - * unintended behaviors caused by accidentally running new logic, while also crashing on an eng - * build to ensure that the refactor author catches issues in testing. - */ - @JvmStatic - inline fun isUnexpectedlyInLegacyMode() = - RefactorFlagUtils.isUnexpectedlyInLegacyMode(isEnabled, FLAG_NAME) - - /** - * Called to ensure code is only run when the flag is disabled. This will throw an exception if - * the flag is enabled to ensure that the refactor author catches issues in testing. - */ - @JvmStatic - inline fun assertInLegacyMode() = RefactorFlagUtils.assertInLegacyMode(isEnabled, FLAG_NAME) -} diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockViewBinder.kt index 2d225562081a..e52ba4f8a51b 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockViewBinder.kt @@ -129,15 +129,19 @@ object KeyguardPreviewClockViewBinder { constrainMaxHeight(customR.id.lockscreen_clock_view_large, 0) val largeClockTopMargin = SystemBarUtils.getStatusBarHeight(context) + - context.resources.getDimensionPixelSize( - customR.dimen.small_clock_padding_top - ) + + context.resources.getDimensionPixelSize(customR.dimen.small_clock_padding_top) + context.resources.getDimensionPixelSize( R.dimen.keyguard_smartspace_top_offset ) + getDimen(context, DATE_WEATHER_VIEW_HEIGHT) + getDimen(context, ENHANCED_SMARTSPACE_HEIGHT) - connect(customR.id.lockscreen_clock_view_large, TOP, PARENT_ID, TOP, largeClockTopMargin) + connect( + customR.id.lockscreen_clock_view_large, + TOP, + PARENT_ID, + TOP, + largeClockTopMargin, + ) connect(customR.id.lockscreen_clock_view_large, START, PARENT_ID, START) connect( customR.id.lockscreen_clock_view_large, @@ -146,12 +150,11 @@ object KeyguardPreviewClockViewBinder { ConstraintSet.END, ) - // In preview, we'll show UDFPS icon for UDFPS devices and nothing for non-UDFPS // devices, but we need position of device entry icon to constrain clock if (getConstraint(lockId) != null) { connect(customR.id.lockscreen_clock_view_large, BOTTOM, lockId, TOP) - } else { + } else { // Copied calculation codes from applyConstraints in DefaultDeviceEntrySection val bottomPaddingPx = context.resources.getDimensionPixelSize(R.dimen.lock_icon_margin_bottom) diff --git a/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlag.kt b/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlag.kt index 7b6b0f614cc2..6097ef53f8df 100644 --- a/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlag.kt +++ b/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlag.kt @@ -20,7 +20,6 @@ package com.android.systemui.scene.shared.flag import com.android.systemui.Flags.FLAG_SCENE_CONTAINER import com.android.systemui.Flags.sceneContainer -import com.android.systemui.deviceentry.shared.DeviceEntryUdfpsRefactor import com.android.systemui.flags.FlagToken import com.android.systemui.flags.RefactorFlagUtils import com.android.systemui.keyguard.KeyguardBottomAreaRefactor @@ -42,8 +41,7 @@ object SceneContainerFlag { KeyguardWmStateRefactor.isEnabled && MigrateClocksToBlueprint.isEnabled && NotificationThrottleHun.isEnabled && - PredictiveBackSysUiFlag.isEnabled && - DeviceEntryUdfpsRefactor.isEnabled + PredictiveBackSysUiFlag.isEnabled // NOTE: Changes should also be made in getSecondaryFlags and @EnableSceneContainer @@ -58,7 +56,6 @@ object SceneContainerFlag { MigrateClocksToBlueprint.token, NotificationThrottleHun.token, PredictiveBackSysUiFlag.token, - DeviceEntryUdfpsRefactor.token, // NOTE: Changes should also be made in isEnabled and @EnableSceneContainer ) diff --git a/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerBaseTest.java deleted file mode 100644 index c51aa04fc7b6..000000000000 --- a/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerBaseTest.java +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright (C) 2022 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. - */ - -package com.android.keyguard; - -import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; -import static com.android.systemui.flags.Flags.DOZING_MIGRATION_1; -import static com.android.systemui.flags.Flags.LOCKSCREEN_ENABLE_LANDSCAPE; -import static com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED; - -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.anyInt; -import static org.mockito.Mockito.reset; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.content.Context; -import android.content.res.Resources; -import android.graphics.Point; -import android.graphics.Rect; -import android.graphics.drawable.AnimatedStateListDrawable; -import android.util.Pair; -import android.view.View; -import android.view.WindowManager; -import android.view.accessibility.AccessibilityManager; -import android.widget.ImageView; - -import com.android.systemui.Flags; -import com.android.systemui.SysuiTestCase; -import com.android.systemui.biometrics.AuthController; -import com.android.systemui.biometrics.AuthRippleController; -import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor; -import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor; -import com.android.systemui.doze.util.BurnInHelperKt; -import com.android.systemui.dump.DumpManager; -import com.android.systemui.flags.FakeFeatureFlags; -import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory; -import com.android.systemui.kosmos.KosmosJavaAdapter; -import com.android.systemui.plugins.FalsingManager; -import com.android.systemui.plugins.statusbar.StatusBarStateController; -import com.android.systemui.res.R; -import com.android.systemui.scene.shared.flag.SceneContainerFlag; -import com.android.systemui.statusbar.StatusBarState; -import com.android.systemui.statusbar.VibratorHelper; -import com.android.systemui.statusbar.policy.ConfigurationController; -import com.android.systemui.statusbar.policy.KeyguardStateController; -import com.android.systemui.util.concurrency.FakeExecutor; -import com.android.systemui.util.time.FakeSystemClock; - -import org.junit.After; -import org.junit.Before; -import org.mockito.Answers; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.mockito.MockitoSession; -import org.mockito.quality.Strictness; - -public class LegacyLockIconViewControllerBaseTest extends SysuiTestCase { - protected static final String UNLOCKED_LABEL = "unlocked"; - protected static final String LOCKED_LABEL = "locked"; - protected static final int PADDING = 10; - - protected MockitoSession mStaticMockSession; - - protected final KosmosJavaAdapter mKosmos = new KosmosJavaAdapter(this); - protected @Mock DeviceEntryInteractor mDeviceEntryInteractor; - protected @Mock LockIconView mLockIconView; - protected @Mock ImageView mLockIcon; - protected @Mock AnimatedStateListDrawable mIconDrawable; - protected @Mock Context mContext; - protected @Mock Resources mResources; - protected @Mock(answer = Answers.RETURNS_DEEP_STUBS) WindowManager mWindowManager; - protected @Mock StatusBarStateController mStatusBarStateController; - protected @Mock KeyguardUpdateMonitor mKeyguardUpdateMonitor; - protected @Mock KeyguardViewController mKeyguardViewController; - protected @Mock KeyguardStateController mKeyguardStateController; - protected @Mock FalsingManager mFalsingManager; - protected @Mock AuthController mAuthController; - protected @Mock DumpManager mDumpManager; - protected @Mock AccessibilityManager mAccessibilityManager; - protected @Mock ConfigurationController mConfigurationController; - protected @Mock VibratorHelper mVibrator; - protected @Mock AuthRippleController mAuthRippleController; - protected FakeExecutor mDelayableExecutor = new FakeExecutor(new FakeSystemClock()); - protected FakeFeatureFlags mFeatureFlags; - - protected @Mock PrimaryBouncerInteractor mPrimaryBouncerInteractor; - - protected LegacyLockIconViewController mUnderTest; - - // Capture listeners so that they can be used to send events - @Captor protected ArgumentCaptor<View.OnAttachStateChangeListener> mAttachCaptor = - ArgumentCaptor.forClass(View.OnAttachStateChangeListener.class); - - @Captor protected ArgumentCaptor<KeyguardStateController.Callback> mKeyguardStateCaptor = - ArgumentCaptor.forClass(KeyguardStateController.Callback.class); - protected KeyguardStateController.Callback mKeyguardStateCallback; - - @Captor protected ArgumentCaptor<StatusBarStateController.StateListener> mStatusBarStateCaptor = - ArgumentCaptor.forClass(StatusBarStateController.StateListener.class); - protected StatusBarStateController.StateListener mStatusBarStateListener; - - @Captor protected ArgumentCaptor<AuthController.Callback> mAuthControllerCallbackCaptor; - protected AuthController.Callback mAuthControllerCallback; - - @Captor protected ArgumentCaptor<KeyguardUpdateMonitorCallback> - mKeyguardUpdateMonitorCallbackCaptor = - ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback.class); - protected KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback; - - @Captor protected ArgumentCaptor<Point> mPointCaptor; - - @Before - public void setUp() throws Exception { - mStaticMockSession = mockitoSession() - .mockStatic(BurnInHelperKt.class) - .strictness(Strictness.LENIENT) - .startMocking(); - MockitoAnnotations.initMocks(this); - - setupLockIconViewMocks(); - when(mContext.getResources()).thenReturn(mResources); - when(mContext.getSystemService(WindowManager.class)).thenReturn(mWindowManager); - Rect windowBounds = new Rect(0, 0, 800, 1200); - when(mWindowManager.getCurrentWindowMetrics().getBounds()).thenReturn(windowBounds); - when(mResources.getString(R.string.accessibility_unlock_button)).thenReturn(UNLOCKED_LABEL); - when(mResources.getString(R.string.accessibility_lock_icon)).thenReturn(LOCKED_LABEL); - when(mResources.getDrawable(anyInt(), any())).thenReturn(mIconDrawable); - when(mResources.getDimensionPixelSize(R.dimen.lock_icon_padding)).thenReturn(PADDING); - when(mAuthController.getScaleFactor()).thenReturn(1f); - - when(mKeyguardStateController.isShowing()).thenReturn(true); - when(mKeyguardStateController.isKeyguardGoingAway()).thenReturn(false); - when(mStatusBarStateController.isDozing()).thenReturn(false); - when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD); - - if (!SceneContainerFlag.isEnabled()) { - mSetFlagsRule.disableFlags(Flags.FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR); - //TODO move this to use @DisableFlags annotation if needed - mSetFlagsRule.disableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT); - } - - mFeatureFlags = new FakeFeatureFlags(); - mFeatureFlags.set(LOCKSCREEN_WALLPAPER_DREAM_ENABLED, false); - mFeatureFlags.set(LOCKSCREEN_ENABLE_LANDSCAPE, false); - - mUnderTest = new LegacyLockIconViewController( - mStatusBarStateController, - mKeyguardUpdateMonitor, - mKeyguardViewController, - mKeyguardStateController, - mFalsingManager, - mAuthController, - mDumpManager, - mAccessibilityManager, - mConfigurationController, - mDelayableExecutor, - mVibrator, - mAuthRippleController, - mResources, - mKosmos.getKeyguardTransitionInteractor(), - KeyguardInteractorFactory.create(mFeatureFlags).getKeyguardInteractor(), - mFeatureFlags, - mPrimaryBouncerInteractor, - mContext, - () -> mDeviceEntryInteractor - ); - } - - @After - public void tearDown() { - mStaticMockSession.finishMocking(); - } - - protected Pair<Float, Point> setupUdfps() { - when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(true); - final Point udfpsLocation = new Point(50, 75); - final float radius = 33f; - when(mAuthController.getUdfpsLocation()).thenReturn(udfpsLocation); - when(mAuthController.getUdfpsRadius()).thenReturn(radius); - - return new Pair(radius, udfpsLocation); - } - - protected void setupShowLockIcon() { - when(mKeyguardStateController.isShowing()).thenReturn(true); - when(mKeyguardStateController.isKeyguardGoingAway()).thenReturn(false); - when(mStatusBarStateController.isDozing()).thenReturn(false); - when(mStatusBarStateController.getDozeAmount()).thenReturn(0f); - when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD); - when(mKeyguardStateController.canDismissLockScreen()).thenReturn(false); - } - - protected void captureAuthControllerCallback() { - verify(mAuthController).addCallback(mAuthControllerCallbackCaptor.capture()); - mAuthControllerCallback = mAuthControllerCallbackCaptor.getValue(); - } - - protected void captureKeyguardStateCallback() { - verify(mKeyguardStateController).addCallback(mKeyguardStateCaptor.capture()); - mKeyguardStateCallback = mKeyguardStateCaptor.getValue(); - } - - protected void captureStatusBarStateListener() { - verify(mStatusBarStateController).addCallback(mStatusBarStateCaptor.capture()); - mStatusBarStateListener = mStatusBarStateCaptor.getValue(); - } - - protected void captureKeyguardUpdateMonitorCallback() { - verify(mKeyguardUpdateMonitor).registerCallback( - mKeyguardUpdateMonitorCallbackCaptor.capture()); - mKeyguardUpdateMonitorCallback = mKeyguardUpdateMonitorCallbackCaptor.getValue(); - } - - protected void setupLockIconViewMocks() { - when(mLockIconView.getResources()).thenReturn(mResources); - when(mLockIconView.getContext()).thenReturn(mContext); - when(mLockIconView.getLockIcon()).thenReturn(mLockIcon); - } - - protected void resetLockIconView() { - reset(mLockIconView); - setupLockIconViewMocks(); - } - - protected void init(boolean useDozeMigrationFlag) { - mFeatureFlags.set(DOZING_MIGRATION_1, useDozeMigrationFlag); - mUnderTest.setLockIconView(mLockIconView); - } -} diff --git a/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerTest.java deleted file mode 100644 index c1ba39e89cf9..000000000000 --- a/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerTest.java +++ /dev/null @@ -1,414 +0,0 @@ -/* - * 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. - */ - -package com.android.keyguard; - -import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT; - -import static com.android.keyguard.LockIconView.ICON_LOCK; -import static com.android.keyguard.LockIconView.ICON_UNLOCK; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.anyBoolean; -import static org.mockito.Mockito.anyInt; -import static org.mockito.Mockito.eq; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.reset; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.graphics.Point; -import android.hardware.biometrics.BiometricSourceType; -import android.testing.TestableLooper; -import android.util.Pair; -import android.view.HapticFeedbackConstants; -import android.view.View; - -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.filters.SmallTest; - -import com.android.systemui.biometrics.UdfpsController; -import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams; -import com.android.systemui.doze.util.BurnInHelperKt; -import com.android.systemui.flags.EnableSceneContainer; -import com.android.systemui.statusbar.StatusBarState; - -import org.junit.Test; -import org.junit.runner.RunWith; - -@SmallTest -@RunWith(AndroidJUnit4.class) -@TestableLooper.RunWithLooper -public class LegacyLockIconViewControllerTest extends LegacyLockIconViewControllerBaseTest { - - @Override - public void setUp() throws Exception { - super.setUp(); - when(mLockIconView.isAttachedToWindow()).thenReturn(true); - } - - @Test - public void testUpdateFingerprintLocationOnInit() { - // GIVEN fp sensor location is available pre-attached - Pair<Float, Point> udfps = setupUdfps(); // first = radius, second = udfps location - - // WHEN lock icon view controller is initialized and attached - init(/* useMigrationFlag= */false); - - // THEN lock icon view location is updated to the udfps location with UDFPS radius - verify(mLockIconView).setCenterLocation(eq(udfps.second), eq(udfps.first), - eq(PADDING)); - } - - @Test - public void testUpdatePaddingBasedOnResolutionScale() { - // GIVEN fp sensor location is available pre-attached & scaled resolution factor is 5 - Pair<Float, Point> udfps = setupUdfps(); // first = radius, second = udfps location - when(mAuthController.getScaleFactor()).thenReturn(5f); - - // WHEN lock icon view controller is initialized and attached - init(/* useMigrationFlag= */false); - - // THEN lock icon view location is updated with the scaled radius - verify(mLockIconView).setCenterLocation(eq(udfps.second), eq(udfps.first), - eq(PADDING * 5)); - } - - @Test - public void testUpdateLockIconLocationOnAuthenticatorsRegistered() { - // GIVEN fp sensor location is not available pre-init - when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(false); - when(mAuthController.getFingerprintSensorLocation()).thenReturn(null); - init(/* useMigrationFlag= */false); - resetLockIconView(); // reset any method call counts for when we verify method calls later - - // GIVEN fp sensor location is available post-attached - captureAuthControllerCallback(); - Pair<Float, Point> udfps = setupUdfps(); - - // WHEN all authenticators are registered - mAuthControllerCallback.onAllAuthenticatorsRegistered(TYPE_FINGERPRINT); - mDelayableExecutor.runAllReady(); - - // THEN lock icon view location is updated with the same coordinates as auth controller vals - verify(mLockIconView).setCenterLocation(eq(udfps.second), eq(udfps.first), - eq(PADDING)); - } - - @Test - public void testUpdateLockIconLocationOnUdfpsLocationChanged() { - // GIVEN fp sensor location is not available pre-init - when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(false); - when(mAuthController.getFingerprintSensorLocation()).thenReturn(null); - init(/* useMigrationFlag= */false); - resetLockIconView(); // reset any method call counts for when we verify method calls later - - // GIVEN fp sensor location is available post-attached - captureAuthControllerCallback(); - Pair<Float, Point> udfps = setupUdfps(); - - // WHEN udfps location changes - mAuthControllerCallback.onUdfpsLocationChanged(new UdfpsOverlayParams()); - mDelayableExecutor.runAllReady(); - - // THEN lock icon view location is updated with the same coordinates as auth controller vals - verify(mLockIconView).setCenterLocation(eq(udfps.second), eq(udfps.first), - eq(PADDING)); - } - - @Test - public void testLockIconViewBackgroundEnabledWhenUdfpsIsSupported() { - // GIVEN Udpfs sensor location is available - setupUdfps(); - - // WHEN the view is attached - init(/* useMigrationFlag= */false); - - // THEN the lock icon view background should be enabled - verify(mLockIconView).setUseBackground(true); - } - - @Test - public void testLockIconViewBackgroundDisabledWhenUdfpsIsNotSupported() { - // GIVEN Udfps sensor location is not supported - when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(false); - - // WHEN the view is attached - init(/* useMigrationFlag= */false); - - // THEN the lock icon view background should be disabled - verify(mLockIconView).setUseBackground(false); - } - - @Test - public void testLockIconStartState() { - // GIVEN lock icon state - setupShowLockIcon(); - - // WHEN lock icon controller is initialized - init(/* useMigrationFlag= */false); - - // THEN the lock icon should show - verify(mLockIconView).updateIcon(ICON_LOCK, false); - } - - @Test - public void testLockIcon_updateToUnlock() { - // GIVEN starting state for the lock icon - setupShowLockIcon(); - - // GIVEN lock icon controller is initialized and view is attached - init(/* useMigrationFlag= */false); - captureKeyguardStateCallback(); - reset(mLockIconView); - - // WHEN the unlocked state changes to canDismissLockScreen=true - when(mKeyguardStateController.canDismissLockScreen()).thenReturn(true); - mKeyguardStateCallback.onUnlockedChanged(); - - // THEN the unlock should show - verify(mLockIconView).updateIcon(ICON_UNLOCK, false); - } - - @Test - public void testLockIcon_clearsIconWhenUnlocked() { - // GIVEN udfps not enrolled - setupUdfps(); - when(mKeyguardUpdateMonitor.isUdfpsEnrolled()).thenReturn(false); - - // GIVEN starting state for the lock icon - setupShowLockIcon(); - when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE); - - // GIVEN lock icon controller is initialized and view is attached - init(/* useMigrationFlag= */false); - captureStatusBarStateListener(); - reset(mLockIconView); - - // WHEN the dozing state changes - mStatusBarStateListener.onDozingChanged(false /* isDozing */); - - // THEN the icon is cleared - verify(mLockIconView).clearIcon(); - } - - @Test - public void testLockIcon_updateToAodLock_whenUdfpsEnrolled() { - // GIVEN udfps enrolled - setupUdfps(); - when(mKeyguardUpdateMonitor.isUdfpsEnrolled()).thenReturn(true); - - // GIVEN starting state for the lock icon - setupShowLockIcon(); - - // GIVEN lock icon controller is initialized and view is attached - init(/* useMigrationFlag= */false); - captureStatusBarStateListener(); - reset(mLockIconView); - - // WHEN the dozing state changes - mStatusBarStateListener.onDozingChanged(true /* isDozing */); - - // THEN the AOD lock icon should show - verify(mLockIconView).updateIcon(ICON_LOCK, true); - } - - @Test - public void testBurnInOffsetsUpdated_onDozeAmountChanged() { - // GIVEN udfps enrolled - setupUdfps(); - when(mKeyguardUpdateMonitor.isUdfpsEnrolled()).thenReturn(true); - - // GIVEN burn-in offset = 5 - int burnInOffset = 5; - when(BurnInHelperKt.getBurnInOffset(anyInt(), anyBoolean())).thenReturn(burnInOffset); - - // GIVEN starting state for the lock icon (keyguard) - setupShowLockIcon(); - init(/* useMigrationFlag= */false); - captureStatusBarStateListener(); - reset(mLockIconView); - - // WHEN dozing updates - mStatusBarStateListener.onDozingChanged(true /* isDozing */); - mStatusBarStateListener.onDozeAmountChanged(1f, 1f); - - // THEN the view's translation is updated to use the AoD burn-in offsets - verify(mLockIconView).setTranslationY(burnInOffset); - verify(mLockIconView).setTranslationX(burnInOffset); - reset(mLockIconView); - - // WHEN the device is no longer dozing - mStatusBarStateListener.onDozingChanged(false /* isDozing */); - mStatusBarStateListener.onDozeAmountChanged(0f, 0f); - - // THEN the view is updated to NO translation (no burn-in offsets anymore) - verify(mLockIconView).setTranslationY(0); - verify(mLockIconView).setTranslationX(0); - } - - @Test - public void lockIconShows_afterUnlockStateChanges() { - // GIVEN lock icon controller is initialized and view is attached - init(/* useMigrationFlag= */false); - captureKeyguardStateCallback(); - captureKeyguardUpdateMonitorCallback(); - - // GIVEN user has unlocked with a biometric auth (ie: face auth) - // and biometric running state changes - when(mKeyguardUpdateMonitor.getUserUnlockedWithBiometric(anyInt())).thenReturn(true); - mKeyguardUpdateMonitorCallback.onBiometricRunningStateChanged(false, - BiometricSourceType.FACE); - reset(mLockIconView); - - // WHEN the unlocked state changes - when(mKeyguardUpdateMonitor.getUserUnlockedWithBiometric(anyInt())).thenReturn(false); - mKeyguardStateCallback.onUnlockedChanged(); - - // THEN the lock icon is shown - verify(mLockIconView).setContentDescription(LOCKED_LABEL); - } - - @Test - public void lockIconAccessibility_notVisibleToUser() { - // GIVEN lock icon controller is initialized and view is attached - init(/* useMigrationFlag= */false); - captureKeyguardStateCallback(); - captureKeyguardUpdateMonitorCallback(); - - // GIVEN user has unlocked with a biometric auth (ie: face auth) - // and biometric running state changes - when(mKeyguardUpdateMonitor.getUserUnlockedWithBiometric(anyInt())).thenReturn(true); - mKeyguardUpdateMonitorCallback.onBiometricRunningStateChanged(false, - BiometricSourceType.FACE); - reset(mLockIconView); - when(mLockIconView.isVisibleToUser()).thenReturn(false); - - // WHEN the unlocked state changes - when(mKeyguardUpdateMonitor.getUserUnlockedWithBiometric(anyInt())).thenReturn(false); - mKeyguardStateCallback.onUnlockedChanged(); - - // THEN the lock icon is shown - verify(mLockIconView).setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO); - } - - @Test - public void lockIconAccessibility_bouncerAnimatingAway() { - // GIVEN lock icon controller is initialized and view is attached - init(/* useMigrationFlag= */false); - captureKeyguardStateCallback(); - captureKeyguardUpdateMonitorCallback(); - - // GIVEN user has unlocked with a biometric auth (ie: face auth) - // and biometric running state changes - when(mKeyguardUpdateMonitor.getUserUnlockedWithBiometric(anyInt())).thenReturn(true); - mKeyguardUpdateMonitorCallback.onBiometricRunningStateChanged(false, - BiometricSourceType.FACE); - reset(mLockIconView); - when(mLockIconView.isVisibleToUser()).thenReturn(true); - when(mPrimaryBouncerInteractor.isAnimatingAway()).thenReturn(true); - - // WHEN the unlocked state changes - when(mKeyguardUpdateMonitor.getUserUnlockedWithBiometric(anyInt())).thenReturn(false); - mKeyguardStateCallback.onUnlockedChanged(); - - // THEN the lock icon is shown - verify(mLockIconView).setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO); - } - - @Test - public void lockIconAccessibility_bouncerNotAnimatingAway_viewVisible() { - // GIVEN lock icon controller is initialized and view is attached - init(/* useMigrationFlag= */false); - captureKeyguardStateCallback(); - captureKeyguardUpdateMonitorCallback(); - - // GIVEN user has unlocked with a biometric auth (ie: face auth) - // and biometric running state changes - when(mKeyguardUpdateMonitor.getUserUnlockedWithBiometric(anyInt())).thenReturn(true); - mKeyguardUpdateMonitorCallback.onBiometricRunningStateChanged(false, - BiometricSourceType.FACE); - reset(mLockIconView); - when(mLockIconView.isVisibleToUser()).thenReturn(true); - when(mPrimaryBouncerInteractor.isAnimatingAway()).thenReturn(false); - - // WHEN the unlocked state changes - when(mKeyguardUpdateMonitor.getUserUnlockedWithBiometric(anyInt())).thenReturn(false); - mKeyguardStateCallback.onUnlockedChanged(); - - // THEN the lock icon is shown - verify(mLockIconView).setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES); - } - - @Test - public void playHaptic_onTouchExploration_performHapticFeedback() { - // WHEN request to vibrate on touch exploration - mUnderTest.vibrateOnTouchExploration(); - - // THEN performHapticFeedback is used - verify(mVibrator).performHapticFeedback(any(), eq(HapticFeedbackConstants.CONTEXT_CLICK)); - } - - @Test - public void playHaptic_onLongPress_performHapticFeedback() { - // WHEN request to vibrate on long press - mUnderTest.vibrateOnLongPress(); - - // THEN uses perform haptic feedback - verify(mVibrator).performHapticFeedback(any(), eq(UdfpsController.LONG_PRESS)); - } - - @Test - public void longPress_showBouncer_sceneContainerNotEnabled() { - init(/* useMigrationFlag= */ false); - when(mFalsingManager.isFalseLongTap(anyInt())).thenReturn(false); - - // WHEN longPress - mUnderTest.onLongPress(); - - // THEN show primary bouncer via keyguard view controller, not scene container - verify(mKeyguardViewController).showPrimaryBouncer(anyBoolean()); - verify(mDeviceEntryInteractor, never()).attemptDeviceEntry(); - } - - @Test - @EnableSceneContainer - public void longPress_showBouncer() { - init(/* useMigrationFlag= */ false); - when(mFalsingManager.isFalseLongTap(anyInt())).thenReturn(false); - - // WHEN longPress - mUnderTest.onLongPress(); - - // THEN show primary bouncer - verify(mKeyguardViewController, never()).showPrimaryBouncer(anyBoolean()); - verify(mDeviceEntryInteractor).attemptDeviceEntry(); - } - - @Test - @EnableSceneContainer - public void longPress_falsingTriggered_doesNotShowBouncer() { - init(/* useMigrationFlag= */ false); - when(mFalsingManager.isFalseLongTap(anyInt())).thenReturn(true); - - // WHEN longPress - mUnderTest.onLongPress(); - - // THEN don't show primary bouncer - verify(mDeviceEntryInteractor, never()).attemptDeviceEntry(); - verify(mKeyguardViewController, never()).showPrimaryBouncer(anyBoolean()); - } -} diff --git a/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerWithCoroutinesTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerWithCoroutinesTest.kt deleted file mode 100644 index 2fd3cb0f0592..000000000000 --- a/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerWithCoroutinesTest.kt +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (C) 2022 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. - */ - -package com.android.keyguard - -import android.view.View -import androidx.test.ext.junit.runners.AndroidJUnit4 -import androidx.test.filters.SmallTest -import com.android.keyguard.LockIconView.ICON_LOCK -import com.android.systemui.doze.util.getBurnInOffset -import com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED -import com.android.systemui.statusbar.StatusBarState -import com.android.systemui.util.mockito.whenever -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.runBlocking -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.Mockito.anyBoolean -import org.mockito.Mockito.anyInt -import org.mockito.Mockito.reset -import org.mockito.Mockito.verify - -@RunWith(AndroidJUnit4::class) -@SmallTest -class LegacyLockIconViewControllerWithCoroutinesTest : LegacyLockIconViewControllerBaseTest() { - - /** After migration, replaces LockIconViewControllerTest version */ - @Test - fun testLockIcon_clearsIconWhenUnlocked() = - runBlocking(IMMEDIATE) { - // GIVEN udfps not enrolled - setupUdfps() - whenever(mKeyguardUpdateMonitor.isUdfpsEnrolled()).thenReturn(false) - - // GIVEN starting state for the lock icon - setupShowLockIcon() - whenever(mStatusBarStateController.state).thenReturn(StatusBarState.SHADE) - - // GIVEN lock icon controller is initialized and view is attached - init(/* useMigrationFlag= */ true) - reset(mLockIconView) - - // WHEN the dozing state changes - mUnderTest.mIsDozingCallback.accept(false) - // THEN the icon is cleared - verify(mLockIconView).clearIcon() - } - - /** After migration, replaces LockIconViewControllerTest version */ - @Test - fun testLockIcon_updateToAodLock_whenUdfpsEnrolled() = - runBlocking(IMMEDIATE) { - // GIVEN udfps enrolled - setupUdfps() - whenever(mKeyguardUpdateMonitor.isUdfpsEnrolled()).thenReturn(true) - - // GIVEN starting state for the lock icon - setupShowLockIcon() - - // GIVEN lock icon controller is initialized and view is attached - init(/* useMigrationFlag= */ true) - reset(mLockIconView) - - // WHEN the dozing state changes - mUnderTest.mIsDozingCallback.accept(true) - - // THEN the AOD lock icon should show - verify(mLockIconView).updateIcon(ICON_LOCK, true) - } - - /** After migration, replaces LockIconViewControllerTest version */ - @Test - fun testBurnInOffsetsUpdated_onDozeAmountChanged() = - runBlocking(IMMEDIATE) { - // GIVEN udfps enrolled - setupUdfps() - whenever(mKeyguardUpdateMonitor.isUdfpsEnrolled()).thenReturn(true) - - // GIVEN burn-in offset = 5 - val burnInOffset = 5 - whenever(getBurnInOffset(anyInt(), anyBoolean())).thenReturn(burnInOffset) - - // GIVEN starting state for the lock icon (keyguard) - setupShowLockIcon() - init(/* useMigrationFlag= */ true) - reset(mLockIconView) - - // WHEN dozing updates - mUnderTest.mIsDozingCallback.accept(true) - mUnderTest.mDozeTransitionCallback.accept(1f) - - // THEN the view's translation is updated to use the AoD burn-in offsets - verify(mLockIconView).setTranslationY(burnInOffset.toFloat()) - verify(mLockIconView).setTranslationX(burnInOffset.toFloat()) - reset(mLockIconView) - - // WHEN the device is no longer dozing - mUnderTest.mIsDozingCallback.accept(false) - mUnderTest.mDozeTransitionCallback.accept(0f) - - // THEN the view is updated to NO translation (no burn-in offsets anymore) - verify(mLockIconView).setTranslationY(0f) - verify(mLockIconView).setTranslationX(0f) - } - - @Test - fun testHideLockIconView_onLockscreenHostedDreamStateChanged() = - runBlocking(IMMEDIATE) { - // GIVEN starting state for the lock icon (keyguard) and wallpaper dream enabled - mFeatureFlags.set(LOCKSCREEN_WALLPAPER_DREAM_ENABLED, true) - setupShowLockIcon() - init(/* useMigrationFlag= */ true) - reset(mLockIconView) - - // WHEN dream starts - mUnderTest.mIsActiveDreamLockscreenHostedCallback.accept( - true /* isActiveDreamLockscreenHosted */ - ) - - // THEN the lock icon is hidden - verify(mLockIconView).visibility = View.INVISIBLE - reset(mLockIconView) - - // WHEN the device is no longer dreaming - mUnderTest.mIsActiveDreamLockscreenHostedCallback.accept( - false /* isActiveDreamLockscreenHosted */ - ) - - // THEN lock icon is visible - verify(mLockIconView).visibility = View.VISIBLE - } - - companion object { - private val IMMEDIATE = Dispatchers.Main.immediate - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt deleted file mode 100644 index 6dc4b10a57da..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt +++ /dev/null @@ -1,351 +0,0 @@ -/* - * 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. - */ - -package com.android.systemui.biometrics - -import android.graphics.Point -import android.hardware.biometrics.BiometricSourceType -import android.hardware.fingerprint.FingerprintSensorPropertiesInternal -import android.testing.TestableLooper.RunWithLooper -import android.util.DisplayMetrics -import androidx.test.ext.junit.runners.AndroidJUnit4 -import androidx.test.filters.SmallTest -import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession -import com.android.keyguard.KeyguardUpdateMonitor -import com.android.keyguard.KeyguardUpdateMonitorCallback -import com.android.keyguard.logging.KeyguardLogger -import com.android.systemui.Flags -import com.android.systemui.Flags.FLAG_LIGHT_REVEAL_MIGRATION -import com.android.systemui.SysuiTestCase -import com.android.systemui.biometrics.data.repository.FakeFacePropertyRepository -import com.android.systemui.deviceentry.domain.interactor.AuthRippleInteractor -import com.android.systemui.keyguard.WakefulnessLifecycle -import com.android.systemui.log.logcatLogBuffer -import com.android.systemui.plugins.statusbar.StatusBarStateController -import com.android.systemui.statusbar.LightRevealScrim -import com.android.systemui.statusbar.NotificationShadeWindowController -import com.android.systemui.statusbar.commandline.CommandRegistry -import com.android.systemui.statusbar.phone.BiometricUnlockController -import com.android.systemui.statusbar.policy.ConfigurationController -import com.android.systemui.statusbar.policy.KeyguardStateController -import com.android.systemui.util.leak.RotationUtils -import com.android.systemui.util.mockito.any -import kotlinx.coroutines.ExperimentalCoroutinesApi -import org.junit.After -import org.junit.Assert.assertFalse -import org.junit.Assert.assertTrue -import org.junit.Before -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.ArgumentCaptor -import org.mockito.ArgumentMatchers -import org.mockito.ArgumentMatchers.eq -import org.mockito.Captor -import org.mockito.Mock -import org.mockito.Mockito.never -import org.mockito.Mockito.reset -import org.mockito.Mockito.verify -import org.mockito.Mockito.`when` -import org.mockito.MockitoAnnotations -import org.mockito.MockitoSession -import org.mockito.quality.Strictness -import javax.inject.Provider - - -@ExperimentalCoroutinesApi -@SmallTest -@RunWith(AndroidJUnit4::class) -class AuthRippleControllerTest : SysuiTestCase() { - private lateinit var staticMockSession: MockitoSession - - private lateinit var controller: AuthRippleController - @Mock private lateinit var rippleView: AuthRippleView - @Mock private lateinit var commandRegistry: CommandRegistry - @Mock private lateinit var configurationController: ConfigurationController - @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor - @Mock private lateinit var authController: AuthController - @Mock private lateinit var authRippleInteractor: AuthRippleInteractor - @Mock private lateinit var keyguardStateController: KeyguardStateController - @Mock - private lateinit var wakefulnessLifecycle: WakefulnessLifecycle - @Mock - private lateinit var notificationShadeWindowController: NotificationShadeWindowController - @Mock - private lateinit var biometricUnlockController: BiometricUnlockController - @Mock - private lateinit var udfpsControllerProvider: Provider<UdfpsController> - @Mock - private lateinit var udfpsController: UdfpsController - @Mock - private lateinit var statusBarStateController: StatusBarStateController - @Mock - private lateinit var lightRevealScrim: LightRevealScrim - @Mock - private lateinit var fpSensorProp: FingerprintSensorPropertiesInternal - - private val facePropertyRepository = FakeFacePropertyRepository() - private val displayMetrics = DisplayMetrics() - - @Captor - private lateinit var biometricUnlockListener: - ArgumentCaptor<BiometricUnlockController.BiometricUnlockEventsListener> - - @Before - fun setUp() { - mSetFlagsRule.disableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR) - MockitoAnnotations.initMocks(this) - staticMockSession = mockitoSession() - .mockStatic(RotationUtils::class.java) - .strictness(Strictness.LENIENT) - .startMocking() - - `when`(RotationUtils.getRotation(context)).thenReturn(RotationUtils.ROTATION_NONE) - `when`(authController.udfpsProps).thenReturn(listOf(fpSensorProp)) - `when`(udfpsControllerProvider.get()).thenReturn(udfpsController) - - controller = AuthRippleController( - context, - authController, - configurationController, - keyguardUpdateMonitor, - keyguardStateController, - wakefulnessLifecycle, - commandRegistry, - notificationShadeWindowController, - udfpsControllerProvider, - statusBarStateController, - displayMetrics, - KeyguardLogger(logcatLogBuffer(AuthRippleController.TAG)), - biometricUnlockController, - lightRevealScrim, - authRippleInteractor, - facePropertyRepository, - rippleView, - ) - controller.init() - } - - @After - fun tearDown() { - staticMockSession.finishMocking() - } - - @Test - fun testFingerprintTrigger_KeyguardShowing_Ripple() { - // GIVEN fp exists, keyguard is showing, unlocking with fp allowed - val fpsLocation = Point(5, 5) - `when`(authController.fingerprintSensorLocation).thenReturn(fpsLocation) - controller.onViewAttached() - `when`(keyguardStateController.isShowing).thenReturn(true) - `when`(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed( - eq(BiometricSourceType.FINGERPRINT))).thenReturn(true) - - // WHEN fingerprint authenticated - verify(biometricUnlockController).addListener(biometricUnlockListener.capture()) - biometricUnlockListener.value - .onBiometricUnlockedWithKeyguardDismissal(BiometricSourceType.FINGERPRINT) - - // THEN update sensor location and show ripple - verify(rippleView).setFingerprintSensorLocation(fpsLocation, 0f) - verify(rippleView).startUnlockedRipple(any()) - } - - @Test - fun testFingerprintTrigger_KeyguardNotShowing_NoRipple() { - // GIVEN fp exists & unlocking with fp allowed - val fpsLocation = Point(5, 5) - `when`(authController.udfpsLocation).thenReturn(fpsLocation) - controller.onViewAttached() - `when`(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed( - eq(BiometricSourceType.FINGERPRINT))).thenReturn(true) - - // WHEN keyguard is NOT showing & fingerprint authenticated - `when`(keyguardStateController.isShowing).thenReturn(false) - val captor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java) - verify(keyguardUpdateMonitor).registerCallback(captor.capture()) - captor.value.onBiometricAuthenticated( - 0 /* userId */, - BiometricSourceType.FINGERPRINT /* type */, - false /* isStrongBiometric */) - - // THEN no ripple - verify(rippleView, never()).startUnlockedRipple(any()) - } - - @Test - fun testFingerprintTrigger_biometricUnlockNotAllowed_NoRipple() { - // GIVEN fp exists & keyguard is showing - val fpsLocation = Point(5, 5) - `when`(authController.udfpsLocation).thenReturn(fpsLocation) - controller.onViewAttached() - `when`(keyguardStateController.isShowing).thenReturn(true) - - // WHEN unlocking with fingerprint is NOT allowed & fingerprint authenticated - `when`(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed( - eq(BiometricSourceType.FINGERPRINT))).thenReturn(false) - val captor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java) - verify(keyguardUpdateMonitor).registerCallback(captor.capture()) - captor.value.onBiometricAuthenticated( - 0 /* userId */, - BiometricSourceType.FINGERPRINT /* type */, - false /* isStrongBiometric */) - - // THEN no ripple - verify(rippleView, never()).startUnlockedRipple(any()) - } - - @Test - fun testNullFaceSensorLocationDoesNothing() { - facePropertyRepository.setSensorLocation(null) - controller.onViewAttached() - - val captor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java) - verify(keyguardUpdateMonitor).registerCallback(captor.capture()) - - captor.value.onBiometricAuthenticated( - 0 /* userId */, - BiometricSourceType.FACE /* type */, - false /* isStrongBiometric */) - verify(rippleView, never()).startUnlockedRipple(any()) - } - - @Test - fun testNullFingerprintSensorLocationDoesNothing() { - `when`(authController.fingerprintSensorLocation).thenReturn(null) - controller.onViewAttached() - - val captor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java) - verify(keyguardUpdateMonitor).registerCallback(captor.capture()) - - captor.value.onBiometricAuthenticated( - 0 /* userId */, - BiometricSourceType.FINGERPRINT /* type */, - false /* isStrongBiometric */) - verify(rippleView, never()).startUnlockedRipple(any()) - } - - @Test - fun registersAndDeregisters() { - controller.onViewAttached() - val captor = ArgumentCaptor - .forClass(KeyguardStateController.Callback::class.java) - verify(keyguardStateController).addCallback(captor.capture()) - val captor2 = ArgumentCaptor - .forClass(WakefulnessLifecycle.Observer::class.java) - verify(wakefulnessLifecycle).addObserver(captor2.capture()) - controller.onViewDetached() - verify(keyguardStateController).removeCallback(any()) - verify(wakefulnessLifecycle).removeObserver(any()) - } - - @Test - @RunWithLooper(setAsMainLooper = true) - fun testAnimatorRunWhenWakeAndUnlock_fingerprint() { - mSetFlagsRule.disableFlags(FLAG_LIGHT_REVEAL_MIGRATION) - val fpsLocation = Point(5, 5) - `when`(authController.fingerprintSensorLocation).thenReturn(fpsLocation) - controller.onViewAttached() - `when`(keyguardStateController.isShowing).thenReturn(true) - `when`(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed( - BiometricSourceType.FINGERPRINT)).thenReturn(true) - `when`(biometricUnlockController.isWakeAndUnlock).thenReturn(true) - - controller.showUnlockRipple(BiometricSourceType.FINGERPRINT) - assertTrue("reveal didn't start on keyguardFadingAway", - controller.startLightRevealScrimOnKeyguardFadingAway) - `when`(keyguardStateController.isKeyguardFadingAway).thenReturn(true) - controller.onKeyguardFadingAwayChanged() - assertFalse("reveal triggers multiple times", - controller.startLightRevealScrimOnKeyguardFadingAway) - } - - @Test - @RunWithLooper(setAsMainLooper = true) - fun testAnimatorRunWhenWakeAndUnlock_faceUdfpsFingerDown() { - mSetFlagsRule.disableFlags(FLAG_LIGHT_REVEAL_MIGRATION) - val faceLocation = Point(5, 5) - facePropertyRepository.setSensorLocation(faceLocation) - controller.onViewAttached() - `when`(keyguardStateController.isShowing).thenReturn(true) - `when`(biometricUnlockController.isWakeAndUnlock).thenReturn(true) - `when`(authController.isUdfpsFingerDown).thenReturn(true) - `when`(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed( - eq(BiometricSourceType.FACE))).thenReturn(true) - - controller.showUnlockRipple(BiometricSourceType.FACE) - assertTrue("reveal didn't start on keyguardFadingAway", - controller.startLightRevealScrimOnKeyguardFadingAway) - `when`(keyguardStateController.isKeyguardFadingAway).thenReturn(true) - controller.onKeyguardFadingAwayChanged() - assertFalse("reveal triggers multiple times", - controller.startLightRevealScrimOnKeyguardFadingAway) - } - - @Test - fun testUpdateRippleColor() { - controller.onViewAttached() - val captor = ArgumentCaptor - .forClass(ConfigurationController.ConfigurationListener::class.java) - verify(configurationController).addCallback(captor.capture()) - - reset(rippleView) - captor.value.onThemeChanged() - verify(rippleView).setLockScreenColor(ArgumentMatchers.anyInt()) - - reset(rippleView) - captor.value.onUiModeChanged() - verify(rippleView).setLockScreenColor(ArgumentMatchers.anyInt()) - } - - @Test - fun testUdfps_onFingerDown_runningForDeviceEntry_showDwellRipple() { - // GIVEN fingerprint detection is running on keyguard - `when`(keyguardUpdateMonitor.isFingerprintDetectionRunning).thenReturn(true) - - // GIVEN view is already attached - controller.onViewAttached() - val captor = ArgumentCaptor.forClass(UdfpsController.Callback::class.java) - verify(udfpsController).addCallback(captor.capture()) - - // GIVEN fp is updated to Point(5, 5) - val fpsLocation = Point(5, 5) - `when`(authController.fingerprintSensorLocation).thenReturn(fpsLocation) - - // WHEN finger is down - captor.value.onFingerDown() - - // THEN update sensor location and show ripple - verify(rippleView).setFingerprintSensorLocation(fpsLocation, 0f) - verify(rippleView).startDwellRipple(false) - } - - @Test - fun testUdfps_onFingerDown_notDeviceEntry_doesNotShowDwellRipple() { - // GIVEN fingerprint detection is NOT running on keyguard - `when`(keyguardUpdateMonitor.isFingerprintDetectionRunning).thenReturn(false) - - // GIVEN view is already attached - controller.onViewAttached() - val captor = ArgumentCaptor.forClass(UdfpsController.Callback::class.java) - verify(udfpsController).addCallback(captor.capture()) - - // WHEN finger is down - captor.value.onFingerDown() - - // THEN doesn't show dwell ripple - verify(rippleView, never()).startDwellRipple(false) - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt deleted file mode 100644 index 9fbe09619ff1..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt +++ /dev/null @@ -1,109 +0,0 @@ -/* - * 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. - */ - -package com.android.systemui.biometrics - -import android.hardware.biometrics.SensorLocationInternal -import android.testing.TestableLooper -import android.testing.ViewUtils -import android.view.LayoutInflater -import android.view.Surface -import androidx.test.ext.junit.runners.AndroidJUnit4 -import androidx.test.filters.SmallTest -import com.android.systemui.res.R -import com.android.systemui.SysuiTestCase -import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams -import com.android.systemui.util.mockito.any -import com.android.systemui.util.mockito.mock -import com.android.systemui.util.mockito.withArgCaptor -import com.google.common.truth.Truth.assertThat -import org.junit.After -import org.junit.Before -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.Mock -import org.mockito.Mockito.never -import org.mockito.Mockito.nullable -import org.mockito.Mockito.verify -import org.mockito.junit.MockitoJUnit - -private const val SENSOR_X = 50 -private const val SENSOR_Y = 250 -private const val SENSOR_RADIUS = 10 - -@SmallTest -@RunWith(AndroidJUnit4::class) -@TestableLooper.RunWithLooper -class UdfpsViewTest : SysuiTestCase() { - - @JvmField @Rule - var rule = MockitoJUnit.rule() - - @Mock - lateinit var hbmProvider: UdfpsDisplayModeProvider - @Mock - lateinit var animationViewController: UdfpsAnimationViewController<UdfpsAnimationView> - - private lateinit var view: UdfpsView - - @Before - fun setup() { - context.setTheme(androidx.appcompat.R.style.Theme_AppCompat) - view = LayoutInflater.from(context).inflate(R.layout.udfps_view, null) as UdfpsView - view.animationViewController = animationViewController - val sensorBounds = SensorLocationInternal("", SENSOR_X, SENSOR_Y, SENSOR_RADIUS).rect - view.overlayParams = UdfpsOverlayParams(sensorBounds, sensorBounds, 1920, - 1080, 1f, Surface.ROTATION_0) - view.setUdfpsDisplayModeProvider(hbmProvider) - ViewUtils.attachView(view) - } - - @After - fun cleanup() { - ViewUtils.detachView(view) - } - - // TODO: Add test to verify view is size of screen - - @Test - fun startAndStopIllumination() { - val onDone: Runnable = mock() - view.configureDisplay(onDone) - - val illuminator = withArgCaptor<Runnable> { - verify(hbmProvider).enable(capture()) - } - - assertThat(view.isDisplayConfigured).isTrue() - verify(animationViewController).onDisplayConfiguring() - verify(animationViewController, never()).onDisplayUnconfigured() - verify(onDone, never()).run() - - // fake illumination event - illuminator.run() - waitForLooper() - verify(onDone).run() - verify(hbmProvider, never()).disable(any()) - - view.unconfigureDisplay() - assertThat(view.isDisplayConfigured).isFalse() - verify(animationViewController).onDisplayUnconfigured() - verify(hbmProvider).disable(nullable(Runnable::class.java)) - } - - private fun waitForLooper() = TestableLooper.get(this).processAllMessages() -} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/flags/EnableSceneContainer.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/flags/EnableSceneContainer.kt index c0152b26d7a3..41402badf141 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/flags/EnableSceneContainer.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/flags/EnableSceneContainer.kt @@ -17,7 +17,6 @@ package com.android.systemui.flags import android.platform.test.annotations.EnableFlags -import com.android.systemui.Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR import com.android.systemui.Flags.FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR import com.android.systemui.Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR import com.android.systemui.Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT @@ -36,7 +35,6 @@ import com.android.systemui.Flags.FLAG_SCENE_CONTAINER FLAG_NOTIFICATION_AVALANCHE_THROTTLE_HUN, FLAG_PREDICTIVE_BACK_SYSUI, FLAG_SCENE_CONTAINER, - FLAG_DEVICE_ENTRY_UDFPS_REFACTOR, ) @Retention(AnnotationRetention.RUNTIME) @Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS) |