• 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.settings.fdn;
18 
19 import android.app.ActionBar;
20 import android.app.FragmentManager;
21 import android.app.FragmentTransaction;
22 import android.os.AsyncResult;
23 import android.os.Bundle;
24 import android.os.Handler;
25 import android.os.Message;
26 import android.preference.PreferenceActivity;
27 import android.preference.PreferenceScreen;
28 import android.util.Log;
29 import android.view.MenuItem;
30 import android.widget.Toast;
31 
32 import com.android.internal.telephony.CommandException;
33 import com.android.internal.telephony.Phone;
34 import com.android.phone.CallFeaturesSetting;
35 import com.android.phone.PhoneGlobals;
36 import com.android.phone.R;
37 import com.android.phone.SubscriptionInfoHelper;
38 
39 /**
40  * FDN settings UI for the Phone app.
41  * Rewritten to look and behave closer to the other preferences.
42  */
43 public class FdnSetting extends PreferenceActivity
44         implements EditPinPreference.OnPinEnteredListener, Pin2LockedDialogFragment.Listener {
45 
46     private static final String LOG_TAG = PhoneGlobals.LOG_TAG;
47     private static final boolean DBG = false;
48 
49     private SubscriptionInfoHelper mSubscriptionInfoHelper;
50     private Phone mPhone;
51 
52     /**
53      * Events we handle.
54      * The first is used for toggling FDN enable, the second for the PIN change.
55      */
56     private static final int EVENT_PIN2_ENTRY_COMPLETE = 100;
57     private static final int EVENT_PIN2_CHANGE_COMPLETE = 200;
58     private static final int EVENT_PIN2_CHANGE_COMPLETE_TOGGLE_FDN = 300;
59 
60     // String keys for preference lookup
61     private static final String BUTTON_FDN_ENABLE_KEY = "button_fdn_enable_key";
62     private static final String BUTTON_CHANGE_PIN2_KEY = "button_change_pin2_key";
63     private static final String FDN_LIST_PREF_SCREEN_KEY = "fdn_list_pref_screen_key";
64 
65     private EditPinPreference mButtonEnableFDN;
66     private EditPinPreference mButtonChangePin2;
67 
68     // State variables
69     private String mOldPin;
70     private String mNewPin;
71     private String mPuk2;
72     private static final int PIN_CHANGE_OLD = 0;
73     private static final int PIN_CHANGE_NEW = 1;
74     private static final int PIN_CHANGE_REENTER = 2;
75     private static final int PIN_CHANGE_PUK = 3;
76     private static final int PIN_CHANGE_NEW_PIN_FOR_PUK = 4;
77     private static final int PIN_CHANGE_REENTER_PIN_FOR_PUK = 5;
78     private int mPinChangeState;
79     private boolean mIsPuk2Locked;    // Indicates we know that we are PUK2 blocked.
80 
81     private static final String SKIP_OLD_PIN_KEY = "skip_old_pin_key";
82     private static final String PIN_CHANGE_STATE_KEY = "pin_change_state_key";
83     private static final String OLD_PIN_KEY = "old_pin_key";
84     private static final String NEW_PIN_KEY = "new_pin_key";
85     private static final String PUK_KEY = "puk_key";
86     private static final String DIALOG_MESSAGE_KEY = "dialog_message_key";
87     private static final String DIALOG_PIN_ENTRY_KEY = "dialog_pin_entry_key";
88     private static final String FDN_DIALOG_MESSAGE_KEY = "fdn_dialog_message_key";
89     private static final String FDN_DIALOG_PIN_ENTRY_KEY = "fdn_dialog_pin_entry_key";
90 
91     // size limits for the pin.
92     private static final int MIN_PIN_LENGTH = 4;
93     private static final int MAX_PIN_LENGTH = 8;
94 
95     /**
96      * Delegate to the respective handlers.
97      */
98     @Override
onPinEntered(EditPinPreference preference, boolean positiveResult)99     public void onPinEntered(EditPinPreference preference, boolean positiveResult) {
100         if (preference == mButtonEnableFDN && (!mIsPuk2Locked || !positiveResult)) {
101             toggleFDNEnable(positiveResult);
102         } else {
103             updatePINChangeState(preference, positiveResult);
104         }
105     }
106 
107     /**
108      * Attempt to toggle FDN activation.
109      */
toggleFDNEnable(boolean positiveResult)110     private void toggleFDNEnable(boolean positiveResult) {
111         if (!positiveResult) {
112             // reset the state on cancel, either to expect PUK2 or PIN2
113             if (!mIsPuk2Locked) {
114                 resetPinChangeState();
115             } else {
116                 resetPinChangeStateForPUK2();
117             }
118             return;
119         }
120 
121         // validate the pin first, before submitting it to the RIL for FDN enable.
122         String password = mButtonEnableFDN.getText();
123         if (validatePin (password, false)) {
124             // get the relevant data for the icc call
125             boolean isEnabled = mPhone.getIccCard().getIccFdnEnabled();
126             Message onComplete = mFDNHandler.obtainMessage(EVENT_PIN2_ENTRY_COMPLETE);
127 
128             // make fdn request
129             mPhone.getIccCard().setIccFdnEnabled(!isEnabled, password, onComplete);
130         } else {
131             // throw up error if the pin is invalid.
132             displayMessage(R.string.invalidPin2);
133         }
134 
135         mButtonEnableFDN.setText("");
136     }
137 
138     /**
139      * Attempt to change the pin.
140      */
updatePINChangeState(EditPinPreference button, boolean positiveResult)141     private void updatePINChangeState(EditPinPreference button, boolean positiveResult) {
142         if (DBG) log("updatePINChangeState positive=" + positiveResult
143                 + " mPinChangeState=" + mPinChangeState
144                 + " mIsPuk2Locked=" + mIsPuk2Locked);
145 
146         if (!positiveResult) {
147             // reset the state on cancel, either to expect PUK2 or PIN2
148             if (!mIsPuk2Locked) {
149                 resetPinChangeState();
150             } else {
151                 resetPinChangeStateForPUK2();
152             }
153             return;
154         }
155 
156         // Progress through the dialog states, generally in this order:
157         //   1. Enter old pin
158         //   2. Enter new pin
159         //   3. Re-Enter new pin
160         // While handling any error conditions that may show up in between.
161         // Also handle the PUK2 entry, if it is requested.
162         //
163         // In general, if any invalid entries are made, the dialog re-
164         // appears with text to indicate what the issue is.
165         switch (mPinChangeState) {
166             case PIN_CHANGE_OLD:
167                 mOldPin = button.getText();
168                 button.setText("");
169                 // if the pin is not valid, display a message and reset the state.
170                 if (validatePin (mOldPin, false)) {
171                     mPinChangeState = PIN_CHANGE_NEW;
172                     displayPinChangeDialog(button);
173                 } else {
174                     displayPinChangeDialog(button, R.string.invalidPin2, true);
175                 }
176                 break;
177             case PIN_CHANGE_NEW:
178                 mNewPin = button.getText();
179                 button.setText("");
180                 // if the new pin is not valid, display a message and reset the state.
181                 if (validatePin (mNewPin, false)) {
182                     mPinChangeState = PIN_CHANGE_REENTER;
183                     displayPinChangeDialog(button);
184                 } else {
185                     displayPinChangeDialog(button, R.string.invalidPin2, true);
186                 }
187                 break;
188             case PIN_CHANGE_REENTER:
189                 if (validatePin(button.getText(), false)) {
190                     // if the re-entered pin is not valid, display a message and reset the state.
191                     if (!mNewPin.equals(button.getText())) {
192                         mPinChangeState = PIN_CHANGE_NEW;
193                         button.setText("");
194                         displayPinChangeDialog(button, R.string.mismatchPin2, true);
195                     } else {
196                         // If the PIN is valid, then we submit the change PIN request or
197                         // display the PUK2 dialog if we KNOW that we're PUK2 locked.
198                         button.setText("");
199                         Message onComplete = mFDNHandler.obtainMessage(
200                                 EVENT_PIN2_CHANGE_COMPLETE);
201                         if (!mIsPuk2Locked) {
202                             mPhone.getIccCard().changeIccFdnPassword(mOldPin,
203                                     mNewPin, onComplete);
204                         } else {
205                             mPhone.getIccCard().supplyPuk2(mPuk2, mNewPin,
206                                     onComplete);
207                         }
208                     }
209                 } else {
210                     button.setText("");
211                     displayPinChangeDialog(button, R.string.invalidPin2, true);
212                 }
213                 break;
214             case PIN_CHANGE_PUK:
215                 // Doh! too many incorrect requests, PUK requested.
216                 mPuk2 = button.getText();
217                 button.setText("");
218                 // if the puk is not valid, display
219                 // a message and reset the state.
220                 if (validatePin(mPuk2, true)) {
221                     mPinChangeState = PIN_CHANGE_NEW_PIN_FOR_PUK;
222                     displayPinChangeDialog(button);
223                 } else {
224                     displayPinChangeDialog(button, R.string.invalidPuk2, true);
225                 }
226                 break;
227             case PIN_CHANGE_NEW_PIN_FOR_PUK:
228                 mNewPin = button.getText();
229                 button.setText("");
230                 // if the new pin is not valid, display
231                 // a message and reset the state.
232                 if (validatePin (mNewPin, false)) {
233                     mPinChangeState = PIN_CHANGE_REENTER_PIN_FOR_PUK;
234                     displayPinChangeDialog(button);
235                 } else {
236                     displayPinChangeDialog(button, R.string.invalidPin2, true);
237                 }
238                 break;
239             case PIN_CHANGE_REENTER_PIN_FOR_PUK:
240                 // if the re-entered pin is not valid, display
241                 // a message and reset the state.
242                 if (!mNewPin.equals(button.getText())) {
243                     mPinChangeState = PIN_CHANGE_NEW_PIN_FOR_PUK;
244                     button.setText("");
245                     displayPinChangeDialog(button, R.string.mismatchPin2, true);
246                 } else {
247                     // Both puk2 and new pin2 are ready to submit
248                     Message onComplete = null;
249                     if (button == mButtonChangePin2) {
250                         button.setText("");
251                         onComplete = mFDNHandler.obtainMessage(EVENT_PIN2_CHANGE_COMPLETE);
252                     } else {
253                         onComplete = mFDNHandler.obtainMessage(
254                                 EVENT_PIN2_CHANGE_COMPLETE_TOGGLE_FDN);
255                     }
256                     mPhone.getIccCard().supplyPuk2(mPuk2, mNewPin, onComplete);
257                 }
258                 break;
259         }
260     }
261 
262     /**
263      * Handler for asynchronous replies from the sim.
264      */
265     private final Handler mFDNHandler = new Handler() {
266         @Override
267         public void handleMessage(Message msg) {
268             switch (msg.what) {
269 
270                 // when we are enabling FDN, either we are unsuccessful and display
271                 // a toast, or just update the UI.
272                 case EVENT_PIN2_ENTRY_COMPLETE: {
273                         if (DBG) log("Handle EVENT_PIN2_ENTRY_COMPLETE");
274                         AsyncResult ar = (AsyncResult) msg.obj;
275                         if (ar.exception != null) {
276                             if (ar.exception instanceof CommandException) {
277                                 int attemptsRemaining = msg.arg1;
278                                 // see if PUK2 is requested and alert the user accordingly.
279                                 CommandException.Error e =
280                                         ((CommandException) ar.exception).getCommandError();
281                                 switch (e) {
282                                     case SIM_PUK2:
283                                         showPin2OrPuk2LockedDialog(Pin2LockedDialogFragment
284                                                 .DIALOG_ID_PUK2_REQUESTED_ON_PIN_ENTRY);
285                                         break;
286                                     case PASSWORD_INCORRECT:
287                                         displayMessage(R.string.pin2_invalid, attemptsRemaining);
288                                         break;
289                                     default:
290                                         displayMessage(R.string.fdn_failed, attemptsRemaining);
291                                         break;
292                                 }
293                             } else {
294                                 displayMessage(R.string.pin2_error_exception);
295                             }
296                         }
297                         updateEnableFDN();
298                     }
299                     break;
300 
301                 // when changing the pin we need to pay attention to whether or not
302                 // the error requests a PUK (usually after too many incorrect tries)
303                 // Set the state accordingly.
304                 case EVENT_PIN2_CHANGE_COMPLETE:
305                 case EVENT_PIN2_CHANGE_COMPLETE_TOGGLE_FDN: {
306                         if (DBG)
307                             log("Handle EVENT_PIN2_CHANGE_COMPLETE");
308                         AsyncResult ar = (AsyncResult) msg.obj;
309                         if (ar.exception != null) {
310                             if (ar.exception instanceof CommandException) {
311                                 int attemptsRemaining = msg.arg1;
312                                 log("Handle EVENT_PIN2_CHANGE_COMPLETE attemptsRemaining="
313                                         + attemptsRemaining);
314                                 CommandException ce = (CommandException) ar.exception;
315                                 if (ce.getCommandError() == CommandException.Error.SIM_PUK2) {
316                                     // throw an alert dialog on the screen, displaying the
317                                     // request for a PUK2.
318                                     showPin2OrPuk2LockedDialog(Pin2LockedDialogFragment
319                                             .DIALOG_ID_PUK2_REQUESTED_ON_PIN_CHANGED);
320                                 } else {
321                                     if (mIsPuk2Locked && attemptsRemaining == 0) {
322                                         showPin2OrPuk2LockedDialog(Pin2LockedDialogFragment
323                                                 .DIALOG_ID_PUK2_LOCKED_OUT);
324                                     } else {
325                                         // set the correct error message depending upon the state.
326                                         // Reset the state depending upon or knowledge of the PUK
327                                         // state.
328                                         if (!mIsPuk2Locked) {
329                                             displayMessage(R.string.badPin2, attemptsRemaining);
330                                             resetPinChangeState();
331                                         } else {
332                                             displayMessage(R.string.badPuk2, attemptsRemaining);
333                                             resetPinChangeStateForPUK2();
334                                         }
335                                     }
336                                 }
337                             } else {
338                                 displayMessage(R.string.pin2_error_exception);
339                             }
340                         } else {
341                             if (mPinChangeState == PIN_CHANGE_PUK) {
342                                 displayMessage(R.string.pin2_unblocked);
343                             } else {
344                                 displayMessage(R.string.pin2_changed);
345                             }
346 
347                             // reset to normal behaviour on successful change.
348                             if (msg.what == EVENT_PIN2_CHANGE_COMPLETE_TOGGLE_FDN) {
349                                 log("Handle EVENT_PIN2_CHANGE_COMPLETE_TOGGLE_FDN");
350                                 // activate/deactivate FDN
351                                 toggleFDNEnable(true);
352                             }
353                             resetPinChangeState();
354                         }
355                     }
356                     mButtonChangePin2.setText("");
357                     mButtonEnableFDN.setText("");
358                     break;
359             }
360         }
361     };
362 
363     /**
364      * Display a toast for message, like the rest of the settings.
365      */
displayMessage(int strId, int attemptsRemaining)366     private void displayMessage(int strId, int attemptsRemaining) {
367         String s = getString(strId);
368         if ((strId == R.string.badPin2) || (strId == R.string.badPuk2) ||
369                 (strId == R.string.pin2_invalid)) {
370             if (attemptsRemaining >= 0) {
371                 s = getString(strId) + getString(R.string.pin2_attempts, attemptsRemaining);
372             } else {
373                 s = getString(strId);
374             }
375         }
376         log("displayMessage: attemptsRemaining=" + attemptsRemaining + " s=" + s);
377         Toast.makeText(this, s, Toast.LENGTH_SHORT).show();
378     }
379 
displayMessage(int strId)380     private void displayMessage(int strId) {
381         displayMessage(strId, -1);
382     }
383 
384     /**
385      * The next two functions are for updating the message field on the dialog.
386      */
displayPinChangeDialog(EditPinPreference button)387     private void displayPinChangeDialog(EditPinPreference button) {
388         displayPinChangeDialog(button, 0, true);
389     }
390 
displayPinChangeDialog(EditPinPreference button, int strId, boolean shouldDisplay)391     private void displayPinChangeDialog(EditPinPreference button,
392             int strId, boolean shouldDisplay) {
393         int msgId;
394         switch (mPinChangeState) {
395             case PIN_CHANGE_OLD:
396                 if (button == mButtonEnableFDN) {
397                     msgId = R.string.enter_pin2_text;
398                 } else {
399                     msgId = R.string.oldPin2Label;
400                 }
401                 break;
402             case PIN_CHANGE_NEW:
403             case PIN_CHANGE_NEW_PIN_FOR_PUK:
404                 msgId = R.string.newPin2Label;
405                 break;
406             case PIN_CHANGE_REENTER:
407             case PIN_CHANGE_REENTER_PIN_FOR_PUK:
408                 msgId = R.string.confirmPin2Label;
409                 break;
410             case PIN_CHANGE_PUK:
411             default:
412                 msgId = R.string.label_puk2_code;
413                 break;
414         }
415 
416         // append the note / additional message, if needed.
417         if (strId != 0) {
418             button.setDialogMessage(getText(msgId) + "\n" + getText(strId));
419         } else {
420             button.setDialogMessage(msgId);
421         }
422 
423         // only display if requested.
424         if (shouldDisplay) {
425             button.showPinDialog();
426         }
427     }
428 
429     /**
430      * Reset the state of the pin change dialog.
431      */
resetPinChangeState()432     private final void resetPinChangeState() {
433         if (DBG) log("resetPinChangeState");
434         mPinChangeState = PIN_CHANGE_OLD;
435         displayPinChangeDialog(mButtonEnableFDN, 0, false);
436         displayPinChangeDialog(mButtonChangePin2, 0, false);
437         mOldPin = mNewPin = "";
438         mIsPuk2Locked = false;
439     }
440 
441     /**
442      * Reset the state of the pin change dialog solely for PUK2 use.
443      */
resetPinChangeStateForPUK2()444     private final void resetPinChangeStateForPUK2() {
445         if (DBG) log("resetPinChangeStateForPUK2");
446         mPinChangeState = PIN_CHANGE_PUK;
447         displayPinChangeDialog(mButtonEnableFDN, 0, false);
448         displayPinChangeDialog(mButtonChangePin2, 0, false);
449         mOldPin = mNewPin = mPuk2 = "";
450         mIsPuk2Locked = true;
451     }
452 
453     /**
454      * Validate the pin entry.
455      *
456      * @param pin This is the pin to validate
457      * @param isPuk Boolean indicating whether we are to treat
458      * the pin input as a puk.
459      */
validatePin(String pin, boolean isPuk)460     private boolean validatePin(String pin, boolean isPuk) {
461 
462         // for pin, we have 4-8 numbers, or puk, we use only 8.
463         int pinMinimum = isPuk ? MAX_PIN_LENGTH : MIN_PIN_LENGTH;
464 
465         // check validity
466         if (pin == null || pin.length() < pinMinimum || pin.length() > MAX_PIN_LENGTH) {
467             return false;
468         } else {
469             return true;
470         }
471     }
472 
473     /**
474      * Reflect the updated FDN state in the UI.
475      */
updateEnableFDN()476     private void updateEnableFDN() {
477         if (mPhone.getIccCard().getIccFdnEnabled()) {
478             mButtonEnableFDN.setTitle(R.string.enable_fdn_ok);
479             mButtonEnableFDN.setSummary(R.string.fdn_enabled);
480             mButtonEnableFDN.setDialogTitle(R.string.disable_fdn);
481         } else {
482             mButtonEnableFDN.setTitle(R.string.disable_fdn_ok);
483             mButtonEnableFDN.setSummary(R.string.fdn_disabled);
484             mButtonEnableFDN.setDialogTitle(R.string.enable_fdn);
485         }
486     }
487 
488     /**
489     * Reflect the updated change PIN2 state in the UI.
490     */
updateChangePIN2()491     private void updateChangePIN2() {
492         if (mPhone.getIccCard().getIccPuk2Blocked()) {
493             showPin2OrPuk2LockedDialog(Pin2LockedDialogFragment.DIALOG_ID_PUK2_LOCKED_OUT);
494             resetPinChangeStateForPUK2();
495         } else if (mPhone.getIccCard().getIccPin2Blocked()) {
496             // If the pin2 is blocked, the state of the change pin2 dialog
497             // should be set for puk2 use (that is, the user should be prompted
498             // to enter puk2 code instead of old pin2).
499             resetPinChangeStateForPUK2();
500         } else {
501             resetPinChangeState();
502         }
503     }
504 
505     @Override
onCreate(Bundle icicle)506     protected void onCreate(Bundle icicle) {
507         super.onCreate(icicle);
508 
509         mSubscriptionInfoHelper = new SubscriptionInfoHelper(this, getIntent());
510         mPhone = mSubscriptionInfoHelper.getPhone();
511 
512         addPreferencesFromResource(R.xml.fdn_setting);
513 
514         //get UI object references
515         PreferenceScreen prefSet = getPreferenceScreen();
516         mButtonEnableFDN = (EditPinPreference) prefSet.findPreference(BUTTON_FDN_ENABLE_KEY);
517         mButtonChangePin2 = (EditPinPreference) prefSet.findPreference(BUTTON_CHANGE_PIN2_KEY);
518 
519         //assign click listener and update state
520         mButtonEnableFDN.setOnPinEnteredListener(this);
521         updateEnableFDN();
522 
523         mButtonChangePin2.setOnPinEnteredListener(this);
524 
525         PreferenceScreen fdnListPref =
526                 (PreferenceScreen) prefSet.findPreference(FDN_LIST_PREF_SCREEN_KEY);
527         fdnListPref.setIntent(mSubscriptionInfoHelper.getIntent(FdnList.class));
528 
529         // Only reset the pin change dialog if we're not in the middle of changing it.
530         if (icicle == null) {
531             resetPinChangeState();
532         } else {
533             mIsPuk2Locked = icicle.getBoolean(SKIP_OLD_PIN_KEY);
534             mPinChangeState = icicle.getInt(PIN_CHANGE_STATE_KEY);
535             mOldPin = icicle.getString(OLD_PIN_KEY);
536             mNewPin = icicle.getString(NEW_PIN_KEY);
537             mPuk2 = icicle.getString(PUK_KEY);
538             mButtonChangePin2.setDialogMessage(
539                     icicle.getString(DIALOG_MESSAGE_KEY));
540             mButtonChangePin2.setText(
541                     icicle.getString(DIALOG_PIN_ENTRY_KEY));
542             mButtonEnableFDN.setDialogMessage(
543                     icicle.getString(FDN_DIALOG_MESSAGE_KEY));
544             mButtonEnableFDN.setText(icicle.getString(FDN_DIALOG_PIN_ENTRY_KEY));
545         }
546 
547         ActionBar actionBar = getActionBar();
548         if (actionBar != null) {
549             // android.R.id.home will be triggered in onOptionsItemSelected()
550             actionBar.setDisplayHomeAsUpEnabled(true);
551             mSubscriptionInfoHelper.setActionBarTitle(
552                     actionBar, getResources(), R.string.fdn_with_label);
553         }
554     }
555 
556     @Override
onResume()557     protected void onResume() {
558         super.onResume();
559         mPhone = mSubscriptionInfoHelper.getPhone();
560         updateEnableFDN();
561         updateChangePIN2();
562     }
563 
564     /**
565      * Save the state of the pin change.
566      */
567     @Override
onSaveInstanceState(Bundle out)568     protected void onSaveInstanceState(Bundle out) {
569         super.onSaveInstanceState(out);
570         out.putBoolean(SKIP_OLD_PIN_KEY, mIsPuk2Locked);
571         out.putInt(PIN_CHANGE_STATE_KEY, mPinChangeState);
572         out.putString(OLD_PIN_KEY, mOldPin);
573         out.putString(NEW_PIN_KEY, mNewPin);
574         out.putString(PUK_KEY, mPuk2);
575         if (mButtonChangePin2.isEnabled()) {
576             out.putString(DIALOG_MESSAGE_KEY, mButtonChangePin2.getDialogMessage().toString());
577             out.putString(DIALOG_PIN_ENTRY_KEY, mButtonChangePin2.getText());
578         }
579         if (mButtonEnableFDN.isEnabled()) {
580             CharSequence dialogMsg = mButtonEnableFDN.getDialogMessage();
581             if (dialogMsg != null) {
582                 out.putString(FDN_DIALOG_MESSAGE_KEY,
583                         mButtonEnableFDN.getDialogMessage().toString());
584             }
585             out.putString(FDN_DIALOG_PIN_ENTRY_KEY, mButtonEnableFDN.getText());
586         }
587     }
588 
589     @Override
onOptionsItemSelected(MenuItem item)590     public boolean onOptionsItemSelected(MenuItem item) {
591         final int itemId = item.getItemId();
592         if (itemId == android.R.id.home) {  // See ActionBar#setDisplayHomeAsUpEnabled()
593             CallFeaturesSetting.goUpToTopLevelSetting(this, mSubscriptionInfoHelper);
594             return true;
595         }
596         return super.onOptionsItemSelected(item);
597     }
598 
log(String msg)599     private void log(String msg) {
600         Log.d(LOG_TAG, "FdnSetting: " + msg);
601     }
602 
603     @Override
onRequestPuk2(int id)604     public void onRequestPuk2(int id) {
605         resetPinChangeStateForPUK2();
606         final EditPinPreference button =
607                 (id == Pin2LockedDialogFragment.DIALOG_ID_PUK2_REQUESTED_ON_PIN_CHANGED)
608                         ? mButtonChangePin2 : mButtonEnableFDN;
609         displayPinChangeDialog(button, 0, true);
610     }
611 
showPin2OrPuk2LockedDialog(int id)612     private void showPin2OrPuk2LockedDialog(int id) {
613         final FragmentManager fragmentManager = getFragmentManager();
614         Pin2LockedDialogFragment dialogFragment = (Pin2LockedDialogFragment) fragmentManager
615                 .findFragmentByTag(Pin2LockedDialogFragment.TAG_PIN2_LOCKED_DIALOG);
616         if (dialogFragment == null) {
617             dialogFragment = new Pin2LockedDialogFragment();
618             Bundle args = new Bundle();
619             args.putInt(Pin2LockedDialogFragment.KEY_DIALOG_ID, id);
620             dialogFragment.setArguments(args);
621             dialogFragment.show(fragmentManager, Pin2LockedDialogFragment.TAG_PIN2_LOCKED_DIALOG);
622         } else {
623             FragmentTransaction transaction = fragmentManager.beginTransaction();
624             transaction.show(dialogFragment);
625             transaction.commitNow();
626         }
627     }
628 }
629 
630