From 2dee94da2c92b89dc8f333b90556557a06d4fe10 Mon Sep 17 00:00:00 2001 From: Aaron Liu Date: Sun, 5 Feb 2023 09:25:04 -0800 Subject: [PATCH] Changes to lockscreen for laying out the 6 digit view This CL aims at making changes for laying out the 6 and non 6 digit PIN view, and also the logic for unlocking automatically after a user sets a 6 digit PIN. Test: Tested by building and flashing on local Bug: b/262935304 Change-Id: Ic9bde6d1572a30bbc1c03164b93c4292ca4318d3 --- .../res-keyguard/drawable/ic_shape_circle.xml | 25 ++++ .../SystemUI/res-keyguard/values/dimens.xml | 9 ++ .../SystemUI/res/drawable/pin_dot_avd.xml | 56 +++++++++ .../keyguard_pin_shape_non_six_digit_view.xml | 23 ++++ .../keyguard_pin_shape_six_digit_view.xml | 23 ++++ .../keyguard/KeyguardInputViewController.java | 8 +- .../keyguard/KeyguardPinViewController.java | 56 ++++++++- .../android/keyguard/PasswordTextView.java | 63 ++++++++-- .../android/keyguard/PinShapeHintingView.java | 111 ++++++++++++++++++ .../com/android/keyguard/PinShapeInput.java | 50 ++++++++ .../keyguard/PinShapeNonHintingView.java | 82 +++++++++++++ .../constants/KeyguardBouncerConstants.kt | 6 + .../keyguard/KeyguardPinViewControllerTest.kt | 20 +++- .../keyguard/PinShapeHintingViewTest.kt | 45 +++++++ .../keyguard/PinShapeNonHintingViewTest.kt | 46 ++++++++ 15 files changed, 611 insertions(+), 12 deletions(-) create mode 100644 packages/SystemUI/res-keyguard/drawable/ic_shape_circle.xml create mode 100644 packages/SystemUI/res/drawable/pin_dot_avd.xml create mode 100644 packages/SystemUI/res/layout/keyguard_pin_shape_non_six_digit_view.xml create mode 100644 packages/SystemUI/res/layout/keyguard_pin_shape_six_digit_view.xml create mode 100644 packages/SystemUI/src/com/android/keyguard/PinShapeHintingView.java create mode 100644 packages/SystemUI/src/com/android/keyguard/PinShapeInput.java create mode 100644 packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java create mode 100644 packages/SystemUI/tests/src/com/android/keyguard/PinShapeHintingViewTest.kt create mode 100644 packages/SystemUI/tests/src/com/android/keyguard/PinShapeNonHintingViewTest.kt diff --git a/packages/SystemUI/res-keyguard/drawable/ic_shape_circle.xml b/packages/SystemUI/res-keyguard/drawable/ic_shape_circle.xml new file mode 100644 index 0000000000000..1d9247c10a3ff --- /dev/null +++ b/packages/SystemUI/res-keyguard/drawable/ic_shape_circle.xml @@ -0,0 +1,25 @@ + + + + + \ No newline at end of file diff --git a/packages/SystemUI/res-keyguard/values/dimens.xml b/packages/SystemUI/res-keyguard/values/dimens.xml index 6cc5b9d7b7e88..b9c7be204d9d6 100644 --- a/packages/SystemUI/res-keyguard/values/dimens.xml +++ b/packages/SystemUI/res-keyguard/values/dimens.xml @@ -69,6 +69,10 @@ 9dp + + + 34dp + 40 @@ -139,4 +143,9 @@ 80dp + + + 34dp + 0dp + diff --git a/packages/SystemUI/res/drawable/pin_dot_avd.xml b/packages/SystemUI/res/drawable/pin_dot_avd.xml new file mode 100644 index 0000000000000..e0cd1fb2e1297 --- /dev/null +++ b/packages/SystemUI/res/drawable/pin_dot_avd.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/SystemUI/res/layout/keyguard_pin_shape_non_six_digit_view.xml b/packages/SystemUI/res/layout/keyguard_pin_shape_non_six_digit_view.xml new file mode 100644 index 0000000000000..cbf9f7abe85a3 --- /dev/null +++ b/packages/SystemUI/res/layout/keyguard_pin_shape_non_six_digit_view.xml @@ -0,0 +1,23 @@ + + + + \ No newline at end of file diff --git a/packages/SystemUI/res/layout/keyguard_pin_shape_six_digit_view.xml b/packages/SystemUI/res/layout/keyguard_pin_shape_six_digit_view.xml new file mode 100644 index 0000000000000..722f52eff59a5 --- /dev/null +++ b/packages/SystemUI/res/layout/keyguard_pin_shape_six_digit_view.xml @@ -0,0 +1,23 @@ + + + + diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java index b143c5b90373f..48844db6f65fb 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java @@ -30,6 +30,7 @@ import com.android.keyguard.KeyguardSecurityModel.SecurityMode; import com.android.systemui.R; import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.dagger.qualifiers.Main; +import com.android.systemui.flags.FeatureFlags; import com.android.systemui.statusbar.policy.DevicePostureController; import com.android.systemui.util.ViewController; import com.android.systemui.util.concurrency.DelayableExecutor; @@ -184,6 +185,7 @@ public abstract class KeyguardInputViewController private final FalsingCollector mFalsingCollector; private final DevicePostureController mDevicePostureController; private final KeyguardViewController mKeyguardViewController; + private final FeatureFlags mFeatureFlags; @Inject public Factory(KeyguardUpdateMonitor keyguardUpdateMonitor, @@ -195,7 +197,8 @@ public abstract class KeyguardInputViewController TelephonyManager telephonyManager, FalsingCollector falsingCollector, EmergencyButtonController.Factory emergencyButtonControllerFactory, DevicePostureController devicePostureController, - KeyguardViewController keyguardViewController) { + KeyguardViewController keyguardViewController, + FeatureFlags featureFlags) { mKeyguardUpdateMonitor = keyguardUpdateMonitor; mLockPatternUtils = lockPatternUtils; mLatencyTracker = latencyTracker; @@ -209,6 +212,7 @@ public abstract class KeyguardInputViewController mFalsingCollector = falsingCollector; mDevicePostureController = devicePostureController; mKeyguardViewController = keyguardViewController; + mFeatureFlags = featureFlags; } /** Create a new {@link KeyguardInputViewController}. */ @@ -236,7 +240,7 @@ public abstract class KeyguardInputViewController mKeyguardUpdateMonitor, securityMode, mLockPatternUtils, keyguardSecurityCallback, mMessageAreaControllerFactory, mLatencyTracker, mLiftToActivateListener, emergencyButtonController, mFalsingCollector, - mDevicePostureController); + mDevicePostureController, mFeatureFlags); } else if (keyguardInputView instanceof KeyguardSimPinView) { return new KeyguardSimPinViewController((KeyguardSimPinView) keyguardInputView, mKeyguardUpdateMonitor, securityMode, mLockPatternUtils, diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java index 35b2db27d8794..db22c5e702920 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java @@ -16,6 +16,8 @@ package com.android.keyguard; +import static com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.DEFAULT_PIN_LENGTH; + import android.view.View; import com.android.internal.util.LatencyTracker; @@ -23,6 +25,8 @@ import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardSecurityModel.SecurityMode; import com.android.systemui.R; import com.android.systemui.classifier.FalsingCollector; +import com.android.systemui.flags.FeatureFlags; +import com.android.systemui.flags.Flags; import com.android.systemui.statusbar.policy.DevicePostureController; public class KeyguardPinViewController @@ -31,6 +35,12 @@ public class KeyguardPinViewController private final DevicePostureController mPostureController; private final DevicePostureController.Callback mPostureCallback = posture -> mView.onDevicePostureChanged(posture); + private LockPatternUtils mLockPatternUtils; + private final FeatureFlags mFeatureFlags; + private View mOkButton = mView.findViewById(R.id.key_enter); + + private int mUserId; + private long mPinLength; protected KeyguardPinViewController(KeyguardPINView view, KeyguardUpdateMonitor keyguardUpdateMonitor, @@ -40,12 +50,15 @@ public class KeyguardPinViewController LatencyTracker latencyTracker, LiftToActivateListener liftToActivateListener, EmergencyButtonController emergencyButtonController, FalsingCollector falsingCollector, - DevicePostureController postureController) { + DevicePostureController postureController, + FeatureFlags featureFlags) { super(view, keyguardUpdateMonitor, securityMode, lockPatternUtils, keyguardSecurityCallback, messageAreaControllerFactory, latencyTracker, liftToActivateListener, emergencyButtonController, falsingCollector); mKeyguardUpdateMonitor = keyguardUpdateMonitor; mPostureController = postureController; + mLockPatternUtils = lockPatternUtils; + mFeatureFlags = featureFlags; } @Override @@ -59,19 +72,58 @@ public class KeyguardPinViewController getKeyguardSecurityCallback().onCancelClicked(); }); } - + mPasswordEntry.setUserActivityListener(this::onUserInput); mPostureController.addCallback(mPostureCallback); } + protected void onUserInput() { + super.onUserInput(); + if (isAutoConfirmation()) { + if (mPasswordEntry.getText().length() == mPinLength) { + verifyPasswordAndUnlock(); + } + } + } + @Override protected void onViewDetached() { super.onViewDetached(); mPostureController.removeCallback(mPostureCallback); } + @Override + public void startAppearAnimation() { + if (mFeatureFlags.isEnabled(Flags.AUTO_PIN_CONFIRMATION)) { + mUserId = KeyguardUpdateMonitor.getCurrentUser(); + mPinLength = mLockPatternUtils.getPinLength(mUserId); + if (isAutoConfirmation()) { + mOkButton.setVisibility(View.INVISIBLE); + } else { + mOkButton.setVisibility(View.VISIBLE); + } + mPasswordEntry.setIsPinHinting(true, isPinHinting()); + } + super.startAppearAnimation(); + } + @Override public boolean startDisappearAnimation(Runnable finishRunnable) { return mView.startDisappearAnimation( mKeyguardUpdateMonitor.needsSlowUnlockTransition(), finishRunnable); } + + /* + Responsible for identifying if PIN hinting is to be enabled or not + */ + private boolean isPinHinting() { + return mLockPatternUtils.getPinLength(mUserId) == DEFAULT_PIN_LENGTH; + } + + /* + Responsible for identifying if auto confirm is enabled or not in Settings + */ + private boolean isAutoConfirmation() { + //Checks if user has enabled the auto confirm in Settings + return mLockPatternUtils.isAutoPinConfirmEnabled(mUserId); + } } diff --git a/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java b/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java index 35cae099e44e9..65edce0d98a09 100644 --- a/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java +++ b/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java @@ -35,13 +35,14 @@ import android.text.InputType; import android.text.TextUtils; import android.util.AttributeSet; import android.view.Gravity; -import android.view.View; +import android.view.LayoutInflater; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityNodeInfo; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; import android.widget.EditText; +import android.widget.FrameLayout; import com.android.settingslib.Utils; import com.android.systemui.R; @@ -52,7 +53,7 @@ import java.util.ArrayList; * A View similar to a textView which contains password text and can animate when the text is * changed */ -public class PasswordTextView extends View { +public class PasswordTextView extends FrameLayout { private static final float DOT_OVERSHOOT_FACTOR = 1.5f; private static final long DOT_APPEAR_DURATION_OVERSHOOT = 320; @@ -95,11 +96,14 @@ public class PasswordTextView extends View { private PowerManager mPM; private int mCharPadding; private final Paint mDrawPaint = new Paint(); + private int mDrawColor; private Interpolator mAppearInterpolator; private Interpolator mDisappearInterpolator; private Interpolator mFastOutSlowInInterpolator; private boolean mShowPassword; private UserActivityListener mUserActivityListener; + private PinShapeInput mPinShapeInput; + private boolean mUsePinShapes = false; public interface UserActivityListener { void onUserActivity(); @@ -141,8 +145,10 @@ public class PasswordTextView extends View { mCharPadding = a.getDimensionPixelSize(R.styleable.PasswordTextView_charPadding, getContext().getResources().getDimensionPixelSize( R.dimen.password_char_padding)); - mDrawPaint.setColor(a.getColor(R.styleable.PasswordTextView_android_textColor, - Color.WHITE)); + mDrawColor = a.getColor(R.styleable.PasswordTextView_android_textColor, + Color.WHITE); + mDrawPaint.setColor(mDrawColor); + } finally { a.recycle(); } @@ -161,6 +167,7 @@ public class PasswordTextView extends View { mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(mContext, android.R.interpolator.fast_out_slow_in); mPM = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); + setWillNotDraw(false); } @Override @@ -171,6 +178,12 @@ public class PasswordTextView extends View { @Override protected void onDraw(Canvas canvas) { + // Do not use legacy draw animations for pin shapes. + if (mUsePinShapes) { + super.onDraw(canvas); + return; + } + float totalDrawingWidth = getDrawingWidth(); float currentDrawPosition; if ((mGravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.LEFT) { @@ -205,9 +218,12 @@ public class PasswordTextView extends View { * Reload colors from resources. **/ public void reloadColors() { - int textColor = Utils.getColorAttr(getContext(), android.R.attr.textColorPrimary) - .getDefaultColor(); - mDrawPaint.setColor(textColor); + mDrawColor = Utils.getColorAttr(getContext(), + android.R.attr.textColorPrimary).getDefaultColor(); + mDrawPaint.setColor(mDrawColor); + if (mPinShapeInput != null) { + mPinShapeInput.setDrawColor(mDrawColor); + } } @Override @@ -252,6 +268,9 @@ public class PasswordTextView extends View { charState = mTextChars.get(newLength - 1); charState.whichChar = c; } + if (mPinShapeInput != null) { + mPinShapeInput.append(); + } charState.startAppearAnimation(); // ensure that the previous element is being swapped @@ -284,6 +303,9 @@ public class PasswordTextView extends View { CharState charState = mTextChars.get(length - 1); charState.startRemoveAnimation(0, 0); sendAccessibilityEventTypeViewTextChanged(textbefore, textbefore.length() - 1, 1, 0); + if (mPinShapeInput != null) { + mPinShapeInput.delete(); + } } userActivity(); } @@ -340,6 +362,9 @@ public class PasswordTextView extends View { if (!animated) { mTextChars.clear(); } + if (mPinShapeInput != null) { + mPinShapeInput.reset(); + } if (announce) { sendAccessibilityEventTypeViewTextChanged(textbefore, 0, textbefore.length(), 0); } @@ -385,6 +410,30 @@ public class PasswordTextView extends View { info.setInputType(InputType.TYPE_NUMBER_VARIATION_PASSWORD); } + /** + * Determines whether AutoConfirmation feature is on. + * + * @param usePinShapes + * @param isPinHinting + */ + public void setIsPinHinting(boolean usePinShapes, boolean isPinHinting) { + mUsePinShapes = usePinShapes; + + if (mPinShapeInput != null) { + removeView(mPinShapeInput.getView()); + mPinShapeInput = null; + } + + if (isPinHinting) { + mPinShapeInput = (PinShapeInput) LayoutInflater.from(mContext).inflate( + R.layout.keyguard_pin_shape_six_digit_view, null); + } else { + mPinShapeInput = (PinShapeInput) LayoutInflater.from(mContext).inflate( + R.layout.keyguard_pin_shape_non_six_digit_view, null); + } + addView(mPinShapeInput.getView()); + } + private class CharState { char whichChar; ValueAnimator textAnimator; diff --git a/packages/SystemUI/src/com/android/keyguard/PinShapeHintingView.java b/packages/SystemUI/src/com/android/keyguard/PinShapeHintingView.java new file mode 100644 index 0000000000000..d37d7dee944bd --- /dev/null +++ b/packages/SystemUI/src/com/android/keyguard/PinShapeHintingView.java @@ -0,0 +1,111 @@ +/* + * 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.keyguard; + +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.view.View; +import android.widget.ImageView; +import android.widget.LinearLayout; + +import androidx.core.graphics.drawable.DrawableCompat; + +import com.android.settingslib.Utils; +import com.android.systemui.R; + +/** + * This class contains implementation for methods that will be used when user has set a + * six digit pin on their device + */ +public class PinShapeHintingView extends LinearLayout implements PinShapeInput { + + private int mPinLength; + private int mDotDiameter; + private int mDotSpacing; + private int mColor = Utils.getColorAttr(getContext(), android.R.attr.textColorPrimary) + .getDefaultColor(); + private int mPosition = 0; + private static final int DEFAULT_PIN_LENGTH = 6; + + public PinShapeHintingView(Context context) { + super(context); + } + + public PinShapeHintingView(Context context, AttributeSet attrs) { + super(context, attrs); + mPinLength = DEFAULT_PIN_LENGTH; + mDotDiameter = context.getResources().getDimensionPixelSize(R.dimen.default_dot_diameter); + mDotSpacing = context.getResources().getDimensionPixelSize(R.dimen.default_dot_spacing); + + for (int i = 0; i < mPinLength; i++) { + ImageView pinDot = new ImageView(context, attrs); + LayoutParams layoutParams = new LayoutParams(mDotDiameter, mDotDiameter); + pinDot.setLayoutParams(layoutParams); + pinDot.setImageResource(R.drawable.pin_dot_avd); + if (pinDot.getDrawable() != null) { + Drawable drawable = DrawableCompat.wrap(pinDot.getDrawable()); + DrawableCompat.setTint(drawable, mColor); + } + addView(pinDot); + } + } + + public PinShapeHintingView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + public PinShapeHintingView(Context context, AttributeSet attrs, int defStyleAttr, + int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } + + @Override + public void append() { + if (mPosition == DEFAULT_PIN_LENGTH) { + return; + } + mPosition++; + } + + @Override + public void delete() { + if (mPosition == 0) { + return; + } + mPosition--; + } + + @Override + public void setDrawColor(int color) { + this.mColor = color; + } + + @Override + public void reset() { + int size = mPosition; + for (int i = 0; i < size; i++) { + delete(); + } + mPosition = 0; + } + + @Override + public View getView() { + return this; + } +} diff --git a/packages/SystemUI/src/com/android/keyguard/PinShapeInput.java b/packages/SystemUI/src/com/android/keyguard/PinShapeInput.java new file mode 100644 index 0000000000000..52ae6bac6d744 --- /dev/null +++ b/packages/SystemUI/src/com/android/keyguard/PinShapeInput.java @@ -0,0 +1,50 @@ +/* + * 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.keyguard; + +import android.view.View; + +/** + * A common interface for classes that provide functionality for the PIN type view + */ +public interface PinShapeInput { + + /** + * This is the method that is triggered when user types in a character + */ + void append(); + + /** + * This is the method that is triggered when user deletes a character + */ + void delete(); + + /** + * This is the method that is triggered for setting the color of the view + */ + void setDrawColor(int color); + + /** + * This is the method that is triggered for resetting the view + */ + void reset(); + + /** + * This is the method that is triggered for getting the view + */ + View getView(); +} diff --git a/packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java b/packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java new file mode 100644 index 0000000000000..e6f8ac3feacc6 --- /dev/null +++ b/packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java @@ -0,0 +1,82 @@ +/* + * 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.keyguard; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.View; +import android.widget.LinearLayout; + +import com.android.settingslib.Utils; + +/** + * This class contains implementation for methods that will be used when user has set a + * non six digit pin on their device + */ +public class PinShapeNonHintingView extends LinearLayout implements PinShapeInput { + + private int mColor = Utils.getColorAttr(getContext(), + android.R.attr.textColorPrimary).getDefaultColor(); + private int mPosition = 0; + + public PinShapeNonHintingView(Context context) { + super(context); + } + + public PinShapeNonHintingView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public PinShapeNonHintingView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + public PinShapeNonHintingView(Context context, AttributeSet attrs, int defStyleAttr, + int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } + + @Override + public void append() { + mPosition++; + } + + @Override + public void delete() { + if (mPosition == 0) { + return; + } else { + mPosition--; + } + } + + @Override + public void setDrawColor(int color) { + this.mColor = color; + } + + @Override + public void reset() { + removeAllViews(); + mPosition = 0; + } + + @Override + public View getView() { + return this; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/shared/constants/KeyguardBouncerConstants.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/constants/KeyguardBouncerConstants.kt index 8222dd54f46d6..3b3ec39d0209f 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/shared/constants/KeyguardBouncerConstants.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/shared/constants/KeyguardBouncerConstants.kt @@ -26,4 +26,10 @@ object KeyguardBouncerConstants { const val EXPANSION_HIDDEN = 1f const val EXPANSION_VISIBLE = 0f const val ALPHA_EXPANSION_THRESHOLD = 0.95f + + /** + * This value is used for denoting the PIN length at which we want to layout the view in which + * PIN hinting is enabled + */ + const val DEFAULT_PIN_LENGTH = 6 } diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt index cdb7bbb9f8233..5ba4aabc1a339 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt @@ -27,11 +27,14 @@ import com.android.systemui.R import com.android.systemui.SysuiTestCase import com.android.systemui.classifier.FalsingCollector import com.android.systemui.classifier.FalsingCollectorFake +import com.android.systemui.flags.FeatureFlags +import com.android.systemui.flags.Flags import com.android.systemui.statusbar.policy.DevicePostureController import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.anyBoolean +import org.mockito.ArgumentMatchers.anyInt import org.mockito.ArgumentMatchers.anyString import org.mockito.Mock import org.mockito.Mockito @@ -71,6 +74,9 @@ class KeyguardPinViewControllerTest : SysuiTestCase() { private val falsingCollector: FalsingCollector = FalsingCollectorFake() @Mock lateinit var postureController: DevicePostureController + @Mock lateinit var featureFlags: FeatureFlags + @Mock lateinit var passwordTextView: PasswordTextView + lateinit var pinViewController: KeyguardPinViewController @Before @@ -82,6 +88,9 @@ class KeyguardPinViewControllerTest : SysuiTestCase() { keyguardMessageAreaControllerFactory.create(any(KeyguardMessageArea::class.java)) ) .thenReturn(keyguardMessageAreaController) + `when`(keyguardPinView.passwordTextViewId).thenReturn(R.id.pinEntry) + `when`(keyguardPinView.findViewById(R.id.pinEntry)) + .thenReturn(passwordTextView) `when`(keyguardPinView.resources).thenReturn(context.resources) pinViewController = KeyguardPinViewController( @@ -95,7 +104,8 @@ class KeyguardPinViewControllerTest : SysuiTestCase() { liftToActivateListener, mEmergencyButtonController, falsingCollector, - postureController + postureController, + featureFlags ) } @@ -112,4 +122,12 @@ class KeyguardPinViewControllerTest : SysuiTestCase() { pinViewController.startAppearAnimation() verify(keyguardMessageAreaController, Mockito.never()).setMessage(anyString(), anyBoolean()) } + + @Test + fun startAppearAnimation_withAutoPinConfirmation() { + `when`(featureFlags.isEnabled(Flags.AUTO_PIN_CONFIRMATION)).thenReturn(true) + `when`(lockPatternUtils.isAutoPinConfirmEnabled(anyInt())).thenReturn(true) + pinViewController.startAppearAnimation() + verify(passwordTextView).setIsPinHinting(true, true) + } } diff --git a/packages/SystemUI/tests/src/com/android/keyguard/PinShapeHintingViewTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/PinShapeHintingViewTest.kt new file mode 100644 index 0000000000000..c13b43158ec60 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/keyguard/PinShapeHintingViewTest.kt @@ -0,0 +1,45 @@ +/* + * 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.keyguard + +import android.view.LayoutInflater +import com.android.systemui.R +import com.android.systemui.SysuiTestCase +import org.junit.Before +import org.junit.Test + +class PinShapeHintingViewTest : SysuiTestCase() { + lateinit var mPinShapeHintingView: PinShapeHintingView + + @Before + fun setup() { + mPinShapeHintingView = + LayoutInflater.from(context).inflate(R.layout.keyguard_pin_shape_six_digit_view, null) + as PinShapeHintingView + } + + @Test + fun testAppend() { + // Add more when animation part is complete + mPinShapeHintingView.append() + } + + @Test + fun testDelete() { + mPinShapeHintingView.delete() + } +} diff --git a/packages/SystemUI/tests/src/com/android/keyguard/PinShapeNonHintingViewTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/PinShapeNonHintingViewTest.kt new file mode 100644 index 0000000000000..1bf27d2c4621f --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/keyguard/PinShapeNonHintingViewTest.kt @@ -0,0 +1,46 @@ +/* + * 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.keyguard + +import android.view.LayoutInflater +import com.android.systemui.R +import com.android.systemui.SysuiTestCase +import org.junit.Before +import org.junit.Test + +class PinShapeNonHintingViewTest : SysuiTestCase() { + lateinit var mPinShapeNonHintingView: PinShapeNonHintingView + + @Before + fun setup() { + mPinShapeNonHintingView = + LayoutInflater.from(context) + .inflate(R.layout.keyguard_pin_shape_non_six_digit_view, null) + as PinShapeNonHintingView + } + + @Test + fun testAppend() { + // Add more when animation part is complete + mPinShapeNonHintingView.append() + } + + @Test + fun testDelete() { + mPinShapeNonHintingView.delete() + } +}