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