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 onActivityCreated(Bundle savedInstanceState)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 onDestroyView()105 public void onDestroyView() { 106 super.onDestroyView(); 107 mSwitchBar.hide(); 108 } 109 showAlert(Intent intent)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 getMetricsCategory()149 protected int getMetricsCategory() { 150 return MetricsLogger.WIFI_CALLING; 151 } 152 153 @Override onCreate(Bundle savedInstanceState)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 onResume()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 onPause()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 onSwitchChanged(Switch switchView, boolean isChecked)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 updateButtonWfcMode(Context context, boolean wfcEnabled, int wfcMode)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 onPreferenceChange(Preference preference, Object newValue)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 getWfcModeSummary(Context context, int wfcMode)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