1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.keyguard; 18 19 import android.view.KeyEvent; 20 import android.view.MotionEvent; 21 import android.view.View; 22 import android.view.View.OnKeyListener; 23 import android.view.View.OnTouchListener; 24 25 import com.android.internal.util.LatencyTracker; 26 import com.android.internal.widget.LockPatternUtils; 27 import com.android.keyguard.KeyguardSecurityModel.SecurityMode; 28 import com.android.systemui.R; 29 import com.android.systemui.classifier.FalsingCollector; 30 31 public abstract class KeyguardPinBasedInputViewController<T extends KeyguardPinBasedInputView> 32 extends KeyguardAbsKeyInputViewController<T> { 33 34 private final LiftToActivateListener mLiftToActivateListener; 35 private final FalsingCollector mFalsingCollector; 36 protected PasswordTextView mPasswordEntry; 37 38 private final OnKeyListener mOnKeyListener = (v, keyCode, event) -> { 39 if (event.getAction() == KeyEvent.ACTION_DOWN) { 40 return mView.onKeyDown(keyCode, event); 41 } 42 return false; 43 }; 44 45 private final OnTouchListener mActionButtonTouchListener = (v, event) -> { 46 if (event.getActionMasked() == MotionEvent.ACTION_DOWN) { 47 mView.doHapticKeyClick(); 48 } 49 return false; 50 }; 51 KeyguardPinBasedInputViewController(T view, KeyguardUpdateMonitor keyguardUpdateMonitor, SecurityMode securityMode, LockPatternUtils lockPatternUtils, KeyguardSecurityCallback keyguardSecurityCallback, KeyguardMessageAreaController.Factory messageAreaControllerFactory, LatencyTracker latencyTracker, LiftToActivateListener liftToActivateListener, EmergencyButtonController emergencyButtonController, FalsingCollector falsingCollector)52 protected KeyguardPinBasedInputViewController(T view, 53 KeyguardUpdateMonitor keyguardUpdateMonitor, 54 SecurityMode securityMode, 55 LockPatternUtils lockPatternUtils, 56 KeyguardSecurityCallback keyguardSecurityCallback, 57 KeyguardMessageAreaController.Factory messageAreaControllerFactory, 58 LatencyTracker latencyTracker, 59 LiftToActivateListener liftToActivateListener, 60 EmergencyButtonController emergencyButtonController, 61 FalsingCollector falsingCollector) { 62 super(view, keyguardUpdateMonitor, securityMode, lockPatternUtils, keyguardSecurityCallback, 63 messageAreaControllerFactory, latencyTracker, falsingCollector, 64 emergencyButtonController); 65 mLiftToActivateListener = liftToActivateListener; 66 mFalsingCollector = falsingCollector; 67 mPasswordEntry = mView.findViewById(mView.getPasswordTextViewId()); 68 } 69 70 @Override onViewAttached()71 protected void onViewAttached() { 72 super.onViewAttached(); 73 74 for (NumPadKey button: mView.getButtons()) { 75 button.setOnTouchListener((v, event) -> { 76 if (event.getActionMasked() == MotionEvent.ACTION_DOWN) { 77 mFalsingCollector.avoidGesture(); 78 } 79 return false; 80 }); 81 } 82 mPasswordEntry.setOnKeyListener(mOnKeyListener); 83 mPasswordEntry.setUserActivityListener(this::onUserInput); 84 85 View deleteButton = mView.findViewById(R.id.delete_button); 86 deleteButton.setOnTouchListener(mActionButtonTouchListener); 87 deleteButton.setOnClickListener(v -> { 88 // check for time-based lockouts 89 if (mPasswordEntry.isEnabled()) { 90 mPasswordEntry.deleteLastChar(); 91 } 92 }); 93 deleteButton.setOnLongClickListener(v -> { 94 // check for time-based lockouts 95 if (mPasswordEntry.isEnabled()) { 96 mView.resetPasswordText(true /* animate */, true /* announce */); 97 } 98 mView.doHapticKeyClick(); 99 return true; 100 }); 101 102 View okButton = mView.findViewById(R.id.key_enter); 103 if (okButton != null) { 104 okButton.setOnTouchListener(mActionButtonTouchListener); 105 okButton.setOnClickListener(new View.OnClickListener() { 106 @Override 107 public void onClick(View v) { 108 if (mPasswordEntry.isEnabled()) { 109 verifyPasswordAndUnlock(); 110 } 111 } 112 }); 113 okButton.setOnHoverListener(mLiftToActivateListener); 114 } 115 } 116 117 @Override onViewDetached()118 protected void onViewDetached() { 119 super.onViewDetached(); 120 121 for (NumPadKey button: mView.getButtons()) { 122 button.setOnTouchListener(null); 123 } 124 } 125 126 @Override onResume(int reason)127 public void onResume(int reason) { 128 super.onResume(reason); 129 mPasswordEntry.requestFocus(); 130 } 131 132 @Override resetState()133 void resetState() { 134 mView.setPasswordEntryEnabled(true); 135 } 136 } 137