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
This commit is contained in:
Aaron Liu
2023-02-05 09:25:04 -08:00
parent 79aa1d7873
commit 2dee94da2c
15 changed files with 611 additions and 12 deletions

View File

@@ -0,0 +1,25 @@
<!--
~ 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="200dp"
android:height="200dp"
android:viewportWidth="200"
android:viewportHeight="200">
<path
android:fillColor="#FF000000"
android:pathData="M100,100m-100,0a100,100 0,1 1,200 0a100,100 0,1 1,-200 0"/>
</vector>

View File

@@ -69,6 +69,10 @@
<!-- The size of the dots in the PIN unlock method. -->
<dimen name="password_dot_size">9dp</dimen>
<!-- The size of the shape in the PIN unlock method. -->
<dimen name="password_shape_size">34dp</dimen>
<!-- The size of PIN text in the PIN unlock method. -->
<integer name="scaled_password_text_size">40</integer>
@@ -139,4 +143,9 @@
<!-- Translation y for appear animation -->
<dimen name="keyguard_host_view_translation_y">80dp</dimen>
<!-- Attributes for placeholder dots in 6 digit PIN view -->
<dimen name="default_dot_diameter">34dp</dimen>
<dimen name="default_dot_spacing">0dp</dimen>
</resources>

View File

@@ -0,0 +1,56 @@
<!--
~ 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.
-->
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt">
<target android:name="time_group">
<aapt:attr name="android:animation">
<set android:ordering="together">
<objectAnimator
android:duration="500"
android:propertyName="translateX"
android:startOffset="0"
android:valueFrom="0"
android:valueTo="1"
android:valueType="floatType" />
</set>
</aapt:attr>
</target>
<aapt:attr name="android:drawable">
<vector
android:width="60dp"
android:height="61dp"
android:viewportHeight="60"
android:viewportWidth="60">
<group android:name="_R_G">
<group
android:name="_R_G_L_0_G"
android:translateX="43.237"
android:translateY="38.112">
<path
android:name="_R_G_L_0_G_D_0_P_0"
android:pathData=" M-13.24 -12.11 C-11.03,-12.11 -9.24,-10.32 -9.24,-8.11 C-9.24,-5.9 -11.03,-4.11 -13.24,-4.11 C-15.44,-4.11 -17.24,-5.9 -17.24,-8.11 C-17.24,-10.32 -15.44,-12.11 -13.24,-12.11c "
android:strokeAlpha="1"
android:strokeColor="#ffffff"
android:strokeLineCap="round"
android:strokeLineJoin="round"
android:strokeWidth="2" />
</group>
</group>
<group android:name="time_group" />
</vector>
</aapt:attr>
</animated-vector>

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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
-->
<com.android.keyguard.PINShapeNonSixDigitView
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent">
</com.android.keyguard.PINShapeNonSixDigitView>

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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
-->
<com.android.keyguard.PINShapeSixDigitView
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent">
</com.android.keyguard.PINShapeSixDigitView>

View File

@@ -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<T extends KeyguardInputView>
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<T extends KeyguardInputView>
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<T extends KeyguardInputView>
mFalsingCollector = falsingCollector;
mDevicePostureController = devicePostureController;
mKeyguardViewController = keyguardViewController;
mFeatureFlags = featureFlags;
}
/** Create a new {@link KeyguardInputViewController}. */
@@ -236,7 +240,7 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView>
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,

View File

@@ -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);
}
}

View File

@@ -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;

View File

@@ -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;
}
}

View File

@@ -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();
}

View File

@@ -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;
}
}

View File

@@ -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
}

View File

@@ -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<PasswordTextView>(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)
}
}

View File

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

View File

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