/* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.settings; import android.app.Activity; import android.app.AlertDialog; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.os.PersistableBundle; import android.preference.ListPreference; import android.preference.Preference; import android.preference.PreferenceScreen; import android.telephony.CarrierConfigManager; import android.telephony.PhoneStateListener; import android.telephony.TelephonyManager; import android.util.Log; import android.widget.Switch; import android.widget.TextView; import com.android.ims.ImsConfig; import com.android.ims.ImsManager; import com.android.internal.logging.MetricsLogger; import com.android.internal.telephony.imsphone.ImsPhone; import com.android.settings.widget.SwitchBar; /** * "Wi-Fi Calling settings" screen. This preference screen lets you * enable/disable Wi-Fi Calling and change Wi-Fi Calling mode. */ public class WifiCallingSettings extends SettingsPreferenceFragment implements SwitchBar.OnSwitchChangeListener, Preference.OnPreferenceChangeListener { private static final String TAG = "WifiCallingSettings"; //String keys for preference lookup private static final String BUTTON_WFC_MODE = "wifi_calling_mode"; //UI objects private SwitchBar mSwitchBar; private Switch mSwitch; private ListPreference mButtonWfcMode; private TextView mEmptyView; private boolean mValidListener = false; private boolean mEditableWfcMode = true; private final PhoneStateListener mPhoneStateListener = new PhoneStateListener() { /* * Enable/disable controls when in/out of a call and depending on * TTY mode and TTY support over VoLTE. * @see android.telephony.PhoneStateListener#onCallStateChanged(int, * java.lang.String) */ @Override public void onCallStateChanged(int state, String incomingNumber) { final SettingsActivity activity = (SettingsActivity) getActivity(); boolean isNonTtyOrTtyOnVolteEnabled = ImsManager .isNonTtyOrTtyOnVolteEnabled(activity); final SwitchBar switchBar = activity.getSwitchBar(); boolean isWfcEnabled = switchBar.getSwitch().isChecked() && isNonTtyOrTtyOnVolteEnabled; switchBar.setEnabled((state == TelephonyManager.CALL_STATE_IDLE) && isNonTtyOrTtyOnVolteEnabled); Preference pref = getPreferenceScreen().findPreference(BUTTON_WFC_MODE); if (pref != null) { pref.setEnabled(isWfcEnabled && (state == TelephonyManager.CALL_STATE_IDLE)); } } }; @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); final SettingsActivity activity = (SettingsActivity) getActivity(); mSwitchBar = activity.getSwitchBar(); mSwitch = mSwitchBar.getSwitch(); mSwitchBar.show(); mEmptyView = (TextView) getView().findViewById(android.R.id.empty); getListView().setEmptyView(mEmptyView); mEmptyView.setText(R.string.wifi_calling_off_explanation); } @Override public void onDestroyView() { super.onDestroyView(); mSwitchBar.hide(); } private void showAlert(Intent intent) { Context context = getActivity(); CharSequence title = intent.getCharSequenceExtra(ImsPhone.EXTRA_KEY_ALERT_TITLE); CharSequence message = intent.getCharSequenceExtra(ImsPhone.EXTRA_KEY_ALERT_MESSAGE); AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setMessage(message) .setTitle(title) .setIcon(android.R.drawable.ic_dialog_alert) .setPositiveButton(android.R.string.ok, null); AlertDialog dialog = builder.create(); dialog.show(); } private IntentFilter mIntentFilter; private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (action.equals(ImsManager.ACTION_IMS_REGISTRATION_ERROR)) { // If this fragment is active then we are immediately // showing alert on screen. There is no need to add // notification in this case. // // In order to communicate to ImsPhone that it should // not show notification, we are changing result code here. setResultCode(Activity.RESULT_CANCELED); // UX requirement is to disable WFC in case of "permanent" registration failures. mSwitch.setChecked(false); showAlert(intent); } } }; @Override protected int getMetricsCategory() { return MetricsLogger.WIFI_CALLING; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.wifi_calling_settings); mButtonWfcMode = (ListPreference) findPreference(BUTTON_WFC_MODE); mButtonWfcMode.setOnPreferenceChangeListener(this); mIntentFilter = new IntentFilter(); mIntentFilter.addAction(ImsManager.ACTION_IMS_REGISTRATION_ERROR); CarrierConfigManager configManager = (CarrierConfigManager) getSystemService(Context.CARRIER_CONFIG_SERVICE); if (configManager != null) { PersistableBundle b = configManager.getConfig(); if (b != null) { mEditableWfcMode = b.getBoolean(CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL); } } } @Override public void onResume() { super.onResume(); final Context context = getActivity(); if (ImsManager.isWfcEnabledByPlatform(context)) { TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); tm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE); mSwitchBar.addOnSwitchChangeListener(this); mValidListener = true; } if (!isWfcModeSupported()) { android.provider.Settings.Global.putInt(context.getContentResolver(), android.provider.Settings.Global.WFC_IMS_MODE, ImsConfig.WfcModeFeatureValueConstants.WIFI_PREFERRED); } // NOTE: Buttons will be enabled/disabled in mPhoneStateListener boolean wfcEnabled = ImsManager.isWfcEnabledByUser(context) && ImsManager.isNonTtyOrTtyOnVolteEnabled(context); mSwitch.setChecked(wfcEnabled); int wfcMode = ImsManager.getWfcMode(context); mButtonWfcMode.setValue(Integer.toString(wfcMode)); updateButtonWfcMode(context, wfcEnabled, wfcMode); context.registerReceiver(mIntentReceiver, mIntentFilter); Intent intent = getActivity().getIntent(); if (intent.getBooleanExtra(ImsPhone.EXTRA_KEY_ALERT_SHOW, false)) { showAlert(intent); } } @Override public void onPause() { super.onPause(); final Context context = getActivity(); if (mValidListener) { mValidListener = false; TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); tm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE); mSwitchBar.removeOnSwitchChangeListener(this); } context.unregisterReceiver(mIntentReceiver); } /** * Listens to the state change of the switch. */ @Override public void onSwitchChanged(Switch switchView, boolean isChecked) { final Context context = getActivity(); ImsManager.setWfcSetting(context, isChecked); int wfcMode = ImsManager.getWfcMode(context); updateButtonWfcMode(context, isChecked, wfcMode); if (isChecked) { MetricsLogger.action(getActivity(), getMetricsCategory(), wfcMode); } else { MetricsLogger.action(getActivity(), getMetricsCategory(), -1); } } private void updateButtonWfcMode(Context context, boolean wfcEnabled, int wfcMode) { mButtonWfcMode.setSummary(getWfcModeSummary(context, wfcMode)); mButtonWfcMode.setEnabled(wfcEnabled); final PreferenceScreen preferenceScreen = getPreferenceScreen(); if (wfcEnabled && isWfcModeSupported()) { preferenceScreen.addPreference(mButtonWfcMode); } else { preferenceScreen.removePreference(mButtonWfcMode); } preferenceScreen.setEnabled(mEditableWfcMode); } @Override public boolean onPreferenceChange(Preference preference, Object newValue) { final Context context = getActivity(); if (preference == mButtonWfcMode) { mButtonWfcMode.setValue((String) newValue); int buttonMode = Integer.valueOf((String) newValue); int currentMode = ImsManager.getWfcMode(context); if (buttonMode != currentMode) { ImsManager.setWfcMode(context, buttonMode); mButtonWfcMode.setSummary(getWfcModeSummary(context, buttonMode)); MetricsLogger.action(getActivity(), getMetricsCategory(), buttonMode); } } return true; } static int getWfcModeSummary(Context context, int wfcMode) { int resId = com.android.internal.R.string.wifi_calling_off_summary; if (ImsManager.isWfcEnabledByUser(context)) { switch (wfcMode) { case ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY: resId = com.android.internal.R.string.wfc_mode_wifi_only_summary; break; case ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED: resId = com.android.internal.R.string.wfc_mode_cellular_preferred_summary; break; case ImsConfig.WfcModeFeatureValueConstants.WIFI_PREFERRED: resId = com.android.internal.R.string.wfc_mode_wifi_preferred_summary; break; default: Log.e(TAG, "Unexpected WFC mode value: " + wfcMode); } } return resId; } private boolean isWfcModeSupported() { return getActivity().getResources().getBoolean( R.bool.config_wfc_mode_supported); } }