OSDN Git Service

Import translations. DO NOT MERGE
[android-x86/packages-apps-Settings.git] / src / com / android / settings / WifiCallingSettings.java
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.ComponentName;
23 import android.content.Context;
24 import android.content.Intent;
25 import android.content.IntentFilter;
26 import android.os.Bundle;
27 import android.os.PersistableBundle;
28 import android.support.v7.preference.ListPreference;
29 import android.support.v7.preference.Preference;
30 import android.support.v7.preference.Preference.OnPreferenceClickListener;
31 import android.support.v7.preference.PreferenceScreen;
32 import android.telephony.CarrierConfigManager;
33 import android.telephony.PhoneStateListener;
34 import android.telephony.TelephonyManager;
35 import android.text.TextUtils;
36 import android.util.Log;
37 import android.widget.Switch;
38 import android.widget.TextView;
39
40 import com.android.ims.ImsConfig;
41 import com.android.ims.ImsManager;
42 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
43 import com.android.internal.telephony.Phone;
44 import com.android.settings.widget.SwitchBar;
45
46 /**
47  * "Wi-Fi Calling settings" screen.  This preference screen lets you
48  * enable/disable Wi-Fi Calling and change Wi-Fi Calling mode.
49  */
50 public class WifiCallingSettings extends SettingsPreferenceFragment
51         implements SwitchBar.OnSwitchChangeListener,
52         Preference.OnPreferenceChangeListener {
53
54     private static final String TAG = "WifiCallingSettings";
55
56     //String keys for preference lookup
57     private static final String BUTTON_WFC_MODE = "wifi_calling_mode";
58     private static final String BUTTON_WFC_ROAMING_MODE = "wifi_calling_roaming_mode";
59     private static final String PREFERENCE_EMERGENCY_ADDRESS = "emergency_address_key";
60
61     private static final int REQUEST_CHECK_WFC_EMERGENCY_ADDRESS = 1;
62
63     public static final String EXTRA_LAUNCH_CARRIER_APP = "EXTRA_LAUNCH_CARRIER_APP";
64
65     public static final int LAUCH_APP_ACTIVATE = 0;
66     public static final int LAUCH_APP_UPDATE = 1;
67
68     //UI objects
69     private SwitchBar mSwitchBar;
70     private Switch mSwitch;
71     private ListPreference mButtonWfcMode;
72     private ListPreference mButtonWfcRoamingMode;
73     private Preference mUpdateAddress;
74     private TextView mEmptyView;
75
76     private boolean mValidListener = false;
77     private boolean mEditableWfcMode = true;
78     private boolean mEditableWfcRoamingMode = true;
79
80     private final PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
81         /*
82          * Enable/disable controls when in/out of a call and depending on
83          * TTY mode and TTY support over VoLTE.
84          * @see android.telephony.PhoneStateListener#onCallStateChanged(int,
85          * java.lang.String)
86          */
87         @Override
88         public void onCallStateChanged(int state, String incomingNumber) {
89             final SettingsActivity activity = (SettingsActivity) getActivity();
90             boolean isNonTtyOrTtyOnVolteEnabled = ImsManager
91                     .isNonTtyOrTtyOnVolteEnabled(activity);
92             final SwitchBar switchBar = activity.getSwitchBar();
93             boolean isWfcEnabled = switchBar.getSwitch().isChecked()
94                     && isNonTtyOrTtyOnVolteEnabled;
95
96             switchBar.setEnabled((state == TelephonyManager.CALL_STATE_IDLE)
97                     && isNonTtyOrTtyOnVolteEnabled);
98
99             boolean isWfcModeEditable = true;
100             boolean isWfcRoamingModeEditable = false;
101             final CarrierConfigManager configManager = (CarrierConfigManager)
102                     activity.getSystemService(Context.CARRIER_CONFIG_SERVICE);
103             if (configManager != null) {
104                 PersistableBundle b = configManager.getConfig();
105                 if (b != null) {
106                     isWfcModeEditable = b.getBoolean(
107                             CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL);
108                     isWfcRoamingModeEditable = b.getBoolean(
109                             CarrierConfigManager.KEY_EDITABLE_WFC_ROAMING_MODE_BOOL);
110                 }
111             }
112
113             Preference pref = getPreferenceScreen().findPreference(BUTTON_WFC_MODE);
114             if (pref != null) {
115                 pref.setEnabled(isWfcEnabled && isWfcModeEditable
116                         && (state == TelephonyManager.CALL_STATE_IDLE));
117             }
118             Preference pref_roam = getPreferenceScreen().findPreference(BUTTON_WFC_ROAMING_MODE);
119             if (pref_roam != null) {
120                 pref_roam.setEnabled(isWfcEnabled && isWfcRoamingModeEditable
121                         && (state == TelephonyManager.CALL_STATE_IDLE));
122             }
123         }
124     };
125
126     private final OnPreferenceClickListener mUpdateAddressListener =
127             new OnPreferenceClickListener() {
128                 /*
129                  * Launch carrier emergency address managemnent activity
130                  */
131                 @Override
132                 public boolean onPreferenceClick(Preference preference) {
133                     final Context context = getActivity();
134                     Intent carrierAppIntent = getCarrierActivityIntent(context);
135                     if (carrierAppIntent != null) {
136                         carrierAppIntent.putExtra(EXTRA_LAUNCH_CARRIER_APP, LAUCH_APP_UPDATE);
137                         startActivity(carrierAppIntent);
138                     }
139                     return true;
140                 }
141     };
142
143     @Override
144     public void onActivityCreated(Bundle savedInstanceState) {
145         super.onActivityCreated(savedInstanceState);
146
147         final SettingsActivity activity = (SettingsActivity) getActivity();
148
149         mSwitchBar = activity.getSwitchBar();
150         mSwitch = mSwitchBar.getSwitch();
151         mSwitchBar.show();
152
153         mEmptyView = (TextView) getView().findViewById(android.R.id.empty);
154         setEmptyView(mEmptyView);
155         String emptyViewText = activity.getString(R.string.wifi_calling_off_explanation)
156                 + activity.getString(R.string.wifi_calling_off_explanation_2);
157         mEmptyView.setText(emptyViewText);
158     }
159
160     @Override
161     public void onDestroyView() {
162         super.onDestroyView();
163         mSwitchBar.hide();
164     }
165
166     private void showAlert(Intent intent) {
167         Context context = getActivity();
168
169         CharSequence title = intent.getCharSequenceExtra(Phone.EXTRA_KEY_ALERT_TITLE);
170         CharSequence message = intent.getCharSequenceExtra(Phone.EXTRA_KEY_ALERT_MESSAGE);
171
172         AlertDialog.Builder builder = new AlertDialog.Builder(context);
173         builder.setMessage(message)
174                 .setTitle(title)
175                 .setIcon(android.R.drawable.ic_dialog_alert)
176                 .setPositiveButton(android.R.string.ok, null);
177         AlertDialog dialog = builder.create();
178         dialog.show();
179     }
180
181     private IntentFilter mIntentFilter;
182
183     private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
184         @Override
185         public void onReceive(Context context, Intent intent) {
186             String action = intent.getAction();
187             if (action.equals(ImsManager.ACTION_IMS_REGISTRATION_ERROR)) {
188                 // If this fragment is active then we are immediately
189                 // showing alert on screen. There is no need to add
190                 // notification in this case.
191                 //
192                 // In order to communicate to ImsPhone that it should
193                 // not show notification, we are changing result code here.
194                 setResultCode(Activity.RESULT_CANCELED);
195
196                 // UX requirement is to disable WFC in case of "permanent" registration failures.
197                 mSwitch.setChecked(false);
198
199                 showAlert(intent);
200             }
201         }
202     };
203
204     @Override
205     public int getMetricsCategory() {
206         return MetricsEvent.WIFI_CALLING;
207     }
208
209     @Override
210     public void onCreate(Bundle savedInstanceState) {
211         super.onCreate(savedInstanceState);
212
213         addPreferencesFromResource(R.xml.wifi_calling_settings);
214
215         mButtonWfcMode = (ListPreference) findPreference(BUTTON_WFC_MODE);
216         mButtonWfcMode.setOnPreferenceChangeListener(this);
217
218         mButtonWfcRoamingMode = (ListPreference) findPreference(BUTTON_WFC_ROAMING_MODE);
219         mButtonWfcRoamingMode.setOnPreferenceChangeListener(this);
220
221         mUpdateAddress = (Preference) findPreference(PREFERENCE_EMERGENCY_ADDRESS);
222         mUpdateAddress.setOnPreferenceClickListener(mUpdateAddressListener);
223
224         mIntentFilter = new IntentFilter();
225         mIntentFilter.addAction(ImsManager.ACTION_IMS_REGISTRATION_ERROR);
226
227         CarrierConfigManager configManager = (CarrierConfigManager)
228                 getSystemService(Context.CARRIER_CONFIG_SERVICE);
229         boolean isWifiOnlySupported = true;
230         if (configManager != null) {
231             PersistableBundle b = configManager.getConfig();
232             if (b != null) {
233                 mEditableWfcMode = b.getBoolean(CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL);
234                 mEditableWfcRoamingMode = b.getBoolean(
235                         CarrierConfigManager.KEY_EDITABLE_WFC_ROAMING_MODE_BOOL);
236                 isWifiOnlySupported = b.getBoolean(
237                         CarrierConfigManager.KEY_CARRIER_WFC_SUPPORTS_WIFI_ONLY_BOOL, true);
238             }
239         }
240
241         if (!isWifiOnlySupported) {
242             mButtonWfcMode.setEntries(R.array.wifi_calling_mode_choices_without_wifi_only);
243             mButtonWfcMode.setEntryValues(R.array.wifi_calling_mode_values_without_wifi_only);
244             mButtonWfcRoamingMode.setEntries(
245                     R.array.wifi_calling_mode_choices_v2_without_wifi_only);
246             mButtonWfcRoamingMode.setEntryValues(
247                     R.array.wifi_calling_mode_values_without_wifi_only);
248         }
249     }
250
251     @Override
252     public void onResume() {
253         super.onResume();
254
255         final Context context = getActivity();
256
257         // NOTE: Buttons will be enabled/disabled in mPhoneStateListener
258         boolean wfcEnabled = ImsManager.isWfcEnabledByUser(context)
259                 && ImsManager.isNonTtyOrTtyOnVolteEnabled(context);
260         mSwitch.setChecked(wfcEnabled);
261         int wfcMode = ImsManager.getWfcMode(context, false);
262         int wfcRoamingMode = ImsManager.getWfcMode(context, true);
263         mButtonWfcMode.setValue(Integer.toString(wfcMode));
264         mButtonWfcRoamingMode.setValue(Integer.toString(wfcRoamingMode));
265         updateButtonWfcMode(context, wfcEnabled, wfcMode, wfcRoamingMode);
266
267         if (ImsManager.isWfcEnabledByPlatform(context)) {
268             TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
269             tm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
270
271             mSwitchBar.addOnSwitchChangeListener(this);
272
273             mValidListener = true;
274         }
275
276         context.registerReceiver(mIntentReceiver, mIntentFilter);
277
278         Intent intent = getActivity().getIntent();
279         if (intent.getBooleanExtra(Phone.EXTRA_KEY_ALERT_SHOW, false)) {
280             showAlert(intent);
281         }
282     }
283
284     @Override
285     public void onPause() {
286         super.onPause();
287
288         final Context context = getActivity();
289
290         if (mValidListener) {
291             mValidListener = false;
292
293             TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
294             tm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
295
296             mSwitchBar.removeOnSwitchChangeListener(this);
297         }
298
299         context.unregisterReceiver(mIntentReceiver);
300     }
301
302     /**
303      * Listens to the state change of the switch.
304      */
305     @Override
306     public void onSwitchChanged(Switch switchView, boolean isChecked) {
307         final Context context = getActivity();
308         Log.d(TAG, "onSwitchChanged(" + isChecked + ")");
309
310         if (!isChecked) {
311             updateWfcMode(context, false);
312             return;
313         }
314
315         // Call address management activity before turning on WFC
316         Intent carrierAppIntent = getCarrierActivityIntent(context);
317         if (carrierAppIntent != null) {
318             carrierAppIntent.putExtra(EXTRA_LAUNCH_CARRIER_APP, LAUCH_APP_ACTIVATE);
319             startActivityForResult(carrierAppIntent, REQUEST_CHECK_WFC_EMERGENCY_ADDRESS);
320         } else {
321             updateWfcMode(context, true);
322         }
323     }
324
325     /*
326      * Get the Intent to launch carrier emergency address management activity.
327      * Return null when no activity found.
328      */
329     private static Intent getCarrierActivityIntent(Context context) {
330         // Retrive component name from carrirt config
331         CarrierConfigManager configManager = context.getSystemService(CarrierConfigManager.class);
332         if (configManager == null) return null;
333
334         PersistableBundle bundle = configManager.getConfig();
335         if (bundle == null) return null;
336
337         String carrierApp = bundle.getString(
338                 CarrierConfigManager.KEY_WFC_EMERGENCY_ADDRESS_CARRIER_APP_STRING);
339         if (TextUtils.isEmpty(carrierApp)) return null;
340
341         ComponentName componentName = ComponentName.unflattenFromString(carrierApp);
342         if (componentName == null) return null;
343
344         // Build and return intent
345         Intent intent = new Intent();
346         intent.setComponent(componentName);
347         return intent;
348     }
349
350     /*
351      * Turn on/off WFC mode with ImsManager and update UI accordingly
352      */
353     private void updateWfcMode(Context context, boolean wfcEnabled) {
354         Log.i(TAG, "updateWfcMode(" + wfcEnabled + ")");
355         ImsManager.setWfcSetting(context, wfcEnabled);
356
357         int wfcMode = ImsManager.getWfcMode(context, false);
358         int wfcRoamingMode = ImsManager.getWfcMode(context, true);
359         updateButtonWfcMode(context, wfcEnabled, wfcMode, wfcRoamingMode);
360         if (wfcEnabled) {
361             mMetricsFeatureProvider.action(getActivity(), getMetricsCategory(), wfcMode);
362         } else {
363             mMetricsFeatureProvider.action(getActivity(), getMetricsCategory(), -1);
364         }
365     }
366
367     @Override
368     public void onActivityResult(int requestCode, int resultCode, Intent data) {
369         super.onActivityResult(requestCode, resultCode, data);
370
371         final Context context = getActivity();
372
373         if (requestCode == REQUEST_CHECK_WFC_EMERGENCY_ADDRESS) {
374             Log.d(TAG, "WFC emergency address activity result = " + resultCode);
375
376             if (resultCode == Activity.RESULT_OK) {
377                 updateWfcMode(context, true);
378             }
379         }
380     }
381
382     private void updateButtonWfcMode(Context context, boolean wfcEnabled,
383                                      int wfcMode, int wfcRoamingMode) {
384         mButtonWfcMode.setSummary(getWfcModeSummary(context, wfcMode));
385         mButtonWfcMode.setEnabled(wfcEnabled && mEditableWfcMode);
386         // mButtonWfcRoamingMode.setSummary is not needed; summary is just selected value.
387         mButtonWfcRoamingMode.setEnabled(wfcEnabled && mEditableWfcRoamingMode);
388
389         final PreferenceScreen preferenceScreen = getPreferenceScreen();
390         boolean updateAddressEnabled = (getCarrierActivityIntent(context) != null);
391         if (wfcEnabled) {
392             if (mEditableWfcMode) {
393                 preferenceScreen.addPreference(mButtonWfcMode);
394             } else {
395                 // Don't show WFC (home) preference if it's not editable.
396                 preferenceScreen.removePreference(mButtonWfcMode);
397             }
398             if (mEditableWfcRoamingMode) {
399                 preferenceScreen.addPreference(mButtonWfcRoamingMode);
400             } else {
401                 // Don't show WFC roaming preference if it's not editable.
402                 preferenceScreen.removePreference(mButtonWfcRoamingMode);
403             }
404             if (updateAddressEnabled) {
405                 preferenceScreen.addPreference(mUpdateAddress);
406             } else {
407                 preferenceScreen.removePreference(mUpdateAddress);
408             }
409         } else {
410             preferenceScreen.removePreference(mButtonWfcMode);
411             preferenceScreen.removePreference(mButtonWfcRoamingMode);
412             preferenceScreen.removePreference(mUpdateAddress);
413         }
414     }
415
416     @Override
417     public boolean onPreferenceChange(Preference preference, Object newValue) {
418         final Context context = getActivity();
419         if (preference == mButtonWfcMode) {
420             mButtonWfcMode.setValue((String) newValue);
421             int buttonMode = Integer.valueOf((String) newValue);
422             int currentWfcMode = ImsManager.getWfcMode(context, false);
423             if (buttonMode != currentWfcMode) {
424                 ImsManager.setWfcMode(context, buttonMode, false);
425                 mButtonWfcMode.setSummary(getWfcModeSummary(context, buttonMode));
426                 mMetricsFeatureProvider.action(getActivity(), getMetricsCategory(), buttonMode);
427             }
428             if (!mEditableWfcRoamingMode) {
429                 int currentWfcRoamingMode = ImsManager.getWfcMode(context, true);
430                 if (buttonMode != currentWfcRoamingMode) {
431                     ImsManager.setWfcMode(context, buttonMode, true);
432                     // mButtonWfcRoamingMode.setSummary is not needed; summary is selected value
433                 }
434             }
435         } else if (preference == mButtonWfcRoamingMode) {
436             mButtonWfcRoamingMode.setValue((String) newValue);
437             int buttonMode = Integer.valueOf((String) newValue);
438             int currentMode = ImsManager.getWfcMode(context, true);
439             if (buttonMode != currentMode) {
440                 ImsManager.setWfcMode(context, buttonMode, true);
441                 // mButtonWfcRoamingMode.setSummary is not needed; summary is just selected value.
442                 mMetricsFeatureProvider.action(getActivity(), getMetricsCategory(), buttonMode);
443             }
444         }
445         return true;
446     }
447
448     public static int getWfcModeSummary(Context context, int wfcMode) {
449         int resId = com.android.internal.R.string.wifi_calling_off_summary;
450         if (ImsManager.isWfcEnabledByUser(context)) {
451             switch (wfcMode) {
452                 case ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY:
453                     resId = com.android.internal.R.string.wfc_mode_wifi_only_summary;
454                     break;
455                 case ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED:
456                     resId = com.android.internal.R.string.wfc_mode_cellular_preferred_summary;
457                     break;
458                 case ImsConfig.WfcModeFeatureValueConstants.WIFI_PREFERRED:
459                     resId = com.android.internal.R.string.wfc_mode_wifi_preferred_summary;
460                     break;
461                 default:
462                     Log.e(TAG, "Unexpected WFC mode value: " + wfcMode);
463             }
464         }
465         return resId;
466     }
467 }