Merge "Add FLAG_RECEIVER_FOREGROUND to run redirect intent at foreground priority"
diff --git a/OWNERS b/OWNERS
index cc683ce..c008e28 100644
--- a/OWNERS
+++ b/OWNERS
@@ -12,5 +12,8 @@
 tmfang@google.com
 yantingyang@google.com
 
+# Emergency only
+luyota@google.com
+
 # Exempt resource files (because they are in a flat directory and too hard to manage via OWNERS)
 per-file *.xml=*
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 5b905fc..5ae01b9 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -12258,6 +12258,15 @@
     <!-- Summary for Wi-Fi calling to explain this feature [CHAR LIMIT=NONE] -->
     <string name="wifi_calling_summary">Use Wi\u2011Fi for calls to improve quality</string>
 
+    <!-- Mobile network settings screen, title of Cross SIM calling setting.  [CHAR LIMIT=NONE] -->
+    <string name="cross_sim_calling_settings_title">Cross SIM calling</string>
+
+    <!-- Cross SIM calling summary.  [CHAR LIMIT=100] -->
+    <string name="cross_sim_calling_setting_summary">Allow another SIM calls and SMSs over this SIM.</string>
+
+    <!-- List of synonyms for the cross SIM calling titles, used to match in settings search [CHAR LIMIT=NONE] -->
+    <string name="keywords_cross_sim_calling">cross sim calling</string>
+
     <!-- Title for enable MMS notification when trying to receive MMS.  [CHAR LIMIT=40] -->
     <string name="enable_receiving_mms_notification_title">Incoming MMS message</string>
     <!-- Title for enable MMS notification when trying to send MMS.  [CHAR LIMIT=40] -->
diff --git a/res/xml/dark_mode_settings.xml b/res/xml/dark_mode_settings.xml
index e076b89..19279e0 100644
--- a/res/xml/dark_mode_settings.xml
+++ b/res/xml/dark_mode_settings.xml
@@ -20,11 +20,9 @@
     android:title="@string/dark_ui_mode"
     settings:keywords="@string/keywords_dark_ui_mode">
 
-    <com.android.settingslib.widget.LayoutPreference
+    <com.android.settingslib.widget.BannerMessagePreference
         android:key="dark_ui_location_off"
-        android:selectable="false"
-        android:layout="@layout/twilight_mode_location_off"
-        settings:allowDividerBelow="true"
+        android:title="@string/twilight_mode_location_off_dialog_message"
         settings:controller="com.android.settings.display.TwilightLocationPreferenceController"/>
 
     <com.android.settingslib.widget.TopIntroPreference
diff --git a/res/xml/mobile_network_settings.xml b/res/xml/mobile_network_settings.xml
index f025f70..bcdd4f8 100644
--- a/res/xml/mobile_network_settings.xml
+++ b/res/xml/mobile_network_settings.xml
@@ -173,6 +173,14 @@
                 android:persistent="true"
                 settings:controller="com.android.settings.network.telephony.VideoCallingPreferenceController"/>
 
+            <SwitchPreference
+                android:key="cross_sim_calling_key"
+                android:title="@string/cross_sim_calling_settings_title"
+                android:persistent="false"
+                android:summary="@string/cross_sim_calling_setting_summary"
+                settings:keywords="@string/keywords_cross_sim_calling"
+                settings:controller="com.android.settings.network.telephony.CrossSimCallingPreferenceController"/>
+
         </PreferenceCategory>
 
         <com.android.settings.network.telephony.cdma.CdmaListPreference
diff --git a/res/xml/night_display_settings.xml b/res/xml/night_display_settings.xml
index 9acccf6..97f5dd2 100644
--- a/res/xml/night_display_settings.xml
+++ b/res/xml/night_display_settings.xml
@@ -20,12 +20,10 @@
     android:title="@string/night_display_title"
     settings:keywords="@string/keywords_display_night_display">
 
-    <com.android.settingslib.widget.LayoutPreference
+    <com.android.settingslib.widget.BannerMessagePreference
         android:key="dark_ui_location_off"
-        android:selectable="false"
-        android:layout="@layout/twilight_mode_location_off"
-        settings:controller="com.android.settings.display.TwilightLocationPreferenceController"
-        settings:allowDividerBelow="true"/>
+        android:title="@string/twilight_mode_location_off_dialog_message"
+        settings:controller="com.android.settings.display.TwilightLocationPreferenceController"/>
 
     <com.android.settingslib.widget.TopIntroPreference
         android:key="night_display_top_intro"
diff --git a/src/com/android/settings/development/qstile/DevelopmentTiles.java b/src/com/android/settings/development/qstile/DevelopmentTiles.java
index b8af740..e64c8c0 100644
--- a/src/com/android/settings/development/qstile/DevelopmentTiles.java
+++ b/src/com/android/settings/development/qstile/DevelopmentTiles.java
@@ -49,6 +49,7 @@
 
 import com.android.internal.app.LocalePicker;
 import com.android.internal.statusbar.IStatusBarService;
+import com.android.internal.view.IInputMethodManager;
 import com.android.settings.R;
 import com.android.settings.development.WirelessDebuggingPreferenceController;
 import com.android.settings.overlay.FeatureFactory;
@@ -197,6 +198,7 @@
         static final int SURFACE_FLINGER_LAYER_TRACE_STATUS_CODE = 1026;
         private IBinder mSurfaceFlinger;
         private IWindowManager mWindowManager;
+        private IInputMethodManager mInputMethodManager;
         private Toast mToast;
 
         @Override
@@ -204,6 +206,8 @@
             super.onCreate();
             mWindowManager = WindowManagerGlobal.getWindowManagerService();
             mSurfaceFlinger = ServiceManager.getService("SurfaceFlinger");
+            mInputMethodManager = IInputMethodManager.Stub.asInterface(
+                    ServiceManager.getService("input_method"));
             Context context = getApplicationContext();
             CharSequence text = "Trace files written to /data/misc/wmtrace";
             mToast = Toast.makeText(context, text, Toast.LENGTH_LONG);
@@ -256,9 +260,19 @@
             return false;
         }
 
+        private boolean isImeTraceEnabled() {
+            try {
+                return mInputMethodManager.isImeTraceEnabled();
+            } catch (RemoteException e) {
+                Log.e(TAG, "Could not get ime trace status, defaulting to false.", e);
+            }
+            return false;
+        }
+
         @Override
         protected boolean isEnabled() {
-            return isWindowTraceEnabled() || isLayerTraceEnabled() || isSystemUiTracingEnabled();
+            return isWindowTraceEnabled() || isLayerTraceEnabled() || isSystemUiTracingEnabled()
+                    || isImeTraceEnabled();
         }
 
         private void setWindowTraceEnabled(boolean isEnabled) {
@@ -308,11 +322,24 @@
             }
         }
 
+        private void setImeTraceEnabled(boolean isEnabled) {
+            try {
+                if (isEnabled) {
+                    mInputMethodManager.startImeTrace();
+                } else {
+                    mInputMethodManager.stopImeTrace();
+                }
+            } catch (RemoteException e) {
+                Log.e(TAG, "Could not set ime trace status." + e.toString());
+            }
+        }
+
         @Override
         protected void setIsEnabled(boolean isEnabled) {
             setWindowTraceEnabled(isEnabled);
             setLayerTraceEnabled(isEnabled);
             setSystemUiTracing(isEnabled);
+            setImeTraceEnabled(isEnabled);
             if (!isEnabled) {
                 mToast.show();
             }
diff --git a/src/com/android/settings/display/TwilightLocationPreferenceController.java b/src/com/android/settings/display/TwilightLocationPreferenceController.java
index 31845c0..af93047 100644
--- a/src/com/android/settings/display/TwilightLocationPreferenceController.java
+++ b/src/com/android/settings/display/TwilightLocationPreferenceController.java
@@ -19,7 +19,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.location.LocationManager;
-import android.view.View;
 
 import androidx.preference.PreferenceScreen;
 
@@ -28,7 +27,7 @@
 import com.android.settings.core.BasePreferenceController;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
-import com.android.settingslib.widget.LayoutPreference;
+import com.android.settingslib.widget.BannerMessagePreference;
 
 /**
  * Controller to take the user to location settings page
@@ -46,14 +45,14 @@
     @Override
     public void displayPreference(PreferenceScreen screen) {
         super.displayPreference(screen);
-        final LayoutPreference preference = screen.findPreference(getPreferenceKey());
-        final View button = preference.findViewById(R.id.go_to_location_setting);
-        button.setOnClickListener(v -> {
-            mMetricsFeatureProvider.logClickedPreference(preference, getMetricsCategory());
-            final Intent intent = new Intent();
-            intent.setClass(mContext, Settings.LocationSettingsActivity.class);
-            mContext.startActivity(intent);
-        });
+        final BannerMessagePreference preference =
+                (BannerMessagePreference) screen.findPreference(getPreferenceKey());
+        preference
+                .setPositiveButtonText(R.string.twilight_mode_launch_location)
+                .setPositiveButtonOnClickListener(v -> {
+                    mMetricsFeatureProvider.logClickedPreference(preference, getMetricsCategory());
+                    launchLocationSettings();
+                });
     }
 
     @Override
@@ -61,4 +60,10 @@
         return mLocationManager.isLocationEnabled() ? CONDITIONALLY_UNAVAILABLE
                 : AVAILABLE_UNSEARCHABLE;
     }
+
+    private void launchLocationSettings() {
+        final Intent intent = new Intent();
+        intent.setClass(mContext, Settings.LocationSettingsActivity.class);
+        mContext.startActivity(intent);
+    }
 }
diff --git a/src/com/android/settings/network/telephony/CrossSimCallingPreferenceController.java b/src/com/android/settings/network/telephony/CrossSimCallingPreferenceController.java
new file mode 100644
index 0000000..01c9707
--- /dev/null
+++ b/src/com/android/settings/network/telephony/CrossSimCallingPreferenceController.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2020 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.network.telephony;
+
+import android.content.Context;
+
+/**
+ * Preference controller for "Cross SIM Calling"
+ **/
+public class CrossSimCallingPreferenceController extends TelephonyTogglePreferenceController {
+
+    /**
+     * Class constructor of cross sim calling.
+     *
+     * @param context of settings
+     * @param key assigned within UI entry of XML file
+     **/
+    public CrossSimCallingPreferenceController(Context context, String key) {
+        super(context, key);
+    }
+
+    /**
+     * Initialization based on given subscription id.
+     *
+     * @param subId is the subscription id
+     * @return this instance after initialization
+     **/
+    public CrossSimCallingPreferenceController init(int subId) {
+        return this;
+    }
+
+    @Override
+    public int getAvailabilityStatus(int subId) {
+        return CONDITIONALLY_UNAVAILABLE;
+    }
+
+    /**
+     * Implementation of abstract methods
+     **/
+    public boolean setChecked(boolean isChecked) {
+        return false;
+    }
+
+    /**
+     * Implementation of abstract methods
+     **/
+    public boolean isChecked() {
+        return false;
+    }
+
+}
diff --git a/src/com/android/settings/network/telephony/MobileNetworkSettings.java b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
index 528e5c7..2a11521 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkSettings.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
@@ -173,8 +173,11 @@
 
         final VideoCallingPreferenceController videoCallingPreferenceController =
                 use(VideoCallingPreferenceController.class).init(mSubId);
+        final CrossSimCallingPreferenceController crossSimCallingPreferenceController =
+                use(CrossSimCallingPreferenceController.class).init(mSubId);
         use(CallingPreferenceCategoryController.class).setChildren(
-                Arrays.asList(wifiCallingPreferenceController, videoCallingPreferenceController));
+                Arrays.asList(wifiCallingPreferenceController, videoCallingPreferenceController,
+                        crossSimCallingPreferenceController));
         use(Enhanced4gLtePreferenceController.class).init(mSubId)
                 .addListener(videoCallingPreferenceController);
         use(Enhanced4gCallingPreferenceController.class).init(mSubId)
diff --git a/src/com/android/settings/widget/HighlightablePreferenceGroupAdapter.java b/src/com/android/settings/widget/HighlightablePreferenceGroupAdapter.java
index 81dc98b..e89e793 100644
--- a/src/com/android/settings/widget/HighlightablePreferenceGroupAdapter.java
+++ b/src/com/android/settings/widget/HighlightablePreferenceGroupAdapter.java
@@ -23,7 +23,6 @@
 import android.animation.ArgbEvaluator;
 import android.animation.ValueAnimator;
 import android.content.Context;
-import android.graphics.Color;
 import android.os.Bundle;
 import android.text.TextUtils;
 import android.util.Log;
@@ -114,7 +113,9 @@
     @VisibleForTesting
     void updateBackground(PreferenceViewHolder holder, int position) {
         View v = holder.itemView;
-        if (position == mHighlightPosition) {
+        if (position == mHighlightPosition
+                && (mHighlightKey != null
+                        && TextUtils.equals(mHighlightKey, getItem(position).getKey()))) {
             // This position should be highlighted. If it's highlighted before - skip animation.
             addHighlightBackground(v, !mFadeInAnimated);
         } else if (Boolean.TRUE.equals(v.getTag(R.id.preference_highlighted))) {
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceControllerTest.java
index 974a52b..6ae670d 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceControllerTest.java
@@ -34,6 +34,7 @@
 
 import com.android.settings.R;
 import com.android.settings.nfc.NfcPreferenceController;
+import com.android.settings.testutils.shadow.ShadowNfcAdapter;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -43,7 +44,7 @@
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.Shadows;
 import org.robolectric.annotation.Config;
-import org.robolectric.shadows.ShadowNfcAdapter;
+import org.robolectric.shadow.api.Shadow;
 import org.robolectric.shadows.ShadowPackageManager;
 import org.robolectric.util.ReflectionHelpers;
 
@@ -70,7 +71,7 @@
         mContentResolver = mContext.getContentResolver();
         mNfcController = new NfcPreferenceController(mContext,
                 NfcPreferenceController.KEY_TOGGLE_NFC);
-        mShadowNfcAdapter = Shadows.shadowOf(NfcAdapter.getNfcAdapter(mContext));
+        mShadowNfcAdapter = Shadow.extract(NfcAdapter.getDefaultAdapter(mContext));
         mShadowPackageManager = Shadows.shadowOf(mContext.getPackageManager());
     }
 
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragmentTest.java
index d6bcb12..aed3787 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragmentTest.java
@@ -18,7 +18,6 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.when;
 
 import android.content.Context;
 import android.nfc.NfcAdapter;
@@ -26,35 +25,38 @@
 
 import com.android.settings.nfc.AndroidBeamPreferenceController;
 import com.android.settings.testutils.shadow.ShadowConnectivityManager;
+import com.android.settings.testutils.shadow.ShadowNfcAdapter;
 import com.android.settings.testutils.shadow.ShadowUserManager;
 import com.android.settingslib.drawer.CategoryKey;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
+import org.robolectric.shadow.api.Shadow;
 
 import java.util.List;
 
 @RunWith(RobolectricTestRunner.class)
 @Config(shadows = {ShadowUserManager.class,
-        ShadowConnectivityManager.class})
+        ShadowConnectivityManager.class, ShadowNfcAdapter.class})
 public class AdvancedConnectedDeviceDashboardFragmentTest {
 
     private AdvancedConnectedDeviceDashboardFragment mFragment;
 
-    @Mock
-    private NfcAdapter mNfcAdapter;
+    private Context mContext;
+    private ShadowNfcAdapter mShadowNfcAdapter;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
 
+        mContext = spy(RuntimeEnvironment.application);
         mFragment = new AdvancedConnectedDeviceDashboardFragment();
+        mShadowNfcAdapter = Shadow.extract(NfcAdapter.getDefaultAdapter(mContext));
     }
 
     @Test
@@ -79,13 +81,10 @@
 
     @Test
     public void testSearchIndexProvider_correctNonIndexables() {
-        Context context = spy(RuntimeEnvironment.application);
-        when(context.getApplicationContext()).thenReturn(context);
-        when(NfcAdapter.getDefaultAdapter(context)).thenReturn(mNfcAdapter);
-        when(mNfcAdapter.isSecureNfcSupported()).thenReturn(true);
+        mShadowNfcAdapter.setSecureNfcSupported(true);
         final List<String> niks =
                 AdvancedConnectedDeviceDashboardFragment.SEARCH_INDEX_DATA_PROVIDER
-                        .getNonIndexableKeys(context);
+                        .getNonIndexableKeys(mContext);
 
         assertThat(niks).contains(AndroidBeamPreferenceController.KEY_ANDROID_BEAM_SETTINGS);
     }
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/NfcAndPaymentFragmentControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/NfcAndPaymentFragmentControllerTest.java
index ffaade3..8acb81c 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/NfcAndPaymentFragmentControllerTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/NfcAndPaymentFragmentControllerTest.java
@@ -29,6 +29,7 @@
 import android.os.UserManager;
 
 import com.android.settings.R;
+import com.android.settings.testutils.shadow.ShadowNfcAdapter;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -37,9 +38,12 @@
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadow.api.Shadow;
 import org.robolectric.util.ReflectionHelpers;
 
 @RunWith(RobolectricTestRunner.class)
+@Config(shadows = ShadowNfcAdapter.class)
 public class NfcAndPaymentFragmentControllerTest {
     private NfcAndPaymentFragmentController mController;
     private Context mContext;
@@ -50,29 +54,28 @@
     private UserManager mUserManager;
     @Mock
     private NfcManager mNfcManager;
-    @Mock
-    private NfcAdapter mNfcAdapter;
+
+    private ShadowNfcAdapter mShadowNfcAdapter;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mContext = spy(RuntimeEnvironment.application);
+        mShadowNfcAdapter = Shadow.extract(NfcAdapter.getDefaultAdapter(mContext));
 
         when(mContext.getApplicationContext()).thenReturn(mContext);
         when(mContext.getPackageManager()).thenReturn(mPackageManager);
         when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
         when(mContext.getSystemService(Context.NFC_SERVICE)).thenReturn(mNfcManager);
-        when(NfcAdapter.getDefaultAdapter(mContext)).thenReturn(mNfcAdapter);
 
         mController = new NfcAndPaymentFragmentController(mContext, "fakeKey");
-        ReflectionHelpers.setField(mController, "mNfcAdapter", mNfcAdapter);
     }
 
     @Test
     public void getAvailabilityStatus_hasNfc_shouldReturnAvailable() {
         when(mPackageManager.hasSystemFeature(anyString())).thenReturn(true);
         when(mUserManager.isAdminUser()).thenReturn(true);
-        when(mNfcAdapter.isEnabled()).thenReturn(true);
+        mShadowNfcAdapter.setEnabled(true);
 
         assertThat(mController.getAvailabilityStatus())
                 .isEqualTo(NfcAndPaymentFragmentController.AVAILABLE);
@@ -87,14 +90,14 @@
 
     @Test
     public void getSummary_nfcOn_shouldProvideOnSummary() {
-        when(mNfcAdapter.isEnabled()).thenReturn(true);
+        mShadowNfcAdapter.setEnabled(true);
         assertThat(mController.getSummary().toString()).contains(
                 mContext.getString(R.string.switch_on_text));
     }
 
     @Test
     public void getSummary_nfcOff_shouldProvideOffSummary() {
-        when(mNfcAdapter.isEnabled()).thenReturn(false);
+        mShadowNfcAdapter.setEnabled(false);
         assertThat(mController.getSummary().toString()).contains(
                 mContext.getString(R.string.switch_off_text));
     }
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/NfcAndPaymentFragmentTest.java b/tests/robotests/src/com/android/settings/connecteddevice/NfcAndPaymentFragmentTest.java
index 46c9cbb..dea0c73 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/NfcAndPaymentFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/NfcAndPaymentFragmentTest.java
@@ -22,9 +22,12 @@
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.nfc.NfcAdapter;
 import android.provider.SearchIndexableResource;
 
+import com.android.settings.testutils.shadow.ShadowNfcAdapter;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -32,16 +35,20 @@
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadow.api.Shadow;
 
 import java.util.List;
 
 @RunWith(RobolectricTestRunner.class)
+@Config(shadows = ShadowNfcAdapter.class)
 public class NfcAndPaymentFragmentTest {
+    @Mock
+    private PackageManager mPackageManager;
+
     private NfcAndPaymentFragment mFragment;
     private Context mContext;
-
-    @Mock
-    private NfcAdapter mNfcAdapter;
+    private ShadowNfcAdapter mShadowNfcAdapter;
 
     @Before
     public void setUp() {
@@ -49,6 +56,9 @@
 
         mFragment = new NfcAndPaymentFragment();
         mContext = spy(RuntimeEnvironment.application);
+        mShadowNfcAdapter = Shadow.extract(NfcAdapter.getDefaultAdapter(mContext));
+
+        when(mContext.getPackageManager()).thenReturn(mPackageManager);
     }
 
     @Test
@@ -64,8 +74,10 @@
     @Test
     public void searchIndexProvider_shouldIndexValidItems() {
         when(mContext.getApplicationContext()).thenReturn(mContext);
-        when(NfcAdapter.getDefaultAdapter(mContext)).thenReturn(mNfcAdapter);
-        when(mNfcAdapter.isSecureNfcSupported()).thenReturn(true);
+        when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_NFC)).thenReturn(true);
+        when(mPackageManager.hasSystemFeature(
+                PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)).thenReturn(true);
+        mShadowNfcAdapter.setSecureNfcSupported(true);
 
         final List<String> niks = NfcAndPaymentFragment.SEARCH_INDEX_DATA_PROVIDER
                 .getNonIndexableKeys(mContext);
diff --git a/tests/robotests/src/com/android/settings/development/qstile/WinscopeTraceTest.java b/tests/robotests/src/com/android/settings/development/qstile/WinscopeTraceTest.java
index cafebe4..b4dab0d 100644
--- a/tests/robotests/src/com/android/settings/development/qstile/WinscopeTraceTest.java
+++ b/tests/robotests/src/com/android/settings/development/qstile/WinscopeTraceTest.java
@@ -37,6 +37,7 @@
 import android.view.IWindowManager;
 import android.widget.Toast;
 
+import com.android.internal.view.IInputMethodManager;
 import com.android.settings.testutils.shadow.ShadowParcel;
 
 import org.junit.After;
@@ -55,6 +56,8 @@
     @Mock
     private IWindowManager mWindowManager;
     @Mock
+    private IInputMethodManager mInputMethodManager;
+    @Mock
     private IBinder mSurfaceFlinger;
     @Mock
     private Toast mToast;
@@ -66,6 +69,7 @@
         MockitoAnnotations.initMocks(this);
         mWinscopeTrace = spy(new DevelopmentTiles.WinscopeTrace());
         ReflectionHelpers.setField(mWinscopeTrace, "mWindowManager", mWindowManager);
+        ReflectionHelpers.setField(mWinscopeTrace, "mInputMethodManager", mInputMethodManager);
         ReflectionHelpers.setField(mWinscopeTrace, "mSurfaceFlinger", mSurfaceFlinger);
         ReflectionHelpers.setField(mWinscopeTrace, "mToast", mToast);
     }
@@ -78,7 +82,7 @@
     @Test
     @Config(shadows = ShadowParcel.class)
     public void wmReturnsTraceEnabled_shouldReturnEnabled() throws RemoteException {
-        // Assume Surface Trace is disabled.
+        // Assume Surface Trace and Input Method Manager are disabled.
         ShadowParcel.sReadBoolResult = false;
         doReturn(true).when(mWindowManager).isWindowTraceEnabled();
         assertThat(mWinscopeTrace.isEnabled()).isTrue();
@@ -87,8 +91,9 @@
     @Test
     @Config(shadows = ShadowParcel.class)
     public void sfReturnsTraceEnabled_shouldReturnEnabled() throws RemoteException {
-        // Assume Window Trace is disabled.
+        // Assume Window Trace and Input Method Manager are disabled.
         doReturn(false).when(mWindowManager).isWindowTraceEnabled();
+        doReturn(false).when(mInputMethodManager).isImeTraceEnabled();
         ShadowParcel.sReadBoolResult = true;
         assertThat(mWinscopeTrace.isEnabled()).isTrue();
         verify(mSurfaceFlinger)
@@ -106,17 +111,49 @@
     }
 
     @Test
-    public void wmAndSfReturnsTraceDisabled_shouldReturnDisabled() throws RemoteException {
+    public void wmAndSfAndImmReturnTraceDisabled_shouldReturnDisabled() throws RemoteException {
         ShadowParcel.sReadBoolResult = false;
         doReturn(false).when(mWindowManager).isWindowTraceEnabled();
+        doReturn(false).when(mInputMethodManager).isImeTraceEnabled();
         assertThat(mWinscopeTrace.isEnabled()).isFalse();
         verify(mSurfaceFlinger)
                 .transact(eq(SURFACE_FLINGER_LAYER_TRACE_STATUS_CODE), any(), any(),
-                        eq(0 /* flags */));
+                eq(0 /* flags */));
         verifyNoMoreInteractions(mSurfaceFlinger);
     }
 
     @Test
+    public void wmAndSfReturnTraceDisabled_immReturnsTraceEnabled_shouldReturnEnabled()
+            throws RemoteException {
+        ShadowParcel.sReadBoolResult = false;
+        doReturn(false).when(mWindowManager).isWindowTraceEnabled();
+        doReturn(true).when(mInputMethodManager).isImeTraceEnabled();
+        assertThat(mWinscopeTrace.isEnabled()).isTrue();
+        verify(mSurfaceFlinger)
+                .transact(eq(SURFACE_FLINGER_LAYER_TRACE_STATUS_CODE), any(), any(),
+                eq(0 /* flags */));
+        verifyNoMoreInteractions(mSurfaceFlinger);
+    }
+
+    @Test
+    @Config(shadows = ShadowParcel.class)
+    public void immReturnsTraceEnabled_shouldReturnEnabled() throws RemoteException {
+        // Assume Window Manager and Surface Trace are disabled.
+        ShadowParcel.sReadBoolResult = false;
+        doReturn(true).when(mInputMethodManager).isImeTraceEnabled();
+        assertThat(mWinscopeTrace.isEnabled()).isTrue();
+    }
+
+    @Test
+    @Config(shadows = ShadowParcel.class)
+    public void immReturnsTraceDisabled_shouldReturnDisabled() throws RemoteException {
+        // Assume Window Manager and Surface Trace are disabled.
+        ShadowParcel.sReadBoolResult = false;
+        doReturn(false).when(mInputMethodManager).isImeTraceEnabled();
+        assertThat(mWinscopeTrace.isEnabled()).isFalse();
+    }
+
+    @Test
     @Config(shadows = ShadowParcel.class)
     public void wmThrowsRemoteExAndSfReturnsTraceDisabled_shouldReturnDisabled()
             throws RemoteException {
@@ -127,9 +164,10 @@
     }
 
     @Test
-    public void sfUnavailableAndWmReturnsTraceDisabled_shouldReturnDisabled()
+    public void sfUnavailableAndWmAndImmReturnTraceDisabled_shouldReturnDisabled()
             throws RemoteException {
         doReturn(false).when(mWindowManager).isWindowTraceEnabled();
+        doReturn(false).when(mInputMethodManager).isImeTraceEnabled();
         ReflectionHelpers.setField(mWinscopeTrace, "mSurfaceFlinger", null);
         assertThat(mWinscopeTrace.isEnabled()).isFalse();
     }
@@ -142,6 +180,13 @@
     }
 
     @Test
+    public void setIsEnableTrue_shouldEnableImeTrace() throws RemoteException {
+        mWinscopeTrace.setIsEnabled(true);
+        verify(mInputMethodManager).startImeTrace();
+        verifyNoMoreInteractions(mInputMethodManager);
+    }
+
+    @Test
     @Config(shadows = ShadowParcel.class)
     public void setIsEnableTrue_shouldEnableLayerTrace() throws RemoteException {
         mWinscopeTrace.setIsEnabled(true);
@@ -163,6 +208,15 @@
 
     @Test
     @Config(shadows = ShadowParcel.class)
+    public void setIsEnableFalse_shouldDisableImeTrace() throws RemoteException {
+        mWinscopeTrace.setIsEnabled(false);
+        verify(mInputMethodManager).stopImeTrace();
+        verifyNoMoreInteractions(mInputMethodManager);
+        verify(mToast).show();
+    }
+
+    @Test
+    @Config(shadows = ShadowParcel.class)
     public void setIsEnableFalse_shouldDisableLayerTrace() throws RemoteException {
         mWinscopeTrace.setIsEnabled(false);
         assertThat(ShadowParcel.sWriteIntResult).isEqualTo(0);
@@ -191,6 +245,17 @@
     }
 
     /**
+     * Verify when input method manager call throws a remote exception, it is handled without
+     * re-throwing the exception.
+     */
+    @Test
+    public void setIsEnableAndImmThrowsRemoteException_shouldFailGracefully()
+            throws RemoteException {
+        doThrow(new RemoteException("Unknown")).when(mInputMethodManager).isImeTraceEnabled();
+        mWinscopeTrace.setIsEnabled(true);
+    }
+
+    /**
      * Verify is surface flinger is not available not calls are made to it.
      */
     @Test
diff --git a/tests/robotests/src/com/android/settings/nfc/AndroidBeamPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/nfc/AndroidBeamPreferenceControllerTest.java
index cd70d66..7e15618 100644
--- a/tests/robotests/src/com/android/settings/nfc/AndroidBeamPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/nfc/AndroidBeamPreferenceControllerTest.java
@@ -31,6 +31,7 @@
 
 import androidx.preference.PreferenceScreen;
 
+import com.android.settings.testutils.shadow.ShadowNfcAdapter;
 import com.android.settingslib.RestrictedLockUtilsInternal;
 import com.android.settingslib.RestrictedPreference;
 
@@ -41,19 +42,20 @@
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadow.api.Shadow;
 import org.robolectric.util.ReflectionHelpers;
 
 import java.util.ArrayList;
 import java.util.List;
 
 @RunWith(RobolectricTestRunner.class)
+@Config(shadows = ShadowNfcAdapter.class)
 public class AndroidBeamPreferenceControllerTest {
 
     Context mContext;
     @Mock
-    private NfcAdapter mNfcAdapter;
-    @Mock
-    NfcManager mManager;
+    NfcManager mNfcManager;
     @Mock
     private UserManager mUserManager;
     @Mock
@@ -63,18 +65,19 @@
 
     private RestrictedPreference mAndroidBeamPreference;
     private AndroidBeamPreferenceController mAndroidBeamController;
+    private ShadowNfcAdapter mShadowNfcAdapter;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mContext = spy(RuntimeEnvironment.application);
+        mShadowNfcAdapter = Shadow.extract(NfcAdapter.getDefaultAdapter(mContext));
 
         when(mContext.getApplicationContext()).thenReturn(mContext);
         when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
-        when(mContext.getSystemService(Context.NFC_SERVICE)).thenReturn(mManager);
+        when(mContext.getSystemService(Context.NFC_SERVICE)).thenReturn(mNfcManager);
         when(RestrictedLockUtilsInternal.hasBaseUserRestriction(mContext,
                 UserManager.DISALLOW_OUTGOING_BEAM, UserHandle.myUserId())).thenReturn(false);
-        when(NfcAdapter.getDefaultAdapter(mContext)).thenReturn(mNfcAdapter);
 
         mAndroidBeamController = new AndroidBeamPreferenceController(mContext,
                 AndroidBeamPreferenceController.KEY_ANDROID_BEAM_SETTINGS);
@@ -95,13 +98,13 @@
 
     @Test
     public void isAvailable_hasNfc_shouldReturnTrue() {
-        when(mNfcAdapter.isEnabled()).thenReturn(true);
+        mShadowNfcAdapter.setEnabled(true);
         assertThat(mAndroidBeamController.isAvailable()).isTrue();
     }
 
     @Test
     public void isAvailable_noNfcFeature_shouldReturnFalse() {
-        when(mNfcAdapter.isEnabled()).thenReturn(true);
+        mShadowNfcAdapter.setEnabled(true);
         when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_NFC_BEAM)).thenReturn(false);
         assertThat(mAndroidBeamController.isAvailable()).isFalse();
     }
@@ -114,7 +117,7 @@
 
     @Test
     public void isBeamEnable_disAllowBeam_shouldReturnFalse() {
-        when(mNfcAdapter.getAdapterState()).thenReturn(NfcAdapter.STATE_OFF);
+        mShadowNfcAdapter.setAdapterState(NfcAdapter.STATE_OFF);
 
         when(RestrictedLockUtilsInternal.hasBaseUserRestriction(mContext,
                 UserManager.DISALLOW_OUTGOING_BEAM, UserHandle.myUserId())).thenReturn(true);
@@ -125,7 +128,7 @@
 
     @Test
     public void isBeamEnable_nfcStateOn_shouldReturnTrue() {
-        when(mNfcAdapter.getAdapterState()).thenReturn(NfcAdapter.STATE_ON);
+        mShadowNfcAdapter.setAdapterState(NfcAdapter.STATE_ON);
         try {
             mAndroidBeamController.onResume();
         } catch (NullPointerException e) {
@@ -137,22 +140,22 @@
 
     @Test
     public void isBeamEnable_nfcStateNotOn_shouldReturnFalse() {
-        when(mNfcAdapter.getAdapterState()).thenReturn(NfcAdapter.STATE_OFF);
+        mShadowNfcAdapter.setAdapterState(NfcAdapter.STATE_OFF);
         mAndroidBeamController.onResume();
         assertThat(mAndroidBeamPreference.isEnabled()).isFalse();
 
-        when(mNfcAdapter.getAdapterState()).thenReturn(NfcAdapter.STATE_TURNING_ON);
+        mShadowNfcAdapter.setAdapterState(NfcAdapter.STATE_TURNING_ON);
         mAndroidBeamController.onResume();
         assertThat(mAndroidBeamPreference.isEnabled()).isFalse();
 
-        when(mNfcAdapter.getAdapterState()).thenReturn(NfcAdapter.STATE_TURNING_OFF);
+        mShadowNfcAdapter.setAdapterState(NfcAdapter.STATE_TURNING_OFF);
         mAndroidBeamController.onResume();
         assertThat(mAndroidBeamPreference.isEnabled()).isFalse();
     }
 
     @Test
     public void updateNonIndexableKeys_available_shouldNotUpdate() {
-        when(mNfcAdapter.isEnabled()).thenReturn(true);
+        mShadowNfcAdapter.setEnabled(true);
         final List<String> keys = new ArrayList<>();
 
         mAndroidBeamController.updateNonIndexableKeys(keys);
diff --git a/tests/robotests/src/com/android/settings/nfc/NfcPaymentPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/nfc/NfcPaymentPreferenceControllerTest.java
index b69e172..026fdee 100644
--- a/tests/robotests/src/com/android/settings/nfc/NfcPaymentPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/nfc/NfcPaymentPreferenceControllerTest.java
@@ -29,6 +29,7 @@
 
 import com.android.settings.R;
 import com.android.settings.nfc.PaymentBackend.PaymentAppInfo;
+import com.android.settings.testutils.shadow.ShadowNfcAdapter;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -37,10 +38,12 @@
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
 
 import java.util.ArrayList;
 
 @RunWith(RobolectricTestRunner.class)
+@Config(shadows = ShadowNfcAdapter.class)
 public class NfcPaymentPreferenceControllerTest {
 
     private static final String PREF_KEY = PaymentSettingsTest.PAYMENT_KEY;
diff --git a/tests/robotests/src/com/android/settings/nfc/NfcPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/nfc/NfcPreferenceControllerTest.java
index 872c712..1d05162 100644
--- a/tests/robotests/src/com/android/settings/nfc/NfcPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/nfc/NfcPreferenceControllerTest.java
@@ -35,6 +35,7 @@
 
 import com.android.settings.nfc.NfcPreferenceController.NfcSliceWorker;
 import com.android.settings.nfc.NfcPreferenceController.NfcSliceWorker.NfcUpdateReceiver;
+import com.android.settings.testutils.shadow.ShadowNfcAdapter;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -43,17 +44,18 @@
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadow.api.Shadow;
 import org.robolectric.util.ReflectionHelpers;
 
 import java.util.ArrayList;
 import java.util.List;
 
 @RunWith(RobolectricTestRunner.class)
+@Config(shadows = ShadowNfcAdapter.class)
 public class NfcPreferenceControllerTest {
 
     @Mock
-    private NfcAdapter mNfcAdapter;
-    @Mock
     NfcManager mManager;
     @Mock
     private UserManager mUserManager;
@@ -63,16 +65,19 @@
     private Context mContext;
     private SwitchPreference mNfcPreference;
     private NfcPreferenceController mNfcController;
+    private ShadowNfcAdapter mShadowNfcAdapter;
+    private NfcAdapter mNfcAdapter;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mContext = spy(RuntimeEnvironment.application);
+        mShadowNfcAdapter = Shadow.extract(NfcAdapter.getDefaultAdapter(mContext));
+        mNfcAdapter = NfcAdapter.getDefaultAdapter(mContext);
 
         when(mContext.getApplicationContext()).thenReturn(mContext);
         when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
         when(mContext.getSystemService(Context.NFC_SERVICE)).thenReturn(mManager);
-        when(NfcAdapter.getDefaultAdapter(mContext)).thenReturn(mNfcAdapter);
 
         mNfcController = new NfcPreferenceController(mContext,
                 NfcPreferenceController.KEY_TOGGLE_NFC);
@@ -83,7 +88,7 @@
 
     @Test
     public void getAvailabilityStatus_hasNfc_shouldReturnAvailable() {
-        when(mNfcAdapter.isEnabled()).thenReturn(true);
+        mShadowNfcAdapter.setEnabled(true);
         assertThat(mNfcController.getAvailabilityStatus())
                 .isEqualTo(NfcPreferenceController.AVAILABLE);
     }
@@ -98,11 +103,11 @@
     @Test
     public void isNfcEnable_nfcStateNotTurning_shouldReturnTrue() {
         mNfcController.displayPreference(mScreen);
-        when(mNfcAdapter.getAdapterState()).thenReturn(NfcAdapter.STATE_ON);
+        mShadowNfcAdapter.setAdapterState(NfcAdapter.STATE_ON);
         mNfcController.onResume();
         assertThat(mNfcPreference.isEnabled()).isTrue();
 
-        when(mNfcAdapter.getAdapterState()).thenReturn(NfcAdapter.STATE_OFF);
+        mShadowNfcAdapter.setAdapterState(NfcAdapter.STATE_OFF);
         mNfcController.onResume();
         assertThat(mNfcPreference.isEnabled()).isTrue();
     }
@@ -110,11 +115,11 @@
     @Test
     public void isNfcEnable_nfcStateTurning_shouldReturnFalse() {
         mNfcController.displayPreference(mScreen);
-        when(mNfcAdapter.getAdapterState()).thenReturn(NfcAdapter.STATE_TURNING_ON);
+        mShadowNfcAdapter.setAdapterState(NfcAdapter.STATE_TURNING_ON);
         mNfcController.onResume();
         assertThat(mNfcPreference.isEnabled()).isFalse();
 
-        when(mNfcAdapter.getAdapterState()).thenReturn(NfcAdapter.STATE_TURNING_OFF);
+        mShadowNfcAdapter.setAdapterState(NfcAdapter.STATE_TURNING_OFF);
         mNfcController.onResume();
         assertThat(mNfcPreference.isEnabled()).isFalse();
     }
@@ -122,29 +127,29 @@
     @Test
     public void isNfcChecked_nfcStateOn_shouldReturnTrue() {
         mNfcController.displayPreference(mScreen);
-        when(mNfcAdapter.getAdapterState()).thenReturn(NfcAdapter.STATE_ON);
+        mShadowNfcAdapter.setAdapterState(NfcAdapter.STATE_ON);
         mNfcController.onResume();
         assertThat(mNfcPreference.isChecked()).isTrue();
 
-        when(mNfcAdapter.getAdapterState()).thenReturn(NfcAdapter.STATE_TURNING_ON);
+        mShadowNfcAdapter.setAdapterState(NfcAdapter.STATE_TURNING_ON);
         mNfcController.onResume();
         assertThat(mNfcPreference.isChecked()).isTrue();
     }
 
     @Test
     public void isNfcChecked_nfcStateOff_shouldReturnFalse() {
-        when(mNfcAdapter.getAdapterState()).thenReturn(NfcAdapter.STATE_OFF);
+        mShadowNfcAdapter.setAdapterState(NfcAdapter.STATE_OFF);
         mNfcController.onResume();
         assertThat(mNfcPreference.isChecked()).isFalse();
 
-        when(mNfcAdapter.getAdapterState()).thenReturn(NfcAdapter.STATE_TURNING_OFF);
+        mShadowNfcAdapter.setAdapterState(NfcAdapter.STATE_TURNING_OFF);
         mNfcController.onResume();
         assertThat(mNfcPreference.isChecked()).isFalse();
     }
 
     @Test
     public void updateNonIndexableKeys_available_shouldNotUpdate() {
-        when(mNfcAdapter.isEnabled()).thenReturn(true);
+        mShadowNfcAdapter.setEnabled(true);
         final List<String> keys = new ArrayList<>();
 
         mNfcController.updateNonIndexableKeys(keys);
@@ -167,7 +172,7 @@
         mNfcController.setChecked(true);
         mNfcController.onResume();
 
-        verify(mNfcAdapter).enable();
+        assertThat(mNfcAdapter.isEnabled()).isTrue();
     }
 
     @Test
@@ -175,7 +180,7 @@
         mNfcController.setChecked(false);
         mNfcController.onResume();
 
-        verify(mNfcAdapter).disable();
+        assertThat(mNfcAdapter.isEnabled()).isFalse();
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/nfc/PaymentSettingsTest.java b/tests/robotests/src/com/android/settings/nfc/PaymentSettingsTest.java
index 6740cb0..32eedd8 100644
--- a/tests/robotests/src/com/android/settings/nfc/PaymentSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/nfc/PaymentSettingsTest.java
@@ -33,6 +33,8 @@
 import androidx.preference.PreferenceManager;
 import androidx.preference.PreferenceScreen;
 
+import com.android.settings.testutils.shadow.ShadowNfcAdapter;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -48,7 +50,7 @@
 import java.util.List;
 
 @RunWith(RobolectricTestRunner.class)
-@Config(shadows = PaymentSettingsTest.ShadowPaymentBackend.class)
+@Config(shadows = {PaymentSettingsTest.ShadowPaymentBackend.class, ShadowNfcAdapter.class})
 public class PaymentSettingsTest {
 
     static final String PAYMENT_KEY = "nfc_payment";
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowNfcAdapter.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowNfcAdapter.java
index fb8c068..54f665c 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowNfcAdapter.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowNfcAdapter.java
@@ -16,6 +16,8 @@
 
 package com.android.settings.testutils.shadow;
 
+import static org.robolectric.shadow.api.Shadow.newInstanceOf;
+
 import android.app.Activity;
 import android.content.Context;
 import android.nfc.NfcAdapter;
@@ -24,16 +26,18 @@
 import org.robolectric.annotation.Implementation;
 import org.robolectric.annotation.Implements;
 import org.robolectric.annotation.Resetter;
-import org.robolectric.util.ReflectionHelpers;
-import org.robolectric.util.ReflectionHelpers.ClassParameter;
 
 /**
  * Shadow of {@link NfcAdapter}.
  */
-@Implements(NfcAdapter.class)
-public class ShadowNfcAdapter {
+@Implements(value = NfcAdapter.class)
+public class ShadowNfcAdapter extends org.robolectric.shadows.ShadowNfcAdapter {
     private static boolean sReaderModeEnabled;
+    private static Object sNfcAdapter = newInstanceOf("android.nfc.NfcAdapter");
+
     private boolean mIsNfcEnabled = false;
+    private int mState = NfcAdapter.STATE_ON;
+    private boolean mIsSecureNfcSupported = false;
 
     @Implementation
     protected void enableReaderMode(Activity activity, NfcAdapter.ReaderCallback callback,
@@ -43,8 +47,7 @@
 
     @Implementation
     protected static NfcAdapter getDefaultAdapter(Context context) {
-        return ReflectionHelpers.callConstructor(
-                NfcAdapter.class, ClassParameter.from(Context.class, context));
+        return (NfcAdapter) sNfcAdapter;
     }
 
     @Implementation
@@ -52,6 +55,28 @@
         return mIsNfcEnabled;
     }
 
+    public void setEnabled(boolean enable) {
+        mIsNfcEnabled = enable;
+    }
+
+    @Implementation
+    protected int getAdapterState() {
+        return mState;
+    }
+
+    public void setAdapterState(int state) {
+        this.mState = state;
+    }
+
+    @Implementation
+    protected boolean isSecureNfcSupported() {
+        return mIsSecureNfcSupported;
+    }
+
+    public void setSecureNfcSupported(boolean supported) {
+        this.mIsSecureNfcSupported = supported;
+    }
+
     @Implementation
     protected boolean enable() {
         mIsNfcEnabled = true;
diff --git a/tests/robotests/src/com/android/settings/widget/HighlightablePreferenceGroupAdapterTest.java b/tests/robotests/src/com/android/settings/widget/HighlightablePreferenceGroupAdapterTest.java
index bf6b95e..23b7edc 100644
--- a/tests/robotests/src/com/android/settings/widget/HighlightablePreferenceGroupAdapterTest.java
+++ b/tests/robotests/src/com/android/settings/widget/HighlightablePreferenceGroupAdapterTest.java
@@ -19,6 +19,7 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
@@ -32,6 +33,7 @@
 import android.os.Bundle;
 import android.view.View;
 
+import androidx.preference.Preference;
 import androidx.preference.PreferenceCategory;
 import androidx.preference.PreferenceScreen;
 import androidx.preference.PreferenceViewHolder;
@@ -65,14 +67,18 @@
     private Context mContext;
     private HighlightablePreferenceGroupAdapter mAdapter;
     private PreferenceViewHolder mViewHolder;
+    private Preference mPreference;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mContext = RuntimeEnvironment.application;
+        mPreference = new Preference(mContext);
+        mPreference.setKey(TEST_KEY);
         when(mPreferenceCatetory.getContext()).thenReturn(mContext);
         mAdapter = spy(new HighlightablePreferenceGroupAdapter(mPreferenceCatetory, TEST_KEY,
                 false /* highlighted*/));
+        when(mAdapter.getItem(anyInt())).thenReturn(mPreference);
         mViewHolder = PreferenceViewHolder.createInstanceForTests(
                 View.inflate(mContext, R.layout.app_preference_item, null));
     }
diff --git a/tests/unit/src/com/android/settings/network/telephony/CrossSimCallingPreferenceControllerTest.java b/tests/unit/src/com/android/settings/network/telephony/CrossSimCallingPreferenceControllerTest.java
new file mode 100644
index 0000000..968afb8
--- /dev/null
+++ b/tests/unit/src/com/android/settings/network/telephony/CrossSimCallingPreferenceControllerTest.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2020 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.network.telephony;
+
+import static org.mockito.Mockito.spy;
+
+import android.content.Context;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class CrossSimCallingPreferenceControllerTest {
+    private static final int SUB_ID = 2;
+
+    private CrossSimCallingPreferenceController mController;
+    private Context mContext;
+
+    @Before
+    public void setUp() {
+        mContext = spy(ApplicationProvider.getApplicationContext());
+
+        mController = new CrossSimCallingPreferenceController(mContext, "cross_sim_calling_key");
+        mController.init(SUB_ID);
+    }
+}