Merge "Avoid unnecessary Html.fromHtml()" into main
diff --git a/src/com/android/settings/network/MobileIconGroupExt.kt b/src/com/android/settings/network/MobileIconGroupExt.kt
new file mode 100644
index 0000000..0435ef0
--- /dev/null
+++ b/src/com/android/settings/network/MobileIconGroupExt.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 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.content.Context
+import android.telephony.SubscriptionManager
+import android.text.Html
+import com.android.settingslib.SignalIcon
+
+fun SignalIcon.MobileIconGroup.getSummaryForSub(context: Context, subId: Int): String =
+    when (dataContentDescription) {
+        0 -> ""
+        else -> {
+            SubscriptionManager.getResourcesForSubId(context, subId)
+                .getString(dataContentDescription)
+        }
+    }
+
+fun String.maybeToHtml(): CharSequence = when {
+    contains(HTML_TAG) -> Html.fromHtml(this, Html.FROM_HTML_MODE_LEGACY)
+    else -> this
+}
+
+private const val HTML_TAG = "</"
diff --git a/src/com/android/settings/network/ProviderModelSliceHelper.java b/src/com/android/settings/network/ProviderModelSliceHelper.java
index e0d1eb1..686990b 100644
--- a/src/com/android/settings/network/ProviderModelSliceHelper.java
+++ b/src/com/android/settings/network/ProviderModelSliceHelper.java
@@ -15,6 +15,7 @@
  */
 package com.android.settings.network;
 
+import static com.android.settings.network.MobileIconGroupExtKt.maybeToHtml;
 import static com.android.settings.network.telephony.MobileNetworkUtils.NO_CELL_DATA_TYPE_ICON;
 
 import android.app.PendingIntent;
@@ -31,7 +32,6 @@
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
-import android.text.Html;
 import android.text.TextUtils;
 import android.util.Log;
 
@@ -176,7 +176,7 @@
 
     protected ListBuilder.RowBuilder createCarrierRow(String networkTypeDescription) {
         final String title = getMobileTitle();
-        final String summary = getMobileSummary(networkTypeDescription);
+        final CharSequence summary = getMobileSummary(networkTypeDescription);
         Drawable drawable = mContext.getDrawable(
                 R.drawable.ic_signal_strength_zero_bar_no_internet);
         try {
@@ -195,7 +195,7 @@
                 .setTitleItem(levelIcon, ListBuilder.ICON_IMAGE)
                 .addEndItem(toggleAction)
                 .setPrimaryAction(primaryAction)
-                .setSubtitle(Html.fromHtml(summary, Html.FROM_HTML_MODE_LEGACY));
+                .setSubtitle(summary);
         return rowBuilder;
     }
 
@@ -255,7 +255,7 @@
         return drawable;
     }
 
-    private String getMobileSummary(String networkTypeDescription) {
+    private CharSequence getMobileSummary(String networkTypeDescription) {
         if (!isMobileDataEnabled()) {
             return mContext.getString(R.string.mobile_data_off_summary);
         }
@@ -268,7 +268,7 @@
                     mContext.getString(R.string.mobile_data_connection_active),
                     networkTypeDescription);
         }
-        return summary;
+        return maybeToHtml(summary);
     }
 
     protected String getMobileTitle() {
diff --git a/src/com/android/settings/network/SubscriptionsPreferenceController.java b/src/com/android/settings/network/SubscriptionsPreferenceController.java
index cc62189..0c3e6bd 100644
--- a/src/com/android/settings/network/SubscriptionsPreferenceController.java
+++ b/src/com/android/settings/network/SubscriptionsPreferenceController.java
@@ -19,6 +19,8 @@
 import static androidx.lifecycle.Lifecycle.Event.ON_PAUSE;
 import static androidx.lifecycle.Lifecycle.Event.ON_RESUME;
 
+import static com.android.settings.network.MobileIconGroupExtKt.getSummaryForSub;
+import static com.android.settings.network.MobileIconGroupExtKt.maybeToHtml;
 import static com.android.settings.network.telephony.MobileNetworkUtils.NO_CELL_DATA_TYPE_ICON;
 import static com.android.settingslib.mobile.MobileMappings.getIconKey;
 import static com.android.settingslib.mobile.MobileMappings.mapIconSets;
@@ -39,7 +41,6 @@
 import android.telephony.TelephonyCallback;
 import android.telephony.TelephonyDisplayInfo;
 import android.telephony.TelephonyManager;
-import android.text.Html;
 import android.util.ArraySet;
 import android.util.Log;
 
@@ -289,18 +290,19 @@
         String result = mSubsPrefCtrlInjector.getNetworkType(mContext, mConfig,
                 mTelephonyDisplayInfo, subId, isCarrierNetworkActive, mCarrierNetworkChangeMode);
         if (mSubsPrefCtrlInjector.isActiveCellularNetwork(mContext) || isCarrierNetworkActive) {
+            String connectionState = mContext.getString(isDds
+                    ? R.string.mobile_data_connection_active
+                    : R.string.mobile_data_temp_connection_active);
             if (result.isEmpty()) {
-                result = mContext.getString(isDds ? R.string.mobile_data_connection_active
-                        : R.string.mobile_data_temp_connection_active);
+                return connectionState;
             } else {
-                result = mContext.getString(R.string.preference_summary_default_combination,
-                        mContext.getString(isDds ? R.string.mobile_data_connection_active
-                                : R.string.mobile_data_temp_connection_active), result);
+                result = mContext.getString(
+                        R.string.preference_summary_default_combination, connectionState, result);
             }
         } else if (!isDataInService) {
-            result = mContext.getString(R.string.mobile_data_no_connection);
+            return mContext.getString(R.string.mobile_data_no_connection);
         }
-        return Html.fromHtml(result, Html.FROM_HTML_MODE_LEGACY);
+        return maybeToHtml(result);
     }
 
     @VisibleForTesting
@@ -579,10 +581,7 @@
                 return "";
             }
 
-            int resId = iconGroup.dataContentDescription;
-            return resId != 0
-                    ? SubscriptionManager.getResourcesForSubId(context, subId).getString(resId)
-                    : "";
+            return getSummaryForSub(iconGroup, context, subId);
         }
 
         /**
diff --git a/src/com/android/settings/network/telephony/NetworkProviderWorker.java b/src/com/android/settings/network/telephony/NetworkProviderWorker.java
index c731bfd..ddfc031 100644
--- a/src/com/android/settings/network/telephony/NetworkProviderWorker.java
+++ b/src/com/android/settings/network/telephony/NetworkProviderWorker.java
@@ -17,6 +17,7 @@
 package com.android.settings.network.telephony;
 
 import static com.android.settings.network.InternetUpdater.INTERNET_ETHERNET;
+import static com.android.settings.network.MobileIconGroupExtKt.getSummaryForSub;
 import static com.android.settingslib.mobile.MobileMappings.getIconKey;
 import static com.android.settingslib.mobile.MobileMappings.mapIconSets;
 
@@ -284,19 +285,14 @@
 
     private String updateNetworkTypeName(Context context, Config config,
             TelephonyDisplayInfo telephonyDisplayInfo, int subId) {
-        String iconKey = getIconKey(telephonyDisplayInfo);
-        int resId = mapIconSets(config).get(iconKey).dataContentDescription;
         if (mWifiPickerTrackerHelper != null
                 && mWifiPickerTrackerHelper.isCarrierNetworkActive()) {
             MobileIconGroup carrierMergedWifiIconGroup = TelephonyIcons.CARRIER_MERGED_WIFI;
-            resId = carrierMergedWifiIconGroup.dataContentDescription;
-            return resId != 0
-                    ? SubscriptionManager.getResourcesForSubId(context, subId)
-                    .getString(resId) : "";
+            return getSummaryForSub(carrierMergedWifiIconGroup, context, subId);
         }
 
-        return resId != 0
-                ? SubscriptionManager.getResourcesForSubId(context, subId).getString(resId) : "";
+        String iconKey = getIconKey(telephonyDisplayInfo);
+        return getSummaryForSub(mapIconSets(config).get(iconKey), context, subId);
     }
 
     @VisibleForTesting
diff --git a/tests/spa_unit/src/com/android/settings/network/MobileIconGroupExtTest.kt b/tests/spa_unit/src/com/android/settings/network/MobileIconGroupExtTest.kt
new file mode 100644
index 0000000..641051d
--- /dev/null
+++ b/tests/spa_unit/src/com/android/settings/network/MobileIconGroupExtTest.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2023 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.text.Spanned
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class MobileIconGroupExtTest {
+    @Test
+    fun maybeToHtml_withoutHtmlTag() {
+        val actual = CONNECTED_5G.maybeToHtml()
+
+        assertThat(actual).isSameInstanceAs(CONNECTED_5G)
+    }
+
+    @Test
+    fun maybeToHtml_withHtmlTag() {
+        val actual = CONNECTED_5GE.maybeToHtml()
+
+        assertThat(actual).isInstanceOf(Spanned::class.java)
+    }
+
+    private companion object {
+        private const val CONNECTED_5G = "Connected / 5G"
+        private const val CONNECTED_5GE = "Connected / <i>5G <small>E</small></i>"
+    }
+}
diff --git a/tests/unit/src/com/android/settings/network/ProviderModelSliceHelperTest.java b/tests/unit/src/com/android/settings/network/ProviderModelSliceHelperTest.java
index 436d37f..2d63c71 100644
--- a/tests/unit/src/com/android/settings/network/ProviderModelSliceHelperTest.java
+++ b/tests/unit/src/com/android/settings/network/ProviderModelSliceHelperTest.java
@@ -42,7 +42,6 @@
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
-import android.text.Html;
 
 import androidx.slice.Slice;
 import androidx.slice.builders.ListBuilder;
@@ -56,7 +55,6 @@
 import com.android.wifitrackerlib.WifiEntry;
 
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -166,11 +164,9 @@
         assertThat(testItem).isNull();
     }
 
-    @Ignore
     @Test
     public void createCarrierRow_hasDdsAndActiveNetworkIsNotCellular_verifyTitleAndSummary() {
         String expectDisplayName = "Name1";
-        CharSequence expectedSubtitle = Html.fromHtml("5G", Html.FROM_HTML_MODE_LEGACY);
         String networkType = "5G";
         mockConnections(true, ServiceState.STATE_IN_SERVICE, expectDisplayName,
                 true, true);
@@ -180,19 +176,17 @@
                 networkType);
 
         assertThat(testRowBuild.getTitle()).isEqualTo(expectDisplayName);
-        assertThat(testRowBuild.getSubtitle()).isEqualTo(expectedSubtitle);
+        assertThat(testRowBuild.getSubtitle()).isEqualTo("5G");
     }
 
-    @Ignore
     @Test
     public void createCarrierRow_wifiOnhasDdsAndActiveNetworkIsCellular_verifyTitleAndSummary() {
         String expectDisplayName = "Name1";
         String networkType = "5G";
         String connectedText = ResourcesUtils.getResourcesString(mContext,
                 "mobile_data_connection_active");
-        CharSequence expectedSubtitle = Html.fromHtml(ResourcesUtils.getResourcesString(mContext,
-                "preference_summary_default_combination", connectedText, networkType),
-                Html.FROM_HTML_MODE_LEGACY);
+        CharSequence expectedSubtitle = ResourcesUtils.getResourcesString(mContext,
+                "preference_summary_default_combination", connectedText, networkType);
         mockConnections(true, ServiceState.STATE_IN_SERVICE, expectDisplayName,
                 true, true);
         addNetworkTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
@@ -204,13 +198,11 @@
         assertThat(testRowBuild.getSubtitle()).isEqualTo(expectedSubtitle);
     }
 
-    @Ignore
     @Test
     public void createCarrierRow_noNetworkAvailable_verifyTitleAndSummary() {
         String expectDisplayName = "Name1";
-        CharSequence expectedSubtitle = Html.fromHtml(
-                ResourcesUtils.getResourcesString(mContext, "mobile_data_no_connection"),
-                Html.FROM_HTML_MODE_LEGACY);
+        CharSequence expectedSubtitle =
+                ResourcesUtils.getResourcesString(mContext, "mobile_data_no_connection");
         String networkType = "";
 
         mockConnections(true, ServiceState.STATE_OUT_OF_SERVICE, expectDisplayName,
diff --git a/tests/unit/src/com/android/settings/network/SubscriptionsPreferenceControllerTest.java b/tests/unit/src/com/android/settings/network/SubscriptionsPreferenceControllerTest.java
index c4abdd1..bca12c1 100644
--- a/tests/unit/src/com/android/settings/network/SubscriptionsPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/network/SubscriptionsPreferenceControllerTest.java
@@ -53,7 +53,6 @@
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyDisplayInfo;
 import android.telephony.TelephonyManager;
-import android.text.Html;
 
 import androidx.lifecycle.LifecycleOwner;
 import androidx.lifecycle.LifecycleRegistry;
@@ -266,8 +265,6 @@
     @Test
     @UiThreadTest
     public void displayPreference_providerAndHasMultiSimAndActive_connectedAndRat() {
-        final CharSequence expectedSummary =
-                Html.fromHtml("Connected / 5G", Html.FROM_HTML_MODE_LEGACY);
         final String networkType = "5G";
         final List<SubscriptionInfo> sub = setupMockSubscriptions(2);
         doReturn(sub.get(0)).when(mSubscriptionManager).getDefaultDataSubscriptionInfo();
@@ -281,14 +278,12 @@
         mController.onResume();
         mController.displayPreference(mPreferenceScreen);
 
-        assertThat(mPreferenceCategory.getPreference(0).getSummary()).isEqualTo(expectedSummary);
+        assertThat(mPreferenceCategory.getPreference(0).getSummary()).isEqualTo("Connected / 5G");
     }
 
     @Test
     @UiThreadTest
     public void displayPreference_providerAndHasMultiSimAndActiveCarrierWifi_connectedAndWPlus() {
-        final CharSequence expectedSummary =
-                Html.fromHtml("Connected / W+", Html.FROM_HTML_MODE_LEGACY);
         final String networkType = "W+";
         final List<SubscriptionInfo> sub = setupMockSubscriptions(2);
         doReturn(sub.get(0)).when(mSubscriptionManager).getDefaultDataSubscriptionInfo();
@@ -302,7 +297,7 @@
         mController.onResume();
         mController.displayPreference(mPreferenceScreen);
 
-        assertThat(mPreferenceCategory.getPreference(0).getSummary()).isEqualTo(expectedSummary);
+        assertThat(mPreferenceCategory.getPreference(0).getSummary()).isEqualTo("Connected / W+");
     }
 
     @Test
@@ -310,8 +305,6 @@
     public void displayPreference_providerAndHasMultiSimButMobileDataOff_notAutoConnect() {
         final String dataOffSummary =
                 ResourcesUtils.getResourcesString(mContext, "mobile_data_off_summary");
-        final CharSequence expectedSummary =
-                Html.fromHtml(dataOffSummary, Html.FROM_HTML_MODE_LEGACY);
         final String networkType = "5G";
         final List<SubscriptionInfo> sub = setupMockSubscriptions(2);
         doReturn(sub.get(0)).when(mSubscriptionManager).getDefaultDataSubscriptionInfo();
@@ -324,14 +317,12 @@
         mController.onResume();
         mController.displayPreference(mPreferenceScreen);
 
-        assertThat(mPreferenceCategory.getPreference(0).getSummary())
-            .isEqualTo(expectedSummary.toString());
+        assertThat(mPreferenceCategory.getPreference(0).getSummary()).isEqualTo(dataOffSummary);
     }
 
     @Test
     @UiThreadTest
     public void displayPreference_providerAndHasMultiSimAndNotActive_showRatOnly() {
-        final CharSequence expectedSummary = Html.fromHtml("5G", Html.FROM_HTML_MODE_LEGACY);
         final String networkType = "5G";
         final List<SubscriptionInfo> sub = setupMockSubscriptions(2);
         doReturn(sub.get(0)).when(mSubscriptionManager).getDefaultDataSubscriptionInfo();
@@ -345,7 +336,7 @@
         mController.onResume();
         mController.displayPreference(mPreferenceScreen);
 
-        assertThat(mPreferenceCategory.getPreference(0).getSummary()).isEqualTo(expectedSummary);
+        assertThat(mPreferenceCategory.getPreference(0).getSummary()).isEqualTo(networkType);
     }
 
     @Test
@@ -362,8 +353,6 @@
     @Test
     @UiThreadTest
     public void onTelephonyDisplayInfoChanged_providerAndHasMultiSimAndActive_connectedAndRat() {
-        final CharSequence expectedSummary =
-                Html.fromHtml("Connected / LTE", Html.FROM_HTML_MODE_LEGACY);
         final String networkType = "LTE";
         final List<SubscriptionInfo> sub = setupMockSubscriptions(2);
         final TelephonyDisplayInfo telephonyDisplayInfo =
@@ -383,14 +372,12 @@
         mController.onTelephonyDisplayInfoChanged(sub.get(0).getSubscriptionId(),
                 telephonyDisplayInfo);
 
-        assertThat(mPreferenceCategory.getPreference(0).getSummary()).isEqualTo(expectedSummary);
+        assertThat(mPreferenceCategory.getPreference(0).getSummary()).isEqualTo("Connected / LTE");
     }
 
     @Test
     @UiThreadTest
     public void onTelephonyDisplayInfoChanged_providerAndHasMultiSimAndNotActive_showRat() {
-        final CharSequence expectedSummary =
-                Html.fromHtml("LTE", Html.FROM_HTML_MODE_LEGACY);
         final String networkType = "LTE";
         final List<SubscriptionInfo> sub = setupMockSubscriptions(2);
         final TelephonyDisplayInfo telephonyDisplayInfo =
@@ -409,7 +396,7 @@
         mController.onTelephonyDisplayInfoChanged(sub.get(0).getSubscriptionId(),
                 telephonyDisplayInfo);
 
-        assertThat(mPreferenceCategory.getPreference(0).getSummary()).isEqualTo(expectedSummary);
+        assertThat(mPreferenceCategory.getPreference(0).getSummary()).isEqualTo(networkType);
     }
 
     @Test
@@ -417,8 +404,6 @@
     public void onTelephonyDisplayInfoChanged_providerAndHasMultiSimAndOutOfService_noConnection() {
         final String noConnectionSummary =
                 ResourcesUtils.getResourcesString(mContext, "mobile_data_no_connection");
-        final CharSequence expectedSummary =
-                Html.fromHtml(noConnectionSummary, Html.FROM_HTML_MODE_LEGACY);
         final String networkType = "LTE";
         final List<SubscriptionInfo> sub = setupMockSubscriptions(2);
         final TelephonyDisplayInfo telephonyDisplayInfo =
@@ -437,7 +422,8 @@
         mController.onTelephonyDisplayInfoChanged(sub.get(0).getSubscriptionId(),
                 telephonyDisplayInfo);
 
-        assertThat(mPreferenceCategory.getPreference(0).getSummary()).isEqualTo(expectedSummary);
+        assertThat(mPreferenceCategory.getPreference(0).getSummary())
+                .isEqualTo(noConnectionSummary);
     }
 
     @Test