blob: b956e99e6085990b1fd37ce1c8d1348ee7f86e7c [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 */
Jim Millerdcb3d842012-08-23 19:18:12 -070016
Jim Miller5ecd8112013-01-09 18:50:26 -080017package com.android.keyguard;
18
Jim Miller5ecd8112013-01-09 18:50:26 -080019import android.content.Context;
Jim Millerdcb3d842012-08-23 19:18:12 -070020import android.app.Activity;
Wink Savilleb896b9f2013-10-23 15:44:26 -070021import android.app.AlertDialog;
Jim Millerdcb3d842012-08-23 19:18:12 -070022import android.app.Dialog;
23import android.app.ProgressDialog;
Jim Millerdcb3d842012-08-23 19:18:12 -070024import android.os.RemoteException;
25import android.os.ServiceManager;
Daniel Sandler23d7a6e2012-11-02 00:21:07 -040026import android.text.InputType;
Jim Miller9cf2c522012-10-04 22:02:29 -070027import android.text.TextWatcher;
Daniel Sandler23d7a6e2012-11-02 00:21:07 -040028import android.text.method.DigitsKeyListener;
Jim Millerdcb3d842012-08-23 19:18:12 -070029import android.util.AttributeSet;
Wink Savilleb896b9f2013-10-23 15:44:26 -070030import android.util.Log;
Jim Millerdcb3d842012-08-23 19:18:12 -070031import android.view.View;
32import android.view.WindowManager;
Jim Millerdcb3d842012-08-23 19:18:12 -070033import android.widget.TextView.OnEditorActionListener;
34
Wink Savilleb896b9f2013-10-23 15:44:26 -070035import com.android.internal.telephony.ITelephony;
36import com.android.internal.telephony.PhoneConstants;
37
38
Daniel Sandler23d7a6e2012-11-02 00:21:07 -040039/**
40 * Displays a PIN pad for entering a PUK (Pin Unlock Kode) provided by a carrier.
41 */
Selim Cinek4e8b9ed2014-06-20 16:37:04 -070042public class KeyguardSimPukView extends KeyguardPinBasedInputView {
Wink Savilleb896b9f2013-10-23 15:44:26 -070043 private static final String LOG_TAG = "KeyguardSimPukView";
Jorim Jaggi5cf17872014-03-26 18:31:48 +010044 private static final boolean DEBUG = KeyguardConstants.DEBUG;
Jim Miller4fc2b012013-11-04 16:47:48 -080045 public static final String TAG = "KeyguardSimPukView";
Jim Millerdcb3d842012-08-23 19:18:12 -070046
47 private ProgressDialog mSimUnlockProgressDialog = null;
Jim Miller4fc2b012013-11-04 16:47:48 -080048 private CheckSimPuk mCheckSimPukThread;
Jim Miller3efe1062012-09-28 16:59:31 -070049 private String mPukText;
Jim Miller3efe1062012-09-28 16:59:31 -070050 private String mPinText;
51 private StateMachine mStateMachine = new StateMachine();
Wink Savilleb896b9f2013-10-23 15:44:26 -070052 private AlertDialog mRemainingAttemptsDialog;
Jim Miller3efe1062012-09-28 16:59:31 -070053
54 private class StateMachine {
55 final int ENTER_PUK = 0;
56 final int ENTER_PIN = 1;
57 final int CONFIRM_PIN = 2;
58 final int DONE = 3;
59 private int state = ENTER_PUK;
60
61 public void next() {
62 int msg = 0;
63 if (state == ENTER_PUK) {
64 if (checkPuk()) {
65 state = ENTER_PIN;
66 msg = R.string.kg_puk_enter_pin_hint;
67 } else {
68 msg = R.string.kg_invalid_sim_puk_hint;
69 }
70 } else if (state == ENTER_PIN) {
71 if (checkPin()) {
72 state = CONFIRM_PIN;
73 msg = R.string.kg_enter_confirm_pin_hint;
74 } else {
75 msg = R.string.kg_invalid_sim_pin_hint;
76 }
77 } else if (state == CONFIRM_PIN) {
78 if (confirmPin()) {
79 state = DONE;
Jim Miller5ecd8112013-01-09 18:50:26 -080080 msg = R.string.keyguard_sim_unlock_progress_dialog_message;
Jim Miller3efe1062012-09-28 16:59:31 -070081 updateSim();
82 } else {
Daniel Sandler23d7a6e2012-11-02 00:21:07 -040083 state = ENTER_PIN; // try again?
Jim Miller3efe1062012-09-28 16:59:31 -070084 msg = R.string.kg_invalid_confirm_pin_hint;
85 }
86 }
Selim Cinek4e8b9ed2014-06-20 16:37:04 -070087 resetPasswordText(true);
Jim Miller3efe1062012-09-28 16:59:31 -070088 if (msg != 0) {
Adam Cohen0a4f9002012-10-12 19:57:16 -070089 mSecurityMessageDisplay.setMessage(msg, true);
Jim Miller3efe1062012-09-28 16:59:31 -070090 }
91 }
92
93 void reset() {
94 mPinText="";
95 mPukText="";
96 state = ENTER_PUK;
Adam Cohen6dbf8612012-10-14 17:26:31 -070097 mSecurityMessageDisplay.setMessage(R.string.kg_puk_enter_puk_hint, true);
Daniel Sandler23d7a6e2012-11-02 00:21:07 -040098 mPasswordEntry.requestFocus();
Jim Miller3efe1062012-09-28 16:59:31 -070099 }
100 }
101
Wink Savilleb896b9f2013-10-23 15:44:26 -0700102 private String getPukPasswordErrorMessage(int attemptsRemaining) {
103 String displayMessage;
104
105 if (attemptsRemaining == 0) {
106 displayMessage = getContext().getString(R.string.kg_password_wrong_puk_code_dead);
107 } else if (attemptsRemaining > 0) {
108 displayMessage = getContext().getResources()
109 .getQuantityString(R.plurals.kg_password_wrong_puk_code, attemptsRemaining,
110 attemptsRemaining);
111 } else {
112 displayMessage = getContext().getString(R.string.kg_password_puk_failed);
113 }
114 if (DEBUG) Log.d(LOG_TAG, "getPukPasswordErrorMessage:"
115 + " attemptsRemaining=" + attemptsRemaining + " displayMessage=" + displayMessage);
116 return displayMessage;
117 }
118
Jim Millerdcb3d842012-08-23 19:18:12 -0700119 public KeyguardSimPukView(Context context) {
120 this(context, null);
121 }
122
123 public KeyguardSimPukView(Context context, AttributeSet attrs) {
124 super(context, attrs);
Jim Millerdcb3d842012-08-23 19:18:12 -0700125 }
126
Daniel Sandler23d7a6e2012-11-02 00:21:07 -0400127 public void resetState() {
Selim Cinek4e8b9ed2014-06-20 16:37:04 -0700128 super.resetState();
Daniel Sandler23d7a6e2012-11-02 00:21:07 -0400129 mStateMachine.reset();
Daniel Sandler23d7a6e2012-11-02 00:21:07 -0400130 }
131
132 @Override
Jim Miller7d5e00a2013-10-11 22:45:57 -0700133 protected boolean shouldLockout(long deadline) {
134 // SIM PUK doesn't have a timed lockout
135 return false;
136 }
137
138 @Override
Daniel Sandler23d7a6e2012-11-02 00:21:07 -0400139 protected int getPasswordTextViewId() {
Jorim Jaggifa9189f2014-04-17 20:17:30 +0200140 return R.id.pukEntry;
Jim Millerdcb3d842012-08-23 19:18:12 -0700141 }
142
143 @Override
144 protected void onFinishInflate() {
145 super.onFinishInflate();
Jim Miller0b728242012-10-28 19:42:30 -0700146
Jim Miller0b728242012-10-28 19:42:30 -0700147 mSecurityMessageDisplay.setTimeout(0); // don't show ownerinfo/charging status by default
Jorim Jaggi40a0b382014-05-27 21:12:27 +0200148 if (mEcaView instanceof EmergencyCarrierArea) {
149 ((EmergencyCarrierArea) mEcaView).setCarrierTextVisible(true);
150 }
Jim Millerdcb3d842012-08-23 19:18:12 -0700151 }
152
Adam Cohen6fb841f2012-10-24 13:15:38 -0700153 @Override
154 public void showUsabilityHint() {
155 }
156
Daniel Sandler23d7a6e2012-11-02 00:21:07 -0400157 @Override
158 public void onPause() {
Jim Millerdcb3d842012-08-23 19:18:12 -0700159 // dismiss the dialog.
160 if (mSimUnlockProgressDialog != null) {
161 mSimUnlockProgressDialog.dismiss();
162 mSimUnlockProgressDialog = null;
163 }
164 }
165
166 /**
167 * Since the IPC can block, we want to run the request in a separate thread
168 * with a callback.
169 */
170 private abstract class CheckSimPuk extends Thread {
171
172 private final String mPin, mPuk;
173
174 protected CheckSimPuk(String puk, String pin) {
175 mPuk = puk;
176 mPin = pin;
177 }
178
Wink Savilleb896b9f2013-10-23 15:44:26 -0700179 abstract void onSimLockChangedResponse(final int result, final int attemptsRemaining);
Jim Millerdcb3d842012-08-23 19:18:12 -0700180
181 @Override
182 public void run() {
183 try {
Jim Miller4fc2b012013-11-04 16:47:48 -0800184 Log.v(TAG, "call supplyPukReportResult()");
Wink Savilleb896b9f2013-10-23 15:44:26 -0700185 final int[] result = ITelephony.Stub.asInterface(ServiceManager
186 .checkService("phone")).supplyPukReportResult(mPuk, mPin);
Jim Miller4fc2b012013-11-04 16:47:48 -0800187 Log.v(TAG, "supplyPukReportResult returned: " + result[0] + " " + result[1]);
Jim Millerdcb3d842012-08-23 19:18:12 -0700188 post(new Runnable() {
189 public void run() {
Wink Savilleb896b9f2013-10-23 15:44:26 -0700190 onSimLockChangedResponse(result[0], result[1]);
Jim Millerdcb3d842012-08-23 19:18:12 -0700191 }
192 });
193 } catch (RemoteException e) {
Jim Miller4fc2b012013-11-04 16:47:48 -0800194 Log.e(TAG, "RemoteException for supplyPukReportResult:", e);
Jim Millerdcb3d842012-08-23 19:18:12 -0700195 post(new Runnable() {
196 public void run() {
Wink Savilleb896b9f2013-10-23 15:44:26 -0700197 onSimLockChangedResponse(PhoneConstants.PIN_GENERAL_FAILURE, -1);
Jim Millerdcb3d842012-08-23 19:18:12 -0700198 }
199 });
200 }
201 }
202 }
203
Jim Millerdcb3d842012-08-23 19:18:12 -0700204 private Dialog getSimUnlockProgressDialog() {
205 if (mSimUnlockProgressDialog == null) {
206 mSimUnlockProgressDialog = new ProgressDialog(mContext);
Daniel Sandler23d7a6e2012-11-02 00:21:07 -0400207 mSimUnlockProgressDialog.setMessage(
208 mContext.getString(R.string.kg_sim_unlock_progress_dialog_message));
Jim Millerdcb3d842012-08-23 19:18:12 -0700209 mSimUnlockProgressDialog.setIndeterminate(true);
210 mSimUnlockProgressDialog.setCancelable(false);
211 if (!(mContext instanceof Activity)) {
212 mSimUnlockProgressDialog.getWindow().setType(
213 WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
214 }
215 }
216 return mSimUnlockProgressDialog;
217 }
218
Wink Savilleb896b9f2013-10-23 15:44:26 -0700219 private Dialog getPukRemainingAttemptsDialog(int remaining) {
220 String msg = getPukPasswordErrorMessage(remaining);
221 if (mRemainingAttemptsDialog == null) {
222 AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
223 builder.setMessage(msg);
224 builder.setCancelable(false);
225 builder.setNeutralButton(R.string.ok, null);
226 mRemainingAttemptsDialog = builder.create();
227 mRemainingAttemptsDialog.getWindow().setType(
228 WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
229 } else {
230 mRemainingAttemptsDialog.setMessage(msg);
231 }
232 return mRemainingAttemptsDialog;
233 }
234
Jim Miller3efe1062012-09-28 16:59:31 -0700235 private boolean checkPuk() {
Jim Millerdcb3d842012-08-23 19:18:12 -0700236 // make sure the puk is at least 8 digits long.
Rakesh Pallerlab8b7bd32014-01-08 15:49:34 +0530237 if (mPasswordEntry.getText().length() == 8) {
Selim Cinek4e8b9ed2014-06-20 16:37:04 -0700238 mPukText = mPasswordEntry.getText();
Jim Miller3efe1062012-09-28 16:59:31 -0700239 return true;
Jim Millerdcb3d842012-08-23 19:18:12 -0700240 }
Jim Miller3efe1062012-09-28 16:59:31 -0700241 return false;
242 }
Jim Millerdcb3d842012-08-23 19:18:12 -0700243
Jim Miller3efe1062012-09-28 16:59:31 -0700244 private boolean checkPin() {
Jim Millerdcb3d842012-08-23 19:18:12 -0700245 // make sure the PIN is between 4 and 8 digits
Daniel Sandler23d7a6e2012-11-02 00:21:07 -0400246 int length = mPasswordEntry.getText().length();
Jim Miller3efe1062012-09-28 16:59:31 -0700247 if (length >= 4 && length <= 8) {
Selim Cinek4e8b9ed2014-06-20 16:37:04 -0700248 mPinText = mPasswordEntry.getText();
Jim Miller3efe1062012-09-28 16:59:31 -0700249 return true;
Jim Millerdcb3d842012-08-23 19:18:12 -0700250 }
Jim Miller3efe1062012-09-28 16:59:31 -0700251 return false;
252 }
Jim Millerdcb3d842012-08-23 19:18:12 -0700253
Jim Miller3efe1062012-09-28 16:59:31 -0700254 public boolean confirmPin() {
Selim Cinek4e8b9ed2014-06-20 16:37:04 -0700255 return mPinText.equals(mPasswordEntry.getText());
Jim Miller3efe1062012-09-28 16:59:31 -0700256 }
257
258 private void updateSim() {
Jim Millerdcb3d842012-08-23 19:18:12 -0700259 getSimUnlockProgressDialog().show();
260
Jim Miller4fc2b012013-11-04 16:47:48 -0800261 if (mCheckSimPukThread == null) {
262 mCheckSimPukThread = new CheckSimPuk(mPukText, mPinText) {
Wink Savilleb896b9f2013-10-23 15:44:26 -0700263 void onSimLockChangedResponse(final int result, final int attemptsRemaining) {
Jim Miller3efe1062012-09-28 16:59:31 -0700264 post(new Runnable() {
Jim Miller4b09dd32012-09-04 14:27:25 -0700265 public void run() {
266 if (mSimUnlockProgressDialog != null) {
267 mSimUnlockProgressDialog.hide();
268 }
Wink Savilleb896b9f2013-10-23 15:44:26 -0700269 if (result == PhoneConstants.PIN_RESULT_SUCCESS) {
270 KeyguardUpdateMonitor.getInstance(getContext()).reportSimUnlocked();
Jim Miller4b09dd32012-09-04 14:27:25 -0700271 mCallback.dismiss(true);
272 } else {
Wink Savilleb896b9f2013-10-23 15:44:26 -0700273 if (result == PhoneConstants.PIN_PASSWORD_INCORRECT) {
274 if (attemptsRemaining <= 2) {
275 // this is getting critical - show dialog
276 getPukRemainingAttemptsDialog(attemptsRemaining).show();
277 } else {
278 // show message
279 mSecurityMessageDisplay.setMessage(
280 getPukPasswordErrorMessage(attemptsRemaining), true);
281 }
282 } else {
283 mSecurityMessageDisplay.setMessage(getContext().getString(
284 R.string.kg_password_puk_failed), true);
285 }
286 if (DEBUG) Log.d(LOG_TAG, "verifyPasswordAndUnlock "
287 + " UpdateSim.onSimCheckResponse: "
288 + " attemptsRemaining=" + attemptsRemaining);
Jim Miller3efe1062012-09-28 16:59:31 -0700289 mStateMachine.reset();
Jim Miller4b09dd32012-09-04 14:27:25 -0700290 }
Jim Miller4fc2b012013-11-04 16:47:48 -0800291 mCheckSimPukThread = null;
Jim Millerdcb3d842012-08-23 19:18:12 -0700292 }
Jim Miller4b09dd32012-09-04 14:27:25 -0700293 });
294 }
Jim Miller4fc2b012013-11-04 16:47:48 -0800295 };
296 mCheckSimPukThread.start();
Jim Miller4b09dd32012-09-04 14:27:25 -0700297 }
Jim Millerdcb3d842012-08-23 19:18:12 -0700298 }
299
300 @Override
Daniel Sandler23d7a6e2012-11-02 00:21:07 -0400301 protected void verifyPasswordAndUnlock() {
302 mStateMachine.next();
Jim Miller9cf2c522012-10-04 22:02:29 -0700303 }
Jorim Jaggic14f8292014-05-27 02:25:45 +0200304
305 @Override
306 public void startAppearAnimation() {
307 // noop.
308 }
Jim Millerdcb3d842012-08-23 19:18:12 -0700309}
Daniel Sandler23d7a6e2012-11-02 00:21:07 -0400310
311