diff --git a/res/layout/wifi_calling_settings_preferences.xml b/res/layout/wifi_calling_settings_preferences.xml
new file mode 100644
index 0000000..4e64f40
--- /dev/null
+++ b/res/layout/wifi_calling_settings_preferences.xml
@@ -0,0 +1,45 @@
+<?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>
diff --git a/res/layout/wifi_calling_settings_tabs.xml b/res/layout/wifi_calling_settings_tabs.xml
new file mode 100644
index 0000000..1e27b47
--- /dev/null
+++ b/res/layout/wifi_calling_settings_tabs.xml
@@ -0,0 +1,36 @@
+<?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>
diff --git a/src/com/android/settings/WifiCallingSettings.java b/src/com/android/settings/WifiCallingSettings.java
index cb661ed..e872fb8 100644
--- a/src/com/android/settings/WifiCallingSettings.java
+++ b/src/com/android/settings/WifiCallingSettings.java
@@ -16,190 +16,38 @@
 
 package com.android.settings;
 
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
+import android.app.Fragment;
+import android.app.FragmentManager;
 import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
 import android.os.Bundle;
-import android.os.PersistableBundle;
-import android.support.v7.preference.ListPreference;
-import android.support.v7.preference.Preference;
-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.support.v13.app.FragmentPagerAdapter;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
 import android.util.Log;
-import android.widget.Switch;
-import android.widget.TextView;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
 
 import com.android.ims.ImsConfig;
 import com.android.ims.ImsManager;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.internal.telephony.Phone;
-import com.android.settings.widget.SwitchBar;
+import com.android.settings.widget.RtlCompatibleViewPager;
+import com.android.settings.widget.SlidingTabLayout;
+
+import java.util.List;
 
 /**
- * "Wi-Fi Calling settings" screen.  This preference screen lets you
- * enable/disable Wi-Fi Calling and change Wi-Fi Calling mode.
+ * "Wi-Fi Calling settings" screen. This is the container fragment which holds
+ * {@link WifiCallingSettingsForSub} fragments.
  */
-public class WifiCallingSettings extends SettingsPreferenceFragment
-        implements SwitchBar.OnSwitchChangeListener,
-        Preference.OnPreferenceChangeListener {
-
+public class WifiCallingSettings extends SettingsPreferenceFragment {
     private static final String TAG = "WifiCallingSettings";
-
-    //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;
+    private List<SubscriptionInfo> mSil;
 
     //UI objects
-    private SwitchBar mSwitchBar;
-    private Switch mSwitch;
-    private ListPreference mButtonWfcMode;
-    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);
-            }
-        }
-    };
+    private RtlCompatibleViewPager mViewPager;
+    private WifiCallingViewPagerAdapter mPagerAdapter;
+    private SlidingTabLayout mTabLayout;
 
     @Override
     public int getMetricsCategory() {
@@ -207,242 +55,81 @@
     }
 
     @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+            Bundle savedInstanceState) {
+        final View view = inflater.inflate(R.layout.wifi_calling_settings_tabs, container, false);
 
-        addPreferencesFromResource(R.xml.wifi_calling_settings);
+        mTabLayout = view.findViewById(R.id.sliding_tabs);
+        mViewPager = (RtlCompatibleViewPager) view.findViewById(R.id.view_pager);
 
-        mButtonWfcMode = (ListPreference) findPreference(BUTTON_WFC_MODE);
-        mButtonWfcMode.setOnPreferenceChangeListener(this);
+        mPagerAdapter = new WifiCallingViewPagerAdapter(getChildFragmentManager(), mViewPager);
+        mViewPager.setAdapter(mPagerAdapter);
 
-        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);
-        }
+        return view;
     }
 
     @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)) {
-            TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
-            tm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
-
-            mSwitchBar.addOnSwitchChangeListener(this);
-
-            mValidListener = true;
-        }
-
-        context.registerReceiver(mIntentReceiver, mIntentFilter);
-
-        Intent intent = getActivity().getIntent();
-        if (intent.getBooleanExtra(Phone.EXTRA_KEY_ALERT_SHOW, false)) {
-            showAlert(intent);
-        }
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        // TODO: besides in onCreate, we should also update subList when SIM / Sub status
+        // changes.
+        updateSubList();
     }
 
     @Override
-    public void onPause() {
-        super.onPause();
+    public void onStart() {
+        super.onStart();
 
-        final Context context = getActivity();
-
-        if (mValidListener) {
-            mValidListener = false;
-
-            TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
-            tm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
-
-            mSwitchBar.removeOnSwitchChangeListener(this);
-        }
-
-        context.unregisterReceiver(mIntentReceiver);
-    }
-
-    /**
-     * Listens to the state change of the switch.
-     */
-    @Override
-    public void onSwitchChanged(Switch switchView, boolean isChecked) {
-        final Context context = getActivity();
-        Log.d(TAG, "onSwitchChanged(" + isChecked + ")");
-
-        if (!isChecked) {
-            updateWfcMode(context, false);
-            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);
+        if (mSil != null && mSil.size() > 1) {
+            mTabLayout.setViewPager(mViewPager);
         } else {
-            updateWfcMode(context, true);
+            mTabLayout.setVisibility(View.GONE);
         }
     }
 
-    /*
-     * Get the Intent to launch carrier emergency address management activity.
-     * 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;
+    private final class WifiCallingViewPagerAdapter extends FragmentPagerAdapter {
+        private final RtlCompatibleViewPager mViewPager;
 
-        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);
-        if (componentName == null) return null;
-
-        // Build and return intent
-        Intent intent = new Intent();
-        intent.setComponent(componentName);
-        return intent;
-    }
-
-    /*
-     * Turn on/off WFC mode with ImsManager and update UI accordingly
-     */
-    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);
+        public WifiCallingViewPagerAdapter(FragmentManager fragmentManager,
+                RtlCompatibleViewPager viewPager) {
+            super(fragmentManager);
+            mViewPager = viewPager;
         }
-    }
 
-    @Override
-    public void onActivityResult(int requestCode, int resultCode, Intent data) {
-        super.onActivityResult(requestCode, resultCode, data);
-
-        final Context context = getActivity();
-
-        if (requestCode == REQUEST_CHECK_WFC_EMERGENCY_ADDRESS) {
-            Log.d(TAG, "WFC emergency address activity result = " + resultCode);
-
-            if (resultCode == Activity.RESULT_OK) {
-                updateWfcMode(context, true);
-            }
+        @Override
+        public CharSequence getPageTitle(int position) {
+            return String.valueOf(mSil.get(position).getDisplayName());
         }
-    }
 
-    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);
+        @Override
+        public Fragment getItem(int position) {
+            Log.d(TAG, "Adapter getItem " + position);
+            final Bundle args = new Bundle();
+            args.putInt(WifiCallingSettingsForSub.FRAGMENT_BUNDLE_SUBID,
+                    mSil.get(position).getSubscriptionId());
+            WifiCallingSettingsForSub fragment = new WifiCallingSettingsForSub();
+            fragment.setArguments(args);
 
-        final PreferenceScreen preferenceScreen = getPreferenceScreen();
-        boolean updateAddressEnabled = (getCarrierActivityIntent(context) != null);
-        if (wfcEnabled) {
-            if (mEditableWfcMode) {
-                preferenceScreen.addPreference(mButtonWfcMode);
+            return fragment;
+        }
+
+        @Override
+        public Object instantiateItem(ViewGroup container, int position) {
+            Log.d(TAG, "Adapter instantiateItem " + position);
+            return super.instantiateItem(container,
+                    mViewPager.getRtlAwareIndex(position));
+        }
+
+        @Override
+        public int getCount() {
+            if (mSil == null) {
+                Log.d(TAG, "Adapter getCount null mSil ");
+                return 0;
             } 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
-    public boolean onPreferenceChange(Preference preference, Object newValue) {
-        final Context context = getActivity();
-        if (preference == mButtonWfcMode) {
-            mButtonWfcMode.setValue((String) newValue);
-            int buttonMode = Integer.valueOf((String) newValue);
-            int currentWfcMode = ImsManager.getWfcMode(context, false);
-            if (buttonMode != currentWfcMode) {
-                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);
+                Log.d(TAG, "Adapter getCount " + mSil.size());
+                return mSil.size();
             }
         }
-        return true;
     }
 
     public static int getWfcModeSummary(Context context, int wfcMode) {
@@ -464,4 +151,22 @@
         }
         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++;
+            }
+        }
+    }
 }
diff --git a/src/com/android/settings/WifiCallingSettingsForSub.java b/src/com/android/settings/WifiCallingSettingsForSub.java
new file mode 100644
index 0000000..57a4ab2
--- /dev/null
+++ b/src/com/android/settings/WifiCallingSettingsForSub.java
@@ -0,0 +1,521 @@
+/*
+ * 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.
+ */
+
+package com.android.settings;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.os.PersistableBundle;
+import android.support.v7.preference.ListPreference;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.Preference.OnPreferenceClickListener;
+import android.support.v7.preference.PreferenceScreen;
+import android.telephony.CarrierConfigManager;
+import android.telephony.PhoneStateListener;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Switch;
+import android.widget.TextView;
+
+import com.android.ims.ImsConfig;
+import com.android.ims.ImsManager;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.telephony.Phone;
+import com.android.settings.widget.SwitchBar;
+
+/**
+ * This is the inner class of {@link WifiCallingSettings} fragment.
+ * The preference screen lets you enable/disable Wi-Fi Calling and change Wi-Fi Calling mode.
+ */
+public class WifiCallingSettingsForSub extends SettingsPreferenceFragment
+        implements SwitchBar.OnSwitchChangeListener,
+        Preference.OnPreferenceChangeListener {
+    private static final String TAG = "WifiCallingSettingsForSub";
+
+    //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";
+
+    protected static final String FRAGMENT_BUNDLE_SUBID = "subId";
+
+    public static final int LAUCH_APP_ACTIVATE = 0;
+    public static final int LAUCH_APP_UPDATE = 1;
+
+    //UI objects
+    private SwitchBar mSwitchBar;
+    private Switch mSwitch;
+    private ListPreference mButtonWfcMode;
+    private ListPreference mButtonWfcRoamingMode;
+    private Preference mUpdateAddress;
+    private TextView mEmptyView;
+
+    private boolean mValidListener = false;
+    private boolean mEditableWfcMode = true;
+    private boolean mEditableWfcRoamingMode = true;
+
+    private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+    private ImsManager mImsManager;
+
+    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 = mImsManager.isNonTtyOrTtyOnVolteEnabled();
+            boolean isWfcEnabled = mSwitchBar.isChecked()
+                    && isNonTtyOrTtyOnVolteEnabled;
+
+            mSwitchBar.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.getConfigForSubId(mSubId);
+                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));
+            }
+        }
+    };
+
+    @Override
+    protected int getHelpResource() {
+        // Helper resource is already defined in the container fragment.
+        return 0;
+    }
+
+    private final OnPreferenceClickListener mUpdateAddressListener =
+            new OnPreferenceClickListener() {
+                /*
+                 * Launch carrier emergency address managemnent activity
+                 */
+                @Override
+                public boolean onPreferenceClick(Preference preference) {
+                    Intent carrierAppIntent = getCarrierActivityIntent();
+                    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();
+
+        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);
+
+        mSwitchBar = getView().findViewById(R.id.switch_bar);
+        mSwitchBar.show();
+        mSwitch = mSwitchBar.getSwitch();
+    }
+
+    @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
+    public int getMetricsCategory() {
+        return MetricsEvent.WIFI_CALLING_FOR_SUB;
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        addPreferencesFromResource(R.xml.wifi_calling_settings);
+
+        // SubId should always be specified when creating this fragment. Either through
+        // fragment.setArguments() or through savedInstanceState.
+        if (getArguments() != null && getArguments().containsKey(FRAGMENT_BUNDLE_SUBID))
+        {
+            mSubId = getArguments().getInt(FRAGMENT_BUNDLE_SUBID);
+        } else if (savedInstanceState != null) {
+            mSubId = savedInstanceState.getInt(
+                    FRAGMENT_BUNDLE_SUBID, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+        }
+
+        mImsManager = ImsManager.getInstance(
+                getActivity(), SubscriptionManager.getPhoneId(mSubId));
+
+        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);
+    }
+
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        outState.putInt(FRAGMENT_BUNDLE_SUBID, mSubId);
+        super.onSaveInstanceState(outState);
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+            Bundle savedInstanceState) {
+
+        View view = inflater.inflate(
+                R.layout.wifi_calling_settings_preferences, container, false);
+
+        final ViewGroup prefs_container = view.findViewById(R.id.prefs_container);
+        Utils.prepareCustomPreferencesList(container, view, prefs_container, false);
+        View prefs = super.onCreateView(inflater, prefs_container, savedInstanceState);
+        prefs_container.addView(prefs);
+
+        return view;
+    }
+
+    private void updateBody() {
+        CarrierConfigManager configManager = (CarrierConfigManager)
+                getSystemService(Context.CARRIER_CONFIG_SERVICE);
+        boolean isWifiOnlySupported = true;
+
+        if (configManager != null) {
+            PersistableBundle b = configManager.getConfigForSubId(mSubId);
+            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);
+        }
+
+
+        // NOTE: Buttons will be enabled/disabled in mPhoneStateListener
+        boolean wfcEnabled = mImsManager.isWfcEnabledByUser()
+                && mImsManager.isNonTtyOrTtyOnVolteEnabled();
+        mSwitch.setChecked(wfcEnabled);
+        int wfcMode = mImsManager.getWfcMode(false);
+        int wfcRoamingMode = mImsManager.getWfcMode(true);
+        mButtonWfcMode.setValue(Integer.toString(wfcMode));
+        mButtonWfcRoamingMode.setValue(Integer.toString(wfcRoamingMode));
+        updateButtonWfcMode(wfcEnabled, wfcMode, wfcRoamingMode);
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+
+        final Context context = getActivity();
+
+        updateBody();
+
+        if (mImsManager.isWfcEnabledByPlatform()) {
+            TelephonyManager tm =
+                    (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
+            tm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
+
+            mSwitchBar.addOnSwitchChangeListener(this);
+
+            mValidListener = true;
+        }
+
+        context.registerReceiver(mIntentReceiver, mIntentFilter);
+
+        Intent intent = getActivity().getIntent();
+        if (intent.getBooleanExtra(Phone.EXTRA_KEY_ALERT_SHOW, false)) {
+            showAlert(intent);
+        }
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+
+        final Context context = getActivity();
+
+        if (mValidListener) {
+            mValidListener = false;
+
+            TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
+            tm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
+
+            mSwitchBar.removeOnSwitchChangeListener(this);
+        }
+
+        context.unregisterReceiver(mIntentReceiver);
+    }
+
+    /**
+     * Listens to the state change of the switch.
+     */
+    @Override
+    public void onSwitchChanged(Switch switchView, boolean isChecked) {
+        Log.d(TAG, "onSwitchChanged(" + isChecked + ")");
+
+        if (!isChecked) {
+            updateWfcMode(false);
+            return;
+        }
+
+        // Call address management activity before turning on WFC
+        Intent carrierAppIntent = getCarrierActivityIntent();
+        if (carrierAppIntent != null) {
+            carrierAppIntent.putExtra(EXTRA_LAUNCH_CARRIER_APP, LAUCH_APP_ACTIVATE);
+            startActivityForResult(carrierAppIntent, REQUEST_CHECK_WFC_EMERGENCY_ADDRESS);
+        } else {
+            updateWfcMode(true);
+        }
+    }
+
+    /*
+     * Get the Intent to launch carrier emergency address management activity.
+     * Return null when no activity found.
+     */
+    private Intent getCarrierActivityIntent() {
+        // Retrive component name from carrier config
+        CarrierConfigManager configManager =
+                getActivity().getSystemService(CarrierConfigManager.class);
+        if (configManager == null) return null;
+
+        PersistableBundle bundle = configManager.getConfigForSubId(mSubId);
+        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);
+        if (componentName == null) return null;
+
+        // Build and return intent
+        Intent intent = new Intent();
+        intent.setComponent(componentName);
+        return intent;
+    }
+
+    /*
+     * Turn on/off WFC mode with ImsManager and update UI accordingly
+     */
+    private void updateWfcMode(boolean wfcEnabled) {
+        Log.i(TAG, "updateWfcMode(" + wfcEnabled + ")");
+        mImsManager.setWfcSetting(wfcEnabled);
+
+        int wfcMode = mImsManager.getWfcMode(false);
+        int wfcRoamingMode = mImsManager.getWfcMode(true);
+        updateButtonWfcMode(wfcEnabled, wfcMode, wfcRoamingMode);
+        if (wfcEnabled) {
+            mMetricsFeatureProvider.action(getActivity(), getMetricsCategory(), wfcMode);
+        } else {
+            mMetricsFeatureProvider.action(getActivity(), getMetricsCategory(), -1);
+        }
+    }
+
+    @Override
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+
+        final Context context = getActivity();
+
+        if (requestCode == REQUEST_CHECK_WFC_EMERGENCY_ADDRESS) {
+            Log.d(TAG, "WFC emergency address activity result = " + resultCode);
+
+            if (resultCode == Activity.RESULT_OK) {
+                updateWfcMode(true);
+            }
+        }
+    }
+
+    private void updateButtonWfcMode(boolean wfcEnabled,
+            int wfcMode, int wfcRoamingMode) {
+        mButtonWfcMode.setSummary(getWfcModeSummary(wfcMode));
+        mButtonWfcMode.setEnabled(wfcEnabled && mEditableWfcMode);
+        // mButtonWfcRoamingMode.setSummary is not needed; summary is just selected value.
+        mButtonWfcRoamingMode.setEnabled(wfcEnabled && mEditableWfcRoamingMode);
+
+        final PreferenceScreen preferenceScreen = getPreferenceScreen();
+        boolean updateAddressEnabled = (getCarrierActivityIntent() != null);
+        if (wfcEnabled) {
+            if (mEditableWfcMode) {
+                preferenceScreen.addPreference(mButtonWfcMode);
+            } 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
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        if (preference == mButtonWfcMode) {
+            Log.d(TAG, "onPreferenceChange mButtonWfcMode " + newValue);
+            mButtonWfcMode.setValue((String) newValue);
+            int buttonMode = Integer.valueOf((String) newValue);
+            int currentWfcMode = mImsManager.getWfcMode(false);
+            if (buttonMode != currentWfcMode) {
+                mImsManager.setWfcMode(buttonMode, false);
+                mButtonWfcMode.setSummary(getWfcModeSummary(buttonMode));
+                mMetricsFeatureProvider.action(getActivity(), getMetricsCategory(), buttonMode);
+            }
+            if (!mEditableWfcRoamingMode) {
+                int currentWfcRoamingMode = mImsManager.getWfcMode(true);
+                if (buttonMode != currentWfcRoamingMode) {
+                    mImsManager.setWfcMode(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 = mImsManager.getWfcMode(true);
+            if (buttonMode != currentMode) {
+                mImsManager.setWfcMode(buttonMode, true);
+                // mButtonWfcRoamingMode.setSummary is not needed; summary is just selected value.
+                mMetricsFeatureProvider.action(getActivity(), getMetricsCategory(), buttonMode);
+            }
+        }
+        return true;
+    }
+
+    private int getWfcModeSummary(int wfcMode) {
+        int resId = com.android.internal.R.string.wifi_calling_off_summary;
+        if (mImsManager.isWfcEnabledByUser()) {
+            switch (wfcMode) {
+                case ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY:
+                    resId = com.android.internal.R.string.wfc_mode_wifi_only_summary;
+                    break;
+                case ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED:
+                    resId = com.android.internal.R.string.wfc_mode_cellular_preferred_summary;
+                    break;
+                case ImsConfig.WfcModeFeatureValueConstants.WIFI_PREFERRED:
+                    resId = com.android.internal.R.string.wfc_mode_wifi_preferred_summary;
+                    break;
+                default:
+                    Log.e(TAG, "Unexpected WFC mode value: " + wfcMode);
+            }
+        }
+        return resId;
+    }
+}
diff --git a/tests/robotests/assets/grandfather_not_implementing_indexable b/tests/robotests/assets/grandfather_not_implementing_indexable
index d4a8d2d..a9fb589 100644
--- a/tests/robotests/assets/grandfather_not_implementing_indexable
+++ b/tests/robotests/assets/grandfather_not_implementing_indexable
@@ -79,6 +79,7 @@
 com.android.settings.SecuritySettings$SecuritySubSettings
 com.android.settings.PrivacySettings
 com.android.settings.WifiCallingSettings
+com.android.settings.WifiCallingSettingsForSub
 com.android.settings.password.SetupChooseLockGeneric$SetupChooseLockGenericFragment
 com.android.settings.SetupRedactionInterstitial$SetupRedactionInterstitialFragment
 com.android.settings.TrustAgentSettings
diff --git a/tests/unit/Android.mk b/tests/unit/Android.mk
index a91dcb1..ec0f0b6 100644
--- a/tests/unit/Android.mk
+++ b/tests/unit/Android.mk
@@ -5,7 +5,7 @@
 LOCAL_MODULE_TAGS := tests
 LOCAL_CERTIFICATE := platform
 
-LOCAL_JAVA_LIBRARIES := android.test.runner
+LOCAL_JAVA_LIBRARIES := android.test.runner telephony-common ims-common
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
     android-support-test \
diff --git a/tests/unit/src/com/android/settings/utils/MockedServiceManager.java b/tests/unit/src/com/android/settings/utils/MockedServiceManager.java
new file mode 100644
index 0000000..ea04974
--- /dev/null
+++ b/tests/unit/src/com/android/settings/utils/MockedServiceManager.java
@@ -0,0 +1,107 @@
+/*
+ * 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.
+ */
+
+package com.android.settings.testutils;
+
+import android.os.IBinder;
+import android.os.ServiceManager;
+import android.util.Log;
+
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+
+// This class is for replacing existing system service with the mocked service.
+// Copied from CellBroadcastReceiver app.
+public final class MockedServiceManager {
+
+    private final String TAG = MockedServiceManager.class.getSimpleName();
+
+    private final HashMap<String, IBinder> mServiceManagerMockedServices = new HashMap<>();
+
+    private final HashMap<InstanceKey, Object> mOldInstances = new HashMap<>();
+
+    private final LinkedList<InstanceKey> mInstanceKeys = new LinkedList<>();
+
+    private static class InstanceKey {
+        final Class mClass;
+        final String mInstName;
+        final Object mObj;
+
+        InstanceKey(final Class c, final String instName, final Object obj) {
+            mClass = c;
+            mInstName = instName;
+            mObj = obj;
+        }
+
+        @Override
+        public int hashCode() {
+            return (mClass.getName().hashCode() * 31 + mInstName.hashCode()) * 31;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj == null || obj.getClass() != getClass()) {
+                return false;
+            }
+
+            InstanceKey other = (InstanceKey) obj;
+            return (other.mClass == mClass && other.mInstName.equals(mInstName)
+                    && other.mObj == mObj);
+        }
+    }
+
+    public MockedServiceManager() throws Exception {
+        replaceInstance(ServiceManager.class, "sCache", null, mServiceManagerMockedServices);
+    }
+
+    public void replaceService(String key, IBinder binder) {
+        mServiceManagerMockedServices.put(key, binder);
+    }
+
+    public void restoreAllServices() throws Exception {
+        restoreInstances();
+    }
+
+    public synchronized void replaceInstance(final Class c, final String instanceName,
+            final Object obj, final Object newValue)
+            throws Exception {
+        Field field = c.getDeclaredField(instanceName);
+        field.setAccessible(true);
+
+        InstanceKey key = new InstanceKey(c, instanceName, obj);
+        if (!mOldInstances.containsKey(key)) {
+            mOldInstances.put(key, field.get(obj));
+            mInstanceKeys.add(key);
+        }
+        field.set(obj, newValue);
+    }
+
+    public synchronized void restoreInstances() throws Exception {
+        Iterator<InstanceKey> it = mInstanceKeys.descendingIterator();
+
+        while (it.hasNext()) {
+            InstanceKey key = it.next();
+            Field field = key.mClass.getDeclaredField(key.mInstName);
+            field.setAccessible(true);
+            field.set(key.mObj, mOldInstances.get(key));
+        }
+
+        mInstanceKeys.clear();
+        mOldInstances.clear();
+    }
+}
diff --git a/tests/unit/src/com/android/settings/wifi/WifiCallingSettingUiTest.java b/tests/unit/src/com/android/settings/wifi/WifiCallingSettingUiTest.java
new file mode 100644
index 0000000..16617d0
--- /dev/null
+++ b/tests/unit/src/com/android/settings/wifi/WifiCallingSettingUiTest.java
@@ -0,0 +1,299 @@
+/**
+ * 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.
+ */
+package com.android.settings.wifi;
+
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.action.ViewActions.click;
+import static android.support.test.espresso.assertion.ViewAssertions.doesNotExist;
+import static android.support.test.espresso.assertion.ViewAssertions.matches;
+import static android.support.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed;
+import static android.support.test.espresso.matcher.ViewMatchers.isSelected;
+import static android.support.test.espresso.matcher.ViewMatchers.withResourceName;
+import static android.support.test.espresso.matcher.ViewMatchers.withText;
+
+import static org.hamcrest.CoreMatchers.allOf;
+import static org.hamcrest.CoreMatchers.anything;
+import static org.junit.Assert.assertEquals;
+import static org.junit.matchers.JUnitMatchers.containsString;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doReturn;
+
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.content.Context;
+import android.content.Intent;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.espresso.NoMatchingViewException;
+import android.support.test.espresso.ViewInteraction;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.uiautomator.UiDevice;
+import android.telephony.SubscriptionInfo;
+
+import com.android.ims.ImsConfig;
+import com.android.ims.ImsManager;
+import com.android.internal.telephony.SubscriptionController;
+import com.android.settings.testutils.MockedServiceManager;
+
+import junit.framework.Assert;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+@RunWith(AndroidJUnit4.class)
+public class WifiCallingSettingUiTest {
+    private static final String SUBSCRIPTION0_NAME = "SUB0";
+    private static final String SUBSCRIPTION1_NAME = "SUB1";
+    private static final String WFC_MODE_TITLE = "Calling preference";
+    private static final String WFC_MODE_WIFI_ONLY = "Wi-Fi only";
+    private static final String WFC_MODE_WIFI_PREFERRED = "Wi-Fi preferred";
+    private static final String WFC_MODE_CELLULAR_PREFERRED = "Mobile preferred";
+
+    private Instrumentation mInstrumentation;
+    private Context mContext;
+    private UiDevice mDevice;
+    @Mock
+    SubscriptionController mSubscriptionController;
+    MockedServiceManager mMockedServiceManager;
+    protected HashMap<Integer, ImsManager> mImsManagerInstances = new HashMap<>();
+    List<SubscriptionInfo> mSils = new ArrayList();
+    @Mock
+    SubscriptionInfo mSubscriptionInfo0;
+    @Mock
+    SubscriptionInfo mSubscriptionInfo1;
+    @Mock
+    ImsManager mImsManager0;
+    @Mock
+    ImsManager mImsManager1;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        mInstrumentation = InstrumentationRegistry.getInstrumentation();
+        mContext = mInstrumentation.getTargetContext();
+        mDevice = UiDevice.getInstance(mInstrumentation);
+
+        mMockedServiceManager = new MockedServiceManager();
+        mMockedServiceManager.replaceService("isub", mSubscriptionController);
+
+        mMockedServiceManager.replaceInstance(
+                ImsManager.class, "sImsManagerInstances", null, mImsManagerInstances);
+        mMockedServiceManager.replaceInstance(
+                SubscriptionController.class, "sInstance", null, mSubscriptionController);
+        doReturn(mSubscriptionController)
+                .when(mSubscriptionController).queryLocalInterface(anyString());
+        mImsManagerInstances.put(0, mImsManager0);
+        mImsManagerInstances.put(1, mImsManager1);
+        doReturn(mSils).when(mSubscriptionController).getActiveSubscriptionInfoList(anyString());
+        doReturn(0).when(mSubscriptionController).getPhoneId(0);
+        doReturn(1).when(mSubscriptionController).getPhoneId(1);
+        doReturn(0).when(mSubscriptionInfo0).getSubscriptionId();
+        doReturn(1).when(mSubscriptionInfo1).getSubscriptionId();
+        doReturn(0).when(mSubscriptionInfo0).getSimSlotIndex();
+        doReturn(1).when(mSubscriptionInfo1).getSimSlotIndex();
+        doReturn(SUBSCRIPTION0_NAME).when(mSubscriptionInfo0).getDisplayName();
+        doReturn(SUBSCRIPTION1_NAME).when(mSubscriptionInfo1).getDisplayName();
+
+        doReturn(true).when(mImsManager0).isWfcEnabledByPlatform();
+        doReturn(true).when(mImsManager0).isNonTtyOrTtyOnVolteEnabled();
+        doReturn(true).when(mImsManager1).isWfcEnabledByPlatform();
+        doReturn(true).when(mImsManager1).isNonTtyOrTtyOnVolteEnabled();
+
+        mDevice.wakeUp();
+        mDevice.pressMenu();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mMockedServiceManager.restoreAllServices();
+    }
+
+    @Test
+    public void testSingleSimUi() throws InterruptedException {
+        configureSingleSim();
+        doReturn(true).when(mImsManager0).isWfcEnabledByUser();
+        doReturn(ImsConfig.WfcModeFeatureValueConstants.WIFI_PREFERRED)
+                .when(mImsManager0).getWfcMode();
+        doReturn(ImsConfig.WfcModeFeatureValueConstants.WIFI_PREFERRED)
+                .when(mImsManager0).getWfcMode(anyBoolean());
+
+        mInstrumentation.startActivitySync(createActivityIntent());
+
+        checkSingleSimUi();
+
+        try {
+            mDevice.setOrientationLeft();
+        } catch (Exception e) {
+            Assert.fail("Exception " + e);
+        }
+
+        // Re-check after rotation. Fragment should be recreated properly.
+        checkSingleSimUi();
+
+        try {
+            mDevice.setOrientationNatural();
+        } catch (Exception e) {
+            Assert.fail("Exception " + e);
+        }
+
+        // Re-check after rotation. Fragment should be resumed properly.
+        checkSingleSimUi();
+    }
+
+    private void checkSingleSimUi() {
+        assertEquals(false, checkExists(onView(withText(SUBSCRIPTION0_NAME))));
+        assertEquals(false, checkExists(onView(withText(SUBSCRIPTION1_NAME))));
+        assertEquals(true, checkExists(onView(withText(WFC_MODE_TITLE))));
+        assertEquals(true, checkExists(onView(withText(WFC_MODE_WIFI_PREFERRED))));
+        checkSwitchBarStatus(true, true);
+        checkEmptyViewStatus(false);
+    }
+
+    @Test
+    public void testNoValidSub() throws InterruptedException {
+        configureDualSim();
+        doReturn(false).when(mImsManager0).isWfcEnabledByPlatform();
+        doReturn(false).when(mImsManager0).isNonTtyOrTtyOnVolteEnabled();
+        doReturn(false).when(mImsManager1).isWfcEnabledByPlatform();
+        doReturn(false).when(mImsManager1).isNonTtyOrTtyOnVolteEnabled();
+        doReturn(false).when(mImsManager0).isWfcEnabledByUser();
+        doReturn(ImsConfig.WfcModeFeatureValueConstants.WIFI_PREFERRED)
+                .when(mImsManager0).getWfcMode();
+        doReturn(ImsConfig.WfcModeFeatureValueConstants.WIFI_PREFERRED)
+                .when(mImsManager0).getWfcMode(anyBoolean());
+
+        Activity activity = mInstrumentation.startActivitySync(createActivityIntent());
+
+        assertEquals(false, checkExists(onView(withText(SUBSCRIPTION0_NAME))));
+        assertEquals(false, checkExists(onView(withText(SUBSCRIPTION1_NAME))));
+        assertEquals(false, checkExists(onView(withText(WFC_MODE_TITLE))));
+
+        checkSwitchBarStatus(false, false);
+        checkEmptyViewStatus(false);
+    }
+
+    @Test
+    public void testWfcDisabled() throws InterruptedException {
+        configureSingleSim();
+        doReturn(false).when(mImsManager0).isWfcEnabledByUser();
+        doReturn(ImsConfig.WfcModeFeatureValueConstants.WIFI_PREFERRED)
+                .when(mImsManager0).getWfcMode();
+        doReturn(ImsConfig.WfcModeFeatureValueConstants.WIFI_PREFERRED)
+                .when(mImsManager0).getWfcMode(anyBoolean());
+
+        Activity activity = mInstrumentation.startActivitySync(createActivityIntent());
+
+        assertEquals(false, checkExists(onView(withText(SUBSCRIPTION0_NAME))));
+        assertEquals(false, checkExists(onView(withText(SUBSCRIPTION1_NAME))));
+        assertEquals(false, checkExists(onView(withText(WFC_MODE_TITLE))));
+
+        checkSwitchBarStatus(true, false);
+        checkEmptyViewStatus(true);
+    }
+
+    @Test
+    public void testDualSimUi() throws InterruptedException {
+        configureDualSim();
+        doReturn(true).when(mImsManager0).isWfcEnabledByUser();
+        doReturn(false).when(mImsManager1).isWfcEnabledByUser();
+        doReturn(ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED)
+                .when(mImsManager0).getWfcMode();
+        doReturn(ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED)
+                .when(mImsManager0).getWfcMode(anyBoolean());
+
+        mInstrumentation.startActivitySync(createActivityIntent());
+
+        assertEquals(true, checkExists(onView(withText(SUBSCRIPTION0_NAME))));
+        assertEquals(true, checkExists(onView(withText(SUBSCRIPTION1_NAME))));
+        assertEquals(true, checkExists(onView(withText(WFC_MODE_TITLE))));
+        assertEquals(true, checkExists(onView(withText(WFC_MODE_CELLULAR_PREFERRED))));
+
+        onView(withText(SUBSCRIPTION0_NAME)).check(matches(isSelected()));
+        checkSwitchBarStatus(true, true);
+        checkEmptyViewStatus(false);
+
+        // Switch to SUB1.
+        onView(withText(SUBSCRIPTION1_NAME)).perform(click());
+
+        checkSwitchBarStatus(true, false);
+        checkEmptyViewStatus(true);
+        onView(withText(SUBSCRIPTION1_NAME)).check(matches(isSelected()));
+    }
+
+    private boolean checkExists(ViewInteraction v) {
+        try {
+            v.check(matches(isCompletelyDisplayed()));
+            return true;
+        } catch (NoMatchingViewException e) {
+            return false;
+        }
+    }
+
+    private Intent createActivityIntent() {
+        Intent intent = new Intent(mContext,
+                com.android.settings.Settings.WifiCallingSettingsActivity.class);
+        intent.setPackage("com.android.settings");
+        intent.setAction("android.intent.action.MAIN");
+        return intent;
+    }
+
+    private void configureSingleSim() {
+        mSils.clear();
+        mSils.add(mSubscriptionInfo0);
+    }
+
+    private void configureDualSim() {
+        mSils.clear();
+        mSils.add(mSubscriptionInfo0);
+        mSils.add(mSubscriptionInfo1);
+    }
+
+    private void checkSwitchBarStatus(boolean shouldDisplay, boolean statusOn) {
+        if (shouldDisplay) {
+            try {
+                onView(allOf(withResourceName("switch_text"), isCompletelyDisplayed()))
+                        .check(matches(withText(containsString(statusOn ? "On" : "Off"))));
+            } catch (Exception e) {
+                Assert.fail("Exception " + e);
+            }
+        } else {
+            onView(allOf(withResourceName("switch_text"), isCompletelyDisplayed()))
+                    .check(doesNotExist());
+        }
+    }
+
+    private void checkEmptyViewStatus(boolean shouldDisplay) {
+        try {
+            if (!shouldDisplay) {
+                onView(allOf(withResourceName("empty"), isCompletelyDisplayed()))
+                        .check(doesNotExist());
+            } else {
+                onView(allOf(withResourceName("empty"), isCompletelyDisplayed()))
+                        .check(matches(anything()));
+            }
+        } catch (Exception e) {
+            Assert.fail("Exception " + e);
+        }
+    }
+}
