blob: 7424fab9873d00e5b278af7c925f9583d3ddc34e [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
19import com.android.internal.telephony.ITelephony;
20
21import android.content.Context;
Jim Millerdcb3d842012-08-23 19:18:12 -070022import android.app.Activity;
23import android.app.Dialog;
24import android.app.ProgressDialog;
Jim Millerdcb3d842012-08-23 19:18:12 -070025import android.os.RemoteException;
26import android.os.ServiceManager;
27import android.text.Editable;
Daniel Sandler23d7a6e2012-11-02 00:21:07 -040028import android.text.InputType;
Jim Miller9cf2c522012-10-04 22:02:29 -070029import android.text.TextWatcher;
Daniel Sandler23d7a6e2012-11-02 00:21:07 -040030import android.text.method.DigitsKeyListener;
Jim Millerdcb3d842012-08-23 19:18:12 -070031import android.util.AttributeSet;
Jim Millerdcb3d842012-08-23 19:18:12 -070032import android.view.View;
33import android.view.WindowManager;
Jim Millerdcb3d842012-08-23 19:18:12 -070034import android.widget.TextView.OnEditorActionListener;
35
Daniel Sandler23d7a6e2012-11-02 00:21:07 -040036/**
37 * Displays a PIN pad for entering a PUK (Pin Unlock Kode) provided by a carrier.
38 */
39public class KeyguardSimPukView extends KeyguardAbsKeyInputView
40 implements KeyguardSecurityView, OnEditorActionListener, TextWatcher {
Jim Millerdcb3d842012-08-23 19:18:12 -070041
42 private ProgressDialog mSimUnlockProgressDialog = null;
Jim Miller4b09dd32012-09-04 14:27:25 -070043 private volatile boolean mCheckInProgress;
Jim Miller3efe1062012-09-28 16:59:31 -070044 private String mPukText;
Jim Miller3efe1062012-09-28 16:59:31 -070045 private String mPinText;
46 private StateMachine mStateMachine = new StateMachine();
47
48 private class StateMachine {
49 final int ENTER_PUK = 0;
50 final int ENTER_PIN = 1;
51 final int CONFIRM_PIN = 2;
52 final int DONE = 3;
53 private int state = ENTER_PUK;
54
55 public void next() {
56 int msg = 0;
57 if (state == ENTER_PUK) {
58 if (checkPuk()) {
59 state = ENTER_PIN;
60 msg = R.string.kg_puk_enter_pin_hint;
61 } else {
62 msg = R.string.kg_invalid_sim_puk_hint;
63 }
64 } else if (state == ENTER_PIN) {
65 if (checkPin()) {
66 state = CONFIRM_PIN;
67 msg = R.string.kg_enter_confirm_pin_hint;
68 } else {
69 msg = R.string.kg_invalid_sim_pin_hint;
70 }
71 } else if (state == CONFIRM_PIN) {
72 if (confirmPin()) {
73 state = DONE;
Jim Miller5ecd8112013-01-09 18:50:26 -080074 msg = R.string.keyguard_sim_unlock_progress_dialog_message;
Jim Miller3efe1062012-09-28 16:59:31 -070075 updateSim();
76 } else {
Daniel Sandler23d7a6e2012-11-02 00:21:07 -040077 state = ENTER_PIN; // try again?
Jim Miller3efe1062012-09-28 16:59:31 -070078 msg = R.string.kg_invalid_confirm_pin_hint;
79 }
80 }
Daniel Sandler23d7a6e2012-11-02 00:21:07 -040081 mPasswordEntry.setText(null);
Jim Miller3efe1062012-09-28 16:59:31 -070082 if (msg != 0) {
Adam Cohen0a4f9002012-10-12 19:57:16 -070083 mSecurityMessageDisplay.setMessage(msg, true);
Jim Miller3efe1062012-09-28 16:59:31 -070084 }
85 }
86
87 void reset() {
88 mPinText="";
89 mPukText="";
90 state = ENTER_PUK;
Adam Cohen6dbf8612012-10-14 17:26:31 -070091 mSecurityMessageDisplay.setMessage(R.string.kg_puk_enter_puk_hint, true);
Daniel Sandler23d7a6e2012-11-02 00:21:07 -040092 mPasswordEntry.requestFocus();
Jim Miller3efe1062012-09-28 16:59:31 -070093 }
94 }
95
Jim Millerdcb3d842012-08-23 19:18:12 -070096 public KeyguardSimPukView(Context context) {
97 this(context, null);
98 }
99
100 public KeyguardSimPukView(Context context, AttributeSet attrs) {
101 super(context, attrs);
Jim Millerdcb3d842012-08-23 19:18:12 -0700102 }
103
Daniel Sandler23d7a6e2012-11-02 00:21:07 -0400104 public void resetState() {
105 mStateMachine.reset();
106 mPasswordEntry.setEnabled(true);
107 }
108
109 @Override
110 protected int getPasswordTextViewId() {
111 return R.id.pinEntry;
Jim Millerdcb3d842012-08-23 19:18:12 -0700112 }
113
114 @Override
115 protected void onFinishInflate() {
116 super.onFinishInflate();
Jim Miller0b728242012-10-28 19:42:30 -0700117
Daniel Sandler23d7a6e2012-11-02 00:21:07 -0400118 final View ok = findViewById(R.id.key_enter);
119 if (ok != null) {
120 ok.setOnClickListener(new View.OnClickListener() {
121 @Override
122 public void onClick(View v) {
123 doHapticKeyClick();
124 verifyPasswordAndUnlock();
125 }
126 });
127 }
128
129 // The delete button is of the PIN keyboard itself in some (e.g. tablet) layouts,
130 // not a separate view
131 View pinDelete = findViewById(R.id.delete_button);
132 if (pinDelete != null) {
133 pinDelete.setVisibility(View.VISIBLE);
134 pinDelete.setOnClickListener(new OnClickListener() {
135 public void onClick(View v) {
136 CharSequence str = mPasswordEntry.getText();
137 if (str.length() > 0) {
138 mPasswordEntry.setText(str.subSequence(0, str.length()-1));
139 }
140 doHapticKeyClick();
141 }
142 });
143 pinDelete.setOnLongClickListener(new View.OnLongClickListener() {
144 public boolean onLongClick(View v) {
145 mPasswordEntry.setText("");
146 doHapticKeyClick();
147 return true;
148 }
149 });
150 }
151
152 mPasswordEntry.setKeyListener(DigitsKeyListener.getInstance());
153 mPasswordEntry.setInputType(InputType.TYPE_CLASS_NUMBER
154 | InputType.TYPE_NUMBER_VARIATION_PASSWORD);
155
156 mPasswordEntry.requestFocus();
157
Jim Miller0b728242012-10-28 19:42:30 -0700158 mSecurityMessageDisplay.setTimeout(0); // don't show ownerinfo/charging status by default
Jim Millerdcb3d842012-08-23 19:18:12 -0700159 }
160
Adam Cohen6fb841f2012-10-24 13:15:38 -0700161 @Override
162 public void showUsabilityHint() {
163 }
164
Daniel Sandler23d7a6e2012-11-02 00:21:07 -0400165 @Override
166 public void onPause() {
Jim Millerdcb3d842012-08-23 19:18:12 -0700167 // dismiss the dialog.
168 if (mSimUnlockProgressDialog != null) {
169 mSimUnlockProgressDialog.dismiss();
170 mSimUnlockProgressDialog = null;
171 }
172 }
173
174 /**
175 * Since the IPC can block, we want to run the request in a separate thread
176 * with a callback.
177 */
178 private abstract class CheckSimPuk extends Thread {
179
180 private final String mPin, mPuk;
181
182 protected CheckSimPuk(String puk, String pin) {
183 mPuk = puk;
184 mPin = pin;
185 }
186
187 abstract void onSimLockChangedResponse(boolean success);
188
189 @Override
190 public void run() {
191 try {
192 final boolean result = ITelephony.Stub.asInterface(ServiceManager
193 .checkService("phone")).supplyPuk(mPuk, mPin);
194
195 post(new Runnable() {
196 public void run() {
197 onSimLockChangedResponse(result);
198 }
199 });
200 } catch (RemoteException e) {
201 post(new Runnable() {
202 public void run() {
203 onSimLockChangedResponse(false);
204 }
205 });
206 }
207 }
208 }
209
Jim Millerdcb3d842012-08-23 19:18:12 -0700210 private Dialog getSimUnlockProgressDialog() {
211 if (mSimUnlockProgressDialog == null) {
212 mSimUnlockProgressDialog = new ProgressDialog(mContext);
Daniel Sandler23d7a6e2012-11-02 00:21:07 -0400213 mSimUnlockProgressDialog.setMessage(
214 mContext.getString(R.string.kg_sim_unlock_progress_dialog_message));
Jim Millerdcb3d842012-08-23 19:18:12 -0700215 mSimUnlockProgressDialog.setIndeterminate(true);
216 mSimUnlockProgressDialog.setCancelable(false);
217 if (!(mContext instanceof Activity)) {
218 mSimUnlockProgressDialog.getWindow().setType(
219 WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
220 }
221 }
222 return mSimUnlockProgressDialog;
223 }
224
Jim Miller3efe1062012-09-28 16:59:31 -0700225 private boolean checkPuk() {
Jim Millerdcb3d842012-08-23 19:18:12 -0700226 // make sure the puk is at least 8 digits long.
Daniel Sandler23d7a6e2012-11-02 00:21:07 -0400227 if (mPasswordEntry.getText().length() >= 8) {
228 mPukText = mPasswordEntry.getText().toString();
Jim Miller3efe1062012-09-28 16:59:31 -0700229 return true;
Jim Millerdcb3d842012-08-23 19:18:12 -0700230 }
Jim Miller3efe1062012-09-28 16:59:31 -0700231 return false;
232 }
Jim Millerdcb3d842012-08-23 19:18:12 -0700233
Jim Miller3efe1062012-09-28 16:59:31 -0700234 private boolean checkPin() {
Jim Millerdcb3d842012-08-23 19:18:12 -0700235 // make sure the PIN is between 4 and 8 digits
Daniel Sandler23d7a6e2012-11-02 00:21:07 -0400236 int length = mPasswordEntry.getText().length();
Jim Miller3efe1062012-09-28 16:59:31 -0700237 if (length >= 4 && length <= 8) {
Daniel Sandler23d7a6e2012-11-02 00:21:07 -0400238 mPinText = mPasswordEntry.getText().toString();
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 public boolean confirmPin() {
Daniel Sandler23d7a6e2012-11-02 00:21:07 -0400245 return mPinText.equals(mPasswordEntry.getText().toString());
Jim Miller3efe1062012-09-28 16:59:31 -0700246 }
247
248 private void updateSim() {
Jim Millerdcb3d842012-08-23 19:18:12 -0700249 getSimUnlockProgressDialog().show();
250
Jim Miller4b09dd32012-09-04 14:27:25 -0700251 if (!mCheckInProgress) {
252 mCheckInProgress = true;
Jim Miller3efe1062012-09-28 16:59:31 -0700253 new CheckSimPuk(mPukText, mPinText) {
Jim Miller4b09dd32012-09-04 14:27:25 -0700254 void onSimLockChangedResponse(final boolean success) {
Jim Miller3efe1062012-09-28 16:59:31 -0700255 post(new Runnable() {
Jim Miller4b09dd32012-09-04 14:27:25 -0700256 public void run() {
257 if (mSimUnlockProgressDialog != null) {
258 mSimUnlockProgressDialog.hide();
259 }
260 if (success) {
261 mCallback.dismiss(true);
262 } else {
Jim Miller3efe1062012-09-28 16:59:31 -0700263 mStateMachine.reset();
Adam Cohen0a4f9002012-10-12 19:57:16 -0700264 mSecurityMessageDisplay.setMessage(R.string.kg_invalid_puk, true);
Jim Miller4b09dd32012-09-04 14:27:25 -0700265 }
266 mCheckInProgress = false;
Jim Millerdcb3d842012-08-23 19:18:12 -0700267 }
Jim Miller4b09dd32012-09-04 14:27:25 -0700268 });
269 }
270 }.start();
271 }
Jim Millerdcb3d842012-08-23 19:18:12 -0700272 }
273
274 @Override
Daniel Sandler23d7a6e2012-11-02 00:21:07 -0400275 protected void verifyPasswordAndUnlock() {
276 mStateMachine.next();
Jim Miller9cf2c522012-10-04 22:02:29 -0700277 }
Jim Millerdcb3d842012-08-23 19:18:12 -0700278}
Daniel Sandler23d7a6e2012-11-02 00:21:07 -0400279
280