blob: 95bbea15a88c8c459e74018bdcd2f04cf76c1391 [file] [log] [blame]
Alan Viverette3da604b2020-06-10 18:34:39 +00001/*
2 * Copyright (C) 2019 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
17package com.android.systemui.biometrics;
18
19import android.content.Context;
20import android.os.UserHandle;
21import android.text.InputType;
22import android.util.AttributeSet;
23import android.view.KeyEvent;
24import android.view.inputmethod.EditorInfo;
25import android.view.inputmethod.InputMethodManager;
26import android.widget.ImeAwareEditText;
27import android.widget.TextView;
28
29import com.android.internal.widget.LockPatternChecker;
30import com.android.internal.widget.LockscreenCredential;
31import com.android.systemui.R;
32
33/**
34 * Pin and Password UI
35 */
36public class AuthCredentialPasswordView extends AuthCredentialView
37 implements TextView.OnEditorActionListener {
38
39 private static final String TAG = "BiometricPrompt/AuthCredentialPasswordView";
40
41 private final InputMethodManager mImm;
42 private ImeAwareEditText mPasswordField;
43
44 public AuthCredentialPasswordView(Context context,
45 AttributeSet attrs) {
46 super(context, attrs);
47 mImm = mContext.getSystemService(InputMethodManager.class);
48 }
49
50 @Override
51 protected void onFinishInflate() {
52 super.onFinishInflate();
53 mPasswordField = findViewById(R.id.lockPassword);
54 mPasswordField.setOnEditorActionListener(this);
55 // TODO: De-dupe the logic with AuthContainerView
56 mPasswordField.setOnKeyListener((v, keyCode, event) -> {
57 if (keyCode != KeyEvent.KEYCODE_BACK) {
58 return false;
59 }
60 if (event.getAction() == KeyEvent.ACTION_UP) {
61 mContainerView.sendEarlyUserCanceled();
62 mContainerView.animateAway(AuthDialogCallback.DISMISSED_USER_CANCELED);
63 }
64 return true;
65 });
66 }
67
68 @Override
69 protected void onAttachedToWindow() {
70 super.onAttachedToWindow();
71
72 mPasswordField.setTextOperationUser(UserHandle.of(mUserId));
73 if (mCredentialType == Utils.CREDENTIAL_PIN) {
74 mPasswordField.setInputType(
75 InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_VARIATION_PASSWORD);
76 }
77
78 mPasswordField.requestFocus();
79 mPasswordField.scheduleShowSoftInput();
80 }
81
82 @Override
83 public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
84 // Check if this was the result of hitting the enter key
85 final boolean isSoftImeEvent = event == null
86 && (actionId == EditorInfo.IME_NULL
87 || actionId == EditorInfo.IME_ACTION_DONE
88 || actionId == EditorInfo.IME_ACTION_NEXT);
89 final boolean isKeyboardEnterKey = event != null
90 && KeyEvent.isConfirmKey(event.getKeyCode())
91 && event.getAction() == KeyEvent.ACTION_DOWN;
92 if (isSoftImeEvent || isKeyboardEnterKey) {
93 checkPasswordAndUnlock();
94 return true;
95 }
96 return false;
97 }
98
99 private void checkPasswordAndUnlock() {
100 try (LockscreenCredential password = mCredentialType == Utils.CREDENTIAL_PIN
101 ? LockscreenCredential.createPinOrNone(mPasswordField.getText())
102 : LockscreenCredential.createPasswordOrNone(mPasswordField.getText())) {
103 if (password.isNone()) {
104 return;
105 }
106
107 mPendingLockCheck = LockPatternChecker.verifyCredential(mLockPatternUtils,
108 password, mOperationId, mEffectiveUserId, this::onCredentialVerified);
109 }
110 }
111
112 @Override
113 protected void onCredentialVerified(byte[] attestation, int timeoutMs) {
114 super.onCredentialVerified(attestation, timeoutMs);
115
116 final boolean matched = attestation != null;
117
118 if (matched) {
119 mImm.hideSoftInputFromWindow(getWindowToken(), 0 /* flags */);
120 } else {
121 mPasswordField.setText("");
122 }
123 }
124}