Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fb310c25 authored by Beverly's avatar Beverly
Browse files

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
parent f1f50ee2
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -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>
+145 −0
Original line number Diff line number Diff line
<?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>
+11 −0
Original line number Diff line number Diff line
@@ -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) {
+2 −0
Original line number Diff line number Diff line
@@ -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);
+20 −0
Original line number Diff line number Diff line
@@ -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);
    }
}