blob: 4e3568b25a3f39b6d7ab5936f1b11af4ef7812fa [file] [log] [blame]
Jim Miller5e0f7ba2009-12-22 19:04:23 -08001/*
Jim Millerdcb3d842012-08-23 19:18:12 -07002 * Copyright (C) 2012 The Android Open Source Project
Jim Miller5e0f7ba2009-12-22 19:04:23 -08003 *
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
Jim Miller5ecd8112013-01-09 18:50:26 -080017package com.android.keyguard;
Jim Miller5e0f7ba2009-12-22 19:04:23 -080018
Jim Millerf7c5d0e2010-03-25 18:37:48 -070019import android.app.admin.DevicePolicyManager;
Michael Jurka1254f2f2012-10-25 11:44:31 -070020import android.content.Context;
Jim Miller54759062010-03-11 15:46:29 -080021import android.content.res.Configuration;
Jim Miller8ecfac12011-07-08 19:15:51 -070022import android.text.Editable;
Jim Millerda3ae8f2011-04-14 15:13:49 -070023import android.text.InputType;
Jim Miller8ecfac12011-07-08 19:15:51 -070024import android.text.TextWatcher;
Jim Miller8b9dda22010-03-02 17:24:48 -080025import android.text.method.DigitsKeyListener;
26import android.text.method.TextKeyListener;
Michael Jurka1254f2f2012-10-25 11:44:31 -070027import android.util.AttributeSet;
28import android.view.View;
Jim Miller858f8ea2011-08-19 14:50:34 -070029import android.view.inputmethod.InputMethodInfo;
30import android.view.inputmethod.InputMethodManager;
31import android.view.inputmethod.InputMethodSubtype;
Jim Millera781d012010-02-05 18:59:25 -080032import android.widget.TextView.OnEditorActionListener;
33
Jim Millera781d012010-02-05 18:59:25 -080034import com.android.internal.widget.PasswordEntryKeyboardHelper;
Michael Jurka1254f2f2012-10-25 11:44:31 -070035import com.android.internal.widget.PasswordEntryKeyboardView;
36
37import java.util.List;
Jim Miller5e0f7ba2009-12-22 19:04:23 -080038/**
Daniel Sandler2c1ce052012-10-24 23:19:34 -040039 * Displays an alphanumeric (latin-1) key entry for the user to enter
Jim Miller5e0f7ba2009-12-22 19:04:23 -080040 * an unlock password
41 */
Jim Miller5e0f7ba2009-12-22 19:04:23 -080042
Daniel Sandler69bdee72012-10-23 16:45:50 -040043public class KeyguardPasswordView extends KeyguardAbsKeyInputView
Jim Miller9cf2c522012-10-04 22:02:29 -070044 implements KeyguardSecurityView, OnEditorActionListener, TextWatcher {
Daniel Sandler69bdee72012-10-23 16:45:50 -040045
Chris Wrena042ac92012-11-07 11:37:06 -050046 private final boolean mShowImeAtScreenOn;
47
Daniel Sandler2c1ce052012-10-24 23:19:34 -040048 InputMethodManager mImm;
Jim Millerac8f5752012-09-07 16:48:41 -070049
Jim Millerdcb3d842012-08-23 19:18:12 -070050 public KeyguardPasswordView(Context context) {
Chris Wrena042ac92012-11-07 11:37:06 -050051 this(context, null);
Jim Millerdcb3d842012-08-23 19:18:12 -070052 }
Jim Miller54759062010-03-11 15:46:29 -080053
Jim Millerdcb3d842012-08-23 19:18:12 -070054 public KeyguardPasswordView(Context context, AttributeSet attrs) {
55 super(context, attrs);
Chris Wrena042ac92012-11-07 11:37:06 -050056 mShowImeAtScreenOn = context.getResources().
57 getBoolean(R.bool.kg_show_ime_at_screen_on);
Jim Millerdcb3d842012-08-23 19:18:12 -070058 }
59
Daniel Sandler69bdee72012-10-23 16:45:50 -040060 protected void resetState() {
Daniel Sandler2c1ce052012-10-24 23:19:34 -040061 mSecurityMessageDisplay.setMessage(R.string.kg_password_instructions, false);
Jim Miller08b2b6b2012-09-14 19:12:40 -070062 mPasswordEntry.setEnabled(true);
Jim Miller08b2b6b2012-09-14 19:12:40 -070063 }
64
Jim Millerdcb3d842012-08-23 19:18:12 -070065 @Override
Daniel Sandler8a26bf52012-10-30 13:29:50 -040066 protected int getPasswordTextViewId() {
67 return R.id.passwordEntry;
68 }
69
70 @Override
Jim Miller86f96372012-10-24 20:14:47 -070071 public boolean needsInput() {
72 return true;
73 }
74
75 @Override
Chris Wrena042ac92012-11-07 11:37:06 -050076 public void onResume(int reason) {
77 super.onResume(reason);
Daniel Sandlerfba4d4a2012-10-30 16:35:15 -040078 mPasswordEntry.requestFocus();
Chris Wrena042ac92012-11-07 11:37:06 -050079 if (reason != KeyguardSecurityView.SCREEN_ON || mShowImeAtScreenOn) {
80 mImm.showSoftInput(mPasswordEntry, InputMethodManager.SHOW_IMPLICIT);
81 }
Daniel Sandler2c1ce052012-10-24 23:19:34 -040082 }
83
84 @Override
85 public void onPause() {
86 super.onPause();
87 mImm.hideSoftInputFromWindow(getWindowToken(), 0);
88 }
89
90 @Override
Jim Millerdcb3d842012-08-23 19:18:12 -070091 protected void onFinishInflate() {
Daniel Sandler69bdee72012-10-23 16:45:50 -040092 super.onFinishInflate();
Jae Yong Sung8171b512010-08-05 10:44:27 -070093
Jim Millerd9d09452011-11-02 18:32:16 -070094 boolean imeOrDeleteButtonVisible = false;
Jim Millerac8f5752012-09-07 16:48:41 -070095
Daniel Sandler2c1ce052012-10-24 23:19:34 -040096 mImm = (InputMethodManager) getContext().getSystemService(
97 Context.INPUT_METHOD_SERVICE);
Ben Komalo51ea88a2011-10-03 10:53:26 -070098
Daniel Sandler2c1ce052012-10-24 23:19:34 -040099 mPasswordEntry.setKeyListener(TextKeyListener.getInstance());
100 mPasswordEntry.setInputType(InputType.TYPE_CLASS_TEXT
101 | InputType.TYPE_TEXT_VARIATION_PASSWORD);
Jim Miller8b9dda22010-03-02 17:24:48 -0800102
Jim Miller6b05d582011-07-18 13:09:59 -0700103 // Poke the wakelock any time the text is selected or modified
104 mPasswordEntry.setOnClickListener(new OnClickListener() {
105 public void onClick(View v) {
Jim Millerdcb3d842012-08-23 19:18:12 -0700106 mCallback.userActivity(0); // TODO: customize timeout for text?
Jim Miller6b05d582011-07-18 13:09:59 -0700107 }
108 });
Jim Millerdcb3d842012-08-23 19:18:12 -0700109
Jim Miller8ecfac12011-07-08 19:15:51 -0700110 mPasswordEntry.addTextChangedListener(new TextWatcher() {
111 public void onTextChanged(CharSequence s, int start, int before, int count) {
112 }
113
114 public void beforeTextChanged(CharSequence s, int start, int count, int after) {
115 }
116
117 public void afterTextChanged(Editable s) {
Adam Cohenac8a59d2012-10-15 13:04:24 -0700118 if (mCallback != null) {
119 mCallback.userActivity(0);
120 }
Jim Miller8ecfac12011-07-08 19:15:51 -0700121 }
122 });
Jim Miller858f8ea2011-08-19 14:50:34 -0700123
Daniel Sandler69bdee72012-10-23 16:45:50 -0400124 mPasswordEntry.requestFocus();
125
Jim Miller858f8ea2011-08-19 14:50:34 -0700126 // If there's more than one IME, enable the IME switcher button
127 View switchImeButton = findViewById(R.id.switch_ime_button);
Daniel Sandler2c1ce052012-10-24 23:19:34 -0400128 if (switchImeButton != null && hasMultipleEnabledIMEsOrSubtypes(mImm, false)) {
Jim Miller858f8ea2011-08-19 14:50:34 -0700129 switchImeButton.setVisibility(View.VISIBLE);
Jim Millerd9d09452011-11-02 18:32:16 -0700130 imeOrDeleteButtonVisible = true;
Jim Miller858f8ea2011-08-19 14:50:34 -0700131 switchImeButton.setOnClickListener(new OnClickListener() {
132 public void onClick(View v) {
Jim Millerdcb3d842012-08-23 19:18:12 -0700133 mCallback.userActivity(0); // Leave the screen on a bit longer
Daniel Sandler2c1ce052012-10-24 23:19:34 -0400134 mImm.showInputMethodPicker();
Jim Miller858f8ea2011-08-19 14:50:34 -0700135 }
136 });
137 }
Jim Millerd9d09452011-11-02 18:32:16 -0700138
Adam Powell70bc9f22012-10-12 22:02:27 -0700139 // If no icon is visible, reset the start margin on the password field so the text is
Jim Millerd9d09452011-11-02 18:32:16 -0700140 // still centered.
141 if (!imeOrDeleteButtonVisible) {
142 android.view.ViewGroup.LayoutParams params = mPasswordEntry.getLayoutParams();
143 if (params instanceof MarginLayoutParams) {
Adam Powell70bc9f22012-10-12 22:02:27 -0700144 final MarginLayoutParams mlp = (MarginLayoutParams) params;
145 mlp.setMarginStart(0);
Jim Millerd9d09452011-11-02 18:32:16 -0700146 mPasswordEntry.setLayoutParams(params);
147 }
148 }
Jim Miller858f8ea2011-08-19 14:50:34 -0700149 }
150
151 /**
152 * Method adapted from com.android.inputmethod.latin.Utils
153 *
154 * @param imm The input method manager
155 * @param shouldIncludeAuxiliarySubtypes
156 * @return true if we have multiple IMEs to choose from
157 */
158 private boolean hasMultipleEnabledIMEsOrSubtypes(InputMethodManager imm,
159 final boolean shouldIncludeAuxiliarySubtypes) {
160 final List<InputMethodInfo> enabledImis = imm.getEnabledInputMethodList();
161
162 // Number of the filtered IMEs
163 int filteredImisCount = 0;
164
165 for (InputMethodInfo imi : enabledImis) {
166 // We can return true immediately after we find two or more filtered IMEs.
167 if (filteredImisCount > 1) return true;
168 final List<InputMethodSubtype> subtypes =
169 imm.getEnabledInputMethodSubtypeList(imi, true);
170 // IMEs that have no subtypes should be counted.
171 if (subtypes.isEmpty()) {
172 ++filteredImisCount;
173 continue;
174 }
175
176 int auxCount = 0;
177 for (InputMethodSubtype subtype : subtypes) {
178 if (subtype.isAuxiliary()) {
179 ++auxCount;
180 }
181 }
182 final int nonAuxCount = subtypes.size() - auxCount;
183
184 // IMEs that have one or more non-auxiliary subtypes should be counted.
185 // If shouldIncludeAuxiliarySubtypes is true, IMEs that have two or more auxiliary
186 // subtypes should be counted as well.
187 if (nonAuxCount > 0 || (shouldIncludeAuxiliarySubtypes && auxCount > 1)) {
188 ++filteredImisCount;
189 continue;
190 }
191 }
192
193 return filteredImisCount > 1
194 // imm.getEnabledInputMethodSubtypeList(null, false) will return the current IME's enabled
195 // input method subtype (The current IME should be LatinIME.)
196 || imm.getEnabledInputMethodSubtypeList(null, false).size() > 1;
Jim Miller5e0f7ba2009-12-22 19:04:23 -0800197 }
Adam Cohen6fb841f2012-10-24 13:15:38 -0700198
199 @Override
200 public void showUsabilityHint() {
201 }
Daniel Sandler16d90922012-11-01 12:41:14 -0400202
203 @Override
204 public int getWrongPasswordStringId() {
205 return R.string.kg_wrong_password;
206 }
Jim Miller5e0f7ba2009-12-22 19:04:23 -0800207}