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