Blanket copy of PhoneApp to services/Telephony.
First phase of splitting out InCallUI from PhoneApp.
Change-Id: I237341c4ff00e96c677caa4580b251ef3432931b
diff --git a/src/com/android/phone/ChangeIccPinScreen.java b/src/com/android/phone/ChangeIccPinScreen.java
new file mode 100644
index 0000000..70bf431
--- /dev/null
+++ b/src/com/android/phone/ChangeIccPinScreen.java
@@ -0,0 +1,306 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.phone;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.os.AsyncResult;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.text.method.DigitsKeyListener;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.ScrollView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.android.internal.telephony.CommandException;
+import com.android.internal.telephony.IccCard;
+import com.android.internal.telephony.Phone;
+
+/**
+ * "Change ICC PIN" UI for the Phone app.
+ */
+public class ChangeIccPinScreen extends Activity {
+ private static final String LOG_TAG = PhoneGlobals.LOG_TAG;
+ private static final boolean DBG = false;
+
+ private static final int EVENT_PIN_CHANGED = 100;
+
+ private enum EntryState {
+ ES_PIN,
+ ES_PUK
+ }
+
+ private EntryState mState;
+
+ private static final int NO_ERROR = 0;
+ private static final int PIN_MISMATCH = 1;
+ private static final int PIN_INVALID_LENGTH = 2;
+
+ private static final int MIN_PIN_LENGTH = 4;
+ private static final int MAX_PIN_LENGTH = 8;
+
+ private Phone mPhone;
+ private boolean mChangePin2;
+ private TextView mBadPinError;
+ private TextView mMismatchError;
+ private EditText mOldPin;
+ private EditText mNewPin1;
+ private EditText mNewPin2;
+ private EditText mPUKCode;
+ private Button mButton;
+ private Button mPUKSubmit;
+ private ScrollView mScrollView;
+
+ private LinearLayout mIccPUKPanel;
+
+ private Handler mHandler = new Handler() {
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case EVENT_PIN_CHANGED:
+ AsyncResult ar = (AsyncResult) msg.obj;
+ handleResult(ar);
+ break;
+ }
+
+ return;
+ }
+ };
+
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ mPhone = PhoneGlobals.getPhone();
+
+ resolveIntent();
+
+ setContentView(R.layout.change_sim_pin_screen);
+
+ mOldPin = (EditText) findViewById(R.id.old_pin);
+ mOldPin.setKeyListener(DigitsKeyListener.getInstance());
+ mOldPin.setMovementMethod(null);
+ mOldPin.setOnClickListener(mClicked);
+
+ mNewPin1 = (EditText) findViewById(R.id.new_pin1);
+ mNewPin1.setKeyListener(DigitsKeyListener.getInstance());
+ mNewPin1.setMovementMethod(null);
+ mNewPin1.setOnClickListener(mClicked);
+
+ mNewPin2 = (EditText) findViewById(R.id.new_pin2);
+ mNewPin2.setKeyListener(DigitsKeyListener.getInstance());
+ mNewPin2.setMovementMethod(null);
+ mNewPin2.setOnClickListener(mClicked);
+
+ mBadPinError = (TextView) findViewById(R.id.bad_pin);
+ mMismatchError = (TextView) findViewById(R.id.mismatch);
+
+ mButton = (Button) findViewById(R.id.button);
+ mButton.setOnClickListener(mClicked);
+
+ mScrollView = (ScrollView) findViewById(R.id.scroll);
+
+ mPUKCode = (EditText) findViewById(R.id.puk_code);
+ mPUKCode.setKeyListener(DigitsKeyListener.getInstance());
+ mPUKCode.setMovementMethod(null);
+ mPUKCode.setOnClickListener(mClicked);
+
+ mPUKSubmit = (Button) findViewById(R.id.puk_submit);
+ mPUKSubmit.setOnClickListener(mClicked);
+
+ mIccPUKPanel = (LinearLayout) findViewById(R.id.puk_panel);
+
+ int id = mChangePin2 ? R.string.change_pin2 : R.string.change_pin;
+ setTitle(getResources().getText(id));
+
+ mState = EntryState.ES_PIN;
+ }
+
+ private void resolveIntent() {
+ Intent intent = getIntent();
+ mChangePin2 = intent.getBooleanExtra("pin2", mChangePin2);
+ }
+
+ private void reset() {
+ mScrollView.scrollTo(0, 0);
+ mBadPinError.setVisibility(View.GONE);
+ mMismatchError.setVisibility(View.GONE);
+ }
+
+ private int validateNewPin(String p1, String p2) {
+ if (p1 == null) {
+ return PIN_INVALID_LENGTH;
+ }
+
+ if (!p1.equals(p2)) {
+ return PIN_MISMATCH;
+ }
+
+ int len1 = p1.length();
+
+ if (len1 < MIN_PIN_LENGTH || len1 > MAX_PIN_LENGTH) {
+ return PIN_INVALID_LENGTH;
+ }
+
+ return NO_ERROR;
+ }
+
+ private View.OnClickListener mClicked = new View.OnClickListener() {
+ public void onClick(View v) {
+ if (v == mOldPin) {
+ mNewPin1.requestFocus();
+ } else if (v == mNewPin1) {
+ mNewPin2.requestFocus();
+ } else if (v == mNewPin2) {
+ mButton.requestFocus();
+ } else if (v == mButton) {
+ IccCard iccCardInterface = mPhone.getIccCard();
+ if (iccCardInterface != null) {
+ String oldPin = mOldPin.getText().toString();
+ String newPin1 = mNewPin1.getText().toString();
+ String newPin2 = mNewPin2.getText().toString();
+
+ int error = validateNewPin(newPin1, newPin2);
+
+ switch (error) {
+ case PIN_INVALID_LENGTH:
+ case PIN_MISMATCH:
+ mNewPin1.getText().clear();
+ mNewPin2.getText().clear();
+ mMismatchError.setVisibility(View.VISIBLE);
+
+ Resources r = getResources();
+ CharSequence text;
+
+ if (error == PIN_MISMATCH) {
+ text = r.getString(R.string.mismatchPin);
+ } else {
+ text = r.getString(R.string.invalidPin);
+ }
+
+ mMismatchError.setText(text);
+ break;
+
+ default:
+ Message callBack = Message.obtain(mHandler,
+ EVENT_PIN_CHANGED);
+
+ if (DBG) log("change pin attempt: old=" + oldPin +
+ ", newPin=" + newPin1);
+
+ reset();
+
+ if (mChangePin2) {
+ iccCardInterface.changeIccFdnPassword(oldPin,
+ newPin1, callBack);
+ } else {
+ iccCardInterface.changeIccLockPassword(oldPin,
+ newPin1, callBack);
+ }
+
+ // TODO: show progress panel
+ }
+ }
+ } else if (v == mPUKCode) {
+ mPUKSubmit.requestFocus();
+ } else if (v == mPUKSubmit) {
+ mPhone.getIccCard().supplyPuk2(mPUKCode.getText().toString(),
+ mNewPin1.getText().toString(),
+ Message.obtain(mHandler, EVENT_PIN_CHANGED));
+ }
+ }
+ };
+
+ private void handleResult(AsyncResult ar) {
+ if (ar.exception == null) {
+ if (DBG) log("handleResult: success!");
+
+ if (mState == EntryState.ES_PUK) {
+ mScrollView.setVisibility(View.VISIBLE);
+ mIccPUKPanel.setVisibility(View.GONE);
+ }
+ // TODO: show success feedback
+ showConfirmation();
+
+ mHandler.postDelayed(new Runnable() {
+ public void run() {
+ finish();
+ }
+ }, 3000);
+
+ } else if (ar.exception instanceof CommandException
+ /* && ((CommandException)ar.exception).getCommandError() ==
+ CommandException.Error.PASSWORD_INCORRECT */ ) {
+ if (mState == EntryState.ES_PIN) {
+ if (DBG) log("handleResult: pin failed!");
+ mOldPin.getText().clear();
+ mBadPinError.setVisibility(View.VISIBLE);
+ CommandException ce = (CommandException) ar.exception;
+ if (ce.getCommandError() == CommandException.Error.SIM_PUK2) {
+ if (DBG) log("handleResult: puk requested!");
+ mState = EntryState.ES_PUK;
+ displayPUKAlert();
+ mScrollView.setVisibility(View.GONE);
+ mIccPUKPanel.setVisibility(View.VISIBLE);
+ mPUKCode.requestFocus();
+ }
+ } else if (mState == EntryState.ES_PUK) {
+ //should really check to see if the error is CommandException.PASSWORD_INCORRECT...
+ if (DBG) log("handleResult: puk2 failed!");
+ displayPUKAlert();
+ mPUKCode.getText().clear();
+ mPUKCode.requestFocus();
+ }
+ }
+ }
+
+ private AlertDialog mPUKAlert;
+ private void displayPUKAlert () {
+ if (mPUKAlert == null) {
+ mPUKAlert = new AlertDialog.Builder(this)
+ .setMessage (R.string.puk_requested)
+ .setCancelable(false)
+ .show();
+ } else {
+ mPUKAlert.show();
+ }
+ //TODO: The 3 second delay here is somewhat arbitrary, reflecting the values
+ //used elsewhere for similar code. This should get revisited with the framework
+ //crew to see if there is some standard we should adhere to.
+ mHandler.postDelayed(new Runnable() {
+ public void run() {
+ mPUKAlert.dismiss();
+ }
+ }, 3000);
+ }
+
+ private void showConfirmation() {
+ int id = mChangePin2 ? R.string.pin2_changed : R.string.pin_changed;
+ Toast.makeText(this, id, Toast.LENGTH_SHORT).show();
+ }
+
+ private void log(String msg) {
+ String prefix = mChangePin2 ? "[ChgPin2]" : "[ChgPin]";
+ Log.d(LOG_TAG, prefix + msg);
+ }
+}