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()
+ }
+}