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 com.android.ims.ImsManager;
20 import com.android.ims.ImsException;
21 import com.android.internal.telephony.Phone;
22 import com.android.internal.telephony.PhoneConstants;
23 import com.android.internal.telephony.PhoneFactory;
24 import com.android.internal.telephony.TelephonyIntents;
25 import com.android.internal.telephony.TelephonyProperties;
26 
27 import java.util.ArrayList;
28 import java.util.Iterator;
29 import java.util.List;
30 
31 import android.app.ActionBar;
32 import android.app.AlertDialog;
33 import android.content.BroadcastReceiver;
34 import android.content.Context;
35 import android.content.DialogInterface;
36 import android.content.Intent;
37 import android.content.IntentFilter;
38 import android.content.SharedPreferences;
39 import android.content.pm.PackageManager.NameNotFoundException;
40 import android.net.Uri;
41 import android.os.AsyncResult;
42 import android.os.Bundle;
43 import android.os.Handler;
44 import android.os.Message;
45 import android.os.SystemProperties;
46 import android.os.UserHandle;
47 import android.os.UserManager;
48 import android.preference.ListPreference;
49 import android.preference.Preference;
50 import android.preference.PreferenceActivity;
51 import android.preference.PreferenceGroup;
52 import android.preference.PreferenceScreen;
53 import android.preference.SwitchPreference;
54 import android.telephony.PhoneStateListener;
55 import android.telephony.SubscriptionInfo;
56 import android.telephony.SubscriptionManager;
57 import android.telephony.TelephonyManager;
58 import android.text.TextUtils;
59 import android.util.Log;
60 import android.view.MenuItem;
61 import android.view.View;
62 import android.widget.ListView;
63 import android.widget.TabHost;
64 import android.widget.TabHost.OnTabChangeListener;
65 import android.widget.TabHost.TabContentFactory;
66 import android.widget.TabHost.TabSpec;
67 import android.widget.TabWidget;
68 
69 /**
70  * "Mobile network settings" screen.  This preference screen lets you
71  * enable/disable mobile data, and control data roaming and other
72  * network-specific mobile data features.  It's used on non-voice-capable
73  * tablets as well as regular phone devices.
74  *
75  * Note that this PreferenceActivity is part of the phone app, even though
76  * you reach it from the "Wireless & Networks" section of the main
77  * Settings app.  It's not part of the "Call settings" hierarchy that's
78  * available from the Phone app (see CallFeaturesSetting for that.)
79  */
80 public class MobileNetworkSettings extends PreferenceActivity
81         implements DialogInterface.OnClickListener,
82         DialogInterface.OnDismissListener, Preference.OnPreferenceChangeListener{
83 
84     // debug data
85     private static final String LOG_TAG = "NetworkSettings";
86     private static final boolean DBG = true;
87     public static final int REQUEST_CODE_EXIT_ECM = 17;
88 
89     // Number of active Subscriptions to show tabs
90     private static final int TAB_THRESHOLD = 2;
91 
92     //String keys for preference lookup
93     private static final String BUTTON_PREFERED_NETWORK_MODE = "preferred_network_mode_key";
94     private static final String BUTTON_ROAMING_KEY = "button_roaming_key";
95     private static final String BUTTON_CDMA_LTE_DATA_SERVICE_KEY = "cdma_lte_data_service_key";
96     private static final String BUTTON_ENABLED_NETWORKS_KEY = "enabled_networks_key";
97     private static final String BUTTON_4G_LTE_KEY = "enhanced_4g_lte";
98     private static final String BUTTON_CELL_BROADCAST_SETTINGS = "cell_broadcast_settings";
99     private static final String BUTTON_APN_EXPAND_KEY = "button_apn_key";
100     private static final String BUTTON_OPERATOR_SELECTION_EXPAND_KEY = "button_carrier_sel_key";
101     private static final String BUTTON_CARRIER_SETTINGS_KEY = "carrier_settings_key";
102     private static final String BUTTON_CDMA_SYSTEM_SELECT_KEY = "cdma_system_select_key";
103 
104     static final int preferredNetworkMode = Phone.PREFERRED_NT_MODE;
105 
106     //Information about logical "up" Activity
107     private static final String UP_ACTIVITY_PACKAGE = "com.android.settings";
108     private static final String UP_ACTIVITY_CLASS =
109             "com.android.settings.Settings$WirelessSettingsActivity";
110 
111     private SubscriptionManager mSubscriptionManager;
112 
113     //UI objects
114     private ListPreference mButtonPreferredNetworkMode;
115     private ListPreference mButtonEnabledNetworks;
116     private SwitchPreference mButtonDataRoam;
117     private SwitchPreference mButton4glte;
118     private Preference mLteDataServicePref;
119 
120     private static final String iface = "rmnet0"; //TODO: this will go away
121     private List<SubscriptionInfo> mActiveSubInfos;
122 
123     private UserManager mUm;
124     private Phone mPhone;
125     private MyHandler mHandler;
126     private boolean mOkClicked;
127 
128     // We assume the the value returned by mTabHost.getCurrentTab() == slotId
129     private TabHost mTabHost;
130 
131     //GsmUmts options and Cdma options
132     GsmUmtsOptions mGsmUmtsOptions;
133     CdmaOptions mCdmaOptions;
134 
135     private Preference mClickedPreference;
136     private boolean mShow4GForLTE;
137     private boolean mIsGlobalCdma;
138     private boolean mUnavailable;
139 
140     private final PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
141         /*
142          * Enable/disable the 'Enhanced 4G LTE Mode' when in/out of a call
143          * and depending on TTY mode and TTY support over VoLTE.
144          * @see android.telephony.PhoneStateListener#onCallStateChanged(int,
145          * java.lang.String)
146          */
147         @Override
148         public void onCallStateChanged(int state, String incomingNumber) {
149             if (DBG) log("PhoneStateListener.onCallStateChanged: state=" + state);
150             Preference pref = getPreferenceScreen().findPreference(BUTTON_4G_LTE_KEY);
151             if (pref != null) {
152                 pref.setEnabled((state == TelephonyManager.CALL_STATE_IDLE) &&
153                         ImsManager.isNonTtyOrTtyOnVolteEnabled(getApplicationContext()));
154             }
155         }
156     };
157 
158     private final BroadcastReceiver mPhoneChangeReceiver = new PhoneChangeReceiver();
159 
160     private class PhoneChangeReceiver extends BroadcastReceiver {
161         @Override
onReceive(Context context, Intent intent)162         public void onReceive(Context context, Intent intent) {
163             if (DBG) log("onReceive:");
164             // When the radio changes (ex: CDMA->GSM), refresh all options.
165             mGsmUmtsOptions = null;
166             mCdmaOptions = null;
167             updateBody();
168         }
169     }
170 
171     //This is a method implemented for DialogInterface.OnClickListener.
172     //  Used to dismiss the dialogs when they come up.
onClick(DialogInterface dialog, int which)173     public void onClick(DialogInterface dialog, int which) {
174         if (which == DialogInterface.BUTTON_POSITIVE) {
175             mPhone.setDataRoamingEnabled(true);
176             mOkClicked = true;
177         } else {
178             // Reset the toggle
179             mButtonDataRoam.setChecked(false);
180         }
181     }
182 
183     @Override
onDismiss(DialogInterface dialog)184     public void onDismiss(DialogInterface dialog) {
185         // Assuming that onClick gets called first
186         mButtonDataRoam.setChecked(mOkClicked);
187     }
188 
189     /**
190      * Invoked on each preference click in this hierarchy, overrides
191      * PreferenceActivity's implementation.  Used to make sure we track the
192      * preference click events.
193      */
194     @Override
onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference)195     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
196         /** TODO: Refactor and get rid of the if's using subclasses */
197         final int phoneSubId = mPhone.getSubId();
198         if (preference.getKey().equals(BUTTON_4G_LTE_KEY)) {
199             return true;
200         } else if (mGsmUmtsOptions != null &&
201                 mGsmUmtsOptions.preferenceTreeClick(preference) == true) {
202             return true;
203         } else if (mCdmaOptions != null &&
204                    mCdmaOptions.preferenceTreeClick(preference) == true) {
205             if (Boolean.parseBoolean(
206                     SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE))) {
207 
208                 mClickedPreference = preference;
209 
210                 // In ECM mode launch ECM app dialog
211                 startActivityForResult(
212                     new Intent(TelephonyIntents.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS, null),
213                     REQUEST_CODE_EXIT_ECM);
214             }
215             return true;
216         } else if (preference == mButtonPreferredNetworkMode) {
217             //displays the value taken from the Settings.System
218             int settingsNetworkMode = android.provider.Settings.Global.getInt(mPhone.getContext().
219                     getContentResolver(),
220                     android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
221                     preferredNetworkMode);
222             mButtonPreferredNetworkMode.setValue(Integer.toString(settingsNetworkMode));
223             return true;
224         } else if (preference == mLteDataServicePref) {
225             String tmpl = android.provider.Settings.Global.getString(getContentResolver(),
226                         android.provider.Settings.Global.SETUP_PREPAID_DATA_SERVICE_URL);
227             if (!TextUtils.isEmpty(tmpl)) {
228                 TelephonyManager tm = (TelephonyManager) getSystemService(
229                         Context.TELEPHONY_SERVICE);
230                 String imsi = tm.getSubscriberId();
231                 if (imsi == null) {
232                     imsi = "";
233                 }
234                 final String url = TextUtils.isEmpty(tmpl) ? null
235                         : TextUtils.expandTemplate(tmpl, imsi).toString();
236                 Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
237                 startActivity(intent);
238             } else {
239                 android.util.Log.e(LOG_TAG, "Missing SETUP_PREPAID_DATA_SERVICE_URL");
240             }
241             return true;
242         }  else if (preference == mButtonEnabledNetworks) {
243             int settingsNetworkMode = android.provider.Settings.Global.getInt(mPhone.getContext().
244                     getContentResolver(),
245                     android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
246                     preferredNetworkMode);
247             mButtonEnabledNetworks.setValue(Integer.toString(settingsNetworkMode));
248             return true;
249         } else if (preference == mButtonDataRoam) {
250             // Do not disable the preference screen if the user clicks Data roaming.
251             return true;
252         } else {
253             // if the button is anything but the simple toggle preference,
254             // we'll need to disable all preferences to reject all click
255             // events until the sub-activity's UI comes up.
256             preferenceScreen.setEnabled(false);
257             // Let the intents be launched by the Preference manager
258             return false;
259         }
260     }
261 
262     private final SubscriptionManager.OnSubscriptionsChangedListener mOnSubscriptionsChangeListener
263             = new SubscriptionManager.OnSubscriptionsChangedListener() {
264         @Override
265         public void onSubscriptionsChanged() {
266             if (DBG) log("onSubscriptionsChanged:");
267             initializeSubscriptions();
268         }
269     };
270 
initializeSubscriptions()271     private void initializeSubscriptions() {
272         int currentTab = 0;
273         if (DBG) log("initializeSubscriptions:+");
274 
275         // Before updating the the active subscription list check
276         // if tab updating is needed as the list is changing.
277         List<SubscriptionInfo> sil = mSubscriptionManager.getActiveSubscriptionInfoList();
278         TabState state = isUpdateTabsNeeded(sil);
279 
280         // Update to the active subscription list
281         mActiveSubInfos.clear();
282         if (sil != null) {
283             mActiveSubInfos.addAll(sil);
284             // If there is only 1 sim then currenTab should represent slot no. of the sim.
285             if (sil.size() == 1) {
286                 currentTab = sil.get(0).getSimSlotIndex();
287             }
288         }
289 
290         switch (state) {
291             case UPDATE: {
292                 if (DBG) log("initializeSubscriptions: UPDATE");
293                 currentTab = mTabHost != null ? mTabHost.getCurrentTab() : 0;
294 
295                 setContentView(R.layout.network_settings);
296 
297                 mTabHost = (TabHost) findViewById(android.R.id.tabhost);
298                 mTabHost.setup();
299 
300                 // Update the tabName. Since the mActiveSubInfos are in slot order
301                 // we can iterate though the tabs and subscription info in one loop. But
302                 // we need to handle the case where a slot may be empty.
303 
304                 Iterator<SubscriptionInfo> siIterator = mActiveSubInfos.listIterator();
305                 SubscriptionInfo si = siIterator.hasNext() ? siIterator.next() : null;
306                 for (int simSlotIndex = 0; simSlotIndex  < mActiveSubInfos.size(); simSlotIndex++) {
307                     String tabName;
308                     if (si != null && si.getSimSlotIndex() == simSlotIndex) {
309                         // Slot is not empty and we match
310                         tabName = String.valueOf(si.getDisplayName());
311                         si = siIterator.hasNext() ? siIterator.next() : null;
312                     } else {
313                         // Slot is empty, set name to unknown
314                         tabName = getResources().getString(R.string.unknown);
315                     }
316                     if (DBG) {
317                         log("initializeSubscriptions: tab=" + simSlotIndex + " name=" + tabName);
318                     }
319 
320                     mTabHost.addTab(buildTabSpec(String.valueOf(simSlotIndex), tabName));
321                 }
322 
323                 mTabHost.setOnTabChangedListener(mTabListener);
324                 mTabHost.setCurrentTab(currentTab);
325                 break;
326             }
327             case NO_TABS: {
328                 if (DBG) log("initializeSubscriptions: NO_TABS");
329 
330                 if (mTabHost != null) {
331                     mTabHost.clearAllTabs();
332                     mTabHost = null;
333                 }
334                 setContentView(R.layout.network_settings);
335                 break;
336             }
337             case DO_NOTHING: {
338                 if (DBG) log("initializeSubscriptions: DO_NOTHING");
339                 if (mTabHost != null) {
340                     currentTab = mTabHost.getCurrentTab();
341                 }
342                 break;
343             }
344         }
345         updatePhone(currentTab);
346         updateBody();
347         if (DBG) log("initializeSubscriptions:-");
348     }
349 
350     private enum TabState {
351         NO_TABS, UPDATE, DO_NOTHING
352     }
isUpdateTabsNeeded(List<SubscriptionInfo> newSil)353     private TabState isUpdateTabsNeeded(List<SubscriptionInfo> newSil) {
354         TabState state = TabState.DO_NOTHING;
355         if (newSil == null) {
356             if (mActiveSubInfos.size() >= TAB_THRESHOLD) {
357                 if (DBG) log("isUpdateTabsNeeded: NO_TABS, size unknown and was tabbed");
358                 state = TabState.NO_TABS;
359             }
360         } else if (newSil.size() < TAB_THRESHOLD && mActiveSubInfos.size() >= TAB_THRESHOLD) {
361             if (DBG) log("isUpdateTabsNeeded: NO_TABS, size went to small");
362             state = TabState.NO_TABS;
363         } else if (newSil.size() >= TAB_THRESHOLD && mActiveSubInfos.size() < TAB_THRESHOLD) {
364             if (DBG) log("isUpdateTabsNeeded: UPDATE, size changed");
365             state = TabState.UPDATE;
366         } else if (newSil.size() >= TAB_THRESHOLD) {
367             Iterator<SubscriptionInfo> siIterator = mActiveSubInfos.iterator();
368             for(SubscriptionInfo newSi : newSil) {
369                 SubscriptionInfo curSi = siIterator.next();
370                 if (!newSi.getDisplayName().equals(curSi.getDisplayName())) {
371                     if (DBG) log("isUpdateTabsNeeded: UPDATE, new name=" + newSi.getDisplayName());
372                     state = TabState.UPDATE;
373                     break;
374                 }
375             }
376         }
377         if (DBG) {
378             log("isUpdateTabsNeeded:- " + state
379                 + " newSil.size()=" + ((newSil != null) ? newSil.size() : 0)
380                 + " mActiveSubInfos.size()=" + mActiveSubInfos.size());
381         }
382         return state;
383     }
384 
385     private OnTabChangeListener mTabListener = new OnTabChangeListener() {
386         @Override
387         public void onTabChanged(String tabId) {
388             if (DBG) log("onTabChanged:");
389             // The User has changed tab; update the body.
390             updatePhone(Integer.parseInt(tabId));
391             updateBody();
392         }
393     };
394 
updatePhone(int slotId)395     private void updatePhone(int slotId) {
396         final SubscriptionInfo sir = findRecordBySlotId(slotId);
397         if (sir != null) {
398             mPhone = PhoneFactory.getPhone(
399                     SubscriptionManager.getPhoneId(sir.getSubscriptionId()));
400         }
401         if (mPhone == null) {
402             // Do the best we can
403             mPhone = PhoneGlobals.getPhone();
404         }
405         if (DBG) log("updatePhone:- slotId=" + slotId + " sir=" + sir);
406     }
407 
408     private TabContentFactory mEmptyTabContent = new TabContentFactory() {
409         @Override
410         public View createTabContent(String tag) {
411             return new View(mTabHost.getContext());
412         }
413     };
414 
buildTabSpec(String tag, String title)415     private TabSpec buildTabSpec(String tag, String title) {
416         return mTabHost.newTabSpec(tag).setIndicator(title).setContent(
417                 mEmptyTabContent);
418     }
419 
420     @Override
onCreate(Bundle icicle)421     protected void onCreate(Bundle icicle) {
422         if (DBG) log("onCreate:+");
423         setTheme(R.style.Theme_Material_Settings);
424         super.onCreate(icicle);
425 
426         mHandler = new MyHandler();
427         mUm = (UserManager) getSystemService(Context.USER_SERVICE);
428         mSubscriptionManager = SubscriptionManager.from(this);
429 
430         if (mUm.hasUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
431             mUnavailable = true;
432             setContentView(R.layout.telephony_disallowed_preference_screen);
433             return;
434         }
435 
436         addPreferencesFromResource(R.xml.network_setting);
437 
438         mButton4glte = (SwitchPreference)findPreference(BUTTON_4G_LTE_KEY);
439 
440         mButton4glte.setOnPreferenceChangeListener(this);
441 
442         try {
443             Context con = createPackageContext("com.android.systemui", 0);
444             int id = con.getResources().getIdentifier("config_show4GForLTE",
445                     "bool", "com.android.systemui");
446             mShow4GForLTE = con.getResources().getBoolean(id);
447         } catch (NameNotFoundException e) {
448             loge("NameNotFoundException for show4GFotLTE");
449             mShow4GForLTE = false;
450         }
451 
452         //get UI object references
453         PreferenceScreen prefSet = getPreferenceScreen();
454 
455         mButtonDataRoam = (SwitchPreference) prefSet.findPreference(BUTTON_ROAMING_KEY);
456         mButtonPreferredNetworkMode = (ListPreference) prefSet.findPreference(
457                 BUTTON_PREFERED_NETWORK_MODE);
458         mButtonEnabledNetworks = (ListPreference) prefSet.findPreference(
459                 BUTTON_ENABLED_NETWORKS_KEY);
460         mButtonDataRoam.setOnPreferenceChangeListener(this);
461 
462         mLteDataServicePref = prefSet.findPreference(BUTTON_CDMA_LTE_DATA_SERVICE_KEY);
463 
464         // Initialize mActiveSubInfo
465         int max = mSubscriptionManager.getActiveSubscriptionInfoCountMax();
466         mActiveSubInfos = new ArrayList<SubscriptionInfo>(max);
467 
468         initializeSubscriptions();
469 
470         IntentFilter intentFilter = new IntentFilter(
471                 TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED);
472         registerReceiver(mPhoneChangeReceiver, intentFilter);
473         if (DBG) log("onCreate:-");
474     }
475 
476     @Override
onResume()477     protected void onResume() {
478         super.onResume();
479         if (DBG) log("onResume:+");
480 
481         if (mUnavailable) {
482             if (DBG) log("onResume:- ignore mUnavailable == false");
483             return;
484         }
485 
486         // upon resumption from the sub-activity, make sure we re-enable the
487         // preferences.
488         getPreferenceScreen().setEnabled(true);
489 
490         // Set UI state in onResume because a user could go home, launch some
491         // app to change this setting's backend, and re-launch this settings app
492         // and the UI state would be inconsistent with actual state
493         mButtonDataRoam.setChecked(mPhone.getDataRoamingEnabled());
494 
495         if (getPreferenceScreen().findPreference(BUTTON_PREFERED_NETWORK_MODE) != null)  {
496             mPhone.getPreferredNetworkType(mHandler.obtainMessage(
497                     MyHandler.MESSAGE_GET_PREFERRED_NETWORK_TYPE));
498         }
499 
500         if (getPreferenceScreen().findPreference(BUTTON_ENABLED_NETWORKS_KEY) != null)  {
501             mPhone.getPreferredNetworkType(mHandler.obtainMessage(
502                     MyHandler.MESSAGE_GET_PREFERRED_NETWORK_TYPE));
503         }
504 
505         if (ImsManager.isVolteEnabledByPlatform(this)
506                 && ImsManager.isVolteProvisionedOnDevice(this)) {
507             TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
508             tm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
509         }
510 
511         mButton4glte.setChecked(ImsManager.isEnhanced4gLteModeSettingEnabledByUser(this)
512                 && ImsManager.isNonTtyOrTtyOnVolteEnabled(this));
513         // NOTE: The button will be enabled/disabled in mPhoneStateListener
514 
515         mSubscriptionManager.addOnSubscriptionsChangedListener(mOnSubscriptionsChangeListener);
516 
517         if (DBG) log("onResume:-");
518 
519     }
520 
updateBody()521     private void updateBody() {
522         final Context context = getApplicationContext();
523         PreferenceScreen prefSet = getPreferenceScreen();
524         boolean isLteOnCdma = mPhone.getLteOnCdmaMode() == PhoneConstants.LTE_ON_CDMA_TRUE;
525         final int phoneSubId = mPhone.getSubId();
526 
527         if (DBG) {
528             log("updateBody: isLteOnCdma=" + isLteOnCdma + " phoneSubId=" + phoneSubId);
529         }
530 
531         if (prefSet != null) {
532             prefSet.removeAll();
533             prefSet.addPreference(mButtonDataRoam);
534             prefSet.addPreference(mButtonPreferredNetworkMode);
535             prefSet.addPreference(mButtonEnabledNetworks);
536             prefSet.addPreference(mButton4glte);
537         }
538 
539         int settingsNetworkMode = android.provider.Settings.Global.getInt(
540                 mPhone.getContext().getContentResolver(),
541                 android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
542                 preferredNetworkMode);
543 
544         mIsGlobalCdma = isLteOnCdma && getResources().getBoolean(R.bool.config_show_cdma);
545         int shouldHideCarrierSettings = android.provider.Settings.Global.getInt(
546                 mPhone.getContext().getContentResolver(),
547                 android.provider.Settings.Global.HIDE_CARRIER_NETWORK_SETTINGS, 0);
548         if (shouldHideCarrierSettings == 1 ) {
549             prefSet.removePreference(mButtonPreferredNetworkMode);
550             prefSet.removePreference(mButtonEnabledNetworks);
551             prefSet.removePreference(mLteDataServicePref);
552         } else if (getResources().getBoolean(R.bool.world_phone) == true) {
553             prefSet.removePreference(mButtonEnabledNetworks);
554             // set the listener for the mButtonPreferredNetworkMode list preference so we can issue
555             // change Preferred Network Mode.
556             mButtonPreferredNetworkMode.setOnPreferenceChangeListener(this);
557 
558             mCdmaOptions = new CdmaOptions(this, prefSet, mPhone);
559             mGsmUmtsOptions = new GsmUmtsOptions(this, prefSet, phoneSubId);
560         } else {
561             prefSet.removePreference(mButtonPreferredNetworkMode);
562             final int phoneType = mPhone.getPhoneType();
563             if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
564                 int lteForced = android.provider.Settings.Global.getInt(
565                         mPhone.getContext().getContentResolver(),
566                         android.provider.Settings.Global.LTE_SERVICE_FORCED + mPhone.getSubId(),
567                         0);
568 
569                 if (isLteOnCdma) {
570                     if (lteForced == 0) {
571                         mButtonEnabledNetworks.setEntries(
572                                 R.array.enabled_networks_cdma_choices);
573                         mButtonEnabledNetworks.setEntryValues(
574                                 R.array.enabled_networks_cdma_values);
575                     } else {
576                         switch (settingsNetworkMode) {
577                             case Phone.NT_MODE_CDMA:
578                             case Phone.NT_MODE_CDMA_NO_EVDO:
579                             case Phone.NT_MODE_EVDO_NO_CDMA:
580                                 mButtonEnabledNetworks.setEntries(
581                                         R.array.enabled_networks_cdma_no_lte_choices);
582                                 mButtonEnabledNetworks.setEntryValues(
583                                         R.array.enabled_networks_cdma_no_lte_values);
584                                 break;
585                             case Phone.NT_MODE_GLOBAL:
586                             case Phone.NT_MODE_LTE_CDMA_AND_EVDO:
587                             case Phone.NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
588                             case Phone.NT_MODE_LTE_ONLY:
589                                 mButtonEnabledNetworks.setEntries(
590                                         R.array.enabled_networks_cdma_only_lte_choices);
591                                 mButtonEnabledNetworks.setEntryValues(
592                                         R.array.enabled_networks_cdma_only_lte_values);
593                                 break;
594                             default:
595                                 mButtonEnabledNetworks.setEntries(
596                                         R.array.enabled_networks_cdma_choices);
597                                 mButtonEnabledNetworks.setEntryValues(
598                                         R.array.enabled_networks_cdma_values);
599                                 break;
600                         }
601                     }
602                 }
603                 mCdmaOptions = new CdmaOptions(this, prefSet, mPhone);
604 
605                 // In World mode force a refresh of GSM Options.
606                 if (isWorldMode()) {
607                     mGsmUmtsOptions = null;
608                 }
609             } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
610                 if (!getResources().getBoolean(R.bool.config_prefer_2g)
611                         && !getResources().getBoolean(R.bool.config_enabled_lte)) {
612                     mButtonEnabledNetworks.setEntries(
613                             R.array.enabled_networks_except_gsm_lte_choices);
614                     mButtonEnabledNetworks.setEntryValues(
615                             R.array.enabled_networks_except_gsm_lte_values);
616                 } else if (!getResources().getBoolean(R.bool.config_prefer_2g)) {
617                     int select = (mShow4GForLTE == true) ?
618                         R.array.enabled_networks_except_gsm_4g_choices
619                         : R.array.enabled_networks_except_gsm_choices;
620                     mButtonEnabledNetworks.setEntries(select);
621                     mButtonEnabledNetworks.setEntryValues(
622                             R.array.enabled_networks_except_gsm_values);
623                 } else if (!getResources().getBoolean(R.bool.config_enabled_lte)) {
624                     mButtonEnabledNetworks.setEntries(
625                             R.array.enabled_networks_except_lte_choices);
626                     mButtonEnabledNetworks.setEntryValues(
627                             R.array.enabled_networks_except_lte_values);
628                 } else if (mIsGlobalCdma) {
629                     mButtonEnabledNetworks.setEntries(
630                             R.array.enabled_networks_cdma_choices);
631                     mButtonEnabledNetworks.setEntryValues(
632                             R.array.enabled_networks_cdma_values);
633                 } else {
634                     int select = (mShow4GForLTE == true) ? R.array.enabled_networks_4g_choices
635                         : R.array.enabled_networks_choices;
636                     mButtonEnabledNetworks.setEntries(select);
637                     mButtonEnabledNetworks.setEntryValues(
638                             R.array.enabled_networks_values);
639                 }
640                 mGsmUmtsOptions = new GsmUmtsOptions(this, prefSet, phoneSubId);
641             } else {
642                 throw new IllegalStateException("Unexpected phone type: " + phoneType);
643             }
644             if (isWorldMode()) {
645                 mButtonEnabledNetworks.setEntries(
646                         R.array.preferred_network_mode_choices_world_mode);
647                 mButtonEnabledNetworks.setEntryValues(
648                         R.array.preferred_network_mode_values_world_mode);
649             }
650             mButtonEnabledNetworks.setOnPreferenceChangeListener(this);
651             if (DBG) log("settingsNetworkMode: " + settingsNetworkMode);
652         }
653 
654         final boolean missingDataServiceUrl = TextUtils.isEmpty(
655                 android.provider.Settings.Global.getString(getContentResolver(),
656                         android.provider.Settings.Global.SETUP_PREPAID_DATA_SERVICE_URL));
657         if (!isLteOnCdma || missingDataServiceUrl) {
658             prefSet.removePreference(mLteDataServicePref);
659         } else {
660             android.util.Log.d(LOG_TAG, "keep ltePref");
661         }
662 
663         // Enable enhanced 4G LTE mode settings depending on whether exists on platform
664         if (!(ImsManager.isVolteEnabledByPlatform(this)
665                 && ImsManager.isVolteProvisionedOnDevice(this))) {
666             Preference pref = prefSet.findPreference(BUTTON_4G_LTE_KEY);
667             if (pref != null) {
668                 prefSet.removePreference(pref);
669             }
670         }
671 
672         ActionBar actionBar = getActionBar();
673         if (actionBar != null) {
674             // android.R.id.home will be triggered in onOptionsItemSelected()
675             actionBar.setDisplayHomeAsUpEnabled(true);
676         }
677 
678         final boolean isSecondaryUser = UserHandle.myUserId() != UserHandle.USER_OWNER;
679         // Enable link to CMAS app settings depending on the value in config.xml.
680         final boolean isCellBroadcastAppLinkEnabled = this.getResources().getBoolean(
681                 com.android.internal.R.bool.config_cellBroadcastAppLinks);
682         if (isSecondaryUser || !isCellBroadcastAppLinkEnabled
683                 || mUm.hasUserRestriction(UserManager.DISALLOW_CONFIG_CELL_BROADCASTS)) {
684             PreferenceScreen root = getPreferenceScreen();
685             Preference ps = findPreference(BUTTON_CELL_BROADCAST_SETTINGS);
686             if (ps != null) {
687                 root.removePreference(ps);
688             }
689         }
690 
691         // Get the networkMode from Settings.System and displays it
692         mButtonDataRoam.setChecked(mPhone.getDataRoamingEnabled());
693         mButtonEnabledNetworks.setValue(Integer.toString(settingsNetworkMode));
694         mButtonPreferredNetworkMode.setValue(Integer.toString(settingsNetworkMode));
695         UpdatePreferredNetworkModeSummary(settingsNetworkMode);
696         UpdateEnabledNetworksValueAndSummary(settingsNetworkMode);
697         // Display preferred network type based on what modem returns b/18676277
698         mPhone.setPreferredNetworkType(settingsNetworkMode, mHandler
699                 .obtainMessage(MyHandler.MESSAGE_SET_PREFERRED_NETWORK_TYPE));
700 
701         /**
702          * Enable/disable depending upon if there are any active subscriptions.
703          *
704          * I've decided to put this enable/disable code at the bottom as the
705          * code above works even when there are no active subscriptions, thus
706          * putting it afterwards is a smaller change. This can be refined later,
707          * but you do need to remember that this all needs to work when subscriptions
708          * change dynamically such as when hot swapping sims.
709          */
710         boolean hasActiveSubscriptions = mActiveSubInfos.size() > 0;
711         mButtonDataRoam.setEnabled(hasActiveSubscriptions);
712         mButtonPreferredNetworkMode.setEnabled(hasActiveSubscriptions);
713         mButtonEnabledNetworks.setEnabled(hasActiveSubscriptions);
714         mButton4glte.setEnabled(hasActiveSubscriptions);
715         mLteDataServicePref.setEnabled(hasActiveSubscriptions);
716         Preference ps;
717         PreferenceScreen root = getPreferenceScreen();
718         ps = findPreference(BUTTON_CELL_BROADCAST_SETTINGS);
719         if (ps != null) {
720             ps.setEnabled(hasActiveSubscriptions);
721         }
722         ps = findPreference(BUTTON_APN_EXPAND_KEY);
723         if (ps != null) {
724             ps.setEnabled(hasActiveSubscriptions);
725         }
726         ps = findPreference(BUTTON_OPERATOR_SELECTION_EXPAND_KEY);
727         if (ps != null) {
728             ps.setEnabled(hasActiveSubscriptions);
729         }
730         ps = findPreference(BUTTON_CARRIER_SETTINGS_KEY);
731         if (ps != null) {
732             ps.setEnabled(hasActiveSubscriptions);
733         }
734         ps = findPreference(BUTTON_CDMA_SYSTEM_SELECT_KEY);
735         if (ps != null) {
736             ps.setEnabled(hasActiveSubscriptions);
737         }
738     }
739 
740     @Override
onPause()741     protected void onPause() {
742         super.onPause();
743         if (DBG) log("onPause:+");
744 
745         if (ImsManager.isVolteEnabledByPlatform(this)
746                 && ImsManager.isVolteProvisionedOnDevice(this)) {
747             TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
748             tm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
749         }
750 
751         mSubscriptionManager
752             .removeOnSubscriptionsChangedListener(mOnSubscriptionsChangeListener);
753         if (DBG) log("onPause:-");
754     }
755 
756     /**
757      * Implemented to support onPreferenceChangeListener to look for preference
758      * changes specifically on CLIR.
759      *
760      * @param preference is the preference to be changed, should be mButtonCLIR.
761      * @param objValue should be the value of the selection, NOT its localized
762      * display value.
763      */
onPreferenceChange(Preference preference, Object objValue)764     public boolean onPreferenceChange(Preference preference, Object objValue) {
765         final int phoneSubId = mPhone.getSubId();
766         if (preference == mButtonPreferredNetworkMode) {
767             //NOTE onPreferenceChange seems to be called even if there is no change
768             //Check if the button value is changed from the System.Setting
769             mButtonPreferredNetworkMode.setValue((String) objValue);
770             int buttonNetworkMode;
771             buttonNetworkMode = Integer.valueOf((String) objValue).intValue();
772             int settingsNetworkMode = android.provider.Settings.Global.getInt(
773                     mPhone.getContext().getContentResolver(),
774                     android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
775                     preferredNetworkMode);
776             if (buttonNetworkMode != settingsNetworkMode) {
777                 int modemNetworkMode;
778                 // if new mode is invalid ignore it
779                 switch (buttonNetworkMode) {
780                     case Phone.NT_MODE_WCDMA_PREF:
781                     case Phone.NT_MODE_GSM_ONLY:
782                     case Phone.NT_MODE_WCDMA_ONLY:
783                     case Phone.NT_MODE_GSM_UMTS:
784                     case Phone.NT_MODE_CDMA:
785                     case Phone.NT_MODE_CDMA_NO_EVDO:
786                     case Phone.NT_MODE_EVDO_NO_CDMA:
787                     case Phone.NT_MODE_GLOBAL:
788                     case Phone.NT_MODE_LTE_CDMA_AND_EVDO:
789                     case Phone.NT_MODE_LTE_GSM_WCDMA:
790                     case Phone.NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
791                     case Phone.NT_MODE_LTE_ONLY:
792                     case Phone.NT_MODE_LTE_WCDMA:
793                         // This is one of the modes we recognize
794                         modemNetworkMode = buttonNetworkMode;
795                         break;
796                     default:
797                         loge("Invalid Network Mode (" + buttonNetworkMode + ") chosen. Ignore.");
798                         return true;
799                 }
800 
801                 android.provider.Settings.Global.putInt(mPhone.getContext().getContentResolver(),
802                         android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
803                         buttonNetworkMode );
804                 //Set the modem network mode
805                 mPhone.setPreferredNetworkType(modemNetworkMode, mHandler
806                         .obtainMessage(MyHandler.MESSAGE_SET_PREFERRED_NETWORK_TYPE));
807             }
808         } else if (preference == mButtonEnabledNetworks) {
809             mButtonEnabledNetworks.setValue((String) objValue);
810             int buttonNetworkMode;
811             buttonNetworkMode = Integer.valueOf((String) objValue).intValue();
812             if (DBG) log("buttonNetworkMode: " + buttonNetworkMode);
813             int settingsNetworkMode = android.provider.Settings.Global.getInt(
814                     mPhone.getContext().getContentResolver(),
815                     android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
816                     preferredNetworkMode);
817             if (buttonNetworkMode != settingsNetworkMode) {
818                 int modemNetworkMode;
819                 // if new mode is invalid ignore it
820                 switch (buttonNetworkMode) {
821                     case Phone.NT_MODE_WCDMA_PREF:
822                     case Phone.NT_MODE_GSM_ONLY:
823                     case Phone.NT_MODE_LTE_GSM_WCDMA:
824                     case Phone.NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
825                     case Phone.NT_MODE_CDMA:
826                     case Phone.NT_MODE_CDMA_NO_EVDO:
827                     case Phone.NT_MODE_LTE_CDMA_AND_EVDO:
828                         // This is one of the modes we recognize
829                         modemNetworkMode = buttonNetworkMode;
830                         break;
831                     default:
832                         loge("Invalid Network Mode (" + buttonNetworkMode + ") chosen. Ignore.");
833                         return true;
834                 }
835 
836                 UpdateEnabledNetworksValueAndSummary(buttonNetworkMode);
837 
838                 android.provider.Settings.Global.putInt(mPhone.getContext().getContentResolver(),
839                         android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
840                         buttonNetworkMode );
841                 //Set the modem network mode
842                 mPhone.setPreferredNetworkType(modemNetworkMode, mHandler
843                         .obtainMessage(MyHandler.MESSAGE_SET_PREFERRED_NETWORK_TYPE));
844             }
845         } else if (preference == mButton4glte) {
846             SwitchPreference ltePref = (SwitchPreference)preference;
847             ltePref.setChecked(!ltePref.isChecked());
848             ImsManager.setEnhanced4gLteModeSetting(this, ltePref.isChecked());
849         } else if (preference == mButtonDataRoam) {
850             if (DBG) log("onPreferenceTreeClick: preference == mButtonDataRoam.");
851 
852             //normally called on the toggle click
853             if (!mButtonDataRoam.isChecked()) {
854                 // First confirm with a warning dialog about charges
855                 mOkClicked = false;
856                 new AlertDialog.Builder(this).setMessage(
857                         getResources().getString(R.string.roaming_warning))
858                         .setTitle(android.R.string.dialog_alert_title)
859                         .setIconAttribute(android.R.attr.alertDialogIcon)
860                         .setPositiveButton(android.R.string.yes, this)
861                         .setNegativeButton(android.R.string.no, this)
862                         .show()
863                         .setOnDismissListener(this);
864             } else {
865                 mPhone.setDataRoamingEnabled(false);
866             }
867             return true;
868         }
869 
870         updateBody();
871         // always let the preference setting proceed.
872         return true;
873     }
874 
875     private class MyHandler extends Handler {
876 
877         static final int MESSAGE_GET_PREFERRED_NETWORK_TYPE = 0;
878         static final int MESSAGE_SET_PREFERRED_NETWORK_TYPE = 1;
879 
880         @Override
handleMessage(Message msg)881         public void handleMessage(Message msg) {
882             switch (msg.what) {
883                 case MESSAGE_GET_PREFERRED_NETWORK_TYPE:
884                     handleGetPreferredNetworkTypeResponse(msg);
885                     break;
886 
887                 case MESSAGE_SET_PREFERRED_NETWORK_TYPE:
888                     handleSetPreferredNetworkTypeResponse(msg);
889                     break;
890             }
891         }
892 
handleGetPreferredNetworkTypeResponse(Message msg)893         private void handleGetPreferredNetworkTypeResponse(Message msg) {
894             final int phoneSubId = mPhone.getSubId();
895             AsyncResult ar = (AsyncResult) msg.obj;
896 
897             if (ar.exception == null) {
898                 int modemNetworkMode = ((int[])ar.result)[0];
899 
900                 if (DBG) {
901                     log ("handleGetPreferredNetworkTypeResponse: modemNetworkMode = " +
902                             modemNetworkMode);
903                 }
904 
905                 int settingsNetworkMode = android.provider.Settings.Global.getInt(
906                         mPhone.getContext().getContentResolver(),
907                         android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
908                         preferredNetworkMode);
909 
910                 if (DBG) {
911                     log("handleGetPreferredNetworkTypeReponse: settingsNetworkMode = " +
912                             settingsNetworkMode);
913                 }
914 
915                 //check that modemNetworkMode is from an accepted value
916                 if (modemNetworkMode == Phone.NT_MODE_WCDMA_PREF ||
917                         modemNetworkMode == Phone.NT_MODE_GSM_ONLY ||
918                         modemNetworkMode == Phone.NT_MODE_WCDMA_ONLY ||
919                         modemNetworkMode == Phone.NT_MODE_GSM_UMTS ||
920                         modemNetworkMode == Phone.NT_MODE_CDMA ||
921                         modemNetworkMode == Phone.NT_MODE_CDMA_NO_EVDO ||
922                         modemNetworkMode == Phone.NT_MODE_EVDO_NO_CDMA ||
923                         modemNetworkMode == Phone.NT_MODE_GLOBAL ||
924                         modemNetworkMode == Phone.NT_MODE_LTE_CDMA_AND_EVDO ||
925                         modemNetworkMode == Phone.NT_MODE_LTE_GSM_WCDMA ||
926                         modemNetworkMode == Phone.NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA ||
927                         modemNetworkMode == Phone.NT_MODE_LTE_ONLY ||
928                         modemNetworkMode == Phone.NT_MODE_LTE_WCDMA) {
929                     if (DBG) {
930                         log("handleGetPreferredNetworkTypeResponse: if 1: modemNetworkMode = " +
931                                 modemNetworkMode);
932                     }
933 
934                     //check changes in modemNetworkMode
935                     if (modemNetworkMode != settingsNetworkMode) {
936                         if (DBG) {
937                             log("handleGetPreferredNetworkTypeResponse: if 2: " +
938                                     "modemNetworkMode != settingsNetworkMode");
939                         }
940 
941                         settingsNetworkMode = modemNetworkMode;
942 
943                         if (DBG) { log("handleGetPreferredNetworkTypeResponse: if 2: " +
944                                 "settingsNetworkMode = " + settingsNetworkMode);
945                         }
946                     }
947 
948                     UpdatePreferredNetworkModeSummary(modemNetworkMode);
949                     UpdateEnabledNetworksValueAndSummary(modemNetworkMode);
950                     // changes the mButtonPreferredNetworkMode accordingly to modemNetworkMode
951                     mButtonPreferredNetworkMode.setValue(Integer.toString(modemNetworkMode));
952                 } else {
953                     if (DBG) log("handleGetPreferredNetworkTypeResponse: else: reset to default");
954                     resetNetworkModeToDefault();
955                 }
956             }
957         }
958 
handleSetPreferredNetworkTypeResponse(Message msg)959         private void handleSetPreferredNetworkTypeResponse(Message msg) {
960             AsyncResult ar = (AsyncResult) msg.obj;
961             final int phoneSubId = mPhone.getSubId();
962 
963             if (ar.exception == null) {
964                 int networkMode = Integer.valueOf(
965                         mButtonPreferredNetworkMode.getValue()).intValue();
966                 android.provider.Settings.Global.putInt(mPhone.getContext().getContentResolver(),
967                         android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
968                         networkMode );
969                 networkMode = Integer.valueOf(
970                         mButtonEnabledNetworks.getValue()).intValue();
971                 android.provider.Settings.Global.putInt(mPhone.getContext().getContentResolver(),
972                         android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
973                         networkMode );
974             } else {
975                 mPhone.getPreferredNetworkType(obtainMessage(MESSAGE_GET_PREFERRED_NETWORK_TYPE));
976             }
977         }
978 
resetNetworkModeToDefault()979         private void resetNetworkModeToDefault() {
980             final int phoneSubId = mPhone.getSubId();
981             //set the mButtonPreferredNetworkMode
982             mButtonPreferredNetworkMode.setValue(Integer.toString(preferredNetworkMode));
983             mButtonEnabledNetworks.setValue(Integer.toString(preferredNetworkMode));
984             //set the Settings.System
985             android.provider.Settings.Global.putInt(mPhone.getContext().getContentResolver(),
986                         android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
987                         preferredNetworkMode );
988             //Set the Modem
989             mPhone.setPreferredNetworkType(preferredNetworkMode,
990                     this.obtainMessage(MyHandler.MESSAGE_SET_PREFERRED_NETWORK_TYPE));
991         }
992     }
993 
UpdatePreferredNetworkModeSummary(int NetworkMode)994     private void UpdatePreferredNetworkModeSummary(int NetworkMode) {
995         switch(NetworkMode) {
996             case Phone.NT_MODE_WCDMA_PREF:
997                 mButtonPreferredNetworkMode.setSummary(
998                         R.string.preferred_network_mode_wcdma_perf_summary);
999                 break;
1000             case Phone.NT_MODE_GSM_ONLY:
1001                 mButtonPreferredNetworkMode.setSummary(
1002                         R.string.preferred_network_mode_gsm_only_summary);
1003                 break;
1004             case Phone.NT_MODE_WCDMA_ONLY:
1005                 mButtonPreferredNetworkMode.setSummary(
1006                         R.string.preferred_network_mode_wcdma_only_summary);
1007                 break;
1008             case Phone.NT_MODE_GSM_UMTS:
1009                 mButtonPreferredNetworkMode.setSummary(
1010                         R.string.preferred_network_mode_gsm_wcdma_summary);
1011                 break;
1012             case Phone.NT_MODE_CDMA:
1013                 switch (mPhone.getLteOnCdmaMode()) {
1014                     case PhoneConstants.LTE_ON_CDMA_TRUE:
1015                         mButtonPreferredNetworkMode.setSummary(
1016                             R.string.preferred_network_mode_cdma_summary);
1017                     break;
1018                     case PhoneConstants.LTE_ON_CDMA_FALSE:
1019                     default:
1020                         mButtonPreferredNetworkMode.setSummary(
1021                             R.string.preferred_network_mode_cdma_evdo_summary);
1022                         break;
1023                 }
1024                 break;
1025             case Phone.NT_MODE_CDMA_NO_EVDO:
1026                 mButtonPreferredNetworkMode.setSummary(
1027                         R.string.preferred_network_mode_cdma_only_summary);
1028                 break;
1029             case Phone.NT_MODE_EVDO_NO_CDMA:
1030                 mButtonPreferredNetworkMode.setSummary(
1031                         R.string.preferred_network_mode_evdo_only_summary);
1032                 break;
1033             case Phone.NT_MODE_LTE_ONLY:
1034                 mButtonPreferredNetworkMode.setSummary(
1035                         R.string.preferred_network_mode_lte_summary);
1036                 break;
1037             case Phone.NT_MODE_LTE_GSM_WCDMA:
1038                 mButtonPreferredNetworkMode.setSummary(
1039                         R.string.preferred_network_mode_lte_gsm_wcdma_summary);
1040                 break;
1041             case Phone.NT_MODE_LTE_CDMA_AND_EVDO:
1042                 mButtonPreferredNetworkMode.setSummary(
1043                         R.string.preferred_network_mode_lte_cdma_evdo_summary);
1044                 break;
1045             case Phone.NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
1046                 if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
1047                     mButtonPreferredNetworkMode.setSummary(
1048                             R.string.preferred_network_mode_global_summary);
1049                 } else {
1050                     mButtonPreferredNetworkMode.setSummary(
1051                             R.string.preferred_network_mode_lte_summary);
1052                 }
1053                 break;
1054             case Phone.NT_MODE_GLOBAL:
1055                 mButtonPreferredNetworkMode.setSummary(
1056                         R.string.preferred_network_mode_cdma_evdo_gsm_wcdma_summary);
1057                 break;
1058             case Phone.NT_MODE_LTE_WCDMA:
1059                 mButtonPreferredNetworkMode.setSummary(
1060                         R.string.preferred_network_mode_lte_wcdma_summary);
1061                 break;
1062             default:
1063                 mButtonPreferredNetworkMode.setSummary(
1064                         R.string.preferred_network_mode_global_summary);
1065         }
1066     }
1067 
UpdateEnabledNetworksValueAndSummary(int NetworkMode)1068     private void UpdateEnabledNetworksValueAndSummary(int NetworkMode) {
1069         switch (NetworkMode) {
1070             case Phone.NT_MODE_WCDMA_ONLY:
1071             case Phone.NT_MODE_GSM_UMTS:
1072             case Phone.NT_MODE_WCDMA_PREF:
1073                 if (!mIsGlobalCdma) {
1074                     mButtonEnabledNetworks.setValue(
1075                             Integer.toString(Phone.NT_MODE_WCDMA_PREF));
1076                     mButtonEnabledNetworks.setSummary(R.string.network_3G);
1077                 } else {
1078                     mButtonEnabledNetworks.setValue(
1079                             Integer.toString(Phone.NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA));
1080                     mButtonEnabledNetworks.setSummary(R.string.network_global);
1081                 }
1082                 break;
1083             case Phone.NT_MODE_GSM_ONLY:
1084                 if (!mIsGlobalCdma) {
1085                     mButtonEnabledNetworks.setValue(
1086                             Integer.toString(Phone.NT_MODE_GSM_ONLY));
1087                     mButtonEnabledNetworks.setSummary(R.string.network_2G);
1088                 } else {
1089                     mButtonEnabledNetworks.setValue(
1090                             Integer.toString(Phone.NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA));
1091                     mButtonEnabledNetworks.setSummary(R.string.network_global);
1092                 }
1093                 break;
1094             case Phone.NT_MODE_LTE_GSM_WCDMA:
1095                 if (isWorldMode()) {
1096                     mButtonEnabledNetworks.setSummary(
1097                             R.string.preferred_network_mode_lte_gsm_umts_summary);
1098                     controlCdmaOptions(false);
1099                     controlGsmOptions(true);
1100                     break;
1101                 }
1102             case Phone.NT_MODE_LTE_ONLY:
1103             case Phone.NT_MODE_LTE_WCDMA:
1104                 if (!mIsGlobalCdma) {
1105                     mButtonEnabledNetworks.setValue(
1106                             Integer.toString(Phone.NT_MODE_LTE_GSM_WCDMA));
1107                     mButtonEnabledNetworks.setSummary((mShow4GForLTE == true)
1108                             ? R.string.network_4G : R.string.network_lte);
1109                 } else {
1110                     mButtonEnabledNetworks.setValue(
1111                             Integer.toString(Phone.NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA));
1112                     mButtonEnabledNetworks.setSummary(R.string.network_global);
1113                 }
1114                 break;
1115             case Phone.NT_MODE_LTE_CDMA_AND_EVDO:
1116                 if (isWorldMode()) {
1117                     mButtonEnabledNetworks.setSummary(
1118                             R.string.preferred_network_mode_lte_cdma_summary);
1119                     controlCdmaOptions(true);
1120                     controlGsmOptions(false);
1121                 } else {
1122                     mButtonEnabledNetworks.setValue(
1123                             Integer.toString(Phone.NT_MODE_LTE_CDMA_AND_EVDO));
1124                     mButtonEnabledNetworks.setSummary(R.string.network_lte);
1125                 }
1126                 break;
1127             case Phone.NT_MODE_CDMA:
1128             case Phone.NT_MODE_EVDO_NO_CDMA:
1129             case Phone.NT_MODE_GLOBAL:
1130                 mButtonEnabledNetworks.setValue(
1131                         Integer.toString(Phone.NT_MODE_CDMA));
1132                 mButtonEnabledNetworks.setSummary(R.string.network_3G);
1133                 break;
1134             case Phone.NT_MODE_CDMA_NO_EVDO:
1135                 mButtonEnabledNetworks.setValue(
1136                         Integer.toString(Phone.NT_MODE_CDMA_NO_EVDO));
1137                 mButtonEnabledNetworks.setSummary(R.string.network_1x);
1138                 break;
1139             case Phone.NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
1140                 if (isWorldMode()) {
1141                     controlCdmaOptions(true);
1142                     controlGsmOptions(false);
1143                 }
1144                 mButtonEnabledNetworks.setValue(
1145                         Integer.toString(Phone.NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA));
1146                 if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
1147                     mButtonEnabledNetworks.setSummary(R.string.network_global);
1148                 } else {
1149                     mButtonEnabledNetworks.setSummary((mShow4GForLTE == true)
1150                             ? R.string.network_4G : R.string.network_lte);
1151                 }
1152                 break;
1153             default:
1154                 String errMsg = "Invalid Network Mode (" + NetworkMode + "). Ignore.";
1155                 loge(errMsg);
1156                 mButtonEnabledNetworks.setSummary(errMsg);
1157         }
1158     }
1159 
1160     @Override
onActivityResult(int requestCode, int resultCode, Intent data)1161     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
1162         switch(requestCode) {
1163         case REQUEST_CODE_EXIT_ECM:
1164             Boolean isChoiceYes =
1165                 data.getBooleanExtra(EmergencyCallbackModeExitDialog.EXTRA_EXIT_ECM_RESULT, false);
1166             if (isChoiceYes) {
1167                 // If the phone exits from ECM mode, show the CDMA Options
1168                 mCdmaOptions.showDialog(mClickedPreference);
1169             } else {
1170                 // do nothing
1171             }
1172             break;
1173 
1174         default:
1175             break;
1176         }
1177     }
1178 
log(String msg)1179     private static void log(String msg) {
1180         Log.d(LOG_TAG, msg);
1181     }
1182 
loge(String msg)1183     private static void loge(String msg) {
1184         Log.e(LOG_TAG, msg);
1185     }
1186 
1187     @Override
onOptionsItemSelected(MenuItem item)1188     public boolean onOptionsItemSelected(MenuItem item) {
1189         final int itemId = item.getItemId();
1190         if (itemId == android.R.id.home) {  // See ActionBar#setDisplayHomeAsUpEnabled()
1191             // Commenting out "logical up" capability. This is a workaround for issue 5278083.
1192             //
1193             // Settings app may not launch this activity via UP_ACTIVITY_CLASS but the other
1194             // Activity that looks exactly same as UP_ACTIVITY_CLASS ("SubSettings" Activity).
1195             // At that moment, this Activity launches UP_ACTIVITY_CLASS on top of the Activity.
1196             // which confuses users.
1197             // TODO: introduce better mechanism for "up" capability here.
1198             /*Intent intent = new Intent(Intent.ACTION_MAIN);
1199             intent.setClassName(UP_ACTIVITY_PACKAGE, UP_ACTIVITY_CLASS);
1200             intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
1201             startActivity(intent);*/
1202             finish();
1203             return true;
1204         }
1205         return super.onOptionsItemSelected(item);
1206     }
1207 
isWorldMode()1208     private boolean isWorldMode() {
1209         boolean worldModeOn = false;
1210         final TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
1211         final String configString = getResources().getString(R.string.config_world_mode);
1212 
1213         if (!TextUtils.isEmpty(configString)) {
1214             String[] configArray = configString.split(";");
1215             // Check if we have World mode configuration set to True only or config is set to True
1216             // and SIM GID value is also set and matches to the current SIM GID.
1217             if (configArray != null &&
1218                    ((configArray.length == 1 && configArray[0].equalsIgnoreCase("true")) ||
1219                        (configArray.length == 2 && !TextUtils.isEmpty(configArray[1]) &&
1220                            tm != null && configArray[1].equalsIgnoreCase(tm.getGroupIdLevel1())))) {
1221                                worldModeOn = true;
1222             }
1223         }
1224 
1225         if (DBG) {
1226             log("isWorldMode=" + worldModeOn);
1227         }
1228 
1229         return worldModeOn;
1230     }
1231 
controlGsmOptions(boolean enable)1232     private void controlGsmOptions(boolean enable) {
1233         PreferenceScreen prefSet = getPreferenceScreen();
1234         if (prefSet == null) {
1235             return;
1236         }
1237 
1238         if (mGsmUmtsOptions == null) {
1239             mGsmUmtsOptions = new GsmUmtsOptions(this, prefSet, mPhone.getSubId());
1240         }
1241         PreferenceScreen apnExpand =
1242                 (PreferenceScreen) prefSet.findPreference(BUTTON_APN_EXPAND_KEY);
1243         PreferenceScreen operatorSelectionExpand =
1244                 (PreferenceScreen) prefSet.findPreference(BUTTON_OPERATOR_SELECTION_EXPAND_KEY);
1245         PreferenceScreen carrierSettings =
1246                 (PreferenceScreen) prefSet.findPreference(BUTTON_CARRIER_SETTINGS_KEY);
1247         if (apnExpand != null) {
1248             apnExpand.setEnabled(isWorldMode() || enable);
1249         }
1250         if (operatorSelectionExpand != null) {
1251             operatorSelectionExpand.setEnabled(enable);
1252         }
1253         if (carrierSettings != null) {
1254             prefSet.removePreference(carrierSettings);
1255         }
1256     }
1257 
controlCdmaOptions(boolean enable)1258     private void controlCdmaOptions(boolean enable) {
1259         PreferenceScreen prefSet = getPreferenceScreen();
1260         if (prefSet == null) {
1261             return;
1262         }
1263         if (enable && mCdmaOptions == null) {
1264             mCdmaOptions = new CdmaOptions(this, prefSet, mPhone);
1265         }
1266         CdmaSystemSelectListPreference systemSelect =
1267                 (CdmaSystemSelectListPreference)prefSet.findPreference
1268                         (BUTTON_CDMA_SYSTEM_SELECT_KEY);
1269         if (systemSelect != null) {
1270             systemSelect.setEnabled(enable);
1271         }
1272     }
1273 
1274     /**
1275      * finds a record with slotId.
1276      * Since the number of SIMs are few, an array is fine.
1277      */
findRecordBySlotId(final int slotId)1278     public SubscriptionInfo findRecordBySlotId(final int slotId) {
1279         if (mActiveSubInfos != null) {
1280             final int subInfoLength = mActiveSubInfos.size();
1281 
1282             for (int i = 0; i < subInfoLength; ++i) {
1283                 final SubscriptionInfo sir = mActiveSubInfos.get(i);
1284                 if (sir.getSimSlotIndex() == slotId) {
1285                     //Right now we take the first subscription on a SIM.
1286                     return sir;
1287                 }
1288             }
1289         }
1290 
1291         return null;
1292     }
1293 }
1294