Home | History | Annotate | Download | only in phone
      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.ProgressDialog;
     20 import android.content.Context;
     21 import android.content.Intent;
     22 import android.os.AsyncResult;
     23 import android.os.Handler;
     24 import android.os.Message;
     25 import android.preference.Preference;
     26 import android.preference.PreferenceCategory;
     27 import android.preference.TwoStatePreference;
     28 import android.telephony.ServiceState;
     29 import android.telephony.SubscriptionManager;
     30 import android.telephony.TelephonyManager;
     31 import android.util.AttributeSet;
     32 import android.util.Log;
     33 
     34 import com.android.internal.logging.MetricsLogger;
     35 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
     36 import com.android.internal.telephony.CommandException;
     37 import com.android.internal.telephony.Phone;
     38 import com.android.internal.telephony.PhoneFactory;
     39 
     40 /**
     41  * "Networks" settings UI for the Phone app.
     42  */
     43 public class NetworkOperators extends PreferenceCategory
     44         implements Preference.OnPreferenceChangeListener {
     45 
     46     private static final String LOG_TAG = "NetworkOperators";
     47     private static final boolean DBG = true;
     48 
     49     private static final int EVENT_AUTO_SELECT_DONE = 100;
     50     private static final int EVENT_GET_NETWORK_SELECTION_MODE_DONE = 200;
     51 
     52     //String keys for preference lookup
     53     public static final String BUTTON_NETWORK_SELECT_KEY = "button_network_select_key";
     54     public static final String BUTTON_AUTO_SELECT_KEY = "button_auto_select_key";
     55     public static final String BUTTON_CHOOSE_NETWORK_KEY = "button_choose_network_key";
     56     public static final String CATEGORY_NETWORK_OPERATORS_KEY = "network_operators_category_key";
     57 
     58     int mPhoneId = SubscriptionManager.INVALID_PHONE_INDEX;
     59     private static final int ALREADY_IN_AUTO_SELECTION = 1;
     60 
     61     //preference objects
     62     private NetworkSelectListPreference mNetworkSelect;
     63     private TwoStatePreference mAutoSelect;
     64     private Preference mChooseNetwork;
     65 
     66     private int mSubId;
     67     private ProgressDialog mProgressDialog;
     68 
     69     // There's two sets of Auto-Select UI in this class.
     70     // If {@code com.android.internal.R.bool.config_enableNewAutoSelectNetworkUI} set as true
     71     // {@link mChooseNetwork} will be used, otherwise {@link mNetworkSelect} will be used.
     72     boolean mEnableNewManualSelectNetworkUI;
     73 
     74     public NetworkOperators(Context context, AttributeSet attrs) {
     75         super(context, attrs);
     76     }
     77 
     78     public NetworkOperators(Context context) {
     79         super(context);
     80     }
     81 
     82     /**
     83      * Initialize NetworkOperators instance.
     84      */
     85     public void initialize() {
     86         mEnableNewManualSelectNetworkUI = getContext().getResources().getBoolean(
     87                 com.android.internal.R.bool.config_enableNewAutoSelectNetworkUI);
     88         mAutoSelect = (TwoStatePreference) findPreference(BUTTON_AUTO_SELECT_KEY);
     89         mChooseNetwork = findPreference(BUTTON_CHOOSE_NETWORK_KEY);
     90         mNetworkSelect = (NetworkSelectListPreference) findPreference(BUTTON_NETWORK_SELECT_KEY);
     91         if (mEnableNewManualSelectNetworkUI) {
     92             removePreference(mNetworkSelect);
     93         } else {
     94             removePreference(mChooseNetwork);
     95         }
     96         mProgressDialog = new ProgressDialog(getContext());
     97     }
     98 
     99     /**
    100      * Update NetworkOperators instance if like subId or queryService are updated.
    101      *
    102      * @param subId Corresponding subscription ID of this network.
    103      * @param queryService The service to do network queries.
    104      */
    105     protected void update(final int subId, INetworkQueryService queryService) {
    106         mSubId = subId;
    107         mPhoneId = SubscriptionManager.getPhoneId(mSubId);
    108 
    109         if (mAutoSelect != null) {
    110             mAutoSelect.setOnPreferenceChangeListener(this);
    111         }
    112 
    113         if (mEnableNewManualSelectNetworkUI) {
    114             if (mChooseNetwork != null) {
    115                 TelephonyManager telephonyManager = (TelephonyManager)
    116                         getContext().getSystemService(Context.TELEPHONY_SERVICE);
    117                 if (DBG) logd("data connection status " + telephonyManager.getDataState());
    118                 if (telephonyManager.getDataState() == telephonyManager.DATA_CONNECTED) {
    119                     mChooseNetwork.setSummary(telephonyManager.getNetworkOperatorName());
    120                 } else {
    121                     mChooseNetwork.setSummary(R.string.network_disconnected);
    122                 }
    123             }
    124         } else {
    125             if (mNetworkSelect != null) {
    126                 mNetworkSelect.initialize(mSubId, queryService, this, mProgressDialog);
    127             }
    128         }
    129         getNetworkSelectionMode();
    130     }
    131 
    132     /**
    133      * Implemented to support onPreferenceChangeListener to look for preference
    134      * changes specifically on auto select button.
    135      *
    136      * @param preference is the preference to be changed, should be auto select button.
    137      * @param newValue should be the value of whether autoSelect is checked.
    138      */
    139     @Override
    140     public boolean onPreferenceChange(Preference preference, Object newValue) {
    141         if (preference == mAutoSelect) {
    142             boolean autoSelect = (Boolean) newValue;
    143             if (DBG) logd("onPreferenceChange autoSelect: " + String.valueOf(autoSelect));
    144             selectNetworkAutomatic(autoSelect);
    145             MetricsLogger.action(getContext(),
    146                     MetricsEvent.ACTION_MOBILE_NETWORK_AUTO_SELECT_NETWORK_TOGGLE, autoSelect);
    147             return true;
    148         }
    149         return false;
    150     }
    151 
    152     private final Handler mHandler = new Handler() {
    153         @Override
    154         public void handleMessage(Message msg) {
    155             AsyncResult ar;
    156             switch (msg.what) {
    157                 case EVENT_AUTO_SELECT_DONE:
    158                     mAutoSelect.setEnabled(true);
    159                     dismissProgressBar();
    160 
    161                     ar = (AsyncResult) msg.obj;
    162                     if (ar.exception != null) {
    163                         if (DBG) logd("automatic network selection: failed!");
    164                         displayNetworkSelectionFailed(ar.exception);
    165                     } else {
    166                         if (DBG) logd("automatic network selection: succeeded!");
    167                         displayNetworkSelectionSucceeded(msg.arg1);
    168                     }
    169 
    170                     break;
    171                 case EVENT_GET_NETWORK_SELECTION_MODE_DONE:
    172                     ar = (AsyncResult) msg.obj;
    173                     if (ar.exception != null) {
    174                         if (DBG) logd("get network selection mode: failed!");
    175                     } else if (ar.result != null) {
    176                         try {
    177                             int[] modes = (int[]) ar.result;
    178                             boolean autoSelect = (modes[0] == 0);
    179                             if (DBG) {
    180                                 logd("get network selection mode: "
    181                                         + (autoSelect ? "auto" : "manual") + " selection");
    182                             }
    183                             if (mAutoSelect != null) {
    184                                 mAutoSelect.setChecked(autoSelect);
    185                             }
    186                             if (mEnableNewManualSelectNetworkUI) {
    187                                 if (mChooseNetwork != null) {
    188                                     mChooseNetwork.setEnabled(!autoSelect);
    189                                 }
    190                             } else {
    191                                 if (mNetworkSelect != null) {
    192                                     mNetworkSelect.setEnabled(!autoSelect);
    193                                 }
    194                             }
    195                         } catch (Exception e) {
    196                             if (DBG) loge("get network selection mode: unable to parse result.");
    197                         }
    198                     }
    199             }
    200             return;
    201         }
    202     };
    203 
    204     // Used by both mAutoSelect and mNetworkSelect buttons.
    205     protected void displayNetworkSelectionFailed(Throwable ex) {
    206         String status;
    207         if ((ex != null && ex instanceof CommandException)
    208                 && ((CommandException) ex).getCommandError()
    209                 == CommandException.Error.ILLEGAL_SIM_OR_ME) {
    210             status = getContext().getResources().getString(R.string.not_allowed);
    211         } else {
    212             status = getContext().getResources().getString(R.string.connect_later);
    213         }
    214 
    215         final PhoneGlobals app = PhoneGlobals.getInstance();
    216         app.notificationMgr.postTransientNotification(
    217                 NotificationMgr.NETWORK_SELECTION_NOTIFICATION, status);
    218 
    219         TelephonyManager tm = (TelephonyManager) app.getSystemService(Context.TELEPHONY_SERVICE);
    220         Phone phone = PhoneFactory.getPhone(mPhoneId);
    221         if (phone != null) {
    222             ServiceState ss = tm.getServiceStateForSubscriber(phone.getSubId());
    223             if (ss != null) {
    224                 app.notificationMgr.updateNetworkSelection(ss.getState(), phone.getSubId());
    225             }
    226         }
    227     }
    228 
    229     // Used by both mAutoSelect and mNetworkSelect buttons.
    230     protected void displayNetworkSelectionSucceeded(int msgArg1) {
    231         String status = null;
    232         if (msgArg1 == ALREADY_IN_AUTO_SELECTION) {
    233             status = getContext().getResources().getString(R.string.already_auto);
    234         } else {
    235             status = getContext().getResources().getString(R.string.registration_done);
    236         }
    237 
    238         final PhoneGlobals app = PhoneGlobals.getInstance();
    239         app.notificationMgr.postTransientNotification(
    240                 NotificationMgr.NETWORK_SELECTION_NOTIFICATION, status);
    241     }
    242 
    243     private void selectNetworkAutomatic(boolean autoSelect) {
    244         if (DBG) logd("selectNetworkAutomatic: " + String.valueOf(autoSelect));
    245 
    246         if (autoSelect) {
    247             if (mEnableNewManualSelectNetworkUI) {
    248                 if (mChooseNetwork != null) {
    249                     mChooseNetwork.setEnabled(!autoSelect);
    250                 }
    251             } else {
    252                 if (mNetworkSelect != null) {
    253                     mNetworkSelect.setEnabled(!autoSelect);
    254                 }
    255             }
    256             if (DBG) logd("select network automatically...");
    257             showAutoSelectProgressBar();
    258             mAutoSelect.setEnabled(false);
    259             Message msg = mHandler.obtainMessage(EVENT_AUTO_SELECT_DONE);
    260             Phone phone = PhoneFactory.getPhone(mPhoneId);
    261             if (phone != null) {
    262                 phone.setNetworkSelectionModeAutomatic(msg);
    263             }
    264         } else {
    265             if (mEnableNewManualSelectNetworkUI) {
    266                 if (mChooseNetwork != null) {
    267                     // Open the choose Network page automatically when user turn off the auto-select
    268                     openChooseNetworkPage();
    269                 }
    270             } else {
    271                 if (mNetworkSelect != null) {
    272                     mNetworkSelect.onClick();
    273                 }
    274             }
    275         }
    276     }
    277 
    278     protected void getNetworkSelectionMode() {
    279         if (DBG) logd("getting network selection mode...");
    280         Message msg = mHandler.obtainMessage(EVENT_GET_NETWORK_SELECTION_MODE_DONE);
    281         Phone phone = PhoneFactory.getPhone(mPhoneId);
    282         if (phone != null) {
    283             phone.getNetworkSelectionMode(msg);
    284         }
    285     }
    286 
    287     private void dismissProgressBar() {
    288         if (mProgressDialog != null && mProgressDialog.isShowing()) {
    289             mProgressDialog.dismiss();
    290         }
    291     }
    292 
    293     private void showAutoSelectProgressBar() {
    294         mProgressDialog.setMessage(
    295                 getContext().getResources().getString(R.string.register_automatically));
    296         mProgressDialog.setCanceledOnTouchOutside(false);
    297         mProgressDialog.setCancelable(false);
    298         mProgressDialog.setIndeterminate(true);
    299         mProgressDialog.show();
    300     }
    301 
    302     /**
    303      * Open the Choose netwotk page via {@alink NetworkSelectSettingActivity}
    304      */
    305     public void openChooseNetworkPage() {
    306         Intent intent = NetworkSelectSettingActivity.getIntent(getContext(), mPhoneId);
    307         getContext().startActivity(intent);
    308     }
    309 
    310     protected boolean preferenceTreeClick(Preference preference) {
    311         if (mEnableNewManualSelectNetworkUI) {
    312             if (DBG) logd("enable New AutoSelectNetwork UI");
    313             if (preference == mChooseNetwork) {
    314                 openChooseNetworkPage();
    315             }
    316             return (preference == mAutoSelect || preference == mChooseNetwork);
    317         } else {
    318             return (preference == mAutoSelect || preference == mNetworkSelect);
    319         }
    320     }
    321 
    322     private void logd(String msg) {
    323         Log.d(LOG_TAG, "[NetworksList] " + msg);
    324     }
    325 
    326     private void loge(String msg) {
    327         Log.e(LOG_TAG, "[NetworksList] " + msg);
    328     }
    329 }