blob: e733afc59bf58f2c0ee316e3dc6b2667ed295686 [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
Michael Jurka1254f2f2012-10-25 11:44:31 -070019import android.content.Context;
Jim Miller8ecfac12011-07-08 19:15:51 -070020import android.text.Editable;
Jim Millerda3ae8f2011-04-14 15:13:49 -070021import android.text.InputType;
Jim Miller8ecfac12011-07-08 19:15:51 -070022import android.text.TextWatcher;
Jim Miller8b9dda22010-03-02 17:24:48 -080023import android.text.method.TextKeyListener;
Michael Jurka1254f2f2012-10-25 11:44:31 -070024import android.util.AttributeSet;
25import android.view.View;
Jim Miller858f8ea2011-08-19 14:50:34 -070026import android.view.inputmethod.InputMethodInfo;
27import android.view.inputmethod.InputMethodManager;
28import android.view.inputmethod.InputMethodSubtype;
Jim Millera781d012010-02-05 18:59:25 -080029import android.widget.TextView.OnEditorActionListener;
30
Michael Jurka1254f2f2012-10-25 11:44:31 -070031import java.util.List;
Jim Miller5e0f7ba2009-12-22 19:04:23 -080032/**
Daniel Sandler2c1ce052012-10-24 23:19:34 -040033 * Displays an alphanumeric (latin-1) key entry for the user to enter
Jim Miller5e0f7ba2009-12-22 19:04:23 -080034 * an unlock password
35 */
Jim Miller5e0f7ba2009-12-22 19:04:23 -080036
Daniel Sandler69bdee72012-10-23 16:45:50 -040037public class KeyguardPasswordView extends KeyguardAbsKeyInputView
Jim Miller9cf2c522012-10-04 22:02:29 -070038 implements KeyguardSecurityView, OnEditorActionListener, TextWatcher {
Daniel Sandler69bdee72012-10-23 16:45:50 -040039
Chris Wrena042ac92012-11-07 11:37:06 -050040 private final boolean mShowImeAtScreenOn;
41
Daniel Sandler2c1ce052012-10-24 23:19:34 -040042 InputMethodManager mImm;
Jim Millerac8f5752012-09-07 16:48:41 -070043
Jim Millerdcb3d842012-08-23 19:18:12 -070044 public KeyguardPasswordView(Context context) {
Chris Wrena042ac92012-11-07 11:37:06 -050045 this(context, null);
Jim Millerdcb3d842012-08-23 19:18:12 -070046 }
Jim Miller54759062010-03-11 15:46:29 -080047
Jim Millerdcb3d842012-08-23 19:18:12 -070048 public KeyguardPasswordView(Context context, AttributeSet attrs) {
49 super(context, attrs);
Chris Wrena042ac92012-11-07 11:37:06 -050050 mShowImeAtScreenOn = context.getResources().
51 getBoolean(R.bool.kg_show_ime_at_screen_on);
Jim Millerdcb3d842012-08-23 19:18:12 -070052 }
53
Daniel Sandler69bdee72012-10-23 16:45:50 -040054 protected void resetState() {
Daniel Sandler2c1ce052012-10-24 23:19:34 -040055 mSecurityMessageDisplay.setMessage(R.string.kg_password_instructions, false);
Jim Miller08b2b6b2012-09-14 19:12:40 -070056 mPasswordEntry.setEnabled(true);
Jim Miller08b2b6b2012-09-14 19:12:40 -070057 }
58
Jim Millerdcb3d842012-08-23 19:18:12 -070059 @Override
Daniel Sandler8a26bf52012-10-30 13:29:50 -040060 protected int getPasswordTextViewId() {
61 return R.id.passwordEntry;
62 }
63
64 @Override
Jim Miller86f96372012-10-24 20:14:47 -070065 public boolean needsInput() {
66 return true;
67 }
68
69 @Override
Chris Wrena042ac92012-11-07 11:37:06 -050070 public void onResume(int reason) {
71 super.onResume(reason);
Daniel Sandlerfba4d4a2012-10-30 16:35:15 -040072 mPasswordEntry.requestFocus();
Chris Wrena042ac92012-11-07 11:37:06 -050073 if (reason != KeyguardSecurityView.SCREEN_ON || mShowImeAtScreenOn) {
74 mImm.showSoftInput(mPasswordEntry, InputMethodManager.SHOW_IMPLICIT);
75 }
Daniel Sandler2c1ce052012-10-24 23:19:34 -040076 }
77
78 @Override
79 public void onPause() {
80 super.onPause();
81 mImm.hideSoftInputFromWindow(getWindowToken(), 0);
82 }
83
84 @Override
Jim Millerdcb3d842012-08-23 19:18:12 -070085 protected void onFinishInflate() {
Daniel Sandler69bdee72012-10-23 16:45:50 -040086 super.onFinishInflate();
Jae Yong Sung8171b512010-08-05 10:44:27 -070087
Jim Millerd9d09452011-11-02 18:32:16 -070088 boolean imeOrDeleteButtonVisible = false;
Jim Millerac8f5752012-09-07 16:48:41 -070089
Daniel Sandler2c1ce052012-10-24 23:19:34 -040090 mImm = (InputMethodManager) getContext().getSystemService(
91 Context.INPUT_METHOD_SERVICE);
Ben Komalo51ea88a2011-10-03 10:53:26 -070092
Daniel Sandler2c1ce052012-10-24 23:19:34 -040093 mPasswordEntry.setKeyListener(TextKeyListener.getInstance());
94 mPasswordEntry.setInputType(InputType.TYPE_CLASS_TEXT
95 | InputType.TYPE_TEXT_VARIATION_PASSWORD);
Jim Miller8b9dda22010-03-02 17:24:48 -080096
Jim Miller6b05d582011-07-18 13:09:59 -070097 // Poke the wakelock any time the text is selected or modified
98 mPasswordEntry.setOnClickListener(new OnClickListener() {
99 public void onClick(View v) {
Jim Millerdcb3d842012-08-23 19:18:12 -0700100 mCallback.userActivity(0); // TODO: customize timeout for text?
Jim Miller6b05d582011-07-18 13:09:59 -0700101 }
102 });
Jim Millerdcb3d842012-08-23 19:18:12 -0700103
Jim Miller8ecfac12011-07-08 19:15:51 -0700104 mPasswordEntry.addTextChangedListener(new TextWatcher() {
105 public void onTextChanged(CharSequence s, int start, int before, int count) {
106 }
107
108 public void beforeTextChanged(CharSequence s, int start, int count, int after) {
109 }
110
111 public void afterTextChanged(Editable s) {
Adam Cohenac8a59d2012-10-15 13:04:24 -0700112 if (mCallback != null) {
113 mCallback.userActivity(0);
114 }
Jim Miller8ecfac12011-07-08 19:15:51 -0700115 }
116 });
Jim Miller858f8ea2011-08-19 14:50:34 -0700117
Daniel Sandler69bdee72012-10-23 16:45:50 -0400118 mPasswordEntry.requestFocus();
119
Jim Miller858f8ea2011-08-19 14:50:34 -0700120 // If there's more than one IME, enable the IME switcher button
121 View switchImeButton = findViewById(R.id.switch_ime_button);
Daniel Sandler2c1ce052012-10-24 23:19:34 -0400122 if (switchImeButton != null && hasMultipleEnabledIMEsOrSubtypes(mImm, false)) {
Jim Miller858f8ea2011-08-19 14:50:34 -0700123 switchImeButton.setVisibility(View.VISIBLE);
Jim Millerd9d09452011-11-02 18:32:16 -0700124 imeOrDeleteButtonVisible = true;
Jim Miller858f8ea2011-08-19 14:50:34 -0700125 switchImeButton.setOnClickListener(new OnClickListener() {
126 public void onClick(View v) {
Jim Millerdcb3d842012-08-23 19:18:12 -0700127 mCallback.userActivity(0); // Leave the screen on a bit longer
Daniel Sandler2c1ce052012-10-24 23:19:34 -0400128 mImm.showInputMethodPicker();
Jim Miller858f8ea2011-08-19 14:50:34 -0700129 }
130 });
131 }
Jim Millerd9d09452011-11-02 18:32:16 -0700132
Adam Powell70bc9f22012-10-12 22:02:27 -0700133 // If no icon is visible, reset the start margin on the password field so the text is
Jim Millerd9d09452011-11-02 18:32:16 -0700134 // still centered.
135 if (!imeOrDeleteButtonVisible) {
136 android.view.ViewGroup.LayoutParams params = mPasswordEntry.getLayoutParams();
137 if (params instanceof MarginLayoutParams) {
Adam Powell70bc9f22012-10-12 22:02:27 -0700138 final MarginLayoutParams mlp = (MarginLayoutParams) params;
139 mlp.setMarginStart(0);
Jim Millerd9d09452011-11-02 18:32:16 -0700140 mPasswordEntry.setLayoutParams(params);
141 }
142 }
Jim Miller858f8ea2011-08-19 14:50:34 -0700143 }
144
145 /**
146 * Method adapted from com.android.inputmethod.latin.Utils
147 *
148 * @param imm The input method manager
149 * @param shouldIncludeAuxiliarySubtypes
150 * @return true if we have multiple IMEs to choose from
151 */
152 private boolean hasMultipleEnabledIMEsOrSubtypes(InputMethodManager imm,
153 final boolean shouldIncludeAuxiliarySubtypes) {
154 final List<InputMethodInfo> enabledImis = imm.getEnabledInputMethodList();
155
156 // Number of the filtered IMEs
157 int filteredImisCount = 0;
158
159 for (InputMethodInfo imi : enabledImis) {
160 // We can return true immediately after we find two or more filtered IMEs.
161 if (filteredImisCount > 1) return true;
162 final List<InputMethodSubtype> subtypes =
163 imm.getEnabledInputMethodSubtypeList(imi, true);
164 // IMEs that have no subtypes should be counted.
165 if (subtypes.isEmpty()) {
166 ++filteredImisCount;
167 continue;
168 }
169
170 int auxCount = 0;
171 for (InputMethodSubtype subtype : subtypes) {
172 if (subtype.isAuxiliary()) {
173 ++auxCount;
174 }
175 }
176 final int nonAuxCount = subtypes.size() - auxCount;
177
178 // IMEs that have one or more non-auxiliary subtypes should be counted.
179 // If shouldIncludeAuxiliarySubtypes is true, IMEs that have two or more auxiliary
180 // subtypes should be counted as well.
181 if (nonAuxCount > 0 || (shouldIncludeAuxiliarySubtypes && auxCount > 1)) {
182 ++filteredImisCount;
183 continue;
184 }
185 }
186
187 return filteredImisCount > 1
188 // imm.getEnabledInputMethodSubtypeList(null, false) will return the current IME's enabled
189 // input method subtype (The current IME should be LatinIME.)
190 || imm.getEnabledInputMethodSubtypeList(null, false).size() > 1;
Jim Miller5e0f7ba2009-12-22 19:04:23 -0800191 }
Adam Cohen6fb841f2012-10-24 13:15:38 -0700192
193 @Override
194 public void showUsabilityHint() {
195 }
Daniel Sandler16d90922012-11-01 12:41:14 -0400196
197 @Override
198 public int getWrongPasswordStringId() {
199 return R.string.kg_wrong_password;
200 }
Jim Miller5e0f7ba2009-12-22 19:04:23 -0800201}