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

Commit cf59cf80 authored by Christoph Schlosser's avatar Christoph Schlosser
Browse files

Show/hide the animation on PIN entry when changing connected devices

Keyguard would previously decide if it should show the animations on a
button when creating the view. This can lead to unexpected behavior
when attaching or detaching a physical keyboard from the device.

Now Keyguard listens to changes on the connected devices and changes
the animation showing/hiding behavior when necessary.

Flag: com.android.internal.widget.flags.hide_last_char_with_physical_input
Test: atest KeyguardPinBasedInputViewControllerTest
Bug: 384694667

Change-Id: Iab3feda1cc692ae7fbe46623665cb5f8329eaefd
parent 32bc5fec
Loading
Loading
Loading
Loading
+118 −1
Original line number Original line Diff line number Diff line
@@ -16,12 +16,18 @@


package com.android.keyguard;
package com.android.keyguard;


import static com.android.internal.widget.flags.Flags.FLAG_HIDE_LAST_CHAR_WITH_PHYSICAL_INPUT;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertThat;


import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.when;


import android.hardware.input.InputManager;
import android.platform.test.annotations.EnableFlags;
import android.testing.TestableLooper.RunWithLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.view.View;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup;
@@ -90,6 +96,8 @@ public class KeyguardPinBasedInputViewControllerTest extends SysuiTestCase {
    @Mock
    @Mock
    private UserActivityNotifier mUserActivityNotifier;
    private UserActivityNotifier mUserActivityNotifier;
    private NumPadKey[] mButtons = new NumPadKey[]{};
    private NumPadKey[] mButtons = new NumPadKey[]{};
    @Mock
    private InputManager mInputManager;


    private KeyguardPinBasedInputViewController mKeyguardPinViewController;
    private KeyguardPinBasedInputViewController mKeyguardPinViewController;


@@ -118,12 +126,13 @@ public class KeyguardPinBasedInputViewControllerTest extends SysuiTestCase {
                new KeyguardKeyboardInteractor(new FakeKeyboardRepository());
                new KeyguardKeyboardInteractor(new FakeKeyboardRepository());
        FakeFeatureFlags featureFlags = new FakeFeatureFlags();
        FakeFeatureFlags featureFlags = new FakeFeatureFlags();
        mSetFlagsRule.enableFlags(com.android.systemui.Flags.FLAG_REVAMPED_BOUNCER_MESSAGES);
        mSetFlagsRule.enableFlags(com.android.systemui.Flags.FLAG_REVAMPED_BOUNCER_MESSAGES);
        when(mLockPatternUtils.isPinEnhancedPrivacyEnabled(anyInt())).thenReturn(false);
        mKeyguardPinViewController = new KeyguardPinBasedInputViewController(mPinBasedInputView,
        mKeyguardPinViewController = new KeyguardPinBasedInputViewController(mPinBasedInputView,
                mKeyguardUpdateMonitor, mSecurityMode, mLockPatternUtils, mKeyguardSecurityCallback,
                mKeyguardUpdateMonitor, mSecurityMode, mLockPatternUtils, mKeyguardSecurityCallback,
                mKeyguardMessageAreaControllerFactory, mLatencyTracker,
                mKeyguardMessageAreaControllerFactory, mLatencyTracker,
                mEmergencyButtonController, mFalsingCollector, featureFlags,
                mEmergencyButtonController, mFalsingCollector, featureFlags,
                mSelectedUserInteractor, keyguardKeyboardInteractor, mBouncerHapticPlayer,
                mSelectedUserInteractor, keyguardKeyboardInteractor, mBouncerHapticPlayer,
                mUserActivityNotifier) {
                mUserActivityNotifier, mInputManager) {
            @Override
            @Override
            public void onResume(int reason) {
            public void onResume(int reason) {
                super.onResume(reason);
                super.onResume(reason);
@@ -148,4 +157,112 @@ public class KeyguardPinBasedInputViewControllerTest extends SysuiTestCase {
        mKeyguardPinViewController.resetState();
        mKeyguardPinViewController.resetState();
        verify(mKeyguardMessageAreaController).setMessage(R.string.keyguard_enter_your_pin);
        verify(mKeyguardMessageAreaController).setMessage(R.string.keyguard_enter_your_pin);
    }
    }

    @Test
    @EnableFlags(FLAG_HIDE_LAST_CHAR_WITH_PHYSICAL_INPUT)
    public void updateAnimations_addDevice_notKeyboard() {
        when(mLockPatternUtils.isPinEnhancedPrivacyEnabled(anyInt())).thenReturn(false);
        verify(mPasswordEntry, times(1)).setShowPassword(true);
        mKeyguardPinViewController.onViewAttached();
        mKeyguardPinViewController.onInputDeviceAdded(1);
        verify(mPasswordEntry, times(1)).setShowPassword(true);
    }

    @Test
    @EnableFlags(FLAG_HIDE_LAST_CHAR_WITH_PHYSICAL_INPUT)
    public void updateAnimations_addDevice_keyboard() {
        when(mLockPatternUtils.isPinEnhancedPrivacyEnabled(anyInt())).thenReturn(true);
        verify(mPasswordEntry, times(1)).setShowPassword(true);
        mKeyguardPinViewController.onViewAttached();
        mKeyguardPinViewController.onInputDeviceAdded(1);
        verify(mPasswordEntry, times(1)).setShowPassword(false);
    }

    @Test
    @EnableFlags(FLAG_HIDE_LAST_CHAR_WITH_PHYSICAL_INPUT)
    public void updateAnimations_addDevice_multipleKeyboards() {
        when(mLockPatternUtils.isPinEnhancedPrivacyEnabled(anyInt())).thenReturn(true);
        verify(mPasswordEntry, times(1)).setShowPassword(true);
        mKeyguardPinViewController.onViewAttached();
        mKeyguardPinViewController.onInputDeviceAdded(1);
        verify(mPasswordEntry, times(1)).setShowPassword(false);
        mKeyguardPinViewController.onInputDeviceAdded(1);
        verify(mPasswordEntry, times(1)).setShowPassword(false);
    }

    @Test
    @EnableFlags(FLAG_HIDE_LAST_CHAR_WITH_PHYSICAL_INPUT)
    public void updateAnimations_removeDevice_notKeyboard() {
        when(mLockPatternUtils.isPinEnhancedPrivacyEnabled(anyInt())).thenReturn(false);
        verify(mPasswordEntry, times(1)).setShowPassword(true);
        mKeyguardPinViewController.onViewAttached();
        mKeyguardPinViewController.onInputDeviceRemoved(1);
        verify(mPasswordEntry, times(1)).setShowPassword(true);
    }

    @Test
    @EnableFlags(FLAG_HIDE_LAST_CHAR_WITH_PHYSICAL_INPUT)
    public void updateAnimations_removeDevice_keyboard() {
        when(mLockPatternUtils.isPinEnhancedPrivacyEnabled(anyInt())).thenReturn(true, false);
        verify(mPasswordEntry, times(1)).setShowPassword(true);
        verify(mPasswordEntry, times(0)).setShowPassword(false);
        mKeyguardPinViewController.onViewAttached();
        verify(mPasswordEntry, times(1)).setShowPassword(true);
        verify(mPasswordEntry, times(1)).setShowPassword(false);
        mKeyguardPinViewController.onInputDeviceRemoved(1);
        verify(mPasswordEntry, times(2)).setShowPassword(true);
        verify(mPasswordEntry, times(1)).setShowPassword(false);
    }

    @Test
    @EnableFlags(FLAG_HIDE_LAST_CHAR_WITH_PHYSICAL_INPUT)
    public void updateAnimations_removeDevice_multipleKeyboards() {
        when(mLockPatternUtils.isPinEnhancedPrivacyEnabled(anyInt())).thenReturn(true, true);
        verify(mPasswordEntry, times(1)).setShowPassword(true);
        verify(mPasswordEntry, times(0)).setShowPassword(false);
        mKeyguardPinViewController.onViewAttached();
        verify(mPasswordEntry, times(1)).setShowPassword(true);
        verify(mPasswordEntry, times(1)).setShowPassword(false);
        mKeyguardPinViewController.onInputDeviceRemoved(1);
        verify(mPasswordEntry, times(1)).setShowPassword(true);
        verify(mPasswordEntry, times(1)).setShowPassword(false);
    }

    @Test
    @EnableFlags(FLAG_HIDE_LAST_CHAR_WITH_PHYSICAL_INPUT)
    public void updateAnimations_updateDevice_notKeyboard() {
        when(mLockPatternUtils.isPinEnhancedPrivacyEnabled(anyInt())).thenReturn(false);
        verify(mPasswordEntry, times(1)).setShowPassword(true);
        mKeyguardPinViewController.onViewAttached();
        mKeyguardPinViewController.onInputDeviceChanged(1);
        verify(mPasswordEntry, times(1)).setShowPassword(true);
    }

    @Test
    @EnableFlags(FLAG_HIDE_LAST_CHAR_WITH_PHYSICAL_INPUT)
    public void updateAnimations_updateDevice_keyboard() {
        when(mLockPatternUtils.isPinEnhancedPrivacyEnabled(anyInt())).thenReturn(true, false);
        verify(mPasswordEntry, times(1)).setShowPassword(true);
        verify(mPasswordEntry, times(0)).setShowPassword(false);
        mKeyguardPinViewController.onViewAttached();
        verify(mPasswordEntry, times(1)).setShowPassword(true);
        verify(mPasswordEntry, times(1)).setShowPassword(false);
        mKeyguardPinViewController.onInputDeviceChanged(1);
        verify(mPasswordEntry, times(2)).setShowPassword(true);
        verify(mPasswordEntry, times(1)).setShowPassword(false);
    }

    @Test
    @EnableFlags(FLAG_HIDE_LAST_CHAR_WITH_PHYSICAL_INPUT)
    public void updateAnimations_updateDevice_multipleKeyboards() {
        when(mLockPatternUtils.isPinEnhancedPrivacyEnabled(anyInt())).thenReturn(true, true);
        verify(mPasswordEntry, times(1)).setShowPassword(true);
        verify(mPasswordEntry, times(0)).setShowPassword(false);
        mKeyguardPinViewController.onViewAttached();
        verify(mPasswordEntry, times(1)).setShowPassword(true);
        verify(mPasswordEntry, times(1)).setShowPassword(false);
        mKeyguardPinViewController.onInputDeviceChanged(1);
        verify(mPasswordEntry, times(1)).setShowPassword(true);
        verify(mPasswordEntry, times(1)).setShowPassword(false);
    }
}
}
+3 −0
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@


package com.android.keyguard
package com.android.keyguard


import android.hardware.input.InputManager
import android.testing.TestableLooper
import android.testing.TestableLooper
import android.view.View
import android.view.View
import android.view.ViewGroup
import android.view.ViewGroup
@@ -104,6 +105,7 @@ class KeyguardPinViewControllerTest : SysuiTestCase() {
    @Mock lateinit var enterButton: View
    @Mock lateinit var enterButton: View
    @Mock lateinit var uiEventLogger: UiEventLogger
    @Mock lateinit var uiEventLogger: UiEventLogger
    @Mock lateinit var mUserActivityNotifier: UserActivityNotifier
    @Mock lateinit var mUserActivityNotifier: UserActivityNotifier
    @Mock lateinit var inputManager: InputManager


    @Captor lateinit var postureCallbackCaptor: ArgumentCaptor<DevicePostureController.Callback>
    @Captor lateinit var postureCallbackCaptor: ArgumentCaptor<DevicePostureController.Callback>


@@ -154,6 +156,7 @@ class KeyguardPinViewControllerTest : SysuiTestCase() {
            keyguardKeyboardInteractor,
            keyguardKeyboardInteractor,
            kosmos.bouncerHapticPlayer,
            kosmos.bouncerHapticPlayer,
            mUserActivityNotifier,
            mUserActivityNotifier,
            inputManager,
        )
        )
    }
    }


+3 −0
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@


package com.android.keyguard
package com.android.keyguard


import android.hardware.input.InputManager
import android.telephony.TelephonyManager
import android.telephony.TelephonyManager
import android.testing.TestableLooper
import android.testing.TestableLooper
import android.view.LayoutInflater
import android.view.LayoutInflater
@@ -73,6 +74,7 @@ class KeyguardSimPinViewControllerTest : SysuiTestCase() {
    @Mock private lateinit var mUserActivityNotifier: UserActivityNotifier
    @Mock private lateinit var mUserActivityNotifier: UserActivityNotifier
    private val updateMonitorCallbackArgumentCaptor =
    private val updateMonitorCallbackArgumentCaptor =
        ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java)
        ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java)
    @Mock private lateinit var inputManager: InputManager


    private val kosmos = testKosmos()
    private val kosmos = testKosmos()


@@ -107,6 +109,7 @@ class KeyguardSimPinViewControllerTest : SysuiTestCase() {
                keyguardKeyboardInteractor,
                keyguardKeyboardInteractor,
                kosmos.bouncerHapticPlayer,
                kosmos.bouncerHapticPlayer,
                mUserActivityNotifier,
                mUserActivityNotifier,
                inputManager,
            )
            )
        underTest.init()
        underTest.init()
        underTest.onViewAttached()
        underTest.onViewAttached()
+3 −0
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@


package com.android.keyguard
package com.android.keyguard


import android.hardware.input.InputManager
import android.telephony.PinResult
import android.telephony.PinResult
import android.telephony.TelephonyManager
import android.telephony.TelephonyManager
import android.testing.TestableLooper
import android.testing.TestableLooper
@@ -65,6 +66,7 @@ class KeyguardSimPukViewControllerTest : SysuiTestCase() {
    private lateinit var keyguardMessageAreaController:
    private lateinit var keyguardMessageAreaController:
        KeyguardMessageAreaController<BouncerKeyguardMessageArea>
        KeyguardMessageAreaController<BouncerKeyguardMessageArea>
    @Mock private lateinit var mUserActivityNotifier: UserActivityNotifier
    @Mock private lateinit var mUserActivityNotifier: UserActivityNotifier
    @Mock private lateinit var inputManager: InputManager


    private val kosmos = testKosmos()
    private val kosmos = testKosmos()


@@ -102,6 +104,7 @@ class KeyguardSimPukViewControllerTest : SysuiTestCase() {
                keyguardKeyboardInteractor,
                keyguardKeyboardInteractor,
                kosmos.bouncerHapticPlayer,
                kosmos.bouncerHapticPlayer,
                mUserActivityNotifier,
                mUserActivityNotifier,
                inputManager,
            )
            )
        underTest.init()
        underTest.init()
    }
    }
+10 −5
Original line number Original line Diff line number Diff line
@@ -21,6 +21,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Nullable;
import android.content.res.ColorStateList;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.Resources;
import android.hardware.input.InputManager;
import android.telephony.TelephonyManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.text.TextUtils;
import android.util.Log;
import android.util.Log;
@@ -219,6 +220,7 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView>
        private final KeyguardKeyboardInteractor mKeyguardKeyboardInteractor;
        private final KeyguardKeyboardInteractor mKeyguardKeyboardInteractor;
        private final BouncerHapticPlayer mBouncerHapticPlayer;
        private final BouncerHapticPlayer mBouncerHapticPlayer;
        private final UserActivityNotifier mUserActivityNotifier;
        private final UserActivityNotifier mUserActivityNotifier;
        private final InputManager mInputManager;


        @Inject
        @Inject
        public Factory(KeyguardUpdateMonitor keyguardUpdateMonitor,
        public Factory(KeyguardUpdateMonitor keyguardUpdateMonitor,
@@ -235,7 +237,8 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView>
                UiEventLogger uiEventLogger,
                UiEventLogger uiEventLogger,
                KeyguardKeyboardInteractor keyguardKeyboardInteractor,
                KeyguardKeyboardInteractor keyguardKeyboardInteractor,
                BouncerHapticPlayer bouncerHapticPlayer,
                BouncerHapticPlayer bouncerHapticPlayer,
                UserActivityNotifier userActivityNotifier) {
                UserActivityNotifier userActivityNotifier,
                InputManager inputManager) {
            mKeyguardUpdateMonitor = keyguardUpdateMonitor;
            mKeyguardUpdateMonitor = keyguardUpdateMonitor;
            mLockPatternUtils = lockPatternUtils;
            mLockPatternUtils = lockPatternUtils;
            mLatencyTracker = latencyTracker;
            mLatencyTracker = latencyTracker;
@@ -254,6 +257,7 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView>
            mKeyguardKeyboardInteractor = keyguardKeyboardInteractor;
            mKeyguardKeyboardInteractor = keyguardKeyboardInteractor;
            mBouncerHapticPlayer = bouncerHapticPlayer;
            mBouncerHapticPlayer = bouncerHapticPlayer;
            mUserActivityNotifier = userActivityNotifier;
            mUserActivityNotifier = userActivityNotifier;
            mInputManager = inputManager;
        }
        }


        /** Create a new {@link KeyguardInputViewController}. */
        /** Create a new {@link KeyguardInputViewController}. */
@@ -285,22 +289,23 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView>
                        emergencyButtonController, mFalsingCollector,
                        emergencyButtonController, mFalsingCollector,
                        mDevicePostureController, mFeatureFlags, mSelectedUserInteractor,
                        mDevicePostureController, mFeatureFlags, mSelectedUserInteractor,
                        mUiEventLogger, mKeyguardKeyboardInteractor, mBouncerHapticPlayer,
                        mUiEventLogger, mKeyguardKeyboardInteractor, mBouncerHapticPlayer,
                        mUserActivityNotifier);
                        mUserActivityNotifier, mInputManager);
            } else if (keyguardInputView instanceof KeyguardSimPinView) {
            } else if (keyguardInputView instanceof KeyguardSimPinView) {
                return new KeyguardSimPinViewController((KeyguardSimPinView) keyguardInputView,
                return new KeyguardSimPinViewController((KeyguardSimPinView) keyguardInputView,
                        mKeyguardUpdateMonitor, securityMode, mLockPatternUtils,
                        mKeyguardUpdateMonitor, securityMode, mLockPatternUtils,
                        keyguardSecurityCallback, mMessageAreaControllerFactory, mLatencyTracker,
                        keyguardSecurityCallback, mMessageAreaControllerFactory, mLatencyTracker,
                        mTelephonyManager, mFalsingCollector,
                        mTelephonyManager, mFalsingCollector,
                        emergencyButtonController, mFeatureFlags, mSelectedUserInteractor,
                        emergencyButtonController, mFeatureFlags, mSelectedUserInteractor,
                        mKeyguardKeyboardInteractor, mBouncerHapticPlayer, mUserActivityNotifier);
                        mKeyguardKeyboardInteractor, mBouncerHapticPlayer, mUserActivityNotifier,
                        mInputManager);
            } else if (keyguardInputView instanceof KeyguardSimPukView) {
            } else if (keyguardInputView instanceof KeyguardSimPukView) {
                return new KeyguardSimPukViewController((KeyguardSimPukView) keyguardInputView,
                return new KeyguardSimPukViewController((KeyguardSimPukView) keyguardInputView,
                        mKeyguardUpdateMonitor, securityMode, mLockPatternUtils,
                        mKeyguardUpdateMonitor, securityMode, mLockPatternUtils,
                        keyguardSecurityCallback, mMessageAreaControllerFactory, mLatencyTracker,
                        keyguardSecurityCallback, mMessageAreaControllerFactory, mLatencyTracker,
                        mTelephonyManager, mFalsingCollector,
                        mTelephonyManager, mFalsingCollector,
                        emergencyButtonController, mFeatureFlags, mSelectedUserInteractor,
                        emergencyButtonController, mFeatureFlags, mSelectedUserInteractor,
                        mKeyguardKeyboardInteractor, mBouncerHapticPlayer, mUserActivityNotifier
                        mKeyguardKeyboardInteractor, mBouncerHapticPlayer, mUserActivityNotifier,
                );
                        mInputManager);
            }
            }


            throw new RuntimeException("Unable to find controller for " + keyguardInputView);
            throw new RuntimeException("Unable to find controller for " + keyguardInputView);
Loading