blob: 826a03d1b65870e8e4ccd0400e15a516c1be9823 [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;
Jorim Jaggid05064b2014-11-20 21:35:33 +010020import android.content.res.ColorStateList;
Jim Miller52a61332014-11-12 19:29:51 -080021import android.content.res.Resources;
Jim Millerdcb3d842012-08-23 19:18:12 -070022import android.app.Activity;
Wink Savilleb896b9f2013-10-23 15:44:26 -070023import android.app.AlertDialog;
Jim Millerdcb3d842012-08-23 19:18:12 -070024import android.app.Dialog;
25import android.app.ProgressDialog;
Jorim Jaggid05064b2014-11-20 21:35:33 +010026import android.graphics.Color;
Jim Millerdcb3d842012-08-23 19:18:12 -070027import android.os.RemoteException;
28import android.os.ServiceManager;
Jim Miller52a61332014-11-12 19:29:51 -080029import android.telephony.SubscriptionInfo;
30import android.telephony.SubscriptionManager;
31import android.telephony.TelephonyManager;
Jim Millerdcb3d842012-08-23 19:18:12 -070032import android.util.AttributeSet;
Wink Savilleb896b9f2013-10-23 15:44:26 -070033import android.util.Log;
Jim Millerdcb3d842012-08-23 19:18:12 -070034import android.view.WindowManager;
Jorim Jaggid05064b2014-11-20 21:35:33 +010035import android.widget.ImageView;
Jim Millerdcb3d842012-08-23 19:18:12 -070036
Wink Savilleb896b9f2013-10-23 15:44:26 -070037import com.android.internal.telephony.ITelephony;
Jim Miller52a61332014-11-12 19:29:51 -080038import com.android.internal.telephony.IccCardConstants;
Wink Savilleb896b9f2013-10-23 15:44:26 -070039import com.android.internal.telephony.PhoneConstants;
Jim Miller52a61332014-11-12 19:29:51 -080040import com.android.internal.telephony.IccCardConstants.State;
Wink Savilleb896b9f2013-10-23 15:44:26 -070041
42
Daniel Sandler23d7a6e2012-11-02 00:21:07 -040043/**
44 * Displays a PIN pad for entering a PUK (Pin Unlock Kode) provided by a carrier.
45 */
Selim Cinek4e8b9ed2014-06-20 16:37:04 -070046public class KeyguardSimPukView extends KeyguardPinBasedInputView {
Wink Savilleb896b9f2013-10-23 15:44:26 -070047 private static final String LOG_TAG = "KeyguardSimPukView";
Jorim Jaggi5cf17872014-03-26 18:31:48 +010048 private static final boolean DEBUG = KeyguardConstants.DEBUG;
Jim Miller4fc2b012013-11-04 16:47:48 -080049 public static final String TAG = "KeyguardSimPukView";
Jim Millerdcb3d842012-08-23 19:18:12 -070050
51 private ProgressDialog mSimUnlockProgressDialog = null;
Jim Miller4fc2b012013-11-04 16:47:48 -080052 private CheckSimPuk mCheckSimPukThread;
Jim Miller3efe1062012-09-28 16:59:31 -070053 private String mPukText;
Jim Miller3efe1062012-09-28 16:59:31 -070054 private String mPinText;
55 private StateMachine mStateMachine = new StateMachine();
Wink Savilleb896b9f2013-10-23 15:44:26 -070056 private AlertDialog mRemainingAttemptsDialog;
Jim Miller52a61332014-11-12 19:29:51 -080057 private int mSubId;
Jorim Jaggid05064b2014-11-20 21:35:33 +010058 private ImageView mSimImageView;
Jim Miller52a61332014-11-12 19:29:51 -080059
60 KeyguardUpdateMonitorCallback mUpdateMonitorCallback = new KeyguardUpdateMonitorCallback() {
61 @Override
62 public void onSimStateChanged(int subId, int slotId, State simState) {
Brad Ebinger4cd3bdc2017-08-21 14:58:52 -070063 if (DEBUG) Log.v(TAG, "onSimStateChanged(subId=" + subId + ",state=" + simState + ")");
64 switch(simState) {
65 // If the SIM is removed, then we must remove the keyguard. It will be put up
66 // again when the PUK locked SIM is re-entered.
67 case ABSENT:
68 // intentional fall-through
69 // If the SIM is unlocked via a key sequence through the emergency dialer, it will
70 // move into the READY state and the PUK lock keyguard should be removed.
71 case READY: {
72 KeyguardUpdateMonitor.getInstance(getContext()).reportSimUnlocked(mSubId);
73 mCallback.dismiss(true, KeyguardUpdateMonitor.getCurrentUser());
74 break;
75 }
76 default:
77 resetState();
78 }
79 }
Jim Miller52a61332014-11-12 19:29:51 -080080 };
81
82 public KeyguardSimPukView(Context context) {
83 this(context, null);
84 }
85
86 public KeyguardSimPukView(Context context, AttributeSet attrs) {
87 super(context, attrs);
88 }
Jim Miller3efe1062012-09-28 16:59:31 -070089
90 private class StateMachine {
91 final int ENTER_PUK = 0;
92 final int ENTER_PIN = 1;
93 final int CONFIRM_PIN = 2;
94 final int DONE = 3;
95 private int state = ENTER_PUK;
96
97 public void next() {
98 int msg = 0;
99 if (state == ENTER_PUK) {
100 if (checkPuk()) {
101 state = ENTER_PIN;
102 msg = R.string.kg_puk_enter_pin_hint;
103 } else {
104 msg = R.string.kg_invalid_sim_puk_hint;
105 }
106 } else if (state == ENTER_PIN) {
107 if (checkPin()) {
108 state = CONFIRM_PIN;
109 msg = R.string.kg_enter_confirm_pin_hint;
110 } else {
111 msg = R.string.kg_invalid_sim_pin_hint;
112 }
113 } else if (state == CONFIRM_PIN) {
114 if (confirmPin()) {
115 state = DONE;
Jim Miller5ecd8112013-01-09 18:50:26 -0800116 msg = R.string.keyguard_sim_unlock_progress_dialog_message;
Jim Miller3efe1062012-09-28 16:59:31 -0700117 updateSim();
118 } else {
Daniel Sandler23d7a6e2012-11-02 00:21:07 -0400119 state = ENTER_PIN; // try again?
Jim Miller3efe1062012-09-28 16:59:31 -0700120 msg = R.string.kg_invalid_confirm_pin_hint;
121 }
122 }
Jim Miller4db942c2016-05-16 18:06:50 -0700123 resetPasswordText(true /* animate */, true /* announce */);
Jim Miller3efe1062012-09-28 16:59:31 -0700124 if (msg != 0) {
Adrian Roosdb327e92016-10-12 16:41:28 -0700125 mSecurityMessageDisplay.setMessage(msg);
Jim Miller3efe1062012-09-28 16:59:31 -0700126 }
127 }
128
129 void reset() {
130 mPinText="";
131 mPukText="";
132 state = ENTER_PUK;
Jim Miller52a61332014-11-12 19:29:51 -0800133 KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
134 mSubId = monitor.getNextSubIdForState(IccCardConstants.State.PUK_REQUIRED);
Wink Savillea54bf652014-12-11 13:37:50 -0800135 if (SubscriptionManager.isValidSubscriptionId(mSubId)) {
Jim Miller52a61332014-11-12 19:29:51 -0800136 int count = TelephonyManager.getDefault().getSimCount();
137 Resources rez = getResources();
138 final String msg;
Jorim Jaggid05064b2014-11-20 21:35:33 +0100139 int color = Color.WHITE;
Jim Miller52a61332014-11-12 19:29:51 -0800140 if (count < 2) {
141 msg = rez.getString(R.string.kg_puk_enter_puk_hint);
142 } else {
143 SubscriptionInfo info = monitor.getSubscriptionInfoForSubId(mSubId);
144 CharSequence displayName = info != null ? info.getDisplayName() : "";
145 msg = rez.getString(R.string.kg_puk_enter_puk_hint_multi, displayName);
Jorim Jaggid05064b2014-11-20 21:35:33 +0100146 if (info != null) {
147 color = info.getIconTint();
148 }
Jim Miller52a61332014-11-12 19:29:51 -0800149 }
Adrian Roosdb327e92016-10-12 16:41:28 -0700150 mSecurityMessageDisplay.setMessage(msg);
Jorim Jaggid05064b2014-11-20 21:35:33 +0100151 mSimImageView.setImageTintList(ColorStateList.valueOf(color));
Jim Miller52a61332014-11-12 19:29:51 -0800152 }
Daniel Sandler23d7a6e2012-11-02 00:21:07 -0400153 mPasswordEntry.requestFocus();
Jim Miller3efe1062012-09-28 16:59:31 -0700154 }
155 }
156
Selim Cinek3122fa82015-06-18 01:38:59 -0700157 @Override
158 protected int getPromtReasonStringRes(int reason) {
159 // No message on SIM Puk
160 return 0;
161 }
162
Wink Savilleb896b9f2013-10-23 15:44:26 -0700163 private String getPukPasswordErrorMessage(int attemptsRemaining) {
164 String displayMessage;
165
166 if (attemptsRemaining == 0) {
167 displayMessage = getContext().getString(R.string.kg_password_wrong_puk_code_dead);
168 } else if (attemptsRemaining > 0) {
169 displayMessage = getContext().getResources()
170 .getQuantityString(R.plurals.kg_password_wrong_puk_code, attemptsRemaining,
171 attemptsRemaining);
172 } else {
173 displayMessage = getContext().getString(R.string.kg_password_puk_failed);
174 }
175 if (DEBUG) Log.d(LOG_TAG, "getPukPasswordErrorMessage:"
176 + " attemptsRemaining=" + attemptsRemaining + " displayMessage=" + displayMessage);
177 return displayMessage;
178 }
179
Jim Miller4db942c2016-05-16 18:06:50 -0700180 @Override
Daniel Sandler23d7a6e2012-11-02 00:21:07 -0400181 public void resetState() {
Selim Cinek4e8b9ed2014-06-20 16:37:04 -0700182 super.resetState();
Daniel Sandler23d7a6e2012-11-02 00:21:07 -0400183 mStateMachine.reset();
Daniel Sandler23d7a6e2012-11-02 00:21:07 -0400184 }
185
186 @Override
Jim Miller7d5e00a2013-10-11 22:45:57 -0700187 protected boolean shouldLockout(long deadline) {
188 // SIM PUK doesn't have a timed lockout
189 return false;
190 }
191
192 @Override
Daniel Sandler23d7a6e2012-11-02 00:21:07 -0400193 protected int getPasswordTextViewId() {
Jorim Jaggifa9189f2014-04-17 20:17:30 +0200194 return R.id.pukEntry;
Jim Millerdcb3d842012-08-23 19:18:12 -0700195 }
196
197 @Override
198 protected void onFinishInflate() {
199 super.onFinishInflate();
Jim Miller0b728242012-10-28 19:42:30 -0700200
Jorim Jaggi40a0b382014-05-27 21:12:27 +0200201 if (mEcaView instanceof EmergencyCarrierArea) {
202 ((EmergencyCarrierArea) mEcaView).setCarrierTextVisible(true);
203 }
Alan Viverette51efddb2017-04-05 10:00:01 -0400204 mSimImageView = findViewById(R.id.keyguard_sim);
Jim Millerdcb3d842012-08-23 19:18:12 -0700205 }
206
Adam Cohen6fb841f2012-10-24 13:15:38 -0700207 @Override
Jim Miller52a61332014-11-12 19:29:51 -0800208 protected void onAttachedToWindow() {
209 super.onAttachedToWindow();
210 KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitorCallback);
211 }
212
213 @Override
214 protected void onDetachedFromWindow() {
215 super.onDetachedFromWindow();
216 KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mUpdateMonitorCallback);
217 }
218
219 @Override
Adam Cohen6fb841f2012-10-24 13:15:38 -0700220 public void showUsabilityHint() {
221 }
222
Daniel Sandler23d7a6e2012-11-02 00:21:07 -0400223 @Override
224 public void onPause() {
Jim Millerdcb3d842012-08-23 19:18:12 -0700225 // dismiss the dialog.
226 if (mSimUnlockProgressDialog != null) {
227 mSimUnlockProgressDialog.dismiss();
228 mSimUnlockProgressDialog = null;
229 }
230 }
231
232 /**
233 * Since the IPC can block, we want to run the request in a separate thread
234 * with a callback.
235 */
236 private abstract class CheckSimPuk extends Thread {
237
238 private final String mPin, mPuk;
Jim Miller52a61332014-11-12 19:29:51 -0800239 private final int mSubId;
Jim Millerdcb3d842012-08-23 19:18:12 -0700240
Jim Miller52a61332014-11-12 19:29:51 -0800241 protected CheckSimPuk(String puk, String pin, int subId) {
Jim Millerdcb3d842012-08-23 19:18:12 -0700242 mPuk = puk;
243 mPin = pin;
Jim Miller52a61332014-11-12 19:29:51 -0800244 mSubId = subId;
Jim Millerdcb3d842012-08-23 19:18:12 -0700245 }
246
Wink Savilleb896b9f2013-10-23 15:44:26 -0700247 abstract void onSimLockChangedResponse(final int result, final int attemptsRemaining);
Jim Millerdcb3d842012-08-23 19:18:12 -0700248
249 @Override
250 public void run() {
251 try {
Jim Miller52a61332014-11-12 19:29:51 -0800252 if (DEBUG) Log.v(TAG, "call supplyPukReportResult()");
Wink Savilleb896b9f2013-10-23 15:44:26 -0700253 final int[] result = ITelephony.Stub.asInterface(ServiceManager
Jim Miller52a61332014-11-12 19:29:51 -0800254 .checkService("phone")).supplyPukReportResultForSubscriber(mSubId, mPuk, mPin);
255 if (DEBUG) {
256 Log.v(TAG, "supplyPukReportResult returned: " + result[0] + " " + result[1]);
257 }
Jim Millerdcb3d842012-08-23 19:18:12 -0700258 post(new Runnable() {
Jim Miller4db942c2016-05-16 18:06:50 -0700259 @Override
Jim Millerdcb3d842012-08-23 19:18:12 -0700260 public void run() {
Wink Savilleb896b9f2013-10-23 15:44:26 -0700261 onSimLockChangedResponse(result[0], result[1]);
Jim Millerdcb3d842012-08-23 19:18:12 -0700262 }
263 });
264 } catch (RemoteException e) {
Jim Miller4fc2b012013-11-04 16:47:48 -0800265 Log.e(TAG, "RemoteException for supplyPukReportResult:", e);
Jim Millerdcb3d842012-08-23 19:18:12 -0700266 post(new Runnable() {
Jim Miller4db942c2016-05-16 18:06:50 -0700267 @Override
Jim Millerdcb3d842012-08-23 19:18:12 -0700268 public void run() {
Wink Savilleb896b9f2013-10-23 15:44:26 -0700269 onSimLockChangedResponse(PhoneConstants.PIN_GENERAL_FAILURE, -1);
Jim Millerdcb3d842012-08-23 19:18:12 -0700270 }
271 });
272 }
273 }
274 }
275
Jim Millerdcb3d842012-08-23 19:18:12 -0700276 private Dialog getSimUnlockProgressDialog() {
277 if (mSimUnlockProgressDialog == null) {
278 mSimUnlockProgressDialog = new ProgressDialog(mContext);
Daniel Sandler23d7a6e2012-11-02 00:21:07 -0400279 mSimUnlockProgressDialog.setMessage(
280 mContext.getString(R.string.kg_sim_unlock_progress_dialog_message));
Jim Millerdcb3d842012-08-23 19:18:12 -0700281 mSimUnlockProgressDialog.setIndeterminate(true);
282 mSimUnlockProgressDialog.setCancelable(false);
283 if (!(mContext instanceof Activity)) {
284 mSimUnlockProgressDialog.getWindow().setType(
285 WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
286 }
287 }
288 return mSimUnlockProgressDialog;
289 }
290
Wink Savilleb896b9f2013-10-23 15:44:26 -0700291 private Dialog getPukRemainingAttemptsDialog(int remaining) {
292 String msg = getPukPasswordErrorMessage(remaining);
293 if (mRemainingAttemptsDialog == null) {
294 AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
295 builder.setMessage(msg);
296 builder.setCancelable(false);
297 builder.setNeutralButton(R.string.ok, null);
298 mRemainingAttemptsDialog = builder.create();
299 mRemainingAttemptsDialog.getWindow().setType(
300 WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
301 } else {
302 mRemainingAttemptsDialog.setMessage(msg);
303 }
304 return mRemainingAttemptsDialog;
305 }
306
Jim Miller3efe1062012-09-28 16:59:31 -0700307 private boolean checkPuk() {
Jim Millerdcb3d842012-08-23 19:18:12 -0700308 // make sure the puk is at least 8 digits long.
Rakesh Pallerlab8b7bd32014-01-08 15:49:34 +0530309 if (mPasswordEntry.getText().length() == 8) {
Selim Cinek4e8b9ed2014-06-20 16:37:04 -0700310 mPukText = mPasswordEntry.getText();
Jim Miller3efe1062012-09-28 16:59:31 -0700311 return true;
Jim Millerdcb3d842012-08-23 19:18:12 -0700312 }
Jim Miller3efe1062012-09-28 16:59:31 -0700313 return false;
314 }
Jim Millerdcb3d842012-08-23 19:18:12 -0700315
Jim Miller3efe1062012-09-28 16:59:31 -0700316 private boolean checkPin() {
Jim Millerdcb3d842012-08-23 19:18:12 -0700317 // make sure the PIN is between 4 and 8 digits
Daniel Sandler23d7a6e2012-11-02 00:21:07 -0400318 int length = mPasswordEntry.getText().length();
Jim Miller3efe1062012-09-28 16:59:31 -0700319 if (length >= 4 && length <= 8) {
Selim Cinek4e8b9ed2014-06-20 16:37:04 -0700320 mPinText = mPasswordEntry.getText();
Jim Miller3efe1062012-09-28 16:59:31 -0700321 return true;
Jim Millerdcb3d842012-08-23 19:18:12 -0700322 }
Jim Miller3efe1062012-09-28 16:59:31 -0700323 return false;
324 }
Jim Millerdcb3d842012-08-23 19:18:12 -0700325
Jim Miller3efe1062012-09-28 16:59:31 -0700326 public boolean confirmPin() {
Selim Cinek4e8b9ed2014-06-20 16:37:04 -0700327 return mPinText.equals(mPasswordEntry.getText());
Jim Miller3efe1062012-09-28 16:59:31 -0700328 }
329
330 private void updateSim() {
Jim Millerdcb3d842012-08-23 19:18:12 -0700331 getSimUnlockProgressDialog().show();
332
Jim Miller4fc2b012013-11-04 16:47:48 -0800333 if (mCheckSimPukThread == null) {
Jim Miller52a61332014-11-12 19:29:51 -0800334 mCheckSimPukThread = new CheckSimPuk(mPukText, mPinText, mSubId) {
Jim Miller4db942c2016-05-16 18:06:50 -0700335 @Override
Wink Savilleb896b9f2013-10-23 15:44:26 -0700336 void onSimLockChangedResponse(final int result, final int attemptsRemaining) {
Jim Miller3efe1062012-09-28 16:59:31 -0700337 post(new Runnable() {
Jim Miller4db942c2016-05-16 18:06:50 -0700338 @Override
Jim Miller4b09dd32012-09-04 14:27:25 -0700339 public void run() {
340 if (mSimUnlockProgressDialog != null) {
341 mSimUnlockProgressDialog.hide();
342 }
Jim Miller4db942c2016-05-16 18:06:50 -0700343 resetPasswordText(true /* animate */,
344 result != PhoneConstants.PIN_RESULT_SUCCESS /* announce */);
Wink Savilleb896b9f2013-10-23 15:44:26 -0700345 if (result == PhoneConstants.PIN_RESULT_SUCCESS) {
Jim Miller52a61332014-11-12 19:29:51 -0800346 KeyguardUpdateMonitor.getInstance(getContext())
347 .reportSimUnlocked(mSubId);
Vadim Tryshev8702ca72016-04-22 08:14:12 -0700348 mCallback.dismiss(true, KeyguardUpdateMonitor.getCurrentUser());
Jim Miller4b09dd32012-09-04 14:27:25 -0700349 } else {
Wink Savilleb896b9f2013-10-23 15:44:26 -0700350 if (result == PhoneConstants.PIN_PASSWORD_INCORRECT) {
351 if (attemptsRemaining <= 2) {
352 // this is getting critical - show dialog
353 getPukRemainingAttemptsDialog(attemptsRemaining).show();
354 } else {
355 // show message
356 mSecurityMessageDisplay.setMessage(
Adrian Roosdb327e92016-10-12 16:41:28 -0700357 getPukPasswordErrorMessage(attemptsRemaining));
Wink Savilleb896b9f2013-10-23 15:44:26 -0700358 }
359 } else {
360 mSecurityMessageDisplay.setMessage(getContext().getString(
Adrian Roosdb327e92016-10-12 16:41:28 -0700361 R.string.kg_password_puk_failed));
Wink Savilleb896b9f2013-10-23 15:44:26 -0700362 }
363 if (DEBUG) Log.d(LOG_TAG, "verifyPasswordAndUnlock "
364 + " UpdateSim.onSimCheckResponse: "
365 + " attemptsRemaining=" + attemptsRemaining);
Jim Miller3efe1062012-09-28 16:59:31 -0700366 mStateMachine.reset();
Jim Miller4b09dd32012-09-04 14:27:25 -0700367 }
Jim Miller4fc2b012013-11-04 16:47:48 -0800368 mCheckSimPukThread = null;
Jim Millerdcb3d842012-08-23 19:18:12 -0700369 }
Jim Miller4b09dd32012-09-04 14:27:25 -0700370 });
371 }
Jim Miller4fc2b012013-11-04 16:47:48 -0800372 };
373 mCheckSimPukThread.start();
Jim Miller4b09dd32012-09-04 14:27:25 -0700374 }
Jim Millerdcb3d842012-08-23 19:18:12 -0700375 }
376
377 @Override
Daniel Sandler23d7a6e2012-11-02 00:21:07 -0400378 protected void verifyPasswordAndUnlock() {
379 mStateMachine.next();
Jim Miller9cf2c522012-10-04 22:02:29 -0700380 }
Jorim Jaggic14f8292014-05-27 02:25:45 +0200381
382 @Override
383 public void startAppearAnimation() {
384 // noop.
385 }
Jorim Jaggi76a16232014-08-08 17:00:47 +0200386
387 @Override
388 public boolean startDisappearAnimation(Runnable finishRunnable) {
389 return false;
390 }
Jim Millerdcb3d842012-08-23 19:18:12 -0700391}
Daniel Sandler23d7a6e2012-11-02 00:21:07 -0400392
393