Home | History | Annotate | Download | only in settings
      1 /*
      2  * Copyright (C) 2015 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.settings;
     18 
     19 import android.app.Activity;
     20 import android.app.AlertDialog;
     21 import android.content.BroadcastReceiver;
     22 import android.content.Context;
     23 import android.content.Intent;
     24 import android.content.IntentFilter;
     25 import android.os.Bundle;
     26 import android.os.PersistableBundle;
     27 import android.support.v7.preference.ListPreference;
     28 import android.support.v7.preference.Preference;
     29 import android.support.v7.preference.PreferenceScreen;
     30 import android.telephony.CarrierConfigManager;
     31 import android.telephony.PhoneStateListener;
     32 import android.telephony.TelephonyManager;
     33 import android.util.Log;
     34 import android.widget.Switch;
     35 import android.widget.TextView;
     36 
     37 import com.android.ims.ImsConfig;
     38 import com.android.ims.ImsManager;
     39 import com.android.internal.logging.MetricsLogger;
     40 import com.android.internal.logging.MetricsProto.MetricsEvent;
     41 import com.android.internal.telephony.Phone;
     42 import com.android.settings.widget.SwitchBar;
     43 
     44 /**
     45  * "Wi-Fi Calling settings" screen.  This preference screen lets you
     46  * enable/disable Wi-Fi Calling and change Wi-Fi Calling mode.
     47  */
     48 public class WifiCallingSettings extends SettingsPreferenceFragment
     49         implements SwitchBar.OnSwitchChangeListener,
     50         Preference.OnPreferenceChangeListener {
     51 
     52     private static final String TAG = "WifiCallingSettings";
     53 
     54     //String keys for preference lookup
     55     private static final String BUTTON_WFC_MODE = "wifi_calling_mode";
     56 
     57     //UI objects
     58     private SwitchBar mSwitchBar;
     59     private Switch mSwitch;
     60     private ListPreference mButtonWfcMode;
     61     private TextView mEmptyView;
     62 
     63     private boolean mValidListener = false;
     64     private boolean mEditableWfcMode = true;
     65 
     66     private final PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
     67         /*
     68          * Enable/disable controls when in/out of a call and depending on
     69          * TTY mode and TTY support over VoLTE.
     70          * @see android.telephony.PhoneStateListener#onCallStateChanged(int,
     71          * java.lang.String)
     72          */
     73         @Override
     74         public void onCallStateChanged(int state, String incomingNumber) {
     75             final SettingsActivity activity = (SettingsActivity) getActivity();
     76             boolean isNonTtyOrTtyOnVolteEnabled = ImsManager
     77                     .isNonTtyOrTtyOnVolteEnabled(activity);
     78             final SwitchBar switchBar = activity.getSwitchBar();
     79             boolean isWfcEnabled = switchBar.getSwitch().isChecked()
     80                     && isNonTtyOrTtyOnVolteEnabled;
     81 
     82             switchBar.setEnabled((state == TelephonyManager.CALL_STATE_IDLE)
     83                     && isNonTtyOrTtyOnVolteEnabled);
     84 
     85             Preference pref = getPreferenceScreen().findPreference(BUTTON_WFC_MODE);
     86             if (pref != null) {
     87                 pref.setEnabled(isWfcEnabled
     88                         && (state == TelephonyManager.CALL_STATE_IDLE));
     89             }
     90         }
     91     };
     92 
     93     @Override
     94     public void onActivityCreated(Bundle savedInstanceState) {
     95         super.onActivityCreated(savedInstanceState);
     96 
     97         final SettingsActivity activity = (SettingsActivity) getActivity();
     98 
     99         mSwitchBar = activity.getSwitchBar();
    100         mSwitch = mSwitchBar.getSwitch();
    101         mSwitchBar.show();
    102 
    103         mEmptyView = (TextView) getView().findViewById(android.R.id.empty);
    104         setEmptyView(mEmptyView);
    105         mEmptyView.setText(R.string.wifi_calling_off_explanation);
    106     }
    107 
    108     @Override
    109     public void onDestroyView() {
    110         super.onDestroyView();
    111         mSwitchBar.hide();
    112     }
    113 
    114     private void showAlert(Intent intent) {
    115         Context context = getActivity();
    116 
    117         CharSequence title = intent.getCharSequenceExtra(Phone.EXTRA_KEY_ALERT_TITLE);
    118         CharSequence message = intent.getCharSequenceExtra(Phone.EXTRA_KEY_ALERT_MESSAGE);
    119 
    120         AlertDialog.Builder builder = new AlertDialog.Builder(context);
    121         builder.setMessage(message)
    122                 .setTitle(title)
    123                 .setIcon(android.R.drawable.ic_dialog_alert)
    124                 .setPositiveButton(android.R.string.ok, null);
    125         AlertDialog dialog = builder.create();
    126         dialog.show();
    127     }
    128 
    129     private IntentFilter mIntentFilter;
    130 
    131     private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
    132         @Override
    133         public void onReceive(Context context, Intent intent) {
    134             String action = intent.getAction();
    135             if (action.equals(ImsManager.ACTION_IMS_REGISTRATION_ERROR)) {
    136                 // If this fragment is active then we are immediately
    137                 // showing alert on screen. There is no need to add
    138                 // notification in this case.
    139                 //
    140                 // In order to communicate to ImsPhone that it should
    141                 // not show notification, we are changing result code here.
    142                 setResultCode(Activity.RESULT_CANCELED);
    143 
    144                 // UX requirement is to disable WFC in case of "permanent" registration failures.
    145                 mSwitch.setChecked(false);
    146 
    147                 showAlert(intent);
    148             }
    149         }
    150     };
    151 
    152     @Override
    153     protected int getMetricsCategory() {
    154         return MetricsEvent.WIFI_CALLING;
    155     }
    156 
    157     @Override
    158     public void onCreate(Bundle savedInstanceState) {
    159         super.onCreate(savedInstanceState);
    160 
    161         addPreferencesFromResource(R.xml.wifi_calling_settings);
    162 
    163         mButtonWfcMode = (ListPreference) findPreference(BUTTON_WFC_MODE);
    164         mButtonWfcMode.setOnPreferenceChangeListener(this);
    165 
    166         mIntentFilter = new IntentFilter();
    167         mIntentFilter.addAction(ImsManager.ACTION_IMS_REGISTRATION_ERROR);
    168 
    169         CarrierConfigManager configManager = (CarrierConfigManager)
    170                 getSystemService(Context.CARRIER_CONFIG_SERVICE);
    171         boolean isWifiOnlySupported = true;
    172         if (configManager != null) {
    173             PersistableBundle b = configManager.getConfig();
    174             if (b != null) {
    175                 mEditableWfcMode = b.getBoolean(CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL);
    176                 isWifiOnlySupported = b.getBoolean(
    177                         CarrierConfigManager.KEY_CARRIER_WFC_SUPPORTS_WIFI_ONLY_BOOL, true);
    178             }
    179         }
    180 
    181         if (!isWifiOnlySupported) {
    182             mButtonWfcMode.setEntries(R.array.wifi_calling_mode_choices_without_wifi_only);
    183             mButtonWfcMode.setEntryValues(R.array.wifi_calling_mode_values_without_wifi_only);
    184         }
    185     }
    186 
    187     @Override
    188     public void onResume() {
    189         super.onResume();
    190 
    191         final Context context = getActivity();
    192 
    193         if (ImsManager.isWfcEnabledByPlatform(context)) {
    194             TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
    195             tm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
    196 
    197             mSwitchBar.addOnSwitchChangeListener(this);
    198 
    199             mValidListener = true;
    200         }
    201 
    202         // NOTE: Buttons will be enabled/disabled in mPhoneStateListener
    203         boolean wfcEnabled = ImsManager.isWfcEnabledByUser(context)
    204                 && ImsManager.isNonTtyOrTtyOnVolteEnabled(context);
    205         mSwitch.setChecked(wfcEnabled);
    206         int wfcMode = ImsManager.getWfcMode(context);
    207         mButtonWfcMode.setValue(Integer.toString(wfcMode));
    208         updateButtonWfcMode(context, wfcEnabled, wfcMode);
    209 
    210         context.registerReceiver(mIntentReceiver, mIntentFilter);
    211 
    212         Intent intent = getActivity().getIntent();
    213         if (intent.getBooleanExtra(Phone.EXTRA_KEY_ALERT_SHOW, false)) {
    214             showAlert(intent);
    215         }
    216     }
    217 
    218     @Override
    219     public void onPause() {
    220         super.onPause();
    221 
    222         final Context context = getActivity();
    223 
    224         if (mValidListener) {
    225             mValidListener = false;
    226 
    227             TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
    228             tm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
    229 
    230             mSwitchBar.removeOnSwitchChangeListener(this);
    231         }
    232 
    233         context.unregisterReceiver(mIntentReceiver);
    234     }
    235 
    236     /**
    237      * Listens to the state change of the switch.
    238      */
    239     @Override
    240     public void onSwitchChanged(Switch switchView, boolean isChecked) {
    241         final Context context = getActivity();
    242 
    243         ImsManager.setWfcSetting(context, isChecked);
    244 
    245         int wfcMode = ImsManager.getWfcMode(context);
    246         updateButtonWfcMode(context, isChecked, wfcMode);
    247         if (isChecked) {
    248             MetricsLogger.action(getActivity(), getMetricsCategory(), wfcMode);
    249         } else {
    250             MetricsLogger.action(getActivity(), getMetricsCategory(), -1);
    251         }
    252     }
    253 
    254     private void updateButtonWfcMode(Context context, boolean wfcEnabled, int wfcMode) {
    255         mButtonWfcMode.setSummary(getWfcModeSummary(context, wfcMode));
    256         mButtonWfcMode.setEnabled(wfcEnabled);
    257 
    258         final PreferenceScreen preferenceScreen = getPreferenceScreen();
    259         if (wfcEnabled) {
    260             preferenceScreen.addPreference(mButtonWfcMode);
    261         } else {
    262             preferenceScreen.removePreference(mButtonWfcMode);
    263         }
    264         preferenceScreen.setEnabled(mEditableWfcMode);
    265     }
    266 
    267     @Override
    268     public boolean onPreferenceChange(Preference preference, Object newValue) {
    269         final Context context = getActivity();
    270         if (preference == mButtonWfcMode) {
    271             mButtonWfcMode.setValue((String) newValue);
    272             int buttonMode = Integer.valueOf((String) newValue);
    273             int currentMode = ImsManager.getWfcMode(context);
    274             if (buttonMode != currentMode) {
    275                 ImsManager.setWfcMode(context, buttonMode);
    276                 mButtonWfcMode.setSummary(getWfcModeSummary(context, buttonMode));
    277                 MetricsLogger.action(getActivity(), getMetricsCategory(), buttonMode);
    278             }
    279         }
    280         return true;
    281     }
    282 
    283     static int getWfcModeSummary(Context context, int wfcMode) {
    284         int resId = com.android.internal.R.string.wifi_calling_off_summary;
    285         if (ImsManager.isWfcEnabledByUser(context)) {
    286             switch (wfcMode) {
    287                 case ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY:
    288                     resId = com.android.internal.R.string.wfc_mode_wifi_only_summary;
    289                     break;
    290                 case ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED:
    291                     resId = com.android.internal.R.string.wfc_mode_cellular_preferred_summary;
    292                     break;
    293                 case ImsConfig.WfcModeFeatureValueConstants.WIFI_PREFERRED:
    294                     resId = com.android.internal.R.string.wfc_mode_wifi_preferred_summary;
    295                     break;
    296                 default:
    297                     Log.e(TAG, "Unexpected WFC mode value: " + wfcMode);
    298             }
    299         }
    300         return resId;
    301     }
    302 }
    303