[Settings] Adjusted the API of Settings app

The API of Settings app get changed in order to support large screen.
This is a fix to adopt the change related to this work.

A short brief:
1. Accept ACTION_MAIN for launching MobileNetworkActivity.
2. Support deep-link intent while MobileNetworkActivity in foreground.
3. Avoid from binding MobileNetworkActivity as a single instance.

Bug: 230047450
Bug: 234406562
Bug: 229371407
Test: local & unittest
Change-Id: Ifcb9d4c564839199d998bd503f390f021c6bf3ad
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 44be1ef..a8e0390 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -249,12 +249,14 @@
             android:name=".Settings$MobileNetworkActivity"
             android:label="@string/network_settings_title"
             android:configChanges="orientation|screenSize|keyboardHidden"
-            android:launchMode="singleInstance"
+            android:launchMode="singleTop"
             android:exported="true">
             <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
                        android:value="com.android.settings.network.telephony.MobileNetworkSettings"/>
             <intent-filter android:priority="1">
                 <!-- Displays the MobileNetworkActivity and opt-in dialog for capability discovery. -->
+                <!-- Please sync with a list created within MobileNetworkIntentConverter.java -->
+                <action android:name="android.intent.action.MAIN" />
                 <action android:name="android.telephony.ims.action.SHOW_CAPABILITY_DISCOVERY_OPT_IN" />
                 <action android:name="android.settings.NETWORK_OPERATOR_SETTINGS" />
                 <action android:name="android.settings.DATA_ROAMING_SETTINGS" />
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index ee0743a..c3ab8e2 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -22,8 +22,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.os.Bundle;
-import android.telephony.SubscriptionInfo;
-import android.telephony.SubscriptionManager;
 import android.telephony.ims.ImsRcsManager;
 import android.text.TextUtils;
 import android.util.FeatureFlagUtils;
@@ -33,8 +31,7 @@
 import com.android.settings.biometrics.face.FaceSettings;
 import com.android.settings.core.FeatureFlags;
 import com.android.settings.enterprise.EnterprisePrivacySettings;
-import com.android.settings.network.SubscriptionUtil;
-import com.android.settings.network.telephony.MobileNetworkUtils;
+import com.android.settings.network.MobileNetworkIntentConverter;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.safetycenter.SafetyCenterManagerWrapper;
 import com.android.settings.security.SecuritySettingsFeatureProvider;
@@ -370,41 +367,37 @@
     public static class PowerMenuSettingsActivity extends SettingsActivity {}
     public static class MobileNetworkActivity extends SettingsActivity {
 
+        public static final String TAG = "MobileNetworkActivity";
         public static final String EXTRA_MMS_MESSAGE = "mms_message";
         public static final String EXTRA_SHOW_CAPABILITY_DISCOVERY_OPT_IN =
                 "show_capability_discovery_opt_in";
 
+        private MobileNetworkIntentConverter mIntentConverter;
+
+        /**
+         * Override of #onNewIntent() requires Activity to have "singleTop" launch mode within
+         * AndroidManifest.xml
+         */
         @Override
-        public Intent getIntent() {
-            final Intent intent = new Intent(super.getIntent());
-            int subId = intent.getIntExtra(android.provider.Settings.EXTRA_SUB_ID,
-                    SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-            SubscriptionInfo subInfo = SubscriptionUtil.getSubscriptionOrDefault(
-                    getApplicationContext(), subId);
-            CharSequence title = SubscriptionUtil.getUniqueSubscriptionDisplayName(
-                    subInfo, getApplicationContext());
-            intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_TITLE, title);
-            intent.putExtra(android.provider.Settings.EXTRA_SUB_ID, subId);
-            if (android.provider.Settings.ACTION_MMS_MESSAGE_SETTING.equals(intent.getAction())) {
-                // highlight "mms_message" preference.
-                intent.putExtra(EXTRA_FRAGMENT_ARG_KEY, EXTRA_MMS_MESSAGE);
-            }
+        protected void onNewIntent(Intent intent) {
+            super.onNewIntent(intent);
 
-            if (doesIntentContainOptInAction(intent)) {
-                intent.putExtra(EXTRA_SHOW_CAPABILITY_DISCOVERY_OPT_IN,
-                        maybeShowContactDiscoveryDialog(subId));
-            }
+            Log.d(TAG, "Starting onNewIntent");
 
-            return intent;
+            createUiFromIntent(null /* savedState */, convertIntent(intent));
         }
 
-        private boolean maybeShowContactDiscoveryDialog(int subId) {
-            // If this activity was launched using ACTION_SHOW_CAPABILITY_DISCOVERY_OPT_IN, show the
-            // associated dialog only if the opt-in has not been granted yet.
-            return MobileNetworkUtils.isContactDiscoveryVisible(getApplicationContext(), subId)
-                    // has the user already enabled this configuration?
-                    && !MobileNetworkUtils.isContactDiscoveryEnabled(
-                            getApplicationContext(), subId);
+        @Override
+        public Intent getIntent() {
+            return convertIntent(super.getIntent());
+        }
+
+        private Intent convertIntent(Intent copyFrom) {
+            if (mIntentConverter == null) {
+                mIntentConverter = new MobileNetworkIntentConverter(this);
+            }
+            Intent intent = mIntentConverter.apply(copyFrom);
+            return (intent == null) ? copyFrom : intent;
         }
 
         public static boolean doesIntentContainOptInAction(Intent intent) {
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index 1a9bdc7..f951501 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -264,7 +264,10 @@
 
         super.onCreate(savedState);
         Log.d(LOG_TAG, "Starting onCreate");
+        createUiFromIntent(savedState, intent);
+    }
 
+    protected void createUiFromIntent(Bundle savedState, Intent intent) {
         long startTime = System.currentTimeMillis();
 
         final FeatureFactory factory = FeatureFactory.getFactory(this);
diff --git a/src/com/android/settings/network/MobileNetworkIntentConverter.java b/src/com/android/settings/network/MobileNetworkIntentConverter.java
new file mode 100644
index 0000000..648ac61
--- /dev/null
+++ b/src/com/android/settings/network/MobileNetworkIntentConverter.java
@@ -0,0 +1,288 @@
+/*
+ * Copyright (C) 2022 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;
+
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.Bundle;
+import android.os.SystemClock;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.telephony.ims.ImsRcsManager;
+import android.text.TextUtils;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
+
+import com.android.settings.Settings.MobileNetworkActivity;
+import com.android.settings.SettingsActivity;
+import com.android.settings.network.telephony.MobileNetworkUtils;
+
+import java.net.URISyntaxException;
+import java.util.Arrays;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Function;
+
+/**
+ * A Java {@link Function} for conversion between {@link Intent} to Settings,
+ * and within Settings itself.
+ */
+public class MobileNetworkIntentConverter implements Function<Intent, Intent> {
+    private static final String TAG = "MobileNetworkIntentConverter";
+
+    private static final ComponentName sTargetComponent = ComponentName
+            .createRelative("com.android.settings",
+                    MobileNetworkActivity.class.getTypeName());
+
+    /**
+     * These actions has better aligned with definitions within AndroidManifest.xml
+     */
+    private static final String [] sPotentialActions = new String [] {
+        null,
+        Intent.ACTION_MAIN,
+        android.provider.Settings.ACTION_NETWORK_OPERATOR_SETTINGS,
+        android.provider.Settings.ACTION_DATA_ROAMING_SETTINGS,
+        android.provider.Settings.ACTION_MMS_MESSAGE_SETTING,
+        ImsRcsManager.ACTION_SHOW_CAPABILITY_DISCOVERY_OPT_IN
+    };
+
+    private static final String RE_ROUTE_TAG = ":reroute:" + TAG;
+    private static final AtomicReference<String> mCachedClassName =
+            new AtomicReference<String>();
+
+    private final Context mAppContext;
+    private final ComponentName mComponent;
+
+    /**
+     * Constructor
+     * @param activity which receiving {@link Intent}
+     */
+    public MobileNetworkIntentConverter(@NonNull Activity activity) {
+        mAppContext = activity.getApplicationContext();
+        mComponent = activity.getComponentName();
+    }
+
+    /**
+     * API defined by {@link Function}.
+     * @param fromIntent is the {@link Intent} for convert.
+     * @return {@link Intent} for sending internally within Settings.
+     *      Return {@code null} when failure.
+     */
+    public Intent apply(Intent fromIntent) {
+        long startTime = SystemClock.elapsedRealtimeNanos();
+
+        Intent potentialReqIntent = null;
+        if (isAttachedToExposedComponents()) {
+            potentialReqIntent = convertFromDeepLink(fromIntent);
+        } else if (mayRequireConvert(fromIntent)) {
+            potentialReqIntent = fromIntent;
+        } else {
+            return null;
+        }
+
+        final Intent reqIntent = potentialReqIntent;
+        String action = reqIntent.getAction();
+
+        // Find out the subscription ID of request.
+        final int subId = extractSubscriptionId(reqIntent);
+
+        // Prepare the arguments Bundle.
+        Function<Intent, Intent> ops = Function.identity();
+
+        if (TextUtils.equals(action,
+                android.provider.Settings.ACTION_NETWORK_OPERATOR_SETTINGS)
+                || TextUtils.equals(action,
+                        android.provider.Settings.ACTION_DATA_ROAMING_SETTINGS)) {
+            // Accepted.
+            ops = ops.andThen(intent -> extractArguments(intent, subId))
+                     .andThen(args -> rePackIntent(args, reqIntent))
+                     .andThen(intent -> updateFragment(intent, mAppContext, subId));
+        } else if (TextUtils.equals(action,
+                android.provider.Settings.ACTION_MMS_MESSAGE_SETTING)) {
+            ops = ops.andThen(intent -> extractArguments(intent, subId))
+                     .andThen(args -> convertMmsArguments(args))
+                     .andThen(args -> rePackIntent(args, reqIntent))
+                     .andThen(intent -> updateFragment(intent, mAppContext, subId));
+        } else if (TextUtils.equals(action,
+                ImsRcsManager.ACTION_SHOW_CAPABILITY_DISCOVERY_OPT_IN)) {
+            ops = ops.andThen(intent -> extractArguments(intent, subId))
+                     .andThen(args -> supportContactDiscoveryDialog(args, mAppContext, subId))
+                     .andThen(args -> rePackIntent(args, reqIntent))
+                     .andThen(intent -> updateFragment(intent, mAppContext, subId));
+        } else if ((sTargetComponent.compareTo(mComponent) == 0)
+                && ((action == null) || Intent.ACTION_MAIN.equals(action))) {
+            Log.d(TAG, "Support default actions direct to this component");
+            ops = ops.andThen(intent -> extractArguments(intent, subId))
+                     .andThen(args -> rePackIntent(args, reqIntent))
+                     .andThen(intent -> replaceIntentAction(intent))
+                     .andThen(intent -> updateFragment(intent, mAppContext, subId));
+        } else {
+            return null;
+        }
+
+        if (!isAttachedToExposedComponents()) {
+            ops = ops.andThen(intent -> configForReRoute(intent));
+        }
+
+        Intent result = ops.apply(reqIntent);
+        if (result != null) {
+            long endTime = SystemClock.elapsedRealtimeNanos();
+            Log.d(TAG, mComponent.toString() + " intent conversion: "
+                    + (endTime - startTime) + " ns");
+        }
+        return result;
+    }
+
+    @VisibleForTesting
+    protected boolean isAttachedToExposedComponents() {
+        return (sTargetComponent.compareTo(mComponent) == 0);
+    }
+
+    protected int extractSubscriptionId(Intent reqIntent) {
+        return reqIntent.getIntExtra(android.provider.Settings.EXTRA_SUB_ID,
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+    }
+
+    protected Bundle extractArguments(Intent reqIntent, int subId) {
+        // Duplicate from SettingsActivity#getIntent()
+        Bundle args = reqIntent.getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS);
+        Bundle result = (args != null) ? new Bundle(args) : new Bundle();
+        result.putParcelable("intent", reqIntent);
+        result.putInt(android.provider.Settings.EXTRA_SUB_ID, subId);
+        return result;
+    }
+
+    protected Bundle convertMmsArguments(Bundle args) {
+        // highlight "mms_message" preference.
+        args.putString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY,
+                MobileNetworkActivity.EXTRA_MMS_MESSAGE);
+        return args;
+    }
+
+    @VisibleForTesting
+    protected boolean mayShowContactDiscoveryDialog(Context context, int subId) {
+        // If this activity was launched using ACTION_SHOW_CAPABILITY_DISCOVERY_OPT_IN, show the
+        // associated dialog only if the opt-in has not been granted yet.
+        return MobileNetworkUtils.isContactDiscoveryVisible(context, subId)
+                // has the user already enabled this configuration?
+                && !MobileNetworkUtils.isContactDiscoveryEnabled(context, subId);
+    }
+
+    protected Bundle supportContactDiscoveryDialog(Bundle args, Context context, int subId) {
+        boolean showDialog = mayShowContactDiscoveryDialog(context, subId);
+        Log.d(TAG, "maybeShowContactDiscoveryDialog subId=" + subId + ", show=" + showDialog);
+        args.putBoolean(MobileNetworkActivity.EXTRA_SHOW_CAPABILITY_DISCOVERY_OPT_IN,
+                showDialog);
+        return args;
+    }
+
+    protected Intent rePackIntent(Bundle args, Intent reqIntent) {
+        Intent intent = new Intent(reqIntent);
+        intent.setComponent(sTargetComponent);
+        intent.putExtra(android.provider.Settings.EXTRA_SUB_ID,
+                args.getInt(android.provider.Settings.EXTRA_SUB_ID));
+        intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS, args);
+        return intent;
+    }
+
+    protected Intent replaceIntentAction(Intent intent) {
+        intent.setAction(android.provider.Settings.ACTION_NETWORK_OPERATOR_SETTINGS);
+        return intent;
+    }
+
+    @VisibleForTesting
+    protected CharSequence getFragmentTitle(Context context, int subId) {
+        SubscriptionInfo subInfo = SubscriptionUtil.getSubscriptionOrDefault(context, subId);
+        return SubscriptionUtil.getUniqueSubscriptionDisplayName(subInfo, context);
+    }
+
+    protected Intent updateFragment(Intent intent, Context context, int subId) {
+        if (intent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_TITLE) == null) {
+            CharSequence title = getFragmentTitle(context, subId);
+            if (title != null) {
+                intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_TITLE, title.toString());
+            }
+        }
+        intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT, getFragmentClass(context));
+        return intent;
+    }
+
+    protected String getFragmentClass(Context context) {
+        String className = mCachedClassName.get();
+        if (className != null) {
+            return className;
+        }
+        try {
+            ActivityInfo ai = context.getPackageManager()
+                    .getActivityInfo(sTargetComponent, PackageManager.GET_META_DATA);
+            if (ai != null && ai.metaData != null) {
+                className = ai.metaData.getString(SettingsActivity.META_DATA_KEY_FRAGMENT_CLASS);
+                if (className != null) {
+                    mCachedClassName.set(className);
+                }
+                return className;
+            }
+        } catch (NameNotFoundException nnfe) {
+            // No recovery
+            Log.d(TAG, "Cannot get Metadata for: " + sTargetComponent.toString());
+        }
+        return null;
+    }
+
+    protected Intent configForReRoute(Intent intent) {
+        if (intent.hasExtra(RE_ROUTE_TAG)) {
+            Log.d(TAG, "Skip re-routed intent " + intent);
+            return null;
+        }
+        return intent.putExtra(RE_ROUTE_TAG, intent.getAction())
+                .setComponent(null);
+    }
+
+    protected static boolean mayRequireConvert(Intent intent) {
+        if (intent == null) {
+            return false;
+        }
+        final String action = intent.getAction();
+        return Arrays.stream(sPotentialActions).anyMatch(potentialAction ->
+                        TextUtils.equals(action, potentialAction)
+                );
+    }
+
+    protected Intent convertFromDeepLink(Intent intent) {
+        if (intent == null) {
+            return null;
+        }
+        if (!TextUtils.equals(intent.getAction(),
+                android.provider.Settings.ACTION_SETTINGS_EMBED_DEEP_LINK_ACTIVITY)) {
+            return intent;
+        }
+        try {
+            return Intent.parseUri(intent.getStringExtra(
+                android.provider.Settings.EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_INTENT_URI),
+                Intent.URI_INTENT_SCHEME);
+        } catch (URISyntaxException exception) {
+            Log.d(TAG, "Intent URI corrupted", exception);
+        }
+        return null;
+    }
+}
diff --git a/tests/unit/src/com/android/settings/network/MobileNetworkIntentConverterTest.java b/tests/unit/src/com/android/settings/network/MobileNetworkIntentConverterTest.java
new file mode 100644
index 0000000..1800156
--- /dev/null
+++ b/tests/unit/src/com/android/settings/network/MobileNetworkIntentConverterTest.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2022 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;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.telephony.ims.ImsRcsManager;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.settings.Settings.MobileNetworkActivity;
+import com.android.settings.SettingsActivity;
+import com.android.settings.Utils;
+import com.android.settings.network.telephony.MobileNetworkSettings;
+
+import java.util.Arrays;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidJUnit4.class)
+public class MobileNetworkIntentConverterTest {
+
+    private static final String ACTIONS_ALLOWED [] = {
+        Intent.ACTION_MAIN,
+        Settings.ACTION_NETWORK_OPERATOR_SETTINGS,
+        Settings.ACTION_DATA_ROAMING_SETTINGS,
+        Settings.ACTION_MMS_MESSAGE_SETTING,
+        ImsRcsManager.ACTION_SHOW_CAPABILITY_DISCOVERY_OPT_IN
+    };
+
+    private static final int TEST_SUBSCRIPTION_ID = 3;
+
+    private static final CharSequence TEST_TITLE_CHAR_SEQUENCE =
+            "Test Title".subSequence(0, 10);
+
+    @Mock
+    private Activity mActivity;
+
+    private MobileNetworkIntentConverter mIntentConverter;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        Context context = spy(ApplicationProvider.getApplicationContext());
+        ComponentName componentName = ComponentName.createRelative(Utils.SETTINGS_PACKAGE_NAME,
+                MobileNetworkActivity.class.getTypeName());
+
+        doReturn(context).when(mActivity).getApplicationContext();
+        doReturn(componentName).when(mActivity).getComponentName();
+
+        mIntentConverter = new MobileNetworkIntentConverter(mActivity) {
+            @Override
+            protected boolean isAttachedToExposedComponents() {
+                return false;
+            }
+        };
+    }
+
+    @Test
+    public void converter_returnNull_whenNotInterested() {
+        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
+        assertThat(mIntentConverter.apply(intent)).isEqualTo(null);
+    }
+
+    @Test
+    public void converter_acceptableIntent_whenInterested() {
+        Arrays.stream(ACTIONS_ALLOWED).forEach(action -> {
+            Intent intent = new Intent(action);
+            assertThat(mIntentConverter.apply(intent)).isNotEqualTo(null);
+        });
+    }
+
+    @Test
+    public void convertSubscriptionId_fromIntentExtra_copyToBundleArgument() {
+        Intent intent = new Intent(ACTIONS_ALLOWED[0]);
+        intent.putExtra(Settings.EXTRA_SUB_ID, TEST_SUBSCRIPTION_ID);
+
+        Intent convertedIntent = mIntentConverter.apply(intent);
+
+        Bundle args = convertedIntent.getBundleExtra(
+                SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS);
+        assertThat(args.getInt(Settings.EXTRA_SUB_ID)).isEqualTo(TEST_SUBSCRIPTION_ID);
+
+        int intExtra = convertedIntent.getIntExtra(
+                Settings.EXTRA_SUB_ID, TEST_SUBSCRIPTION_ID - 1);
+        assertThat(intExtra).isEqualTo(TEST_SUBSCRIPTION_ID);
+    }
+
+    @Test
+    public void supportMms_addExtra_whenIntentForMms() {
+        Intent intent = new Intent(Settings.ACTION_MMS_MESSAGE_SETTING);
+
+        Intent convertedIntent = mIntentConverter.apply(intent);
+
+        Bundle args = convertedIntent.getBundleExtra(
+                    SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS);
+        assertThat(args).isNotEqualTo(null);
+        assertThat(args.getString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY)).isEqualTo(
+                    MobileNetworkActivity.EXTRA_MMS_MESSAGE);
+    }
+
+    @Test
+    public void supportContacts_addExtra_whenIntentForContacts() {
+        Intent intent = new Intent(ImsRcsManager.ACTION_SHOW_CAPABILITY_DISCOVERY_OPT_IN);
+        MobileNetworkIntentConverter converter = new MobileNetworkIntentConverter(mActivity) {
+            @Override
+            protected boolean isAttachedToExposedComponents() {
+                return false;
+            }
+            @Override
+            protected boolean mayShowContactDiscoveryDialog(Context context, int subId) {
+                return true;
+            }
+        };
+
+        Intent convertedIntent = converter.apply(intent);
+
+        Bundle args = convertedIntent.getBundleExtra(
+                    SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS);
+        assertThat(args).isNotEqualTo(null);
+        assertThat(args.getBoolean(MobileNetworkActivity.EXTRA_SHOW_CAPABILITY_DISCOVERY_OPT_IN))
+                .isEqualTo(true);
+    }
+
+    @Test
+    public void convertFormat_forSettings_fragmentPresentation() {
+        MobileNetworkIntentConverter converter = new MobileNetworkIntentConverter(mActivity) {
+            @Override
+            protected boolean isAttachedToExposedComponents() {
+                return false;
+            }
+            @Override
+            protected CharSequence getFragmentTitle(Context context, int subId) {
+                return TEST_TITLE_CHAR_SEQUENCE;
+            }
+        };
+
+        Intent intent = new Intent(ACTIONS_ALLOWED[0]);
+
+        Intent convertedIntent = converter.apply(intent);
+
+        assertThat(convertedIntent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_TITLE))
+                .isEqualTo(TEST_TITLE_CHAR_SEQUENCE.toString());
+        assertThat(convertedIntent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT))
+                .isEqualTo(MobileNetworkSettings.class.getTypeName());
+    }
+
+    @Test
+    public void convertFormat_deepLink_unwrapIntent() {
+        MobileNetworkIntentConverter converter = new MobileNetworkIntentConverter(mActivity) {
+            @Override
+            protected boolean isAttachedToExposedComponents() {
+                return true;
+            }
+        };
+
+        Intent intent = new Intent(ACTIONS_ALLOWED[0]);
+        String intentUri = intent.toUri(Intent.URI_INTENT_SCHEME);
+
+        Intent deepLinkIntent = new Intent(Settings.ACTION_SETTINGS_EMBED_DEEP_LINK_ACTIVITY);
+        deepLinkIntent.putExtra(Settings.EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_INTENT_URI, intentUri);
+
+        assertThat(converter.apply(deepLinkIntent)).isNotEqualTo(null);
+    }
+}