Update lock icon view when biometrics cleared

To ensure when face auth is the only biometric
enrolled, that the unlocked icon immediately
becomes the locked icon on screen off (when
biometrics authentication states are cleared).

Also add the unlocked => locked icon transition
so there isn't a jump-cut animation when
AoD is enabled and the unlocked icon transitions
to the locked icon.

Fixes: 264217642
Test: manual
 1. enroll face auth only without bypass enabled
 2. unlock the lock screen (see unlocked icon)
 3. let the screen timeout
 4. tap screen to wakeup
 Observe: lock icon (not unlocked icon)
Test: atest LockIconViewControllerTest
Change-Id: I317725fee4519ad0af39a1a7ade0361263643902
This commit is contained in:
Beverly
2023-01-05 16:34:11 +00:00
parent f1f50ee221
commit fb310c25ee
5 changed files with 183 additions and 0 deletions

View File

@@ -99,4 +99,9 @@
android:fromId="@id/unlocked"
android:toId="@id/locked_aod"
android:drawable="@drawable/unlocked_to_aod_lock" />
<transition
android:fromId="@id/unlocked"
android:toId="@id/locked"
android:drawable="@drawable/unlocked_to_locked" />
</animated-selector>

View File

@@ -0,0 +1,145 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- 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.
-->
<animated-vector xmlns:aapt="http://schemas.android.com/aapt" xmlns:android="http://schemas.android.com/apk/res/android">
<aapt:attr name="android:drawable">
<vector android:height="65dp" android:width="46dp" android:viewportHeight="65" android:viewportWidth="46">
<group android:name="_R_G">
<group android:name="_R_G_L_2_G_T_1" android:translateX="22.75" android:translateY="22.25" android:scaleX="1.02" android:scaleY="1.02">
<group android:name="_R_G_L_2_G" android:translateX="-8.75" android:translateY="-8.75">
<path android:name="_R_G_L_2_G_D_0_P_0" android:strokeColor="#FF000000" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2" android:strokeAlpha="1" android:pathData=" M27.19 14.81 C27.19,14.81 27.19,8.3 27.19,8.3 C27.19,4.92 24.44,2.88 21.19,2.75 C17.74,2.62 15,4.74 15,8.11 C15,8.11 15,15 15,15 " />
</group>
</group>
<group android:name="_R_G_L_1_G_N_4_T_1" android:translateX="22.75" android:translateY="22.25" android:scaleX="1.02" android:scaleY="1.02">
<group android:name="_R_G_L_1_G_N_4_T_0" android:translateX="-8.75" android:translateY="-8.75">
<group android:name="_R_G_L_1_G" android:translateX="8.995" android:translateY="18.431" android:scaleX="0.98039" android:scaleY="0.98039">
<path android:name="_R_G_L_1_G_D_0_P_0" android:strokeColor="#FF000000" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2" android:strokeAlpha="1" android:pathData=" M11.25 -0.64 C11.25,-0.64 11.25,13.64 11.25,13.64 C11.25,15.22 9.97,16.5 8.39,16.5 C8.39,16.5 -8.39,16.5 -8.39,16.5 C-9.97,16.5 -11.25,15.22 -11.25,13.64 C-11.25,13.64 -11.25,-0.64 -11.25,-0.64 C-11.25,-2.22 -9.97,-3.5 -8.39,-3.5 C-8.39,-3.5 8.39,-3.5 8.39,-3.5 C9.97,-3.5 11.25,-2.22 11.25,-0.64c " />
</group>
</group>
</group>
<group android:name="_R_G_L_0_G_N_4_T_1" android:translateX="22.75" android:translateY="22.25" android:scaleX="1.02" android:scaleY="1.02">
<group android:name="_R_G_L_0_G_N_4_T_0" android:translateX="-8.75" android:translateY="-8.75">
<group android:name="_R_G_L_0_G" android:translateX="8.995000000000001" android:translateY="18.345000000000002" android:pivotX="-0.031" android:pivotY="4.406" android:scaleX="0.98039" android:scaleY="0.98039">
<path android:name="_R_G_L_0_G_D_0_P_0" android:fillColor="#FF000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-0.09 8.63 C1.2,8.63 2.25,7.57 2.25,6.28 C2.25,4.99 1.2,3.94 -0.09,3.94 C-1.39,3.94 -2.44,4.99 -2.44,6.28 C-2.44,7.57 -1.39,8.63 -0.09,8.63c " />
</group>
</group>
</group>
</group>
<group android:name="time_group" />
</vector>
</aapt:attr>
<target android:name="_R_G_L_2_G_D_0_P_0">
<aapt:attr name="android:animation">
<set android:ordering="together">
<objectAnimator android:propertyName="strokeWidth" android:duration="333" android:startOffset="0" android:valueFrom="2" android:valueTo="2" android:valueType="floatType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.2,0 0.833,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
</set>
</aapt:attr>
</target>
<target android:name="_R_G_L_2_G_D_0_P_0">
<aapt:attr name="android:animation">
<set android:ordering="together">
<objectAnimator android:propertyName="pathData" android:duration="83" android:startOffset="0" android:valueFrom="M27.19 14.81 C27.19,14.81 27.19,8.3 27.19,8.3 C27.19,4.92 24.44,2.88 21.19,2.75 C17.74,2.62 15,4.74 15,8.11 C15,8.11 15,15 15,15 " android:valueTo="M27.13 10.19 C27.13,10.19 27.13,3.67 27.13,3.67 C27.13,0.3 24.38,-1.75 21.13,-1.87 C17.68,-2.01 14.94,0.11 14.94,3.49 C14.94,3.49 15,15 15,15 " android:valueType="pathType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.456,0 0.464,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator android:propertyName="pathData" android:duration="133" android:startOffset="83" android:valueFrom="M27.13 10.19 C27.13,10.19 27.13,3.67 27.13,3.67 C27.13,0.3 24.38,-1.75 21.13,-1.87 C17.68,-2.01 14.94,0.11 14.94,3.49 C14.94,3.49 15,15 15,15 " android:valueTo="M2.5 10.38 C2.5,10.38 2.5,3.99 2.5,3.99 C2.5,0.61 5.3,-2.12 8.75,-2.12 C12.2,-2.12 15,0.61 15,3.99 C15,3.99 15,15 15,15 " android:valueType="pathType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.606,0 0.035,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator android:propertyName="pathData" android:duration="117" android:startOffset="217" android:valueFrom="M2.5 10.38 C2.5,10.38 2.5,3.99 2.5,3.99 C2.5,0.61 5.3,-2.12 8.75,-2.12 C12.2,-2.12 15,0.61 15,3.99 C15,3.99 15,15 15,15 " android:valueTo="M2.52 14.65 C2.52,14.65 2.5,8.61 2.5,8.61 C2.5,5.24 5.3,2.5 8.75,2.5 C12.2,2.5 15,5.24 15,8.61 C15,8.61 15.02,14.65 15.02,14.65 " android:valueType="pathType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.511,0 0.409,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
</set>
</aapt:attr>
</target>
<target android:name="_R_G_L_2_G_T_1">
<aapt:attr name="android:animation">
<set android:ordering="together">
<objectAnimator android:propertyName="translateY" android:duration="333" android:startOffset="0" android:valueFrom="22.25" android:valueTo="22.25" android:valueType="floatType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.535,0 0.426,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator android:propertyName="translateY" android:duration="67" android:startOffset="333" android:valueFrom="22.25" android:valueTo="24.25" android:valueType="floatType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.535,0 0.426,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator android:propertyName="translateY" android:duration="100" android:startOffset="400" android:valueFrom="24.25" android:valueTo="22.25" android:valueType="floatType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.641,0 0.499,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
</set>
</aapt:attr>
</target>
<target android:name="_R_G_L_1_G_N_4_T_1">
<aapt:attr name="android:animation">
<set android:ordering="together">
<objectAnimator android:propertyName="translateY" android:duration="333" android:startOffset="0" android:valueFrom="22.25" android:valueTo="22.25" android:valueType="floatType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.535,0 0.426,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator android:propertyName="translateY" android:duration="67" android:startOffset="333" android:valueFrom="22.25" android:valueTo="24.25" android:valueType="floatType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.535,0 0.426,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator android:propertyName="translateY" android:duration="100" android:startOffset="400" android:valueFrom="24.25" android:valueTo="22.25" android:valueType="floatType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.641,0 0.499,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
</set>
</aapt:attr>
</target>
<target android:name="_R_G_L_0_G_N_4_T_1">
<aapt:attr name="android:animation">
<set android:ordering="together">
<objectAnimator android:propertyName="translateY" android:duration="333" android:startOffset="0" android:valueFrom="22.25" android:valueTo="22.25" android:valueType="floatType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.535,0 0.426,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator android:propertyName="translateY" android:duration="67" android:startOffset="333" android:valueFrom="22.25" android:valueTo="24.25" android:valueType="floatType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.535,0 0.426,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator android:propertyName="translateY" android:duration="100" android:startOffset="400" android:valueFrom="24.25" android:valueTo="22.25" android:valueType="floatType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.641,0 0.499,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
</set>
</aapt:attr>
</target>
<target android:name="time_group">
<aapt:attr name="android:animation">
<set android:ordering="together">
<objectAnimator android:propertyName="translateX" android:duration="850" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType" />
</set>
</aapt:attr>
</target>
</animated-vector>

View File

@@ -500,6 +500,17 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
updateVisibility();
}
@Override
public void onBiometricsCleared() {
final boolean wasUserUnlockedWithBiometric = mUserUnlockedWithBiometric;
mUserUnlockedWithBiometric =
mKeyguardUpdateMonitor.getUserUnlockedWithBiometric(
KeyguardUpdateMonitor.getCurrentUser());
if (wasUserUnlockedWithBiometric != mUserUnlockedWithBiometric) {
updateVisibility();
}
}
@Override
public void onBiometricRunningStateChanged(boolean running,
BiometricSourceType biometricSourceType) {

View File

@@ -68,6 +68,7 @@ import org.mockito.quality.Strictness;
public class LockIconViewControllerBaseTest 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;
@@ -130,6 +131,7 @@ public class LockIconViewControllerBaseTest extends SysuiTestCase {
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);

View File

@@ -262,6 +262,26 @@ public class LockIconViewControllerTest extends LockIconViewControllerBaseTest {
// 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_afterBiometricsCleared() {
// GIVEN lock icon controller is initialized and view is attached
init(/* useMigrationFlag= */false);
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 biometrics are cleared
when(mKeyguardUpdateMonitor.getUserUnlockedWithBiometric(anyInt())).thenReturn(false);
mKeyguardUpdateMonitorCallback.onBiometricsCleared();
// THEN the lock icon is shown
verify(mLockIconView).setContentDescription(LOCKED_LABEL);
}
}