This fixes an NULL pointer exception in Settings.
[android/platform/packages/apps/Phone.git] / src / com / android / phone / Settings.java
1 /*
2  * Copyright (C) 2006 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.app.AlertDialog;
20 import android.content.DialogInterface;
21 import android.os.Message;
22 import android.os.Handler;
23 import android.os.Bundle;
24 import android.os.AsyncResult;
25 import android.preference.CheckBoxPreference;
26 import android.preference.ListPreference;
27 import android.preference.Preference;
28 import android.preference.PreferenceActivity;
29 import android.preference.PreferenceScreen;
30 import android.util.Log;
31
32 import com.android.internal.telephony.Phone;
33 import com.android.internal.telephony.PhoneFactory;
34
35 /**
36  * List of Phone-specific settings screens.
37  */
38 public class Settings extends PreferenceActivity implements DialogInterface.OnClickListener,
39         DialogInterface.OnDismissListener, Preference.OnPreferenceChangeListener{
40
41     // debug data
42     private static final String LOG_TAG = "NetworkSettings";
43     private static final boolean DBG = true;
44
45     //String keys for preference lookup
46     private static final String BUTTON_PREFERED_NETWORK_MODE = "preferred_network_mode_key";
47     private static final String BUTTON_ROAMING_KEY = "button_roaming_key";
48     private static final String BUTTON_PREFER_2G_KEY = "button_prefer_2g_key";
49     private static final String BUTTON_CDMA_SYSTEM_SELECT_KEY = "cdma_system_select_key";
50     private static final String GSM_OPTIONS_KEY = "gsm_umts_options_key";
51     private static final String CDMA_OPTIONS_KEY = "cdma_options_key";
52
53     // Used for CDMA roaming mode
54     private static final int CDMA_ROAMING_MODE_HOME = 0;
55     private static final int CDMA_ROAMING_MODE_AFFILIATED = 1;
56     private static final int CDMA_ROAMING_MODE_ANY = 2;
57
58     // PREFERRED_CDMA_ROAMING_MODE  0 - Home Networks only, preferred
59     //                              1 - Roaming on affiliated networks
60     //                              2 - Roaming on any network
61     static final int PREFERRED_CDMA_ROAMING_MODE = 0;
62
63     static final int preferredNetworkMode = Phone.PREFERRED_NT_MODE;
64
65     //UI objects
66     private ListPreference mButtonPreferredNetworkMode;
67     private CheckBoxPreference mButtonDataRoam;
68     private CheckBoxPreference mButtonPrefer2g;
69     private ListPreference mButtonCdmaRoam;
70
71     private Phone mPhone;
72     private MyHandler mHandler;
73     private boolean mOkClicked;
74
75
76     //This is a method implemented for DialogInterface.OnClickListener.
77     //  Used to dismiss the dialogs when they come up.
78     public void onClick(DialogInterface dialog, int which) {
79         if (which == DialogInterface.BUTTON1) {
80             mPhone.setDataRoamingEnabled(true);
81             mOkClicked = true;
82         } else {
83             // Reset the toggle
84             mButtonDataRoam.setChecked(false);
85         }
86     }
87
88     public void onDismiss(DialogInterface dialog) {
89         // Assuming that onClick gets called first
90         if (!mOkClicked) {
91             mButtonDataRoam.setChecked(false);
92         }
93     }
94
95     /**
96      * Invoked on each preference click in this hierarchy, overrides
97      * PreferenceActivity's implementation.  Used to make sure we track the
98      * preference click events.
99      */
100     @Override
101     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
102         if (preference == mButtonPreferredNetworkMode) {
103             //displays the value taken from the Settings.System
104             int settingsNetworkMode = android.provider.Settings.Secure.getInt(mPhone.getContext().
105                     getContentResolver(), android.provider.Settings.Secure.PREFERRED_NETWORK_MODE,
106                     preferredNetworkMode);
107             mButtonPreferredNetworkMode.setValue(Integer.toString(settingsNetworkMode));
108             return true;
109         }
110         else if (preference == mButtonDataRoam) {
111             if (DBG) log("onPreferenceTreeClick: preference == mButtonDataRoam.");
112
113             //normally called on the toggle click
114             if (mButtonDataRoam.isChecked()) {
115                 // First confirm with a warning dialog about charges
116                 mOkClicked = false;
117                 new AlertDialog.Builder(this).setMessage(
118                         getResources().getString(R.string.roaming_warning))
119                         .setTitle(android.R.string.dialog_alert_title)
120                         .setIcon(android.R.drawable.ic_dialog_alert)
121                         .setPositiveButton(android.R.string.yes, this)
122                         .setNegativeButton(android.R.string.no, this)
123                         .show()
124                         .setOnDismissListener(this);
125             }
126             else {
127                 mPhone.setDataRoamingEnabled(false);
128             }
129             return true;
130         }
131         else if (preference == mButtonCdmaRoam) {
132             if (DBG) log("onPreferenceTreeClick: preference == mButtonCdmaRoam.");
133             //displays the value taken from the Settings.System
134             int cdmaRoamingMode = android.provider.Settings.Secure.getInt(
135                     mPhone.getContext().getContentResolver(),
136                     android.provider.Settings.Secure.CDMA_ROAMING_MODE, PREFERRED_CDMA_ROAMING_MODE);
137             mButtonCdmaRoam.setValue(Integer.toString(cdmaRoamingMode));
138             return true;
139         }
140         else if (preference == mButtonPrefer2g) {
141             int networkType = mButtonPrefer2g.isChecked() ? Phone.NT_MODE_GSM_ONLY
142                     : Phone.NT_MODE_WCDMA_PREF;
143             android.provider.Settings.Secure.putInt(mPhone.getContext().getContentResolver(),
144                     android.provider.Settings.Secure.PREFERRED_NETWORK_MODE,
145                     networkType);
146             mPhone.setPreferredNetworkType(networkType,
147                     mHandler.obtainMessage(MyHandler.MESSAGE_SET_PREFERRED_NETWORK_TYPE));
148             return true;
149         }
150         else {
151             // if the button is anything but the simple toggle preference,
152             // we'll need to disable all preferences to reject all click
153             // events until the sub-activity's UI comes up.
154             preferenceScreen.setEnabled(false);
155             // Let the intents be launched by the Preference manager
156             return false;
157         }
158     }
159
160     @Override
161     protected void onCreate(Bundle icicle) {
162         super.onCreate(icicle);
163
164         mPhone = PhoneFactory.getDefaultPhone();
165
166         if (mPhone.getPhoneName().equals("CDMA")) {
167             addPreferencesFromResource(R.xml.network_setting_cdma);
168
169         } else {
170             addPreferencesFromResource(R.xml.network_setting);
171         }
172
173         //get UI object references
174         PreferenceScreen prefSet = getPreferenceScreen();
175
176         mHandler = new MyHandler();
177         mButtonDataRoam = (CheckBoxPreference) prefSet.findPreference(BUTTON_ROAMING_KEY);
178
179         // Remove the other network type options
180         boolean isCdma = mPhone.getPhoneName().equals("CDMA");
181
182         // TODO: The radio technology could be changed dynamically after the phone has been created
183         if (isCdma) {
184             mButtonCdmaRoam =
185                 (ListPreference) prefSet.findPreference(BUTTON_CDMA_SYSTEM_SELECT_KEY);
186             // set the listener for the mButtonCdmaRoam list preference so we can issue
187             // change CDMA Roaming Mode.
188             mButtonCdmaRoam.setOnPreferenceChangeListener(this);
189
190             //Get the settingsCdmaRoamingMode from Settings.System and displays it
191             int settingsCdmaRoamingMode = android.provider.Settings.Secure.getInt(
192                     mPhone.getContext().getContentResolver(),
193                     android.provider.Settings.Secure.CDMA_ROAMING_MODE,
194                     PREFERRED_CDMA_ROAMING_MODE);
195             mButtonCdmaRoam.setValue(Integer.toString(settingsCdmaRoamingMode));
196         } else {
197             mButtonPrefer2g = (CheckBoxPreference) prefSet.findPreference(BUTTON_PREFER_2G_KEY);
198         }
199     }
200
201     @Override
202     protected void onResume() {
203         super.onResume();
204
205         // upon resumption from the sub-activity, make sure we re-enable the
206         // preferences.
207         getPreferenceScreen().setEnabled(true);
208
209         // Set UI state in onResume because a user could go home, launch some
210         // app to change this setting's backend, and re-launch this settings app
211         // and the UI state would be inconsistent with actual state
212         mButtonDataRoam.setChecked(mPhone.getDataRoamingEnabled());
213         if (mPhone.getPhoneName().equals("CDMA")) {
214             mPhone.queryCdmaRoamingPreference(
215                     mHandler.obtainMessage(MyHandler.MESSAGE_QUERY_ROAMING_PREFERENCE));
216         } else {
217             // Get the state for 'prefer 2g' setting
218             mPhone.getPreferredNetworkType(mHandler.obtainMessage(
219                     MyHandler.MESSAGE_GET_PREFERRED_NETWORK_TYPE));
220         }
221     }
222
223     /**
224      * Implemented to support onPreferenceChangeListener to look for preference
225      * changes specifically on CLIR.
226      *
227      * @param preference is the preference to be changed, should be mButtonCLIR.
228      * @param objValue should be the value of the selection, NOT its localized
229      * display value.
230      */
231     public boolean onPreferenceChange(Preference preference, Object objValue) {
232         if (preference == mButtonPreferredNetworkMode) {
233             //NOTE onPreferenceChange seems to be called even if there is no change
234             //Check if the button value is changed from the System.Setting
235             mButtonPreferredNetworkMode.setValue((String) objValue);
236             int buttonNetworkMode;
237             buttonNetworkMode = Integer.valueOf((String) objValue).intValue();
238             int settingsNetworkMode = android.provider.Settings.Secure.getInt(
239                     mPhone.getContext().getContentResolver(),
240                     android.provider.Settings.Secure.PREFERRED_NETWORK_MODE, preferredNetworkMode);
241             if (buttonNetworkMode != settingsNetworkMode) {
242                 int modemNetworkMode;
243                 switch(buttonNetworkMode) {
244                     case Phone.NT_MODE_GLOBAL:
245                         modemNetworkMode = Phone.NT_MODE_GLOBAL;
246                         break;
247                     case Phone.NT_MODE_EVDO_NO_CDMA:
248                         modemNetworkMode = Phone.NT_MODE_EVDO_NO_CDMA;
249                         break;
250                     case Phone.NT_MODE_CDMA_NO_EVDO:
251                         modemNetworkMode = Phone.NT_MODE_CDMA_NO_EVDO;
252                         break;
253                     case Phone.NT_MODE_CDMA:
254                         modemNetworkMode = Phone.NT_MODE_CDMA;
255                         break;
256                     case Phone.NT_MODE_GSM_UMTS:
257                         modemNetworkMode = Phone.NT_MODE_GSM_UMTS;
258                         break;
259                     case Phone.NT_MODE_WCDMA_ONLY:
260                         modemNetworkMode = Phone.NT_MODE_WCDMA_ONLY;
261                         break;
262                     case Phone.NT_MODE_GSM_ONLY:
263                         modemNetworkMode = Phone.NT_MODE_GSM_ONLY;
264                         break;
265                     case Phone.NT_MODE_WCDMA_PREF:
266                         modemNetworkMode = Phone.NT_MODE_WCDMA_PREF;
267                         break;
268                     default:
269                         modemNetworkMode = Phone.PREFERRED_NT_MODE;
270                 }
271                 updatePreferredNetworkModeSummary(buttonNetworkMode);
272
273                 android.provider.Settings.Secure.putInt(mPhone.getContext().getContentResolver(),
274                         android.provider.Settings.Secure.PREFERRED_NETWORK_MODE,
275                         buttonNetworkMode );
276                 //Set the modem network mode
277                 mPhone.setPreferredNetworkType(modemNetworkMode, mHandler
278                         .obtainMessage(MyHandler.MESSAGE_SET_PREFERRED_NETWORK_TYPE));
279             }
280         } else if (preference == mButtonCdmaRoam) {
281             //NOTE onPreferenceChange seems to be called even if there is no change
282             //Check if the button value is changed from the System.Setting
283             mButtonCdmaRoam.setValue((String) objValue);
284             int buttonCdmaRoamingMode;
285             buttonCdmaRoamingMode = Integer.valueOf((String) objValue).intValue();
286             int settingsCdmaRoamingMode = android.provider.Settings.Secure.getInt(
287                     mPhone.getContext().getContentResolver(),
288                     android.provider.Settings.Secure.CDMA_ROAMING_MODE, PREFERRED_CDMA_ROAMING_MODE);
289             if (buttonCdmaRoamingMode != settingsCdmaRoamingMode) {
290                 int statusCdmaRoamingMode;
291                 switch(buttonCdmaRoamingMode) {
292                     case CDMA_ROAMING_MODE_ANY:
293                         statusCdmaRoamingMode = Phone.CDMA_RM_ANY;
294                         break;
295                         /*
296                     case CDMA_ROAMING_MODE_AFFILIATED:
297                         statusCdmaRoamingMode = Phone.CDMA_RM_AFFILIATED;
298                         break;
299                         */
300                     case CDMA_ROAMING_MODE_HOME:
301                     default:
302                         statusCdmaRoamingMode = Phone.CDMA_RM_HOME;
303                 }
304                 //Set the Settings.System network mode
305                 android.provider.Settings.Secure.putInt(mPhone.getContext().getContentResolver(),
306                         android.provider.Settings.Secure.CDMA_ROAMING_MODE,
307                         buttonCdmaRoamingMode );
308                 //Set the roaming preference mode
309                 mPhone.setCdmaRoamingPreference(statusCdmaRoamingMode, mHandler
310                         .obtainMessage(MyHandler.MESSAGE_SET_ROAMING_PREFERENCE));
311             }
312         }
313
314         // always let the preference setting proceed.
315         return true;
316     }
317
318     private class MyHandler extends Handler {
319
320         private static final int MESSAGE_GET_PREFERRED_NETWORK_TYPE = 0;
321         private static final int MESSAGE_SET_PREFERRED_NETWORK_TYPE = 1;
322         private static final int MESSAGE_QUERY_ROAMING_PREFERENCE = 2;
323         private static final int MESSAGE_SET_ROAMING_PREFERENCE = 3;
324
325         @Override
326         public void handleMessage(Message msg) {
327             switch (msg.what) {
328                 case MESSAGE_GET_PREFERRED_NETWORK_TYPE:
329                     handleGetPreferredNetworkTypeResponse(msg);
330                     break;
331
332                 case MESSAGE_SET_PREFERRED_NETWORK_TYPE:
333                     handleSetPreferredNetworkTypeResponse(msg);
334                     break;
335                 case MESSAGE_QUERY_ROAMING_PREFERENCE:
336                     handleQueryCdmaRoamingPreference(msg);
337                     break;
338
339                 case MESSAGE_SET_ROAMING_PREFERENCE:
340                     handleSetCdmaRoamingPreference(msg);
341                     break;
342              }
343         }
344
345         private void handleGetPreferredNetworkTypeResponse(Message msg) {
346             AsyncResult ar = (AsyncResult) msg.obj;
347
348             if (ar.exception == null) {
349                 int modemNetworkMode = ((int[])ar.result)[0];
350
351                 if (DBG) {
352                     log ("handleGetPreferredNetworkTypeResponse: modemNetworkMode = " +
353                             modemNetworkMode);
354                 }
355
356                 int settingsNetworkMode = android.provider.Settings.Secure.getInt(
357                         mPhone.getContext().getContentResolver(),
358                         android.provider.Settings.Secure.PREFERRED_NETWORK_MODE,
359                         preferredNetworkMode);
360
361                 if (DBG) {
362                     log("handleGetPreferredNetworkTypeReponse: settingsNetworkMode = " +
363                             settingsNetworkMode);
364                 }
365
366                 //check that modemNetworkMode is from an accepted value
367                 if (modemNetworkMode == Phone.NT_MODE_WCDMA_PREF ||
368                         modemNetworkMode == Phone.NT_MODE_GSM_ONLY ||
369                         modemNetworkMode == Phone.NT_MODE_WCDMA_ONLY ||
370                         modemNetworkMode == Phone.NT_MODE_GSM_UMTS ||
371                         modemNetworkMode == Phone.NT_MODE_CDMA ||
372                         modemNetworkMode == Phone.NT_MODE_CDMA_NO_EVDO ||
373                         modemNetworkMode == Phone.NT_MODE_EVDO_NO_CDMA ||
374                         modemNetworkMode == Phone.NT_MODE_GLOBAL ) {
375                     if (DBG) {
376                         log("handleGetPreferredNetworkTypeResponse: if 1: modemNetworkMode = " +
377                                 modemNetworkMode);
378                     }
379
380                     //check changes in modemNetworkMode and updates settingsNetworkMode
381                     if (modemNetworkMode != settingsNetworkMode) {
382                         if (DBG) {
383                             log("handleGetPreferredNetworkTypeResponse: if 2: " +
384                                     "modemNetworkMode != settingsNetworkMode");
385                         }
386
387                         settingsNetworkMode = modemNetworkMode;
388
389                         if (DBG) { log("handleGetPreferredNetworkTypeResponse: if 2: " +
390                                 "settingsNetworkMode = " + settingsNetworkMode);
391                         }
392
393                         //changes the Settings.System accordingly to modemNetworkMode
394                         android.provider.Settings.Secure.putInt(
395                                 mPhone.getContext().getContentResolver(),
396                                 android.provider.Settings.Secure.PREFERRED_NETWORK_MODE,
397                                 settingsNetworkMode );
398                     }
399                     if (mPhone.getPhoneName().equals("CDMA")) {
400                         updatePreferredNetworkModeSummary(modemNetworkMode);
401                         // changes the mButtonPreferredNetworkMode accordingly to modemNetworkMode
402                         mButtonPreferredNetworkMode.setValue(Integer.toString(modemNetworkMode));
403                     } else {
404                         mButtonPrefer2g.setChecked(modemNetworkMode == Phone.NT_MODE_GSM_ONLY);
405                     }
406                 } else {
407                     if (DBG) log("handleGetPreferredNetworkTypeResponse: else: reset to default");
408                     resetNetworkModeToDefault();
409                 }
410             }
411         }
412
413         private void handleSetPreferredNetworkTypeResponse(Message msg) {
414             AsyncResult ar = (AsyncResult) msg.obj;
415
416             if (ar.exception == null) {
417                 int networkMode;
418                 if (mPhone.getPhoneName().equals("CDMA")) {
419                     networkMode =
420                         Integer.valueOf(mButtonPreferredNetworkMode.getValue()).intValue();
421                 } else {
422                     networkMode = mButtonPrefer2g.isChecked()
423                             ? Phone.NT_MODE_GSM_ONLY : Phone.NT_MODE_WCDMA_PREF;
424                 }
425                 android.provider.Settings.Secure.putInt(mPhone.getContext().getContentResolver(),
426                         android.provider.Settings.Secure.PREFERRED_NETWORK_MODE,
427                         networkMode);
428             } else {
429                 mPhone.getPreferredNetworkType(obtainMessage(MESSAGE_GET_PREFERRED_NETWORK_TYPE));
430             }
431         }
432
433         private void resetNetworkModeToDefault() {
434             if (mPhone.getPhoneName().equals("CDMA")) {
435                 //set the mButtonPreferredNetworkMode
436                 mButtonPreferredNetworkMode.setValue(Integer.toString(preferredNetworkMode));
437             } else {
438                 mButtonPrefer2g.setChecked(preferredNetworkMode == Phone.NT_MODE_GSM_ONLY);
439             }
440             //set the Settings.System
441             android.provider.Settings.Secure.putInt(mPhone.getContext().getContentResolver(),
442                         android.provider.Settings.Secure.PREFERRED_NETWORK_MODE,
443                         preferredNetworkMode );
444             //Set the Modem
445             mPhone.setPreferredNetworkType(preferredNetworkMode,
446                     this.obtainMessage(MyHandler.MESSAGE_SET_PREFERRED_NETWORK_TYPE));
447         }
448
449         private void handleQueryCdmaRoamingPreference(Message msg) {
450             mPhone = PhoneFactory.getDefaultPhone();
451             AsyncResult ar = (AsyncResult) msg.obj;
452
453             if (ar.exception == null) {
454                 int statusCdmaRoamingMode = ((int[])ar.result)[0];
455                 int settingsRoamingMode = android.provider.Settings.Secure.getInt(
456                         mPhone.getContext().getContentResolver(),
457                         android.provider.Settings.Secure.CDMA_ROAMING_MODE,
458                         PREFERRED_CDMA_ROAMING_MODE);
459                 //check that statusCdmaRoamingMode is from an accepted value
460                 if (statusCdmaRoamingMode == Phone.CDMA_RM_HOME ||
461                         statusCdmaRoamingMode == Phone.CDMA_RM_AFFILIATED ||
462                         statusCdmaRoamingMode == Phone.CDMA_RM_ANY ) {
463                     //check changes in statusCdmaRoamingMode and updates settingsRoamingMode
464                     if (statusCdmaRoamingMode != settingsRoamingMode) {
465                         settingsRoamingMode = statusCdmaRoamingMode;
466                         //changes the Settings.System accordingly to statusCdmaRoamingMode
467                         android.provider.Settings.Secure.putInt(
468                                 mPhone.getContext().getContentResolver(),
469                                 android.provider.Settings.Secure.CDMA_ROAMING_MODE,
470                                 settingsRoamingMode );
471                     }
472                     //changes the mButtonPreferredNetworkMode accordingly to modemNetworkMode
473                     mButtonCdmaRoam.setValue(
474                             Integer.toString(statusCdmaRoamingMode));
475                 } else {
476                     resetCdmaRoamingModeToDefault();
477                 }
478             }
479         }
480
481         private void handleSetCdmaRoamingPreference(Message msg) {
482             mPhone = PhoneFactory.getDefaultPhone();
483             AsyncResult ar = (AsyncResult) msg.obj;
484
485             if (ar.exception == null) {
486                 int cdmaRoamingMode = Integer.valueOf(mButtonCdmaRoam.getValue()).intValue();
487                 android.provider.Settings.Secure.putInt(mPhone.getContext().getContentResolver(),
488                         android.provider.Settings.Secure.CDMA_ROAMING_MODE,
489                         cdmaRoamingMode );
490             } else {
491                 mPhone.queryCdmaRoamingPreference(obtainMessage(MESSAGE_QUERY_ROAMING_PREFERENCE));
492             }
493         }
494
495         private void resetCdmaRoamingModeToDefault() {
496             mPhone = PhoneFactory.getDefaultPhone();
497             //set cdmaRoamingMode to default
498             int cdmaRoamingMode = PREFERRED_CDMA_ROAMING_MODE;
499             int statusCdmaRoamingMode = Phone.CDMA_RM_HOME;
500             //set the mButtonCdmaRoam
501             mButtonCdmaRoam.setValue(Integer.toString(cdmaRoamingMode));
502             //set the Settings.System
503             android.provider.Settings.Secure.putInt(mPhone.getContext().getContentResolver(),
504                         android.provider.Settings.Secure.CDMA_ROAMING_MODE,
505                         cdmaRoamingMode );
506             //Set the Status
507             mPhone.setCdmaRoamingPreference(statusCdmaRoamingMode,
508                     this.obtainMessage(MyHandler.MESSAGE_SET_ROAMING_PREFERENCE));
509         }
510     }
511
512     private void updatePreferredNetworkModeSummary(int NetworkMode) {
513         if (!mPhone.getPhoneName().equals("CDMA")) return;
514         mButtonPreferredNetworkMode.setSummary(mButtonPreferredNetworkMode.getEntry());
515     }
516
517     private static void log(String msg) {
518         Log.d(LOG_TAG, msg);
519     }
520 }