blob: 99a40ba5ebf41859131c9474e92ef1dc4635bc5a [file] [log] [blame]
Kevin Chyn8110ebb2019-10-02 11:16:31 -07001/*
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.text.InputType;
21import android.util.AttributeSet;
22import android.view.KeyEvent;
23import android.view.inputmethod.EditorInfo;
24import android.view.inputmethod.InputMethodManager;
25import android.widget.EditText;
26import android.widget.TextView;
27
28import com.android.internal.widget.LockPatternChecker;
29import com.android.internal.widget.LockPatternUtils;
30import com.android.systemui.R;
31
32/**
33 * Pin and Password UI
34 */
35public class AuthCredentialPasswordView extends AuthCredentialView
36 implements TextView.OnEditorActionListener {
37
38 private static final String TAG = "BiometricPrompt/AuthCredentialPasswordView";
39
40 private final InputMethodManager mImm;
41 private EditText mPasswordField;
42
43 public AuthCredentialPasswordView(Context context,
44 AttributeSet attrs) {
45 super(context, attrs);
46 mImm = mContext.getSystemService(InputMethodManager.class);
47 }
48
49 @Override
50 protected void onFinishInflate() {
51 super.onFinishInflate();
52 mPasswordField = findViewById(R.id.lockPassword);
53 mPasswordField.setOnEditorActionListener(this);
54
55 if (mCredentialType == Utils.CREDENTIAL_PIN) {
56 mPasswordField.setInputType(
57 InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_VARIATION_PASSWORD);
58 }
59
60 mPasswordField.setOnKeyListener((v, keyCode, event) -> {
61 if (keyCode != KeyEvent.KEYCODE_BACK) {
62 return false;
63 }
64 if (event.getAction() == KeyEvent.ACTION_UP) {
65 mContainerView.animateAway(AuthDialogCallback.DISMISSED_USER_CANCELED);
66 }
67 return true;
68 });
69 }
70
71 @Override
72 protected void onAttachedToWindow() {
73 super.onAttachedToWindow();
74
75 // Wait a bit to focus the field so the focusable flag on the window is already set then.
76 post(() -> {
77 mPasswordField.requestFocus();
78 mImm.showSoftInput(mPasswordField, InputMethodManager.SHOW_IMPLICIT);
79 });
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 final byte[] password = LockPatternUtils.charSequenceToByteArray(mPasswordField.getText());
101 if (password == null || password.length == 0) {
102 return;
103 }
104
105 mPendingLockCheck = LockPatternChecker.checkPassword(mLockPatternUtils,
106 password, mUserId, this::onCredentialChecked);
107 }
108
109 @Override
110 protected void onCredentialChecked(boolean matched, int timeoutMs) {
111 super.onCredentialChecked(matched, timeoutMs);
112
113 if (matched) {
114 mImm.hideSoftInputFromWindow(getWindowToken(), 0 /* flags */);
115 } else {
116 mPasswordField.setText("");
117 }
118 }
119}