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