• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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