1 /* 2 * Copyright (C) 2017 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.wifi.calling; 18 19 import android.app.Activity; 20 import android.app.settings.SettingsEnums; 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.content.res.Resources; 27 import android.os.Bundle; 28 import android.os.PersistableBundle; 29 import android.telephony.CarrierConfigManager; 30 import android.telephony.PhoneStateListener; 31 import android.telephony.SubscriptionManager; 32 import android.telephony.TelephonyCallback; 33 import android.telephony.TelephonyManager; 34 import android.telephony.ims.ImsManager; 35 import android.telephony.ims.ImsMmTelManager; 36 import android.telephony.ims.ProvisioningManager; 37 import android.text.TextUtils; 38 import android.util.Log; 39 import android.view.LayoutInflater; 40 import android.view.View; 41 import android.view.ViewGroup; 42 import android.widget.Switch; 43 import android.widget.TextView; 44 45 import androidx.appcompat.app.AlertDialog; 46 import androidx.preference.Preference; 47 import androidx.preference.Preference.OnPreferenceClickListener; 48 import androidx.preference.PreferenceScreen; 49 50 import com.android.ims.ImsConfig; 51 import com.android.internal.annotations.VisibleForTesting; 52 import com.android.internal.telephony.Phone; 53 import com.android.settings.R; 54 import com.android.settings.SettingsActivity; 55 import com.android.settings.SettingsPreferenceFragment; 56 import com.android.settings.Utils; 57 import com.android.settings.core.SubSettingLauncher; 58 import com.android.settings.network.ims.WifiCallingQueryImsState; 59 import com.android.settings.widget.SettingsMainSwitchBar; 60 import com.android.settingslib.widget.OnMainSwitchChangeListener; 61 62 /** 63 * This is the inner class of {@link WifiCallingSettings} fragment. 64 * The preference screen lets you enable/disable Wi-Fi Calling and change Wi-Fi Calling mode. 65 */ 66 public class WifiCallingSettingsForSub extends SettingsPreferenceFragment 67 implements OnMainSwitchChangeListener, 68 Preference.OnPreferenceChangeListener { 69 private static final String TAG = "WifiCallingForSub"; 70 71 //String keys for preference lookup 72 private static final String BUTTON_WFC_MODE = "wifi_calling_mode"; 73 private static final String BUTTON_WFC_ROAMING_MODE = "wifi_calling_roaming_mode"; 74 private static final String PREFERENCE_EMERGENCY_ADDRESS = "emergency_address_key"; 75 76 @VisibleForTesting 77 static final int REQUEST_CHECK_WFC_EMERGENCY_ADDRESS = 1; 78 @VisibleForTesting 79 static final int REQUEST_CHECK_WFC_DISCLAIMER = 2; 80 81 public static final String EXTRA_LAUNCH_CARRIER_APP = "EXTRA_LAUNCH_CARRIER_APP"; 82 public static final String EXTRA_SUB_ID = "EXTRA_SUB_ID"; 83 84 protected static final String FRAGMENT_BUNDLE_SUBID = "subId"; 85 86 public static final int LAUCH_APP_ACTIVATE = 0; 87 public static final int LAUCH_APP_UPDATE = 1; 88 89 //UI objects 90 private SettingsMainSwitchBar mSwitchBar; 91 private ListWithEntrySummaryPreference mButtonWfcMode; 92 private ListWithEntrySummaryPreference mButtonWfcRoamingMode; 93 private Preference mUpdateAddress; 94 private TextView mEmptyView; 95 96 private boolean mValidListener = false; 97 private boolean mEditableWfcMode = true; 98 private boolean mEditableWfcRoamingMode = true; 99 private boolean mUseWfcHomeModeForRoaming = false; 100 101 private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; 102 private ImsMmTelManager mImsMmTelManager; 103 private ProvisioningManager mProvisioningManager; 104 private TelephonyManager mTelephonyManager; 105 106 private final PhoneTelephonyCallback mTelephonyCallback = new PhoneTelephonyCallback(); 107 108 private class PhoneTelephonyCallback extends TelephonyCallback implements 109 TelephonyCallback.CallStateListener { 110 /* 111 * Enable/disable controls when in/out of a call and depending on 112 * TTY mode and TTY support over VoLTE. 113 * @see android.telephony.PhoneStateListener#onCallStateChanged(int, 114 * java.lang.String) 115 */ 116 @Override onCallStateChanged(int state)117 public void onCallStateChanged(int state) { 118 final SettingsActivity activity = (SettingsActivity) getActivity(); 119 final boolean isNonTtyOrTtyOnVolteEnabled = 120 queryImsState(WifiCallingSettingsForSub.this.mSubId).isAllowUserControl(); 121 final boolean isWfcEnabled = mSwitchBar.isChecked() 122 && isNonTtyOrTtyOnVolteEnabled; 123 boolean isCallStateIdle = getTelephonyManagerForSub( 124 WifiCallingSettingsForSub.this.mSubId).getCallState() 125 == TelephonyManager.CALL_STATE_IDLE; 126 mSwitchBar.setEnabled(isCallStateIdle 127 && isNonTtyOrTtyOnVolteEnabled); 128 129 boolean isWfcModeEditable = true; 130 boolean isWfcRoamingModeEditable = false; 131 final CarrierConfigManager configManager = (CarrierConfigManager) 132 activity.getSystemService(Context.CARRIER_CONFIG_SERVICE); 133 if (configManager != null) { 134 PersistableBundle b = 135 configManager.getConfigForSubId(WifiCallingSettingsForSub.this.mSubId); 136 if (b != null) { 137 isWfcModeEditable = b.getBoolean( 138 CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL); 139 isWfcRoamingModeEditable = b.getBoolean( 140 CarrierConfigManager.KEY_EDITABLE_WFC_ROAMING_MODE_BOOL); 141 } 142 } 143 144 final Preference pref = getPreferenceScreen().findPreference(BUTTON_WFC_MODE); 145 if (pref != null) { 146 pref.setEnabled(isWfcEnabled && isWfcModeEditable 147 && isCallStateIdle); 148 } 149 final Preference pref_roam = 150 getPreferenceScreen().findPreference(BUTTON_WFC_ROAMING_MODE); 151 if (pref_roam != null) { 152 pref_roam.setEnabled(isWfcEnabled && isWfcRoamingModeEditable 153 && isCallStateIdle); 154 } 155 } 156 } 157 158 /* 159 * Launch carrier emergency address managemnent activity 160 */ 161 private final OnPreferenceClickListener mUpdateAddressListener = 162 preference -> { 163 final Intent carrierAppIntent = getCarrierActivityIntent(); 164 if (carrierAppIntent != null) { 165 carrierAppIntent.putExtra(EXTRA_LAUNCH_CARRIER_APP, LAUCH_APP_UPDATE); 166 startActivity(carrierAppIntent); 167 } 168 return true; 169 }; 170 171 private final ProvisioningManager.Callback mProvisioningCallback = 172 new ProvisioningManager.Callback() { 173 @Override 174 public void onProvisioningIntChanged(int item, int value) { 175 if (item == ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED 176 || item == ImsConfig.ConfigConstants.VLT_SETTING_ENABLED) { 177 // The provisioning policy might have changed. Update the body to make sure 178 // this change takes effect if needed. 179 updateBody(); 180 } 181 } 182 }; 183 184 @Override onActivityCreated(Bundle savedInstanceState)185 public void onActivityCreated(Bundle savedInstanceState) { 186 super.onActivityCreated(savedInstanceState); 187 188 mEmptyView = getView().findViewById(android.R.id.empty); 189 setEmptyView(mEmptyView); 190 final Resources res = getResourcesForSubId(); 191 final String emptyViewText = res.getString(R.string.wifi_calling_off_explanation, 192 res.getString(R.string.wifi_calling_off_explanation_2)); 193 mEmptyView.setText(emptyViewText); 194 195 mSwitchBar = getView().findViewById(R.id.switch_bar); 196 mSwitchBar.show(); 197 } 198 199 @Override onDestroyView()200 public void onDestroyView() { 201 super.onDestroyView(); 202 mSwitchBar.hide(); 203 } 204 205 @VisibleForTesting showAlert(Intent intent)206 void showAlert(Intent intent) { 207 final Context context = getActivity(); 208 209 final CharSequence title = intent.getCharSequenceExtra(Phone.EXTRA_KEY_ALERT_TITLE); 210 final CharSequence message = intent.getCharSequenceExtra(Phone.EXTRA_KEY_ALERT_MESSAGE); 211 212 final AlertDialog.Builder builder = new AlertDialog.Builder(context); 213 builder.setMessage(message) 214 .setTitle(title) 215 .setIcon(android.R.drawable.ic_dialog_alert) 216 .setPositiveButton(android.R.string.ok, null); 217 final AlertDialog dialog = builder.create(); 218 dialog.show(); 219 } 220 221 private IntentFilter mIntentFilter; 222 223 private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { 224 @Override 225 public void onReceive(Context context, Intent intent) { 226 final String action = intent.getAction(); 227 if (action.equals(ImsManager.ACTION_WFC_IMS_REGISTRATION_ERROR)) { 228 // If this fragment is active then we are immediately 229 // showing alert on screen. There is no need to add 230 // notification in this case. 231 // 232 // In order to communicate to ImsPhone that it should 233 // not show notification, we are changing result code here. 234 setResultCode(Activity.RESULT_CANCELED); 235 236 showAlert(intent); 237 } 238 } 239 }; 240 241 @Override getMetricsCategory()242 public int getMetricsCategory() { 243 return SettingsEnums.WIFI_CALLING_FOR_SUB; 244 } 245 246 @Override getHelpResource()247 public int getHelpResource() { 248 // Return 0 to suppress help icon. The help will be populated by parent page. 249 return 0; 250 } 251 252 @VisibleForTesting getTelephonyManagerForSub(int subId)253 TelephonyManager getTelephonyManagerForSub(int subId) { 254 if (mTelephonyManager == null) { 255 mTelephonyManager = getContext().getSystemService(TelephonyManager.class); 256 } 257 return mTelephonyManager.createForSubscriptionId(subId); 258 } 259 260 @VisibleForTesting queryImsState(int subId)261 WifiCallingQueryImsState queryImsState(int subId) { 262 return new WifiCallingQueryImsState(getContext(), subId); 263 } 264 265 @VisibleForTesting getImsProvisioningManager()266 ProvisioningManager getImsProvisioningManager() { 267 if (!SubscriptionManager.isValidSubscriptionId(mSubId)) { 268 return null; 269 } 270 return ProvisioningManager.createForSubscriptionId(mSubId); 271 } 272 273 @VisibleForTesting getImsMmTelManager()274 ImsMmTelManager getImsMmTelManager() { 275 if (!SubscriptionManager.isValidSubscriptionId(mSubId)) { 276 return null; 277 } 278 return ImsMmTelManager.createForSubscriptionId(mSubId); 279 } 280 281 @Override onCreate(Bundle savedInstanceState)282 public void onCreate(Bundle savedInstanceState) { 283 super.onCreate(savedInstanceState); 284 285 addPreferencesFromResource(R.xml.wifi_calling_settings); 286 287 // SubId should always be specified when creating this fragment. Either through 288 // fragment.setArguments() or through savedInstanceState. 289 if (getArguments() != null && getArguments().containsKey(FRAGMENT_BUNDLE_SUBID)) { 290 mSubId = getArguments().getInt(FRAGMENT_BUNDLE_SUBID); 291 } else if (savedInstanceState != null) { 292 mSubId = savedInstanceState.getInt( 293 FRAGMENT_BUNDLE_SUBID, SubscriptionManager.INVALID_SUBSCRIPTION_ID); 294 } 295 296 mProvisioningManager = getImsProvisioningManager(); 297 mImsMmTelManager = getImsMmTelManager(); 298 299 mButtonWfcMode = findPreference(BUTTON_WFC_MODE); 300 mButtonWfcMode.setOnPreferenceChangeListener(this); 301 302 mButtonWfcRoamingMode = findPreference(BUTTON_WFC_ROAMING_MODE); 303 mButtonWfcRoamingMode.setOnPreferenceChangeListener(this); 304 305 mUpdateAddress = findPreference(PREFERENCE_EMERGENCY_ADDRESS); 306 mUpdateAddress.setOnPreferenceClickListener(mUpdateAddressListener); 307 308 mIntentFilter = new IntentFilter(); 309 mIntentFilter.addAction(ImsManager.ACTION_WFC_IMS_REGISTRATION_ERROR); 310 } 311 312 @Override onSaveInstanceState(Bundle outState)313 public void onSaveInstanceState(Bundle outState) { 314 outState.putInt(FRAGMENT_BUNDLE_SUBID, mSubId); 315 super.onSaveInstanceState(outState); 316 } 317 318 @Override onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)319 public View onCreateView(LayoutInflater inflater, ViewGroup container, 320 Bundle savedInstanceState) { 321 322 final View view = inflater.inflate( 323 R.layout.wifi_calling_settings_preferences, container, false); 324 325 final ViewGroup prefs_container = view.findViewById(R.id.prefs_container); 326 Utils.prepareCustomPreferencesList(container, view, prefs_container, false); 327 final View prefs = super.onCreateView(inflater, prefs_container, savedInstanceState); 328 prefs_container.addView(prefs); 329 330 return view; 331 } 332 333 @VisibleForTesting isWfcProvisionedOnDevice()334 boolean isWfcProvisionedOnDevice() { 335 return queryImsState(mSubId).isWifiCallingProvisioned(); 336 } 337 updateBody()338 private void updateBody() { 339 if (!isWfcProvisionedOnDevice()) { 340 // This screen is not allowed to be shown due to provisioning policy and should 341 // therefore be closed. 342 finish(); 343 return; 344 } 345 346 final CarrierConfigManager configManager = (CarrierConfigManager) 347 getSystemService(Context.CARRIER_CONFIG_SERVICE); 348 boolean isWifiOnlySupported = true; 349 350 if (configManager != null) { 351 final PersistableBundle b = configManager.getConfigForSubId(mSubId); 352 if (b != null) { 353 mEditableWfcMode = b.getBoolean( 354 CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL); 355 mEditableWfcRoamingMode = b.getBoolean( 356 CarrierConfigManager.KEY_EDITABLE_WFC_ROAMING_MODE_BOOL); 357 mUseWfcHomeModeForRoaming = b.getBoolean( 358 CarrierConfigManager.KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL, 359 false); 360 isWifiOnlySupported = b.getBoolean( 361 CarrierConfigManager.KEY_CARRIER_WFC_SUPPORTS_WIFI_ONLY_BOOL, true); 362 } 363 } 364 365 final Resources res = getResourcesForSubId(); 366 mButtonWfcMode.setTitle(res.getString(R.string.wifi_calling_mode_title)); 367 mButtonWfcMode.setDialogTitle(res.getString(R.string.wifi_calling_mode_dialog_title)); 368 mButtonWfcRoamingMode.setTitle(res.getString(R.string.wifi_calling_roaming_mode_title)); 369 mButtonWfcRoamingMode.setDialogTitle( 370 res.getString(R.string.wifi_calling_roaming_mode_dialog_title)); 371 372 if (isWifiOnlySupported) { 373 // Set string resources WITH option wifi only in mButtonWfcMode. 374 mButtonWfcMode.setEntries( 375 res.getStringArray(R.array.wifi_calling_mode_choices)); 376 mButtonWfcMode.setEntryValues(res.getStringArray(R.array.wifi_calling_mode_values)); 377 mButtonWfcMode.setEntrySummaries( 378 res.getStringArray(R.array.wifi_calling_mode_summaries)); 379 380 // Set string resources WITH option wifi only in mButtonWfcRoamingMode. 381 mButtonWfcRoamingMode.setEntries( 382 res.getStringArray(R.array.wifi_calling_mode_choices_v2)); 383 mButtonWfcRoamingMode.setEntryValues( 384 res.getStringArray(R.array.wifi_calling_mode_values)); 385 mButtonWfcRoamingMode.setEntrySummaries( 386 res.getStringArray(R.array.wifi_calling_mode_summaries)); 387 } else { 388 // Set string resources WITHOUT option wifi only in mButtonWfcMode. 389 mButtonWfcMode.setEntries( 390 res.getStringArray(R.array.wifi_calling_mode_choices_without_wifi_only)); 391 mButtonWfcMode.setEntryValues( 392 res.getStringArray(R.array.wifi_calling_mode_values_without_wifi_only)); 393 mButtonWfcMode.setEntrySummaries( 394 res.getStringArray(R.array.wifi_calling_mode_summaries_without_wifi_only)); 395 396 // Set string resources WITHOUT option wifi only in mButtonWfcRoamingMode. 397 mButtonWfcRoamingMode.setEntries( 398 res.getStringArray(R.array.wifi_calling_mode_choices_v2_without_wifi_only)); 399 mButtonWfcRoamingMode.setEntryValues( 400 res.getStringArray(R.array.wifi_calling_mode_values_without_wifi_only)); 401 mButtonWfcRoamingMode.setEntrySummaries( 402 res.getStringArray(R.array.wifi_calling_mode_summaries_without_wifi_only)); 403 } 404 405 // NOTE: Buttons will be enabled/disabled in mTelephonyCallback 406 final WifiCallingQueryImsState queryIms = queryImsState(mSubId); 407 final boolean wfcEnabled = queryIms.isEnabledByUser() 408 && queryIms.isAllowUserControl(); 409 mSwitchBar.setChecked(wfcEnabled); 410 final int wfcMode = mImsMmTelManager.getVoWiFiModeSetting(); 411 final int wfcRoamingMode = mImsMmTelManager.getVoWiFiRoamingModeSetting(); 412 mButtonWfcMode.setValue(Integer.toString(wfcMode)); 413 mButtonWfcRoamingMode.setValue(Integer.toString(wfcRoamingMode)); 414 updateButtonWfcMode(wfcEnabled, wfcMode, wfcRoamingMode); 415 } 416 417 @Override onResume()418 public void onResume() { 419 super.onResume(); 420 421 updateBody(); 422 423 final Context context = getActivity(); 424 if (queryImsState(mSubId).isWifiCallingSupported()) { 425 getTelephonyManagerForSub(mSubId).registerTelephonyCallback( 426 context.getMainExecutor(), mTelephonyCallback); 427 428 mSwitchBar.addOnSwitchChangeListener(this); 429 430 mValidListener = true; 431 } 432 433 context.registerReceiver(mIntentReceiver, mIntentFilter); 434 435 final Intent intent = getActivity().getIntent(); 436 if (intent.getBooleanExtra(Phone.EXTRA_KEY_ALERT_SHOW, false)) { 437 showAlert(intent); 438 } 439 440 // Register callback for provisioning changes. 441 registerProvisioningChangedCallback(); 442 } 443 444 @Override onPause()445 public void onPause() { 446 super.onPause(); 447 448 final Context context = getActivity(); 449 450 if (mValidListener) { 451 mValidListener = false; 452 453 getTelephonyManagerForSub(mSubId).unregisterTelephonyCallback(mTelephonyCallback); 454 455 mSwitchBar.removeOnSwitchChangeListener(this); 456 } 457 458 context.unregisterReceiver(mIntentReceiver); 459 460 // Remove callback for provisioning changes. 461 unregisterProvisioningChangedCallback(); 462 } 463 464 /** 465 * Listens to the state change of the switch. 466 */ 467 @Override onSwitchChanged(Switch switchView, boolean isChecked)468 public void onSwitchChanged(Switch switchView, boolean isChecked) { 469 Log.d(TAG, "onSwitchChanged(" + isChecked + ")"); 470 471 if (!isChecked) { 472 updateWfcMode(false); 473 return; 474 } 475 476 // Launch disclaimer fragment before turning on WFC 477 final Context context = getActivity(); 478 final Bundle args = new Bundle(); 479 args.putInt(EXTRA_SUB_ID, mSubId); 480 new SubSettingLauncher(context) 481 .setDestination(WifiCallingDisclaimerFragment.class.getName()) 482 .setArguments(args) 483 .setTitleRes(R.string.wifi_calling_settings_title) 484 .setSourceMetricsCategory(getMetricsCategory()) 485 .setResultListener(this, REQUEST_CHECK_WFC_DISCLAIMER) 486 .launch(); 487 } 488 489 /* 490 * Get the Intent to launch carrier emergency address management activity. 491 * Return null when no activity found. 492 */ getCarrierActivityIntent()493 private Intent getCarrierActivityIntent() { 494 // Retrive component name from carrier config 495 final CarrierConfigManager configManager = 496 getActivity().getSystemService(CarrierConfigManager.class); 497 if (configManager == null) return null; 498 499 final PersistableBundle bundle = configManager.getConfigForSubId(mSubId); 500 if (bundle == null) return null; 501 502 final String carrierApp = bundle.getString( 503 CarrierConfigManager.KEY_WFC_EMERGENCY_ADDRESS_CARRIER_APP_STRING); 504 if (TextUtils.isEmpty(carrierApp)) return null; 505 506 final ComponentName componentName = ComponentName.unflattenFromString(carrierApp); 507 if (componentName == null) return null; 508 509 // Build and return intent 510 final Intent intent = new Intent(); 511 intent.setComponent(componentName); 512 intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, mSubId); 513 return intent; 514 } 515 516 /* 517 * Turn on/off WFC mode with ImsManager and update UI accordingly 518 */ updateWfcMode(boolean wfcEnabled)519 private void updateWfcMode(boolean wfcEnabled) { 520 Log.i(TAG, "updateWfcMode(" + wfcEnabled + ")"); 521 mImsMmTelManager.setVoWiFiSettingEnabled(wfcEnabled); 522 523 final int wfcMode = mImsMmTelManager.getVoWiFiModeSetting(); 524 final int wfcRoamingMode = mImsMmTelManager.getVoWiFiRoamingModeSetting(); 525 updateButtonWfcMode(wfcEnabled, wfcMode, wfcRoamingMode); 526 if (wfcEnabled) { 527 mMetricsFeatureProvider.action(getActivity(), getMetricsCategory(), wfcMode); 528 } else { 529 mMetricsFeatureProvider.action(getActivity(), getMetricsCategory(), -1); 530 } 531 } 532 533 @Override onActivityResult(int requestCode, int resultCode, Intent data)534 public void onActivityResult(int requestCode, int resultCode, Intent data) { 535 super.onActivityResult(requestCode, resultCode, data); 536 537 Log.d(TAG, "WFC activity request = " + requestCode + " result = " + resultCode); 538 539 switch (requestCode) { 540 case REQUEST_CHECK_WFC_EMERGENCY_ADDRESS: 541 if (resultCode == Activity.RESULT_OK) { 542 updateWfcMode(true); 543 } 544 break; 545 case REQUEST_CHECK_WFC_DISCLAIMER: 546 if (resultCode == Activity.RESULT_OK) { 547 // Call address management activity before turning on WFC 548 final Intent carrierAppIntent = getCarrierActivityIntent(); 549 if (carrierAppIntent != null) { 550 carrierAppIntent.putExtra(EXTRA_LAUNCH_CARRIER_APP, LAUCH_APP_ACTIVATE); 551 startActivityForResult(carrierAppIntent, 552 REQUEST_CHECK_WFC_EMERGENCY_ADDRESS); 553 } else { 554 updateWfcMode(true); 555 } 556 } 557 break; 558 default: 559 Log.e(TAG, "Unexpected request: " + requestCode); 560 break; 561 } 562 } 563 updateButtonWfcMode(boolean wfcEnabled, int wfcMode, int wfcRoamingMode)564 private void updateButtonWfcMode(boolean wfcEnabled, 565 int wfcMode, int wfcRoamingMode) { 566 mButtonWfcMode.setSummary(getWfcModeSummary(wfcMode)); 567 mButtonWfcMode.setEnabled(wfcEnabled && mEditableWfcMode); 568 // mButtonWfcRoamingMode.setSummary is not needed; summary is just selected value. 569 mButtonWfcRoamingMode.setEnabled(wfcEnabled && mEditableWfcRoamingMode); 570 571 final PreferenceScreen preferenceScreen = getPreferenceScreen(); 572 final boolean updateAddressEnabled = (getCarrierActivityIntent() != null); 573 if (wfcEnabled) { 574 if (mEditableWfcMode) { 575 preferenceScreen.addPreference(mButtonWfcMode); 576 } else { 577 // Don't show WFC (home) preference if it's not editable. 578 preferenceScreen.removePreference(mButtonWfcMode); 579 } 580 if (mEditableWfcRoamingMode && !mUseWfcHomeModeForRoaming) { 581 preferenceScreen.addPreference(mButtonWfcRoamingMode); 582 } else { 583 // Don't show WFC roaming preference if it's not editable. 584 preferenceScreen.removePreference(mButtonWfcRoamingMode); 585 } 586 if (updateAddressEnabled) { 587 preferenceScreen.addPreference(mUpdateAddress); 588 } else { 589 preferenceScreen.removePreference(mUpdateAddress); 590 } 591 } else { 592 preferenceScreen.removePreference(mButtonWfcMode); 593 preferenceScreen.removePreference(mButtonWfcRoamingMode); 594 preferenceScreen.removePreference(mUpdateAddress); 595 } 596 } 597 598 @Override onPreferenceChange(Preference preference, Object newValue)599 public boolean onPreferenceChange(Preference preference, Object newValue) { 600 if (preference == mButtonWfcMode) { 601 Log.d(TAG, "onPreferenceChange mButtonWfcMode " + newValue); 602 mButtonWfcMode.setValue((String) newValue); 603 final int buttonMode = Integer.valueOf((String) newValue); 604 final int currentWfcMode = mImsMmTelManager.getVoWiFiModeSetting(); 605 if (buttonMode != currentWfcMode) { 606 mImsMmTelManager.setVoWiFiModeSetting(buttonMode); 607 mButtonWfcMode.setSummary(getWfcModeSummary(buttonMode)); 608 mMetricsFeatureProvider.action(getActivity(), getMetricsCategory(), buttonMode); 609 610 if (mUseWfcHomeModeForRoaming) { 611 mImsMmTelManager.setVoWiFiRoamingModeSetting(buttonMode); 612 // mButtonWfcRoamingMode.setSummary is not needed; summary is selected value 613 } 614 } 615 } else if (preference == mButtonWfcRoamingMode) { 616 mButtonWfcRoamingMode.setValue((String) newValue); 617 final int buttonMode = Integer.valueOf((String) newValue); 618 final int currentMode = mImsMmTelManager.getVoWiFiRoamingModeSetting(); 619 if (buttonMode != currentMode) { 620 mImsMmTelManager.setVoWiFiRoamingModeSetting(buttonMode); 621 // mButtonWfcRoamingMode.setSummary is not needed; summary is just selected value. 622 mMetricsFeatureProvider.action(getActivity(), getMetricsCategory(), buttonMode); 623 } 624 } 625 return true; 626 } 627 getWfcModeSummary(int wfcMode)628 private CharSequence getWfcModeSummary(int wfcMode) { 629 int resId = com.android.internal.R.string.wifi_calling_off_summary; 630 if (queryImsState(mSubId).isEnabledByUser()) { 631 switch (wfcMode) { 632 case ImsMmTelManager.WIFI_MODE_WIFI_ONLY: 633 resId = com.android.internal.R.string.wfc_mode_wifi_only_summary; 634 break; 635 case ImsMmTelManager.WIFI_MODE_CELLULAR_PREFERRED: 636 resId = com.android.internal.R.string.wfc_mode_cellular_preferred_summary; 637 break; 638 case ImsMmTelManager.WIFI_MODE_WIFI_PREFERRED: 639 resId = com.android.internal.R.string.wfc_mode_wifi_preferred_summary; 640 break; 641 default: 642 Log.e(TAG, "Unexpected WFC mode value: " + wfcMode); 643 } 644 } 645 return getResourcesForSubId().getString(resId); 646 } 647 648 @VisibleForTesting getResourcesForSubId()649 Resources getResourcesForSubId() { 650 return SubscriptionManager.getResourcesForSubId(getContext(), mSubId); 651 } 652 653 @VisibleForTesting registerProvisioningChangedCallback()654 void registerProvisioningChangedCallback() { 655 if (mProvisioningManager == null) { 656 return; 657 } 658 try { 659 mProvisioningManager.registerProvisioningChangedCallback(getContext().getMainExecutor(), 660 mProvisioningCallback); 661 } catch (Exception ex) { 662 Log.w(TAG, "onResume: Unable to register callback for provisioning changes."); 663 } 664 } 665 666 @VisibleForTesting unregisterProvisioningChangedCallback()667 void unregisterProvisioningChangedCallback() { 668 if (mProvisioningManager == null) { 669 return; 670 } 671 mProvisioningManager.unregisterProvisioningChangedCallback(mProvisioningCallback); 672 } 673 } 674