1 /* 2 * Copyright (C) 2008 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 17 package com.android.phone; 18 19 import android.content.Context; 20 import android.os.AsyncResult; 21 import android.os.Bundle; 22 import android.os.Handler; 23 import android.os.Message; 24 import android.text.Editable; 25 import android.text.Spannable; 26 import android.text.TextUtils; 27 import android.text.TextWatcher; 28 import android.text.method.DialerKeyListener; 29 import android.util.Log; 30 import android.view.KeyEvent; 31 import android.view.View; 32 import android.widget.Button; 33 import android.widget.EditText; 34 import android.widget.LinearLayout; 35 import android.widget.TextView; 36 37 import com.android.internal.telephony.Phone; 38 import com.android.internal.telephony.PhoneFactory; 39 40 /** 41 * "SIM network unlock" PIN entry screen. 42 * 43 * @see PhoneApp.EVENT_SIM_NETWORK_LOCKED 44 * 45 * TODO: This UI should be part of the lock screen, not the 46 * phone app (see bug 1804111). 47 */ 48 public class IccNetworkDepersonalizationPanel extends IccPanel { 49 50 //debug constants 51 private static final boolean DBG = false; 52 53 //events 54 private static final int EVENT_ICC_NTWRK_DEPERSONALIZATION_RESULT = 100; 55 56 private Phone mPhone; 57 58 //UI elements 59 private EditText mPinEntry; 60 private LinearLayout mEntryPanel; 61 private LinearLayout mStatusPanel; 62 private TextView mStatusText; 63 64 private Button mUnlockButton; 65 private Button mDismissButton; 66 67 //private textwatcher to control text entry. 68 private TextWatcher mPinEntryWatcher = new TextWatcher() { 69 public void beforeTextChanged(CharSequence buffer, int start, int olen, int nlen) { 70 } 71 72 public void onTextChanged(CharSequence buffer, int start, int olen, int nlen) { 73 } 74 75 public void afterTextChanged(Editable buffer) { 76 if (SpecialCharSequenceMgr.handleChars( 77 getContext(), buffer.toString())) { 78 mPinEntry.getText().clear(); 79 } 80 } 81 }; 82 83 //handler for unlock function results 84 private Handler mHandler = new Handler() { 85 public void handleMessage(Message msg) { 86 if (msg.what == EVENT_ICC_NTWRK_DEPERSONALIZATION_RESULT) { 87 AsyncResult res = (AsyncResult) msg.obj; 88 if (res.exception != null) { 89 if (DBG) log("network depersonalization request failure."); 90 indicateError(); 91 postDelayed(new Runnable() { 92 public void run() { 93 hideAlert(); 94 mPinEntry.getText().clear(); 95 mPinEntry.requestFocus(); 96 } 97 }, 3000); 98 } else { 99 if (DBG) log("network depersonalization success."); 100 indicateSuccess(); 101 postDelayed(new Runnable() { 102 public void run() { 103 dismiss(); 104 } 105 }, 3000); 106 } 107 } 108 } 109 }; 110 111 //constructor 112 public IccNetworkDepersonalizationPanel(Context context) { 113 super(context); 114 } 115 116 @Override 117 protected void onCreate(Bundle icicle) { 118 super.onCreate(icicle); 119 setContentView(R.layout.sim_ndp); 120 121 // PIN entry text field 122 mPinEntry = (EditText) findViewById(R.id.pin_entry); 123 mPinEntry.setKeyListener(DialerKeyListener.getInstance()); 124 mPinEntry.setOnClickListener(mUnlockListener); 125 126 // Attach the textwatcher 127 CharSequence text = mPinEntry.getText(); 128 Spannable span = (Spannable) text; 129 span.setSpan(mPinEntryWatcher, 0, text.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE); 130 131 mEntryPanel = (LinearLayout) findViewById(R.id.entry_panel); 132 133 mUnlockButton = (Button) findViewById(R.id.ndp_unlock); 134 mUnlockButton.setOnClickListener(mUnlockListener); 135 136 // The "Dismiss" button is present in some (but not all) products, 137 // based on the "sim_network_unlock_allow_dismiss" resource. 138 mDismissButton = (Button) findViewById(R.id.ndp_dismiss); 139 if (getContext().getResources().getBoolean(R.bool.sim_network_unlock_allow_dismiss)) { 140 if (DBG) log("Enabling 'Dismiss' button..."); 141 mDismissButton.setVisibility(View.VISIBLE); 142 mDismissButton.setOnClickListener(mDismissListener); 143 } else { 144 if (DBG) log("Removing 'Dismiss' button..."); 145 mDismissButton.setVisibility(View.GONE); 146 } 147 148 //status panel is used since we're having problems with the alert dialog. 149 mStatusPanel = (LinearLayout) findViewById(R.id.status_panel); 150 mStatusText = (TextView) findViewById(R.id.status_text); 151 152 mPhone = PhoneFactory.getDefaultPhone(); 153 } 154 155 @Override 156 protected void onStart() { 157 super.onStart(); 158 } 159 160 //Mirrors IccPinUnlockPanel.onKeyDown(). 161 public boolean onKeyDown(int keyCode, KeyEvent event) { 162 if (keyCode == KeyEvent.KEYCODE_BACK) { 163 return true; 164 } 165 166 return super.onKeyDown(keyCode, event); 167 } 168 169 View.OnClickListener mUnlockListener = new View.OnClickListener() { 170 public void onClick(View v) { 171 String pin = mPinEntry.getText().toString(); 172 173 if (TextUtils.isEmpty(pin)) { 174 return; 175 } 176 177 if (DBG) log("requesting network depersonalization with code " + pin); 178 mPhone.getIccCard().supplyNetworkDepersonalization(pin, 179 Message.obtain(mHandler, EVENT_ICC_NTWRK_DEPERSONALIZATION_RESULT)); 180 indicateBusy(); 181 } 182 }; 183 184 private void indicateBusy() { 185 mStatusText.setText(R.string.requesting_unlock); 186 mEntryPanel.setVisibility(View.GONE); 187 mStatusPanel.setVisibility(View.VISIBLE); 188 } 189 190 private void indicateError() { 191 mStatusText.setText(R.string.unlock_failed); 192 mEntryPanel.setVisibility(View.GONE); 193 mStatusPanel.setVisibility(View.VISIBLE); 194 } 195 196 private void indicateSuccess() { 197 mStatusText.setText(R.string.unlock_success); 198 mEntryPanel.setVisibility(View.GONE); 199 mStatusPanel.setVisibility(View.VISIBLE); 200 } 201 202 private void hideAlert() { 203 mEntryPanel.setVisibility(View.VISIBLE); 204 mStatusPanel.setVisibility(View.GONE); 205 } 206 207 View.OnClickListener mDismissListener = new View.OnClickListener() { 208 public void onClick(View v) { 209 if (DBG) log("mDismissListener: skipping depersonalization..."); 210 dismiss(); 211 } 212 }; 213 214 private void log(String msg) { 215 Log.v(TAG, "[IccNetworkDepersonalizationPanel] " + msg); 216 } 217 } 218