Loading res/layout/wifi_calling_settings_preferences.xml 0 → 100644 +45 −0 Original line number Original line Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2014 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. --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/tabs_container" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <com.android.settings.widget.SwitchBar android:id="@+id/switch_bar" android:layout_height="?android:attr/actionBarSize" android:layout_width="match_parent" android:background="@drawable/switchbar_background" android:theme="?attr/switchBarTheme" /> <FrameLayout android:id="@android:id/tabcontent" android:layout_width="0dip" android:layout_height="0dip" /> <FrameLayout android:id="@+id/prefs_container" android:layout_width="match_parent" android:layout_height="0dip" android:layout_weight="1" android:clipChildren="false" android:clipToPadding="false" android:smoothScrollbar="false" /> </LinearLayout> res/layout/wifi_calling_settings_tabs.xml 0 → 100644 +36 −0 Original line number Original line Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2017 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. --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/tabs_container" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <com.android.settings.widget.SlidingTabLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/sliding_tabs" android:layout_width="match_parent" android:layout_height="wrap_content" android:scrollbars="none" android:fillViewport="true"/> <com.android.settings.widget.RtlCompatibleViewPager android:id="@+id/view_pager" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout> src/com/android/settings/WifiCallingSettings.java +87 −382 Original line number Original line Diff line number Diff line Loading @@ -16,190 +16,38 @@ package com.android.settings; package com.android.settings; import android.app.Activity; import android.app.Fragment; import android.app.AlertDialog; import android.app.FragmentManager; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.os.Bundle; import android.os.PersistableBundle; import android.support.v13.app.FragmentPagerAdapter; import android.support.v7.preference.ListPreference; import android.telephony.SubscriptionInfo; import android.support.v7.preference.Preference; import android.telephony.SubscriptionManager; import android.support.v7.preference.Preference.OnPreferenceClickListener; import android.support.v7.preference.PreferenceScreen; import android.telephony.CarrierConfigManager; import android.telephony.PhoneStateListener; import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.Log; import android.util.Log; import android.widget.Switch; import android.view.LayoutInflater; import android.widget.TextView; import android.view.View; import android.view.ViewGroup; import com.android.ims.ImsConfig; import com.android.ims.ImsConfig; import com.android.ims.ImsManager; import com.android.ims.ImsManager; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.telephony.Phone; import com.android.settings.widget.RtlCompatibleViewPager; import com.android.settings.widget.SwitchBar; import com.android.settings.widget.SlidingTabLayout; import java.util.List; /** /** * "Wi-Fi Calling settings" screen. This preference screen lets you * "Wi-Fi Calling settings" screen. This is the container fragment which holds * enable/disable Wi-Fi Calling and change Wi-Fi Calling mode. * {@link WifiCallingSettingsForSub} fragments. */ */ public class WifiCallingSettings extends SettingsPreferenceFragment public class WifiCallingSettings extends SettingsPreferenceFragment { implements SwitchBar.OnSwitchChangeListener, Preference.OnPreferenceChangeListener { private static final String TAG = "WifiCallingSettings"; private static final String TAG = "WifiCallingSettings"; private List<SubscriptionInfo> mSil; //String keys for preference lookup private static final String BUTTON_WFC_MODE = "wifi_calling_mode"; private static final String BUTTON_WFC_ROAMING_MODE = "wifi_calling_roaming_mode"; private static final String PREFERENCE_EMERGENCY_ADDRESS = "emergency_address_key"; private static final int REQUEST_CHECK_WFC_EMERGENCY_ADDRESS = 1; public static final String EXTRA_LAUNCH_CARRIER_APP = "EXTRA_LAUNCH_CARRIER_APP"; public static final int LAUCH_APP_ACTIVATE = 0; public static final int LAUCH_APP_UPDATE = 1; //UI objects //UI objects private SwitchBar mSwitchBar; private RtlCompatibleViewPager mViewPager; private Switch mSwitch; private WifiCallingViewPagerAdapter mPagerAdapter; private ListPreference mButtonWfcMode; private SlidingTabLayout mTabLayout; private ListPreference mButtonWfcRoamingMode; private Preference mUpdateAddress; private TextView mEmptyView; private boolean mValidListener = false; private boolean mEditableWfcMode = true; private boolean mEditableWfcRoamingMode = 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); boolean isWfcModeEditable = true; boolean isWfcRoamingModeEditable = false; final CarrierConfigManager configManager = (CarrierConfigManager) activity.getSystemService(Context.CARRIER_CONFIG_SERVICE); if (configManager != null) { PersistableBundle b = configManager.getConfig(); if (b != null) { isWfcModeEditable = b.getBoolean( CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL); isWfcRoamingModeEditable = b.getBoolean( CarrierConfigManager.KEY_EDITABLE_WFC_ROAMING_MODE_BOOL); } } Preference pref = getPreferenceScreen().findPreference(BUTTON_WFC_MODE); if (pref != null) { pref.setEnabled(isWfcEnabled && isWfcModeEditable && (state == TelephonyManager.CALL_STATE_IDLE)); } Preference pref_roam = getPreferenceScreen().findPreference(BUTTON_WFC_ROAMING_MODE); if (pref_roam != null) { pref_roam.setEnabled(isWfcEnabled && isWfcRoamingModeEditable && (state == TelephonyManager.CALL_STATE_IDLE)); } } }; private final OnPreferenceClickListener mUpdateAddressListener = new OnPreferenceClickListener() { /* * Launch carrier emergency address managemnent activity */ @Override public boolean onPreferenceClick(Preference preference) { final Context context = getActivity(); Intent carrierAppIntent = getCarrierActivityIntent(context); if (carrierAppIntent != null) { carrierAppIntent.putExtra(EXTRA_LAUNCH_CARRIER_APP, LAUCH_APP_UPDATE); startActivity(carrierAppIntent); } return true; } }; @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); setEmptyView(mEmptyView); String emptyViewText = activity.getString(R.string.wifi_calling_off_explanation) + activity.getString(R.string.wifi_calling_off_explanation_2); mEmptyView.setText(emptyViewText); } @Override public void onDestroyView() { super.onDestroyView(); mSwitchBar.hide(); } private void showAlert(Intent intent) { Context context = getActivity(); CharSequence title = intent.getCharSequenceExtra(Phone.EXTRA_KEY_ALERT_TITLE); CharSequence message = intent.getCharSequenceExtra(Phone.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 @Override public int getMetricsCategory() { public int getMetricsCategory() { Loading @@ -207,242 +55,81 @@ public class WifiCallingSettings extends SettingsPreferenceFragment } } @Override @Override public void onCreate(Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup container, super.onCreate(savedInstanceState); Bundle savedInstanceState) { final View view = inflater.inflate(R.layout.wifi_calling_settings_tabs, container, false); addPreferencesFromResource(R.xml.wifi_calling_settings); mButtonWfcMode = (ListPreference) findPreference(BUTTON_WFC_MODE); mButtonWfcMode.setOnPreferenceChangeListener(this); mButtonWfcRoamingMode = (ListPreference) findPreference(BUTTON_WFC_ROAMING_MODE); mButtonWfcRoamingMode.setOnPreferenceChangeListener(this); mUpdateAddress = (Preference) findPreference(PREFERENCE_EMERGENCY_ADDRESS); mUpdateAddress.setOnPreferenceClickListener(mUpdateAddressListener); mIntentFilter = new IntentFilter(); mIntentFilter.addAction(ImsManager.ACTION_IMS_REGISTRATION_ERROR); CarrierConfigManager configManager = (CarrierConfigManager) getSystemService(Context.CARRIER_CONFIG_SERVICE); boolean isWifiOnlySupported = true; if (configManager != null) { PersistableBundle b = configManager.getConfig(); if (b != null) { mEditableWfcMode = b.getBoolean(CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL); mEditableWfcRoamingMode = b.getBoolean( CarrierConfigManager.KEY_EDITABLE_WFC_ROAMING_MODE_BOOL); isWifiOnlySupported = b.getBoolean( CarrierConfigManager.KEY_CARRIER_WFC_SUPPORTS_WIFI_ONLY_BOOL, true); } } if (!isWifiOnlySupported) { mButtonWfcMode.setEntries(R.array.wifi_calling_mode_choices_without_wifi_only); mButtonWfcMode.setEntryValues(R.array.wifi_calling_mode_values_without_wifi_only); mButtonWfcRoamingMode.setEntries( R.array.wifi_calling_mode_choices_v2_without_wifi_only); mButtonWfcRoamingMode.setEntryValues( R.array.wifi_calling_mode_values_without_wifi_only); } } @Override public void onResume() { super.onResume(); final Context context = getActivity(); // NOTE: Buttons will be enabled/disabled in mPhoneStateListener boolean wfcEnabled = ImsManager.isWfcEnabledByUser(context) && ImsManager.isNonTtyOrTtyOnVolteEnabled(context); mSwitch.setChecked(wfcEnabled); int wfcMode = ImsManager.getWfcMode(context, false); int wfcRoamingMode = ImsManager.getWfcMode(context, true); mButtonWfcMode.setValue(Integer.toString(wfcMode)); mButtonWfcRoamingMode.setValue(Integer.toString(wfcRoamingMode)); updateButtonWfcMode(context, wfcEnabled, wfcMode, wfcRoamingMode); if (ImsManager.isWfcEnabledByPlatform(context)) { mTabLayout = view.findViewById(R.id.sliding_tabs); TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); mViewPager = (RtlCompatibleViewPager) view.findViewById(R.id.view_pager); tm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE); mSwitchBar.addOnSwitchChangeListener(this); mValidListener = true; } context.registerReceiver(mIntentReceiver, mIntentFilter); mPagerAdapter = new WifiCallingViewPagerAdapter(getChildFragmentManager(), mViewPager); mViewPager.setAdapter(mPagerAdapter); Intent intent = getActivity().getIntent(); return view; if (intent.getBooleanExtra(Phone.EXTRA_KEY_ALERT_SHOW, false)) { showAlert(intent); } } } @Override @Override public void onPause() { public void onCreate(Bundle icicle) { super.onPause(); super.onCreate(icicle); // TODO: besides in onCreate, we should also update subList when SIM / Sub status final Context context = getActivity(); // changes. updateSubList(); 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 @Override public void onSwitchChanged(Switch switchView, boolean isChecked) { public void onStart() { final Context context = getActivity(); super.onStart(); Log.d(TAG, "onSwitchChanged(" + isChecked + ")"); if (!isChecked) { if (mSil != null && mSil.size() > 1) { updateWfcMode(context, false); mTabLayout.setViewPager(mViewPager); return; } // Call address management activity before turning on WFC Intent carrierAppIntent = getCarrierActivityIntent(context); if (carrierAppIntent != null) { carrierAppIntent.putExtra(EXTRA_LAUNCH_CARRIER_APP, LAUCH_APP_ACTIVATE); startActivityForResult(carrierAppIntent, REQUEST_CHECK_WFC_EMERGENCY_ADDRESS); } else { } else { updateWfcMode(context, true); mTabLayout.setVisibility(View.GONE); } } } } /* private final class WifiCallingViewPagerAdapter extends FragmentPagerAdapter { * Get the Intent to launch carrier emergency address management activity. private final RtlCompatibleViewPager mViewPager; * Return null when no activity found. */ private static Intent getCarrierActivityIntent(Context context) { // Retrive component name from carrirt config CarrierConfigManager configManager = context.getSystemService(CarrierConfigManager.class); if (configManager == null) return null; PersistableBundle bundle = configManager.getConfig(); if (bundle == null) return null; String carrierApp = bundle.getString( CarrierConfigManager.KEY_WFC_EMERGENCY_ADDRESS_CARRIER_APP_STRING); if (TextUtils.isEmpty(carrierApp)) return null; ComponentName componentName = ComponentName.unflattenFromString(carrierApp); public WifiCallingViewPagerAdapter(FragmentManager fragmentManager, if (componentName == null) return null; RtlCompatibleViewPager viewPager) { super(fragmentManager); // Build and return intent mViewPager = viewPager; Intent intent = new Intent(); intent.setComponent(componentName); return intent; } } /* @Override * Turn on/off WFC mode with ImsManager and update UI accordingly public CharSequence getPageTitle(int position) { */ return String.valueOf(mSil.get(position).getDisplayName()); private void updateWfcMode(Context context, boolean wfcEnabled) { Log.i(TAG, "updateWfcMode(" + wfcEnabled + ")"); ImsManager.setWfcSetting(context, wfcEnabled); int wfcMode = ImsManager.getWfcMode(context, false); int wfcRoamingMode = ImsManager.getWfcMode(context, true); updateButtonWfcMode(context, wfcEnabled, wfcMode, wfcRoamingMode); if (wfcEnabled) { mMetricsFeatureProvider.action(getActivity(), getMetricsCategory(), wfcMode); } else { mMetricsFeatureProvider.action(getActivity(), getMetricsCategory(), -1); } } } @Override @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { public Fragment getItem(int position) { super.onActivityResult(requestCode, resultCode, data); Log.d(TAG, "Adapter getItem " + position); final Bundle args = new Bundle(); final Context context = getActivity(); args.putInt(WifiCallingSettingsForSub.FRAGMENT_BUNDLE_SUBID, mSil.get(position).getSubscriptionId()); if (requestCode == REQUEST_CHECK_WFC_EMERGENCY_ADDRESS) { WifiCallingSettingsForSub fragment = new WifiCallingSettingsForSub(); Log.d(TAG, "WFC emergency address activity result = " + resultCode); fragment.setArguments(args); if (resultCode == Activity.RESULT_OK) { return fragment; updateWfcMode(context, true); } } } } private void updateButtonWfcMode(Context context, boolean wfcEnabled, int wfcMode, int wfcRoamingMode) { mButtonWfcMode.setSummary(getWfcModeSummary(context, wfcMode)); mButtonWfcMode.setEnabled(wfcEnabled && mEditableWfcMode); // mButtonWfcRoamingMode.setSummary is not needed; summary is just selected value. mButtonWfcRoamingMode.setEnabled(wfcEnabled && mEditableWfcRoamingMode); final PreferenceScreen preferenceScreen = getPreferenceScreen(); @Override boolean updateAddressEnabled = (getCarrierActivityIntent(context) != null); public Object instantiateItem(ViewGroup container, int position) { if (wfcEnabled) { Log.d(TAG, "Adapter instantiateItem " + position); if (mEditableWfcMode) { return super.instantiateItem(container, preferenceScreen.addPreference(mButtonWfcMode); mViewPager.getRtlAwareIndex(position)); } else { // Don't show WFC (home) preference if it's not editable. preferenceScreen.removePreference(mButtonWfcMode); } if (mEditableWfcRoamingMode) { preferenceScreen.addPreference(mButtonWfcRoamingMode); } else { // Don't show WFC roaming preference if it's not editable. preferenceScreen.removePreference(mButtonWfcRoamingMode); } if (updateAddressEnabled) { preferenceScreen.addPreference(mUpdateAddress); } else { preferenceScreen.removePreference(mUpdateAddress); } } else { preferenceScreen.removePreference(mButtonWfcMode); preferenceScreen.removePreference(mButtonWfcRoamingMode); preferenceScreen.removePreference(mUpdateAddress); } } } @Override @Override public boolean onPreferenceChange(Preference preference, Object newValue) { public int getCount() { final Context context = getActivity(); if (mSil == null) { if (preference == mButtonWfcMode) { Log.d(TAG, "Adapter getCount null mSil "); mButtonWfcMode.setValue((String) newValue); return 0; int buttonMode = Integer.valueOf((String) newValue); } else { int currentWfcMode = ImsManager.getWfcMode(context, false); Log.d(TAG, "Adapter getCount " + mSil.size()); if (buttonMode != currentWfcMode) { return mSil.size(); ImsManager.setWfcMode(context, buttonMode, false); mButtonWfcMode.setSummary(getWfcModeSummary(context, buttonMode)); mMetricsFeatureProvider.action(getActivity(), getMetricsCategory(), buttonMode); } if (!mEditableWfcRoamingMode) { int currentWfcRoamingMode = ImsManager.getWfcMode(context, true); if (buttonMode != currentWfcRoamingMode) { ImsManager.setWfcMode(context, buttonMode, true); // mButtonWfcRoamingMode.setSummary is not needed; summary is selected value } } } else if (preference == mButtonWfcRoamingMode) { mButtonWfcRoamingMode.setValue((String) newValue); int buttonMode = Integer.valueOf((String) newValue); int currentMode = ImsManager.getWfcMode(context, true); if (buttonMode != currentMode) { ImsManager.setWfcMode(context, buttonMode, true); // mButtonWfcRoamingMode.setSummary is not needed; summary is just selected value. mMetricsFeatureProvider.action(getActivity(), getMetricsCategory(), buttonMode); } } } } return true; } } public static int getWfcModeSummary(Context context, int wfcMode) { public static int getWfcModeSummary(Context context, int wfcMode) { Loading @@ -464,4 +151,22 @@ public class WifiCallingSettings extends SettingsPreferenceFragment } } return resId; return resId; } } private void updateSubList() { mSil = SubscriptionManager.from(getActivity()).getActiveSubscriptionInfoList(); // Only config Wfc if it's enabled by platform. if (mSil == null) { return; } for (int i = 0; i < mSil.size();) { ImsManager imsManager = ImsManager.getInstance(getActivity(), mSil.get(i).getSimSlotIndex()); if (!imsManager.isWfcEnabledByPlatform()) { mSil.remove(i); } else { i++; } } } } } Loading
res/layout/wifi_calling_settings_preferences.xml 0 → 100644 +45 −0 Original line number Original line Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2014 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. --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/tabs_container" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <com.android.settings.widget.SwitchBar android:id="@+id/switch_bar" android:layout_height="?android:attr/actionBarSize" android:layout_width="match_parent" android:background="@drawable/switchbar_background" android:theme="?attr/switchBarTheme" /> <FrameLayout android:id="@android:id/tabcontent" android:layout_width="0dip" android:layout_height="0dip" /> <FrameLayout android:id="@+id/prefs_container" android:layout_width="match_parent" android:layout_height="0dip" android:layout_weight="1" android:clipChildren="false" android:clipToPadding="false" android:smoothScrollbar="false" /> </LinearLayout>
res/layout/wifi_calling_settings_tabs.xml 0 → 100644 +36 −0 Original line number Original line Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2017 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. --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/tabs_container" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <com.android.settings.widget.SlidingTabLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/sliding_tabs" android:layout_width="match_parent" android:layout_height="wrap_content" android:scrollbars="none" android:fillViewport="true"/> <com.android.settings.widget.RtlCompatibleViewPager android:id="@+id/view_pager" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout>
src/com/android/settings/WifiCallingSettings.java +87 −382 Original line number Original line Diff line number Diff line Loading @@ -16,190 +16,38 @@ package com.android.settings; package com.android.settings; import android.app.Activity; import android.app.Fragment; import android.app.AlertDialog; import android.app.FragmentManager; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.os.Bundle; import android.os.PersistableBundle; import android.support.v13.app.FragmentPagerAdapter; import android.support.v7.preference.ListPreference; import android.telephony.SubscriptionInfo; import android.support.v7.preference.Preference; import android.telephony.SubscriptionManager; import android.support.v7.preference.Preference.OnPreferenceClickListener; import android.support.v7.preference.PreferenceScreen; import android.telephony.CarrierConfigManager; import android.telephony.PhoneStateListener; import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.Log; import android.util.Log; import android.widget.Switch; import android.view.LayoutInflater; import android.widget.TextView; import android.view.View; import android.view.ViewGroup; import com.android.ims.ImsConfig; import com.android.ims.ImsConfig; import com.android.ims.ImsManager; import com.android.ims.ImsManager; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.telephony.Phone; import com.android.settings.widget.RtlCompatibleViewPager; import com.android.settings.widget.SwitchBar; import com.android.settings.widget.SlidingTabLayout; import java.util.List; /** /** * "Wi-Fi Calling settings" screen. This preference screen lets you * "Wi-Fi Calling settings" screen. This is the container fragment which holds * enable/disable Wi-Fi Calling and change Wi-Fi Calling mode. * {@link WifiCallingSettingsForSub} fragments. */ */ public class WifiCallingSettings extends SettingsPreferenceFragment public class WifiCallingSettings extends SettingsPreferenceFragment { implements SwitchBar.OnSwitchChangeListener, Preference.OnPreferenceChangeListener { private static final String TAG = "WifiCallingSettings"; private static final String TAG = "WifiCallingSettings"; private List<SubscriptionInfo> mSil; //String keys for preference lookup private static final String BUTTON_WFC_MODE = "wifi_calling_mode"; private static final String BUTTON_WFC_ROAMING_MODE = "wifi_calling_roaming_mode"; private static final String PREFERENCE_EMERGENCY_ADDRESS = "emergency_address_key"; private static final int REQUEST_CHECK_WFC_EMERGENCY_ADDRESS = 1; public static final String EXTRA_LAUNCH_CARRIER_APP = "EXTRA_LAUNCH_CARRIER_APP"; public static final int LAUCH_APP_ACTIVATE = 0; public static final int LAUCH_APP_UPDATE = 1; //UI objects //UI objects private SwitchBar mSwitchBar; private RtlCompatibleViewPager mViewPager; private Switch mSwitch; private WifiCallingViewPagerAdapter mPagerAdapter; private ListPreference mButtonWfcMode; private SlidingTabLayout mTabLayout; private ListPreference mButtonWfcRoamingMode; private Preference mUpdateAddress; private TextView mEmptyView; private boolean mValidListener = false; private boolean mEditableWfcMode = true; private boolean mEditableWfcRoamingMode = 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); boolean isWfcModeEditable = true; boolean isWfcRoamingModeEditable = false; final CarrierConfigManager configManager = (CarrierConfigManager) activity.getSystemService(Context.CARRIER_CONFIG_SERVICE); if (configManager != null) { PersistableBundle b = configManager.getConfig(); if (b != null) { isWfcModeEditable = b.getBoolean( CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL); isWfcRoamingModeEditable = b.getBoolean( CarrierConfigManager.KEY_EDITABLE_WFC_ROAMING_MODE_BOOL); } } Preference pref = getPreferenceScreen().findPreference(BUTTON_WFC_MODE); if (pref != null) { pref.setEnabled(isWfcEnabled && isWfcModeEditable && (state == TelephonyManager.CALL_STATE_IDLE)); } Preference pref_roam = getPreferenceScreen().findPreference(BUTTON_WFC_ROAMING_MODE); if (pref_roam != null) { pref_roam.setEnabled(isWfcEnabled && isWfcRoamingModeEditable && (state == TelephonyManager.CALL_STATE_IDLE)); } } }; private final OnPreferenceClickListener mUpdateAddressListener = new OnPreferenceClickListener() { /* * Launch carrier emergency address managemnent activity */ @Override public boolean onPreferenceClick(Preference preference) { final Context context = getActivity(); Intent carrierAppIntent = getCarrierActivityIntent(context); if (carrierAppIntent != null) { carrierAppIntent.putExtra(EXTRA_LAUNCH_CARRIER_APP, LAUCH_APP_UPDATE); startActivity(carrierAppIntent); } return true; } }; @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); setEmptyView(mEmptyView); String emptyViewText = activity.getString(R.string.wifi_calling_off_explanation) + activity.getString(R.string.wifi_calling_off_explanation_2); mEmptyView.setText(emptyViewText); } @Override public void onDestroyView() { super.onDestroyView(); mSwitchBar.hide(); } private void showAlert(Intent intent) { Context context = getActivity(); CharSequence title = intent.getCharSequenceExtra(Phone.EXTRA_KEY_ALERT_TITLE); CharSequence message = intent.getCharSequenceExtra(Phone.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 @Override public int getMetricsCategory() { public int getMetricsCategory() { Loading @@ -207,242 +55,81 @@ public class WifiCallingSettings extends SettingsPreferenceFragment } } @Override @Override public void onCreate(Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup container, super.onCreate(savedInstanceState); Bundle savedInstanceState) { final View view = inflater.inflate(R.layout.wifi_calling_settings_tabs, container, false); addPreferencesFromResource(R.xml.wifi_calling_settings); mButtonWfcMode = (ListPreference) findPreference(BUTTON_WFC_MODE); mButtonWfcMode.setOnPreferenceChangeListener(this); mButtonWfcRoamingMode = (ListPreference) findPreference(BUTTON_WFC_ROAMING_MODE); mButtonWfcRoamingMode.setOnPreferenceChangeListener(this); mUpdateAddress = (Preference) findPreference(PREFERENCE_EMERGENCY_ADDRESS); mUpdateAddress.setOnPreferenceClickListener(mUpdateAddressListener); mIntentFilter = new IntentFilter(); mIntentFilter.addAction(ImsManager.ACTION_IMS_REGISTRATION_ERROR); CarrierConfigManager configManager = (CarrierConfigManager) getSystemService(Context.CARRIER_CONFIG_SERVICE); boolean isWifiOnlySupported = true; if (configManager != null) { PersistableBundle b = configManager.getConfig(); if (b != null) { mEditableWfcMode = b.getBoolean(CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL); mEditableWfcRoamingMode = b.getBoolean( CarrierConfigManager.KEY_EDITABLE_WFC_ROAMING_MODE_BOOL); isWifiOnlySupported = b.getBoolean( CarrierConfigManager.KEY_CARRIER_WFC_SUPPORTS_WIFI_ONLY_BOOL, true); } } if (!isWifiOnlySupported) { mButtonWfcMode.setEntries(R.array.wifi_calling_mode_choices_without_wifi_only); mButtonWfcMode.setEntryValues(R.array.wifi_calling_mode_values_without_wifi_only); mButtonWfcRoamingMode.setEntries( R.array.wifi_calling_mode_choices_v2_without_wifi_only); mButtonWfcRoamingMode.setEntryValues( R.array.wifi_calling_mode_values_without_wifi_only); } } @Override public void onResume() { super.onResume(); final Context context = getActivity(); // NOTE: Buttons will be enabled/disabled in mPhoneStateListener boolean wfcEnabled = ImsManager.isWfcEnabledByUser(context) && ImsManager.isNonTtyOrTtyOnVolteEnabled(context); mSwitch.setChecked(wfcEnabled); int wfcMode = ImsManager.getWfcMode(context, false); int wfcRoamingMode = ImsManager.getWfcMode(context, true); mButtonWfcMode.setValue(Integer.toString(wfcMode)); mButtonWfcRoamingMode.setValue(Integer.toString(wfcRoamingMode)); updateButtonWfcMode(context, wfcEnabled, wfcMode, wfcRoamingMode); if (ImsManager.isWfcEnabledByPlatform(context)) { mTabLayout = view.findViewById(R.id.sliding_tabs); TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); mViewPager = (RtlCompatibleViewPager) view.findViewById(R.id.view_pager); tm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE); mSwitchBar.addOnSwitchChangeListener(this); mValidListener = true; } context.registerReceiver(mIntentReceiver, mIntentFilter); mPagerAdapter = new WifiCallingViewPagerAdapter(getChildFragmentManager(), mViewPager); mViewPager.setAdapter(mPagerAdapter); Intent intent = getActivity().getIntent(); return view; if (intent.getBooleanExtra(Phone.EXTRA_KEY_ALERT_SHOW, false)) { showAlert(intent); } } } @Override @Override public void onPause() { public void onCreate(Bundle icicle) { super.onPause(); super.onCreate(icicle); // TODO: besides in onCreate, we should also update subList when SIM / Sub status final Context context = getActivity(); // changes. updateSubList(); 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 @Override public void onSwitchChanged(Switch switchView, boolean isChecked) { public void onStart() { final Context context = getActivity(); super.onStart(); Log.d(TAG, "onSwitchChanged(" + isChecked + ")"); if (!isChecked) { if (mSil != null && mSil.size() > 1) { updateWfcMode(context, false); mTabLayout.setViewPager(mViewPager); return; } // Call address management activity before turning on WFC Intent carrierAppIntent = getCarrierActivityIntent(context); if (carrierAppIntent != null) { carrierAppIntent.putExtra(EXTRA_LAUNCH_CARRIER_APP, LAUCH_APP_ACTIVATE); startActivityForResult(carrierAppIntent, REQUEST_CHECK_WFC_EMERGENCY_ADDRESS); } else { } else { updateWfcMode(context, true); mTabLayout.setVisibility(View.GONE); } } } } /* private final class WifiCallingViewPagerAdapter extends FragmentPagerAdapter { * Get the Intent to launch carrier emergency address management activity. private final RtlCompatibleViewPager mViewPager; * Return null when no activity found. */ private static Intent getCarrierActivityIntent(Context context) { // Retrive component name from carrirt config CarrierConfigManager configManager = context.getSystemService(CarrierConfigManager.class); if (configManager == null) return null; PersistableBundle bundle = configManager.getConfig(); if (bundle == null) return null; String carrierApp = bundle.getString( CarrierConfigManager.KEY_WFC_EMERGENCY_ADDRESS_CARRIER_APP_STRING); if (TextUtils.isEmpty(carrierApp)) return null; ComponentName componentName = ComponentName.unflattenFromString(carrierApp); public WifiCallingViewPagerAdapter(FragmentManager fragmentManager, if (componentName == null) return null; RtlCompatibleViewPager viewPager) { super(fragmentManager); // Build and return intent mViewPager = viewPager; Intent intent = new Intent(); intent.setComponent(componentName); return intent; } } /* @Override * Turn on/off WFC mode with ImsManager and update UI accordingly public CharSequence getPageTitle(int position) { */ return String.valueOf(mSil.get(position).getDisplayName()); private void updateWfcMode(Context context, boolean wfcEnabled) { Log.i(TAG, "updateWfcMode(" + wfcEnabled + ")"); ImsManager.setWfcSetting(context, wfcEnabled); int wfcMode = ImsManager.getWfcMode(context, false); int wfcRoamingMode = ImsManager.getWfcMode(context, true); updateButtonWfcMode(context, wfcEnabled, wfcMode, wfcRoamingMode); if (wfcEnabled) { mMetricsFeatureProvider.action(getActivity(), getMetricsCategory(), wfcMode); } else { mMetricsFeatureProvider.action(getActivity(), getMetricsCategory(), -1); } } } @Override @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { public Fragment getItem(int position) { super.onActivityResult(requestCode, resultCode, data); Log.d(TAG, "Adapter getItem " + position); final Bundle args = new Bundle(); final Context context = getActivity(); args.putInt(WifiCallingSettingsForSub.FRAGMENT_BUNDLE_SUBID, mSil.get(position).getSubscriptionId()); if (requestCode == REQUEST_CHECK_WFC_EMERGENCY_ADDRESS) { WifiCallingSettingsForSub fragment = new WifiCallingSettingsForSub(); Log.d(TAG, "WFC emergency address activity result = " + resultCode); fragment.setArguments(args); if (resultCode == Activity.RESULT_OK) { return fragment; updateWfcMode(context, true); } } } } private void updateButtonWfcMode(Context context, boolean wfcEnabled, int wfcMode, int wfcRoamingMode) { mButtonWfcMode.setSummary(getWfcModeSummary(context, wfcMode)); mButtonWfcMode.setEnabled(wfcEnabled && mEditableWfcMode); // mButtonWfcRoamingMode.setSummary is not needed; summary is just selected value. mButtonWfcRoamingMode.setEnabled(wfcEnabled && mEditableWfcRoamingMode); final PreferenceScreen preferenceScreen = getPreferenceScreen(); @Override boolean updateAddressEnabled = (getCarrierActivityIntent(context) != null); public Object instantiateItem(ViewGroup container, int position) { if (wfcEnabled) { Log.d(TAG, "Adapter instantiateItem " + position); if (mEditableWfcMode) { return super.instantiateItem(container, preferenceScreen.addPreference(mButtonWfcMode); mViewPager.getRtlAwareIndex(position)); } else { // Don't show WFC (home) preference if it's not editable. preferenceScreen.removePreference(mButtonWfcMode); } if (mEditableWfcRoamingMode) { preferenceScreen.addPreference(mButtonWfcRoamingMode); } else { // Don't show WFC roaming preference if it's not editable. preferenceScreen.removePreference(mButtonWfcRoamingMode); } if (updateAddressEnabled) { preferenceScreen.addPreference(mUpdateAddress); } else { preferenceScreen.removePreference(mUpdateAddress); } } else { preferenceScreen.removePreference(mButtonWfcMode); preferenceScreen.removePreference(mButtonWfcRoamingMode); preferenceScreen.removePreference(mUpdateAddress); } } } @Override @Override public boolean onPreferenceChange(Preference preference, Object newValue) { public int getCount() { final Context context = getActivity(); if (mSil == null) { if (preference == mButtonWfcMode) { Log.d(TAG, "Adapter getCount null mSil "); mButtonWfcMode.setValue((String) newValue); return 0; int buttonMode = Integer.valueOf((String) newValue); } else { int currentWfcMode = ImsManager.getWfcMode(context, false); Log.d(TAG, "Adapter getCount " + mSil.size()); if (buttonMode != currentWfcMode) { return mSil.size(); ImsManager.setWfcMode(context, buttonMode, false); mButtonWfcMode.setSummary(getWfcModeSummary(context, buttonMode)); mMetricsFeatureProvider.action(getActivity(), getMetricsCategory(), buttonMode); } if (!mEditableWfcRoamingMode) { int currentWfcRoamingMode = ImsManager.getWfcMode(context, true); if (buttonMode != currentWfcRoamingMode) { ImsManager.setWfcMode(context, buttonMode, true); // mButtonWfcRoamingMode.setSummary is not needed; summary is selected value } } } else if (preference == mButtonWfcRoamingMode) { mButtonWfcRoamingMode.setValue((String) newValue); int buttonMode = Integer.valueOf((String) newValue); int currentMode = ImsManager.getWfcMode(context, true); if (buttonMode != currentMode) { ImsManager.setWfcMode(context, buttonMode, true); // mButtonWfcRoamingMode.setSummary is not needed; summary is just selected value. mMetricsFeatureProvider.action(getActivity(), getMetricsCategory(), buttonMode); } } } } return true; } } public static int getWfcModeSummary(Context context, int wfcMode) { public static int getWfcModeSummary(Context context, int wfcMode) { Loading @@ -464,4 +151,22 @@ public class WifiCallingSettings extends SettingsPreferenceFragment } } return resId; return resId; } } private void updateSubList() { mSil = SubscriptionManager.from(getActivity()).getActiveSubscriptionInfoList(); // Only config Wfc if it's enabled by platform. if (mSil == null) { return; } for (int i = 0; i < mSil.size();) { ImsManager imsManager = ImsManager.getInstance(getActivity(), mSil.get(i).getSimSlotIndex()); if (!imsManager.isWfcEnabledByPlatform()) { mSil.remove(i); } else { i++; } } } } }