blob: e5b4b7308a674c1a0e0f478b3ff7adb7aa2ed42c [file] [log] [blame]
Jim Millerdcb3d842012-08-23 19:18:12 -07001/*
2 * Copyright (C) 2012 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 */
16package com.android.internal.policy.impl.keyguard;
17
18import android.app.Activity;
19import android.app.Dialog;
20import android.app.ProgressDialog;
21import android.content.Context;
Jim Millerdcb3d842012-08-23 19:18:12 -070022import android.os.RemoteException;
23import android.os.ServiceManager;
24import android.text.Editable;
Daniel Sandler23d7a6e2012-11-02 00:21:07 -040025import android.text.InputType;
Jim Miller9cf2c522012-10-04 22:02:29 -070026import android.text.TextWatcher;
Daniel Sandler23d7a6e2012-11-02 00:21:07 -040027import android.text.method.DigitsKeyListener;
Jim Millerdcb3d842012-08-23 19:18:12 -070028import android.util.AttributeSet;
Jim Millerdcb3d842012-08-23 19:18:12 -070029import android.view.View;
30import android.view.WindowManager;
Jim Millerdcb3d842012-08-23 19:18:12 -070031import android.widget.TextView.OnEditorActionListener;
32
33import com.android.internal.telephony.ITelephony;
Daniel Sandler23d7a6e2012-11-02 00:21:07 -040034
Jim Millerdcb3d842012-08-23 19:18:12 -070035import com.android.internal.R;
36
Daniel Sandler23d7a6e2012-11-02 00:21:07 -040037/**
38 * Displays a PIN pad for entering a PUK (Pin Unlock Kode) provided by a carrier.
39 */
40public class KeyguardSimPukView extends KeyguardAbsKeyInputView
41 implements KeyguardSecurityView, OnEditorActionListener, TextWatcher {
Jim Millerdcb3d842012-08-23 19:18:12 -070042
43 private ProgressDialog mSimUnlockProgressDialog = null;
Jim Miller4b09dd32012-09-04 14:27:25 -070044 private volatile boolean mCheckInProgress;
Jim Miller3efe1062012-09-28 16:59:31 -070045 private String mPukText;
Jim Miller3efe1062012-09-28 16:59:31 -070046 private String mPinText;
47 private StateMachine mStateMachine = new StateMachine();
48
49 private class StateMachine {
50 final int ENTER_PUK = 0;
51 final int ENTER_PIN = 1;
52 final int CONFIRM_PIN = 2;
53 final int DONE = 3;
54 private int state = ENTER_PUK;
55
56 public void next() {
57 int msg = 0;
58 if (state == ENTER_PUK) {
59 if (checkPuk()) {
60 state = ENTER_PIN;
61 msg = R.string.kg_puk_enter_pin_hint;
62 } else {
63 msg = R.string.kg_invalid_sim_puk_hint;
64 }
65 } else if (state == ENTER_PIN) {
66 if (checkPin()) {
67 state = CONFIRM_PIN;
68 msg = R.string.kg_enter_confirm_pin_hint;
69 } else {
70 msg = R.string.kg_invalid_sim_pin_hint;
71 }
72 } else if (state == CONFIRM_PIN) {
73 if (confirmPin()) {
74 state = DONE;
Jim Miller838906b2012-10-19 18:41:25 -070075 msg =
76 com.android.internal.R.string.lockscreen_sim_unlock_progress_dialog_message;
Jim Miller3efe1062012-09-28 16:59:31 -070077 updateSim();
78 } else {
Daniel Sandler23d7a6e2012-11-02 00:21:07 -040079 state = ENTER_PIN; // try again?
Jim Miller3efe1062012-09-28 16:59:31 -070080 msg = R.string.kg_invalid_confirm_pin_hint;
81 }
82 }
Daniel Sandler23d7a6e2012-11-02 00:21:07 -040083 mPasswordEntry.setText(null);
Jim Miller3efe1062012-09-28 16:59:31 -070084 if (msg != 0) {
Adam Cohen0a4f9002012-10-12 19:57:16 -070085 mSecurityMessageDisplay.setMessage(msg, true);
Jim Miller3efe1062012-09-28 16:59:31 -070086 }
87 }
88
89 void reset() {
90 mPinText="";
91 mPukText="";
92 state = ENTER_PUK;
Adam Cohen6dbf8612012-10-14 17:26:31 -070093 mSecurityMessageDisplay.setMessage(R.string.kg_puk_enter_puk_hint, true);
Daniel Sandler23d7a6e2012-11-02 00:21:07 -040094 mPasswordEntry.requestFocus();
Jim Miller3efe1062012-09-28 16:59:31 -070095 }
96 }
97
Jim Millerdcb3d842012-08-23 19:18:12 -070098 public KeyguardSimPukView(Context context) {
99 this(context, null);
100 }
101
102 public KeyguardSimPukView(Context context, AttributeSet attrs) {
103 super(context, attrs);
Jim Millerdcb3d842012-08-23 19:18:12 -0700104 }
105
Daniel Sandler23d7a6e2012-11-02 00:21:07 -0400106 public void resetState() {
107 mStateMachine.reset();
108 mPasswordEntry.setEnabled(true);
109 }
110
111 @Override
112 protected int getPasswordTextViewId() {
113 return R.id.pinEntry;
Jim Millerdcb3d842012-08-23 19:18:12 -0700114 }
115
116 @Override
117 protected void onFinishInflate() {
118 super.onFinishInflate();
Jim Miller0b728242012-10-28 19:42:30 -0700119
Daniel Sandler23d7a6e2012-11-02 00:21:07 -0400120 final View ok = findViewById(R.id.key_enter);
121 if (ok != null) {
122 ok.setOnClickListener(new View.OnClickListener() {
123 @Override
124 public void onClick(View v) {
125 doHapticKeyClick();
126 verifyPasswordAndUnlock();
127 }
128 });
129 }
130
131 // The delete button is of the PIN keyboard itself in some (e.g. tablet) layouts,
132 // not a separate view
133 View pinDelete = findViewById(R.id.delete_button);
134 if (pinDelete != null) {
135 pinDelete.setVisibility(View.VISIBLE);
136 pinDelete.setOnClickListener(new OnClickListener() {
137 public void onClick(View v) {
138 CharSequence str = mPasswordEntry.getText();
139 if (str.length() > 0) {
140 mPasswordEntry.setText(str.subSequence(0, str.length()-1));
141 }
142 doHapticKeyClick();
143 }
144 });
145 pinDelete.setOnLongClickListener(new View.OnLongClickListener() {
146 public boolean onLongClick(View v) {
147 mPasswordEntry.setText("");
148 doHapticKeyClick();
149 return true;
150 }
151 });
152 }
153
154 mPasswordEntry.setKeyListener(DigitsKeyListener.getInstance());
155 mPasswordEntry.setInputType(InputType.TYPE_CLASS_NUMBER
156 | InputType.TYPE_NUMBER_VARIATION_PASSWORD);
157
158 mPasswordEntry.requestFocus();
159
Jim Miller0b728242012-10-28 19:42:30 -0700160 mSecurityMessageDisplay.setTimeout(0); // don't show ownerinfo/charging status by default
Jim Millerdcb3d842012-08-23 19:18:12 -0700161 }
162
Adam Cohen6fb841f2012-10-24 13:15:38 -0700163 @Override
164 public void showUsabilityHint() {
165 }
166
Daniel Sandler23d7a6e2012-11-02 00:21:07 -0400167 @Override
168 public void onPause() {
Jim Millerdcb3d842012-08-23 19:18:12 -0700169 // dismiss the dialog.
170 if (mSimUnlockProgressDialog != null) {
171 mSimUnlockProgressDialog.dismiss();
172 mSimUnlockProgressDialog = null;
173 }
174 }
175
176 /**
177 * Since the IPC can block, we want to run the request in a separate thread
178 * with a callback.
179 */
180 private abstract class CheckSimPuk extends Thread {
181
182 private final String mPin, mPuk;
183
184 protected CheckSimPuk(String puk, String pin) {
185 mPuk = puk;
186 mPin = pin;
187 }
188
189 abstract void onSimLockChangedResponse(boolean success);
190
191 @Override
192 public void run() {
193 try {
194 final boolean result = ITelephony.Stub.asInterface(ServiceManager
195 .checkService("phone")).supplyPuk(mPuk, mPin);
196
197 post(new Runnable() {
198 public void run() {
199 onSimLockChangedResponse(result);
200 }
201 });
202 } catch (RemoteException e) {
203 post(new Runnable() {
204 public void run() {
205 onSimLockChangedResponse(false);
206 }
207 });
208 }
209 }
210 }
211
Jim Millerdcb3d842012-08-23 19:18:12 -0700212 private Dialog getSimUnlockProgressDialog() {
213 if (mSimUnlockProgressDialog == null) {
214 mSimUnlockProgressDialog = new ProgressDialog(mContext);
Daniel Sandler23d7a6e2012-11-02 00:21:07 -0400215 mSimUnlockProgressDialog.setMessage(
216 mContext.getString(R.string.kg_sim_unlock_progress_dialog_message));
Jim Millerdcb3d842012-08-23 19:18:12 -0700217 mSimUnlockProgressDialog.setIndeterminate(true);
218 mSimUnlockProgressDialog.setCancelable(false);
219 if (!(mContext instanceof Activity)) {
220 mSimUnlockProgressDialog.getWindow().setType(
221 WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
222 }
223 }
224 return mSimUnlockProgressDialog;
225 }
226
Jim Miller3efe1062012-09-28 16:59:31 -0700227 private boolean checkPuk() {
Jim Millerdcb3d842012-08-23 19:18:12 -0700228 // make sure the puk is at least 8 digits long.
Daniel Sandler23d7a6e2012-11-02 00:21:07 -0400229 if (mPasswordEntry.getText().length() >= 8) {
230 mPukText = mPasswordEntry.getText().toString();
Jim Miller3efe1062012-09-28 16:59:31 -0700231 return true;
Jim Millerdcb3d842012-08-23 19:18:12 -0700232 }
Jim Miller3efe1062012-09-28 16:59:31 -0700233 return false;
234 }
Jim Millerdcb3d842012-08-23 19:18:12 -0700235
Jim Miller3efe1062012-09-28 16:59:31 -0700236 private boolean checkPin() {
Jim Millerdcb3d842012-08-23 19:18:12 -0700237 // make sure the PIN is between 4 and 8 digits
Daniel Sandler23d7a6e2012-11-02 00:21:07 -0400238 int length = mPasswordEntry.getText().length();
Jim Miller3efe1062012-09-28 16:59:31 -0700239 if (length >= 4 && length <= 8) {
Daniel Sandler23d7a6e2012-11-02 00:21:07 -0400240 mPinText = mPasswordEntry.getText().toString();
Jim Miller3efe1062012-09-28 16:59:31 -0700241 return true;
Jim Millerdcb3d842012-08-23 19:18:12 -0700242 }
Jim Miller3efe1062012-09-28 16:59:31 -0700243 return false;
244 }
Jim Millerdcb3d842012-08-23 19:18:12 -0700245
Jim Miller3efe1062012-09-28 16:59:31 -0700246 public boolean confirmPin() {
Daniel Sandler23d7a6e2012-11-02 00:21:07 -0400247 return mPinText.equals(mPasswordEntry.getText().toString());
Jim Miller3efe1062012-09-28 16:59:31 -0700248 }
249
250 private void updateSim() {
Jim Millerdcb3d842012-08-23 19:18:12 -0700251 getSimUnlockProgressDialog().show();
252
Jim Miller4b09dd32012-09-04 14:27:25 -0700253 if (!mCheckInProgress) {
254 mCheckInProgress = true;
Jim Miller3efe1062012-09-28 16:59:31 -0700255 new CheckSimPuk(mPukText, mPinText) {
Jim Miller4b09dd32012-09-04 14:27:25 -0700256 void onSimLockChangedResponse(final boolean success) {
Jim Miller3efe1062012-09-28 16:59:31 -0700257 post(new Runnable() {
Jim Miller4b09dd32012-09-04 14:27:25 -0700258 public void run() {
259 if (mSimUnlockProgressDialog != null) {
260 mSimUnlockProgressDialog.hide();
261 }
262 if (success) {
263 mCallback.dismiss(true);
264 } else {
Jim Miller3efe1062012-09-28 16:59:31 -0700265 mStateMachine.reset();
Adam Cohen0a4f9002012-10-12 19:57:16 -0700266 mSecurityMessageDisplay.setMessage(R.string.kg_invalid_puk, true);
Jim Miller4b09dd32012-09-04 14:27:25 -0700267 }
268 mCheckInProgress = false;
Jim Millerdcb3d842012-08-23 19:18:12 -0700269 }
Jim Miller4b09dd32012-09-04 14:27:25 -0700270 });
271 }
272 }.start();
273 }
Jim Millerdcb3d842012-08-23 19:18:12 -0700274 }
275
276 @Override
Daniel Sandler23d7a6e2012-11-02 00:21:07 -0400277 protected void verifyPasswordAndUnlock() {
278 mStateMachine.next();
Jim Miller9cf2c522012-10-04 22:02:29 -0700279 }
Jim Millerdcb3d842012-08-23 19:18:12 -0700280}
Daniel Sandler23d7a6e2012-11-02 00:21:07 -0400281
282