blob: 0784495734519afcb382331cc7f77f190030c01d [file] [log] [blame]
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001/*
2 * Copyright (C) 2006 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 */
16
17package com.android.phone;
18
19import android.app.Activity;
20import android.app.AlertDialog;
Steve Statia7bee4652024-02-27 17:48:05 +000021import android.content.Context;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070022import android.content.Intent;
23import android.content.res.Resources;
24import android.os.AsyncResult;
25import android.os.Bundle;
26import android.os.Handler;
27import android.os.Message;
Steve Statia7bee4652024-02-27 17:48:05 +000028import android.os.UserManager;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070029import android.text.method.DigitsKeyListener;
30import android.util.Log;
31import android.view.View;
32import android.widget.Button;
33import android.widget.EditText;
34import android.widget.LinearLayout;
35import android.widget.ScrollView;
36import android.widget.TextView;
37import android.widget.Toast;
38
39import com.android.internal.telephony.CommandException;
40import com.android.internal.telephony.IccCard;
41import com.android.internal.telephony.Phone;
42
43/**
44 * "Change ICC PIN" UI for the Phone app.
45 */
46public class ChangeIccPinScreen extends Activity {
47 private static final String LOG_TAG = PhoneGlobals.LOG_TAG;
48 private static final boolean DBG = false;
49
50 private static final int EVENT_PIN_CHANGED = 100;
Steve Statia7bee4652024-02-27 17:48:05 +000051
Santos Cordon7d4ddf62013-07-10 11:58:08 -070052 private enum EntryState {
53 ES_PIN,
54 ES_PUK
55 }
Steve Statia7bee4652024-02-27 17:48:05 +000056
Santos Cordon7d4ddf62013-07-10 11:58:08 -070057 private EntryState mState;
58
59 private static final int NO_ERROR = 0;
60 private static final int PIN_MISMATCH = 1;
61 private static final int PIN_INVALID_LENGTH = 2;
62
63 private static final int MIN_PIN_LENGTH = 4;
64 private static final int MAX_PIN_LENGTH = 8;
65
Steve Statia7bee4652024-02-27 17:48:05 +000066 private UserManager mUserManager;
67 private boolean mDisallowedConfig;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070068 private Phone mPhone;
69 private boolean mChangePin2;
70 private TextView mBadPinError;
71 private TextView mMismatchError;
72 private EditText mOldPin;
73 private EditText mNewPin1;
74 private EditText mNewPin2;
75 private EditText mPUKCode;
76 private Button mButton;
77 private Button mPUKSubmit;
78 private ScrollView mScrollView;
79
80 private LinearLayout mIccPUKPanel;
81
82 private Handler mHandler = new Handler() {
83 public void handleMessage(Message msg) {
84 switch (msg.what) {
85 case EVENT_PIN_CHANGED:
86 AsyncResult ar = (AsyncResult) msg.obj;
87 handleResult(ar);
88 break;
89 }
90
91 return;
92 }
93 };
94
95 public void onCreate(Bundle icicle) {
96 super.onCreate(icicle);
97
Steve Statia7bee4652024-02-27 17:48:05 +000098 mUserManager = this.getSystemService(UserManager.class);
99 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
100 mDisallowedConfig = true;
101 }
102
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700103 mPhone = PhoneGlobals.getPhone();
104
105 resolveIntent();
106
107 setContentView(R.layout.change_sim_pin_screen);
Steve Statia7bee4652024-02-27 17:48:05 +0000108 setupView();
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700109
Steve Statia7bee4652024-02-27 17:48:05 +0000110 mState = EntryState.ES_PIN;
111 }
112
113 private void setupView() {
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700114 mOldPin = (EditText) findViewById(R.id.old_pin);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700115 mNewPin1 = (EditText) findViewById(R.id.new_pin1);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700116 mNewPin2 = (EditText) findViewById(R.id.new_pin2);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700117 mBadPinError = (TextView) findViewById(R.id.bad_pin);
118 mMismatchError = (TextView) findViewById(R.id.mismatch);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700119 mButton = (Button) findViewById(R.id.button);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700120 mScrollView = (ScrollView) findViewById(R.id.scroll);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700121 mPUKCode = (EditText) findViewById(R.id.puk_code);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700122 mPUKSubmit = (Button) findViewById(R.id.puk_submit);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700123 mIccPUKPanel = (LinearLayout) findViewById(R.id.puk_panel);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700124 int id = mChangePin2 ? R.string.change_pin2 : R.string.change_pin;
125 setTitle(getResources().getText(id));
Steve Statia7bee4652024-02-27 17:48:05 +0000126
127 if (mDisallowedConfig) {
128 mOldPin.setEnabled(false);
129 mOldPin.setAlpha(.5f);
130
131 mNewPin1.setEnabled(false);
132 mNewPin1.setAlpha(.5f);
133
134 mNewPin2.setEnabled(false);
135 mNewPin2.setAlpha(.5f);
136
137 mButton.setEnabled(false);
138 mButton.setAlpha(.5f);
139
140 mPUKCode.setEnabled(false);
141 mPUKCode.setAlpha(.5f);
142
143 mPUKSubmit.setEnabled(false);
144 mPUKSubmit.setAlpha(.5f);
145 } else {
146 mOldPin.setKeyListener(DigitsKeyListener.getInstance());
147 mOldPin.setMovementMethod(null);
148 mOldPin.setOnClickListener(mClicked);
149
150 mNewPin1.setKeyListener(DigitsKeyListener.getInstance());
151 mNewPin1.setMovementMethod(null);
152 mNewPin1.setOnClickListener(mClicked);
153
154 mNewPin2.setKeyListener(DigitsKeyListener.getInstance());
155 mNewPin2.setMovementMethod(null);
156 mNewPin2.setOnClickListener(mClicked);
157
158 mButton.setOnClickListener(mClicked);
159
160 mPUKCode.setKeyListener(DigitsKeyListener.getInstance());
161 mPUKCode.setMovementMethod(null);
162 mPUKCode.setOnClickListener(mClicked);
163
164 mPUKSubmit.setOnClickListener(mClicked);
165 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700166 }
167
168 private void resolveIntent() {
169 Intent intent = getIntent();
170 mChangePin2 = intent.getBooleanExtra("pin2", mChangePin2);
171 }
172
173 private void reset() {
174 mScrollView.scrollTo(0, 0);
175 mBadPinError.setVisibility(View.GONE);
176 mMismatchError.setVisibility(View.GONE);
177 }
178
179 private int validateNewPin(String p1, String p2) {
180 if (p1 == null) {
181 return PIN_INVALID_LENGTH;
182 }
183
184 if (!p1.equals(p2)) {
185 return PIN_MISMATCH;
186 }
187
188 int len1 = p1.length();
189
190 if (len1 < MIN_PIN_LENGTH || len1 > MAX_PIN_LENGTH) {
191 return PIN_INVALID_LENGTH;
192 }
193
194 return NO_ERROR;
195 }
196
197 private View.OnClickListener mClicked = new View.OnClickListener() {
198 public void onClick(View v) {
199 if (v == mOldPin) {
200 mNewPin1.requestFocus();
201 } else if (v == mNewPin1) {
202 mNewPin2.requestFocus();
203 } else if (v == mNewPin2) {
204 mButton.requestFocus();
205 } else if (v == mButton) {
206 IccCard iccCardInterface = mPhone.getIccCard();
207 if (iccCardInterface != null) {
208 String oldPin = mOldPin.getText().toString();
209 String newPin1 = mNewPin1.getText().toString();
210 String newPin2 = mNewPin2.getText().toString();
211
212 int error = validateNewPin(newPin1, newPin2);
213
214 switch (error) {
215 case PIN_INVALID_LENGTH:
216 case PIN_MISMATCH:
217 mNewPin1.getText().clear();
218 mNewPin2.getText().clear();
219 mMismatchError.setVisibility(View.VISIBLE);
220
221 Resources r = getResources();
222 CharSequence text;
223
224 if (error == PIN_MISMATCH) {
225 text = r.getString(R.string.mismatchPin);
226 } else {
227 text = r.getString(R.string.invalidPin);
228 }
229
230 mMismatchError.setText(text);
231 break;
232
233 default:
234 Message callBack = Message.obtain(mHandler,
235 EVENT_PIN_CHANGED);
236
237 if (DBG) log("change pin attempt: old=" + oldPin +
238 ", newPin=" + newPin1);
239
240 reset();
241
242 if (mChangePin2) {
243 iccCardInterface.changeIccFdnPassword(oldPin,
244 newPin1, callBack);
245 } else {
246 iccCardInterface.changeIccLockPassword(oldPin,
247 newPin1, callBack);
248 }
249
250 // TODO: show progress panel
251 }
252 }
253 } else if (v == mPUKCode) {
254 mPUKSubmit.requestFocus();
255 } else if (v == mPUKSubmit) {
256 mPhone.getIccCard().supplyPuk2(mPUKCode.getText().toString(),
257 mNewPin1.getText().toString(),
258 Message.obtain(mHandler, EVENT_PIN_CHANGED));
259 }
260 }
261 };
262
263 private void handleResult(AsyncResult ar) {
264 if (ar.exception == null) {
265 if (DBG) log("handleResult: success!");
266
267 if (mState == EntryState.ES_PUK) {
268 mScrollView.setVisibility(View.VISIBLE);
269 mIccPUKPanel.setVisibility(View.GONE);
270 }
271 // TODO: show success feedback
272 showConfirmation();
273
274 mHandler.postDelayed(new Runnable() {
275 public void run() {
276 finish();
277 }
278 }, 3000);
279
280 } else if (ar.exception instanceof CommandException
281 /* && ((CommandException)ar.exception).getCommandError() ==
282 CommandException.Error.PASSWORD_INCORRECT */ ) {
283 if (mState == EntryState.ES_PIN) {
284 if (DBG) log("handleResult: pin failed!");
285 mOldPin.getText().clear();
286 mBadPinError.setVisibility(View.VISIBLE);
287 CommandException ce = (CommandException) ar.exception;
288 if (ce.getCommandError() == CommandException.Error.SIM_PUK2) {
289 if (DBG) log("handleResult: puk requested!");
290 mState = EntryState.ES_PUK;
291 displayPUKAlert();
292 mScrollView.setVisibility(View.GONE);
293 mIccPUKPanel.setVisibility(View.VISIBLE);
294 mPUKCode.requestFocus();
295 }
296 } else if (mState == EntryState.ES_PUK) {
297 //should really check to see if the error is CommandException.PASSWORD_INCORRECT...
298 if (DBG) log("handleResult: puk2 failed!");
299 displayPUKAlert();
300 mPUKCode.getText().clear();
301 mPUKCode.requestFocus();
302 }
303 }
304 }
305
306 private AlertDialog mPUKAlert;
307 private void displayPUKAlert () {
308 if (mPUKAlert == null) {
Sooraj Sasindran9dbb2882021-10-19 11:40:34 -0700309 mPUKAlert = FrameworksUtils.makeAlertDialogBuilder(this)
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700310 .setMessage (R.string.puk_requested)
311 .setCancelable(false)
312 .show();
313 } else {
314 mPUKAlert.show();
315 }
316 //TODO: The 3 second delay here is somewhat arbitrary, reflecting the values
317 //used elsewhere for similar code. This should get revisited with the framework
318 //crew to see if there is some standard we should adhere to.
319 mHandler.postDelayed(new Runnable() {
320 public void run() {
321 mPUKAlert.dismiss();
322 }
323 }, 3000);
324 }
325
326 private void showConfirmation() {
327 int id = mChangePin2 ? R.string.pin2_changed : R.string.pin_changed;
328 Toast.makeText(this, id, Toast.LENGTH_SHORT).show();
329 }
330
331 private void log(String msg) {
332 String prefix = mChangePin2 ? "[ChgPin2]" : "[ChgPin]";
333 Log.d(LOG_TAG, prefix + msg);
334 }
335}