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