Merge "Add Dynamic tiles"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index e57705e..a12c982 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -609,8 +609,6 @@
             </intent-filter>
             <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
                 android:value="com.android.settings.inputmethod.AvailableVirtualKeyboardFragment" />
-            <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
-                android:value="true" />
         </activity>
 
         <activity
@@ -679,8 +677,6 @@
                 <category android:name="android.intent.category.VOICE_LAUNCH" />
                 <category android:name="android.intent.category.DEFAULT" />
             </intent-filter>
-            <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
-                android:value="true" />
         </activity>
 
         <activity
@@ -698,8 +694,6 @@
             </intent-filter>
             <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
                 android:value="com.android.settings.inputmethod.UserDictionaryList" />
-            <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
-                android:value="true" />
         </activity>
 
         <activity android:name=".inputmethod.UserDictionaryAddWordActivity"
@@ -713,8 +707,6 @@
                 <action android:name="com.android.settings.USER_DICTIONARY_INSERT" />
                 <category android:name="android.intent.category.DEFAULT" />
             </intent-filter>
-            <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
-                android:value="true" />
         </activity>
 
         <activity
diff --git a/res/layout-sw360dp/homepage_condition_full_tile.xml b/res/layout-sw360dp/homepage_condition_full_tile.xml
index 4a8ad0a..e1c7b01 100644
--- a/res/layout-sw360dp/homepage_condition_full_tile.xml
+++ b/res/layout-sw360dp/homepage_condition_full_tile.xml
@@ -26,7 +26,7 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:paddingStart="@dimen/homepage_card_padding_start"
-        android:paddingEnd="@dimen/homepage_card_padding_end"
+        android:paddingEnd="@dimen/homepage_full_card_padding_end"
         android:paddingTop="@dimen/homepage_condition_full_card_padding_top"
         android:paddingBottom="@dimen/homepage_condition_full_card_padding_bottom"
         android:orientation="horizontal"
diff --git a/res/layout/homepage_dismissal_view.xml b/res/layout/homepage_dismissal_view.xml
index 7d1abf3..6d8f711 100644
--- a/res/layout/homepage_dismissal_view.xml
+++ b/res/layout/homepage_dismissal_view.xml
@@ -26,31 +26,32 @@
     <TextView
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_marginLeft="@dimen/homepage_card_padding_start"
-        android:layout_marginTop="@dimen/homepage_card_padding_start"
+        android:layout_marginStart="@dimen/homepage_card_dismissal_side_margin"
+        android:layout_marginTop="@dimen/homepage_card_dismissal_margin_top"
         android:text="@string/contextual_card_dismiss_confirm_message"
         android:textAppearance="@style/TextAppearance.ContextualCardDismissalText"/>
 
     <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="match_parent"
+        android:layout_marginBottom="@dimen/homepage_card_dismissal_margin_bottom"
         android:gravity="bottom|end">
 
         <Button
-            android:id="@+id/keep"
-            style="@style/ContextualCardDismissalButton"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginBottom="@dimen/homepage_card_dismissal_margin_bottom"
-            android:text="@string/contextual_card_dismiss_keep"/>
-
-        <Button
             android:id="@+id/remove"
             style="@style/ContextualCardDismissalButton"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_marginBottom="@dimen/homepage_card_dismissal_margin_bottom"
             android:text="@string/contextual_card_dismiss_remove"/>
 
+        <Button
+            android:id="@+id/keep"
+            style="@style/ContextualCardDismissalButton"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="@dimen/homepage_card_dismissal_button_side_margin"
+            android:layout_marginEnd="@dimen/homepage_card_dismissal_button_side_margin"
+            android:text="@string/contextual_card_dismiss_keep"/>
+
     </LinearLayout>
 </LinearLayout>
\ No newline at end of file
diff --git a/res/layout/mobile_network_settings_container_v2.xml b/res/layout/mobile_network_settings_container_v2.xml
new file mode 100644
index 0000000..ed7296b
--- /dev/null
+++ b/res/layout/mobile_network_settings_container_v2.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2019 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+
+    <Toolbar
+        android:id="@+id/mobile_action_bar"
+        style="?android:attr/actionBarStyle"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:navigationContentDescription="@*android:string/action_bar_up_description"
+        android:theme="?android:attr/actionBarTheme"/>
+
+    <FrameLayout
+        android:id="@+id/main_content"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"/>
+
+</LinearLayout>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 8b535e3..416c8d7 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -329,10 +329,16 @@
     <dimen name="homepage_card_side_margin">4dp</dimen>
     <dimen name="homepage_card_padding_start">16dp</dimen>
     <dimen name="homepage_card_padding_end">16dp</dimen>
+    <dimen name="homepage_full_card_padding_end">12dp</dimen>
     <dimen name="homepage_half_card_padding_top">12dp</dimen>
     <dimen name="homepage_half_card_padding_bottom">16dp</dimen>
     <dimen name="homepage_half_card_title_margin_top">12dp</dimen>
+
+    <!-- Homepage dismissal cards size and padding -->
+    <dimen name="homepage_card_dismissal_margin_top">16dp</dimen>
     <dimen name="homepage_card_dismissal_margin_bottom">2dp</dimen>
+    <dimen name="homepage_card_dismissal_side_margin">16dp</dimen>
+    <dimen name="homepage_card_dismissal_button_side_margin">6dp</dimen>
 
     <!-- Horizontal divider size and margin -->
     <dimen name="horizontal_divider_margin_top">4dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 56735a5..313521a 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -10344,6 +10344,34 @@
     <!-- Mobile network settings screen, title of Mobile data switch preference [CHAR LIMIT=NONE] -->
     <string name="mobile_data_settings_summary">Access data using mobile network</string>
 
+    <!-- Summary of the 'Mobile network' item on the Network & internet page when there is no mobile
+         service setup yet (eg no SIM card inserted and no eSIM configured). Tapping it leads to a
+         UI where the user can setup service. [CHAR LIMIT=50] -->
+    <string name="mobile_network_summary_add_a_network">Add a network</string>
+    <!-- Summary of the 'Mobile network' item on the Network & internet page when there is more than
+         one mobile service configured (aka "dual SIM") - it shows a count of SIM/eSIM and tapping
+         it leads to a page showing a list of the mobile service subscriptions. [CHAR LIMIT=40] -->
+    <plurals name="mobile_network_summary_count">
+        <item quantity="one"><xliff:g id="count" example="1">%1$d</xliff:g> SIM</item>
+        <item quantity="other"><xliff:g id="count" example="2">%1$d</xliff:g> SIMs</item>
+    </plurals>
+
+    <!-- Title of item shown at the bottom of the page listing multiple mobile service
+         subscriptions; tapping it leads to a UI to add more [CHAR LIMIT=40] -->
+    <string name="mobile_network_list_add_more">Add more</string>
+    <!-- Summary for an item in the page listing multiple mobile service subscriptions, indicating
+         that service is active and is tied to a physical SIM card [CHAR LIMIT=40] -->
+    <string name="mobile_network_active_sim">Active SIM</string>
+    <!-- Summary for an item in the page listing multiple mobile service subscriptions, indicating
+         that service is inactive and is tied to a physical SIM card [CHAR LIMIT=40] -->
+    <string name="mobile_network_inactive_sim">Inactive SIM</string>
+    <!-- Summary for an item in the page listing multiple mobile service subscriptions, indicating
+         that service is active and is tied to an eSIM profile [CHAR LIMIT=40] -->
+    <string name="mobile_network_active_esim">Active eSIM</string>
+    <!-- Summary for an item in the page listing multiple mobile service subscriptions, indicating
+         that service is inactive and is tied to an eSIM profile [CHAR LIMIT=40] -->
+    <string name="mobile_network_inactive_esim">Inactive eSIM</string>
+
     <!-- Title for preferred network type [CHAR LIMIT=NONE] -->
     <string name="preferred_network_mode_title">Preferred network type</string>
     <!-- Summary for preferred network type [CHAR LIMIT=NONE] -->
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 1668b37..8b92d7e 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -460,6 +460,7 @@
 
     <style name="ContextualCardDismissalButton"
            parent="android:Widget.DeviceDefault.Button.Borderless.Colored">
+        <item name="android:minWidth">10dp</item>
         <item name="android:minHeight">16dp</item>
         <item name="android:textAllCaps">false</item>
     </style>
diff --git a/res/xml/mobile_network_list.xml b/res/xml/mobile_network_list.xml
new file mode 100644
index 0000000..81704e5
--- /dev/null
+++ b/res/xml/mobile_network_list.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+
+<PreferenceScreen
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:key="mobile_network_list_screen"
+    android:title="@string/network_settings_title">
+
+    <Preference
+        android:key="add_more"
+        android:title="@string/mobile_network_list_add_more"
+        android:icon="@drawable/ic_menu_add"
+        android:order="100" />
+
+</PreferenceScreen>
diff --git a/res/xml/network_and_internet_v2.xml b/res/xml/network_and_internet_v2.xml
index 8e0b426..bde7889 100644
--- a/res/xml/network_and_internet_v2.xml
+++ b/res/xml/network_and_internet_v2.xml
@@ -40,15 +40,14 @@
     </com.android.settings.widget.MasterSwitchPreference>
 
     <com.android.settingslib.RestrictedPreference
-        android:key="mobile_network_settings"
+        android:key="mobile_network_list"
         android:title="@string/network_settings_title"
         android:summary="@string/summary_placeholder"
         android:icon="@drawable/ic_network_cell"
         android:order="-15"
         settings:keywords="@string/keywords_more_mobile_networks"
         settings:userRestriction="no_config_mobile_networks"
-        settings:useAdminDisabledSummary="true">
-    </com.android.settingslib.RestrictedPreference>
+        settings:useAdminDisabledSummary="true" />
 
     <com.android.settingslib.RestrictedSwitchPreference
         android:key="toggle_airplane"
diff --git a/src/com/android/settings/development/ForceMSAAPreferenceController.java b/src/com/android/settings/development/ForceMSAAPreferenceController.java
index be6efca..ce539c7 100644
--- a/src/com/android/settings/development/ForceMSAAPreferenceController.java
+++ b/src/com/android/settings/development/ForceMSAAPreferenceController.java
@@ -17,7 +17,7 @@
 package com.android.settings.development;
 
 import android.content.Context;
-import android.os.SystemProperties;
+import android.sysprop.DisplayProperties;
 
 import androidx.annotation.VisibleForTesting;
 import androidx.preference.Preference;
@@ -32,9 +32,6 @@
 
     private static final String FORCE_MSAA_KEY = "force_msaa";
 
-    @VisibleForTesting
-    static final String MSAA_PROPERTY = "debug.egl.force_msaa";
-
     public ForceMSAAPreferenceController(Context context) {
         super(context);
     }
@@ -47,22 +44,21 @@
     @Override
     public boolean onPreferenceChange(Preference preference, Object newValue) {
         final boolean isEnabled = (Boolean) newValue;
-        SystemProperties.set(MSAA_PROPERTY,
-                isEnabled ? Boolean.toString(true) : Boolean.toString(false));
+        DisplayProperties.debug_force_msaa(isEnabled);
         SystemPropPoker.getInstance().poke();
         return true;
     }
 
     @Override
     public void updateState(Preference preference) {
-        final boolean isEnabled = SystemProperties.getBoolean(MSAA_PROPERTY, false /* default */);
+        final boolean isEnabled = DisplayProperties.debug_force_msaa().orElse(false);
         ((SwitchPreference) mPreference).setChecked(isEnabled);
     }
 
     @Override
     protected void onDeveloperOptionsSwitchDisabled() {
         super.onDeveloperOptionsSwitchDisabled();
-        SystemProperties.set(MSAA_PROPERTY, Boolean.toString(false));
+        DisplayProperties.debug_force_msaa(false);
         ((SwitchPreference) mPreference).setChecked(false);
     }
 }
diff --git a/src/com/android/settings/development/RtlLayoutPreferenceController.java b/src/com/android/settings/development/RtlLayoutPreferenceController.java
index 97b366a..913259e 100644
--- a/src/com/android/settings/development/RtlLayoutPreferenceController.java
+++ b/src/com/android/settings/development/RtlLayoutPreferenceController.java
@@ -17,8 +17,8 @@
 package com.android.settings.development;
 
 import android.content.Context;
-import android.os.SystemProperties;
 import android.provider.Settings;
+import android.sysprop.DisplayProperties;
 
 import androidx.annotation.VisibleForTesting;
 import androidx.preference.Preference;
@@ -79,8 +79,6 @@
         Settings.Global.putInt(mContext.getContentResolver(),
                 Settings.Global.DEVELOPMENT_FORCE_RTL,
                 isEnabled ? SETTING_VALUE_ON : SETTING_VALUE_OFF);
-        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL,
-                isEnabled ? Integer.toString(SETTING_VALUE_ON)
-                        : Integer.toString(SETTING_VALUE_OFF));
+        DisplayProperties.debug_force_rtl(isEnabled);
     }
 }
diff --git a/src/com/android/settings/development/ShowLayoutBoundsPreferenceController.java b/src/com/android/settings/development/ShowLayoutBoundsPreferenceController.java
index fb091b7..18551bf 100644
--- a/src/com/android/settings/development/ShowLayoutBoundsPreferenceController.java
+++ b/src/com/android/settings/development/ShowLayoutBoundsPreferenceController.java
@@ -17,7 +17,7 @@
 package com.android.settings.development;
 
 import android.content.Context;
-import android.os.SystemProperties;
+import android.sysprop.DisplayProperties;
 import android.view.View;
 
 import androidx.preference.Preference;
@@ -44,23 +44,21 @@
     @Override
     public boolean onPreferenceChange(Preference preference, Object newValue) {
         final boolean isEnabled = (Boolean) newValue;
-        SystemProperties.set(View.DEBUG_LAYOUT_PROPERTY,
-                isEnabled ? Boolean.toString(true) : Boolean.toString(false));
+        DisplayProperties.debug_layout(isEnabled);
         SystemPropPoker.getInstance().poke();
         return true;
     }
 
     @Override
     public void updateState(Preference preference) {
-        final boolean isEnabled = SystemProperties.getBoolean(View.DEBUG_LAYOUT_PROPERTY,
-                false /* default */);
+        final boolean isEnabled = DisplayProperties.debug_layout().orElse(false);
         ((SwitchPreference) mPreference).setChecked(isEnabled);
     }
 
     @Override
     protected void onDeveloperOptionsSwitchDisabled() {
         super.onDeveloperOptionsSwitchDisabled();
-        SystemProperties.set(View.DEBUG_LAYOUT_PROPERTY, Boolean.toString(false));
+        DisplayProperties.debug_layout(false);
         ((SwitchPreference) mPreference).setChecked(false);
     }
 }
diff --git a/src/com/android/settings/development/qstile/DevelopmentTiles.java b/src/com/android/settings/development/qstile/DevelopmentTiles.java
index 827705d..849ed2f 100644
--- a/src/com/android/settings/development/qstile/DevelopmentTiles.java
+++ b/src/com/android/settings/development/qstile/DevelopmentTiles.java
@@ -27,6 +27,7 @@
 import android.provider.Settings;
 import android.service.quicksettings.Tile;
 import android.service.quicksettings.TileService;
+import android.sysprop.DisplayProperties;
 import android.util.Log;
 import android.view.IWindowManager;
 import android.view.ThreadedRenderer;
@@ -98,12 +99,12 @@
 
         @Override
         protected boolean isEnabled() {
-            return SystemProperties.getBoolean(View.DEBUG_LAYOUT_PROPERTY, false);
+            return DisplayProperties.debug_layout().orElse(false);
         }
 
         @Override
         protected void setIsEnabled(boolean isEnabled) {
-            SystemProperties.set(View.DEBUG_LAYOUT_PROPERTY, isEnabled ? "true" : "false");
+            DisplayProperties.debug_layout(isEnabled);
         }
     }
 
@@ -139,7 +140,7 @@
         protected void setIsEnabled(boolean isEnabled) {
             Settings.Global.putInt(
                     getContentResolver(), Settings.Global.DEVELOPMENT_FORCE_RTL, isEnabled ? 1 : 0);
-            SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, isEnabled ? "1" : "0");
+            DisplayProperties.debug_force_rtl(isEnabled);
             LocalePicker.updateLocales(getResources().getConfiguration().getLocales());
         }
     }
diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCard.java b/src/com/android/settings/homepage/contextualcards/ContextualCard.java
index 4673ad1..7b8a0c3 100644
--- a/src/com/android/settings/homepage/contextualcards/ContextualCard.java
+++ b/src/com/android/settings/homepage/contextualcards/ContextualCard.java
@@ -22,6 +22,10 @@
 import android.net.Uri;
 import android.text.TextUtils;
 
+import androidx.annotation.LayoutRes;
+
+import com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
@@ -63,9 +67,10 @@
     private final int mIconResId;
     private final int mCardAction;
     private final long mExpireTimeMS;
-    private final boolean mIsHalfWidth;
     private final boolean mIsLargeCard;
     private final Drawable mIconDrawable;
+    @LayoutRes
+    private final int mViewType;
 
     public String getName() {
         return mName;
@@ -139,10 +144,6 @@
         return mIconDrawable;
     }
 
-    public boolean isHalfWidth() {
-        return mIsHalfWidth;
-    }
-
     public boolean isLargeCard() {
         return mIsLargeCard;
     }
@@ -151,6 +152,10 @@
         return TextUtils.isEmpty(mSliceUri);
     }
 
+    public int getViewType() {
+        return mViewType;
+    }
+
     public Builder mutate() {
         return mBuilder;
     }
@@ -174,8 +179,8 @@
         mCardAction = builder.mCardAction;
         mExpireTimeMS = builder.mExpireTimeMS;
         mIconDrawable = builder.mIconDrawable;
-        mIsHalfWidth = builder.mIsHalfWidth;
         mIsLargeCard = builder.mIsLargeCard;
+        mViewType = builder.mViewType;
     }
 
     ContextualCard(Cursor c) {
@@ -215,13 +220,12 @@
         mBuilder.setCardAction(mCardAction);
         mExpireTimeMS = c.getLong(c.getColumnIndex(CardDatabaseHelper.CardColumns.EXPIRE_TIME_MS));
         mBuilder.setExpireTimeMS(mExpireTimeMS);
-        mIsHalfWidth = (c.getInt(
-                c.getColumnIndex(CardDatabaseHelper.CardColumns.SUPPORT_HALF_WIDTH)) == 1);
-        mBuilder.setIsHalfWidth(mIsHalfWidth);
         mIsLargeCard = false;
         mBuilder.setIsLargeCard(mIsLargeCard);
         mIconDrawable = null;
         mBuilder.setIconDrawable(mIconDrawable);
+        mViewType = getViewTypeByCardType(mCardType);
+        mBuilder.setViewType(mViewType);
     }
 
     @Override
@@ -245,6 +249,13 @@
         return TextUtils.equals(mName, that.mName);
     }
 
+    private int getViewTypeByCardType(int cardType) {
+        if (cardType == CardType.SLICE) {
+            return SliceContextualCardRenderer.VIEW_TYPE_FULL_WIDTH;
+        }
+        return 0;
+    }
+
     public static class Builder {
         private String mName;
         private int mCardType;
@@ -263,8 +274,9 @@
         private int mCardAction;
         private long mExpireTimeMS;
         private Drawable mIconDrawable;
-        private boolean mIsHalfWidth;
         private boolean mIsLargeCard;
+        @LayoutRes
+        private int mViewType;
 
         public Builder setName(String name) {
             mName = name;
@@ -351,13 +363,13 @@
             return this;
         }
 
-        public Builder setIsHalfWidth(boolean isHalfWidth) {
-            mIsHalfWidth = isHalfWidth;
+        public Builder setIsLargeCard(boolean isLargeCard) {
+            mIsLargeCard = isLargeCard;
             return this;
         }
 
-        public Builder setIsLargeCard(boolean isLargeCard) {
-            mIsLargeCard = isLargeCard;
+        public Builder setViewType(@LayoutRes int viewType) {
+            mViewType = viewType;
             return this;
         }
 
diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardLookupTable.java b/src/com/android/settings/homepage/contextualcards/ContextualCardLookupTable.java
index 90974f6..1f2e89b 100644
--- a/src/com/android/settings/homepage/contextualcards/ContextualCardLookupTable.java
+++ b/src/com/android/settings/homepage/contextualcards/ContextualCardLookupTable.java
@@ -24,14 +24,10 @@
 import com.android.settings.homepage.contextualcards.ContextualCard.CardType;
 import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardController;
 import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardRenderer;
-import com.android.settings.homepage.contextualcards.conditional
-        .ConditionHeaderContextualCardRenderer;
-import com.android.settings.homepage.contextualcards.legacysuggestion
-        .LegacySuggestionContextualCardController;
-import com.android.settings.homepage.contextualcards.legacysuggestion
-        .LegacySuggestionContextualCardRenderer;
-import com.android.settings.homepage.contextualcards.conditional
-        .ConditionFooterContextualCardRenderer;
+import com.android.settings.homepage.contextualcards.conditional.ConditionFooterContextualCardRenderer;
+import com.android.settings.homepage.contextualcards.conditional.ConditionHeaderContextualCardRenderer;
+import com.android.settings.homepage.contextualcards.legacysuggestion.LegacySuggestionContextualCardController;
+import com.android.settings.homepage.contextualcards.legacysuggestion.LegacySuggestionContextualCardRenderer;
 import com.android.settings.homepage.contextualcards.slices.SliceContextualCardController;
 import com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer;
 
@@ -72,11 +68,11 @@
     static final Set<ControllerRendererMapping> LOOKUP_TABLE =
             new TreeSet<ControllerRendererMapping>() {{
                 add(new ControllerRendererMapping(CardType.CONDITIONAL,
-                        ConditionContextualCardRenderer.HALF_WIDTH_VIEW_TYPE,
+                        ConditionContextualCardRenderer.VIEW_TYPE_HALF_WIDTH,
                         ConditionContextualCardController.class,
                         ConditionContextualCardRenderer.class));
                 add(new ControllerRendererMapping(CardType.CONDITIONAL,
-                        ConditionContextualCardRenderer.FULL_WIDTH_VIEW_TYPE,
+                        ConditionContextualCardRenderer.VIEW_TYPE_FULL_WIDTH,
                         ConditionContextualCardController.class,
                         ConditionContextualCardRenderer.class));
                 add(new ControllerRendererMapping(CardType.LEGACY_SUGGESTION,
@@ -111,15 +107,6 @@
         return null;
     }
 
-    public static Class<? extends ContextualCardRenderer> getCardRendererClassByCardType(
-            @CardType int cardType) {
-        return LOOKUP_TABLE.stream()
-                .filter(m -> m.mCardType == cardType)
-                .findFirst()
-                .map(mapping -> mapping.mRendererClass)
-                .orElse(null);
-    }
-
     public static Class<? extends ContextualCardRenderer> getCardRendererClassByViewType(
             int viewType) throws IllegalStateException {
         List<ControllerRendererMapping> validMappings = LOOKUP_TABLE.stream()
diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardManager.java b/src/com/android/settings/homepage/contextualcards/ContextualCardManager.java
index 12088f8..7a2c2e9 100644
--- a/src/com/android/settings/homepage/contextualcards/ContextualCardManager.java
+++ b/src/com/android/settings/homepage/contextualcards/ContextualCardManager.java
@@ -33,6 +33,7 @@
 import androidx.loader.app.LoaderManager;
 import androidx.loader.content.Loader;
 
+import com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
@@ -236,8 +237,10 @@
             final ContextualCard current = result.get(index);
             if (current.getCategory() == SUGGESTION_VALUE
                     && previous.getCategory() == SUGGESTION_VALUE) {
-                result.set(index - 1, previous.mutate().setIsHalfWidth(true).build());
-                result.set(index, current.mutate().setIsHalfWidth(true).build());
+                result.set(index - 1, previous.mutate().setViewType(
+                        SliceContextualCardRenderer.VIEW_TYPE_HALF_WIDTH).build());
+                result.set(index, current.mutate().setViewType(
+                        SliceContextualCardRenderer.VIEW_TYPE_HALF_WIDTH).build());
                 index++;
             }
         }
diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardRenderer.java b/src/com/android/settings/homepage/contextualcards/ContextualCardRenderer.java
index 283a079..fc1bda2 100644
--- a/src/com/android/settings/homepage/contextualcards/ContextualCardRenderer.java
+++ b/src/com/android/settings/homepage/contextualcards/ContextualCardRenderer.java
@@ -27,17 +27,11 @@
 public interface ContextualCardRenderer {
 
     /**
-     * The layout type of the renderer.
-     */
-    @LayoutRes
-    int getViewType(boolean isHalfWidth);
-
-    /**
      * When {@link ContextualCardsAdapter} calls {@link ContextualCardsAdapter#onCreateViewHolder},
      * this method will be called to retrieve the corresponding
      * {@link androidx.recyclerview.widget.RecyclerView.ViewHolder}.
      */
-    RecyclerView.ViewHolder createViewHolder(View view);
+    RecyclerView.ViewHolder createViewHolder(View view, @LayoutRes int viewType);
 
     /**
      * When {@link ContextualCardsAdapter} calls {@link ContextualCardsAdapter#onBindViewHolder},
diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardsAdapter.java b/src/com/android/settings/homepage/contextualcards/ContextualCardsAdapter.java
index 13b509d..241834d 100644
--- a/src/com/android/settings/homepage/contextualcards/ContextualCardsAdapter.java
+++ b/src/com/android/settings/homepage/contextualcards/ContextualCardsAdapter.java
@@ -21,11 +21,15 @@
 import android.view.View;
 import android.view.ViewGroup;
 
+import androidx.annotation.LayoutRes;
 import androidx.lifecycle.LifecycleOwner;
 import androidx.recyclerview.widget.DiffUtil;
 import androidx.recyclerview.widget.GridLayoutManager;
 import androidx.recyclerview.widget.RecyclerView;
 
+import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardRenderer;
+import com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
@@ -62,24 +66,22 @@
     @Override
     public int getItemViewType(int position) {
         final ContextualCard card = mContextualCards.get(position);
-        final ContextualCardRenderer renderer = mControllerRendererPool.getRendererByCardType(
-                mContext, mLifecycleOwner, card.getCardType());
-        return renderer.getViewType(card.isHalfWidth());
+        return card.getViewType();
     }
 
     @Override
-    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, @LayoutRes int viewType) {
         final ContextualCardRenderer renderer = mControllerRendererPool.getRendererByViewType(
                 mContext, mLifecycleOwner, viewType);
         final View view = LayoutInflater.from(parent.getContext()).inflate(viewType, parent, false);
-        return renderer.createViewHolder(view);
+        return renderer.createViewHolder(view, viewType);
     }
 
     @Override
     public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
         final ContextualCard card = mContextualCards.get(position);
-        final ContextualCardRenderer renderer = mControllerRendererPool.getRendererByCardType(
-                mContext, mLifecycleOwner, card.getCardType());
+        final ContextualCardRenderer renderer = mControllerRendererPool.getRendererByViewType(
+                mContext, mLifecycleOwner, card.getViewType());
         renderer.bindView(holder, card);
     }
 
@@ -98,11 +100,14 @@
             gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                 @Override
                 public int getSpanSize(int position) {
-                    final ContextualCard card = mContextualCards.get(position);
-                    if (card.isHalfWidth()) {
-                        return HALF_WIDTH;
+                    final int viewType = mContextualCards.get(position).getViewType();
+                    switch (viewType) {
+                        case ConditionContextualCardRenderer.VIEW_TYPE_HALF_WIDTH:
+                        case SliceContextualCardRenderer.VIEW_TYPE_HALF_WIDTH:
+                            return HALF_WIDTH;
+                        default:
+                            return FULL_WIDTH;
                     }
-                    return FULL_WIDTH;
                 }
             });
         }
diff --git a/src/com/android/settings/homepage/contextualcards/ControllerRendererPool.java b/src/com/android/settings/homepage/contextualcards/ControllerRendererPool.java
index 992d4c9..755a105 100644
--- a/src/com/android/settings/homepage/contextualcards/ControllerRendererPool.java
+++ b/src/com/android/settings/homepage/contextualcards/ControllerRendererPool.java
@@ -26,14 +26,10 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardController;
 import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardRenderer;
-import com.android.settings.homepage.contextualcards.conditional
-        .ConditionHeaderContextualCardRenderer;
-import com.android.settings.homepage.contextualcards.legacysuggestion
-        .LegacySuggestionContextualCardController;
-import com.android.settings.homepage.contextualcards.legacysuggestion
-        .LegacySuggestionContextualCardRenderer;
-import com.android.settings.homepage.contextualcards.conditional
-        .ConditionFooterContextualCardRenderer;
+import com.android.settings.homepage.contextualcards.conditional.ConditionFooterContextualCardRenderer;
+import com.android.settings.homepage.contextualcards.conditional.ConditionHeaderContextualCardRenderer;
+import com.android.settings.homepage.contextualcards.legacysuggestion.LegacySuggestionContextualCardController;
+import com.android.settings.homepage.contextualcards.legacysuggestion.LegacySuggestionContextualCardRenderer;
 import com.android.settings.homepage.contextualcards.slices.SliceContextualCardController;
 import com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer;
 
@@ -90,13 +86,6 @@
         return getRenderer(context, lifecycleOwner, clz);
     }
 
-    public ContextualCardRenderer getRendererByCardType(Context context,
-            LifecycleOwner lifecycleOwner, @ContextualCard.CardType int cardType) {
-        final Class<? extends ContextualCardRenderer> clz =
-                ContextualCardLookupTable.getCardRendererClassByCardType(cardType);
-        return getRenderer(context, lifecycleOwner, clz);
-    }
-
     private ContextualCardRenderer getRenderer(Context context, LifecycleOwner lifecycleOwner,
             @NonNull Class<? extends ContextualCardRenderer> clz) {
         for (ContextualCardRenderer renderer : mRenderers) {
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/AirplaneModeConditionController.java b/src/com/android/settings/homepage/contextualcards/conditional/AirplaneModeConditionController.java
index f33633e..a4a5a7a 100644
--- a/src/com/android/settings/homepage/contextualcards/conditional/AirplaneModeConditionController.java
+++ b/src/com/android/settings/homepage/contextualcards/conditional/AirplaneModeConditionController.java
@@ -79,7 +79,7 @@
                 .setTitleText(mAppContext.getText(R.string.condition_airplane_title).toString())
                 .setSummaryText(mAppContext.getText(R.string.condition_airplane_summary).toString())
                 .setIconDrawable(mAppContext.getDrawable(R.drawable.ic_airplanemode_active))
-                .setIsHalfWidth(true)
+                .setViewType(ConditionContextualCardRenderer.VIEW_TYPE_HALF_WIDTH)
                 .build();
     }
 
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/BackgroundDataConditionController.java b/src/com/android/settings/homepage/contextualcards/conditional/BackgroundDataConditionController.java
index 4e40556..550dfc0 100644
--- a/src/com/android/settings/homepage/contextualcards/conditional/BackgroundDataConditionController.java
+++ b/src/com/android/settings/homepage/contextualcards/conditional/BackgroundDataConditionController.java
@@ -73,7 +73,7 @@
                 .setTitleText(mAppContext.getText(R.string.condition_bg_data_title).toString())
                 .setSummaryText(mAppContext.getText(R.string.condition_bg_data_summary).toString())
                 .setIconDrawable(mAppContext.getDrawable(R.drawable.ic_data_saver))
-                .setIsHalfWidth(true)
+                .setViewType(ConditionContextualCardRenderer.VIEW_TYPE_HALF_WIDTH)
                 .build();
     }
 
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/BatterySaverConditionController.java b/src/com/android/settings/homepage/contextualcards/conditional/BatterySaverConditionController.java
index bce7c5d..73aa588 100644
--- a/src/com/android/settings/homepage/contextualcards/conditional/BatterySaverConditionController.java
+++ b/src/com/android/settings/homepage/contextualcards/conditional/BatterySaverConditionController.java
@@ -82,7 +82,7 @@
                 .setTitleText(mAppContext.getText(R.string.condition_battery_title).toString())
                 .setSummaryText(mAppContext.getText(R.string.condition_battery_summary).toString())
                 .setIconDrawable(mAppContext.getDrawable(R.drawable.ic_battery_saver_accent_24dp))
-                .setIsHalfWidth(true)
+                .setViewType(ConditionContextualCardRenderer.VIEW_TYPE_HALF_WIDTH)
                 .build();
     }
 
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/CellularDataConditionController.java b/src/com/android/settings/homepage/contextualcards/conditional/CellularDataConditionController.java
index 05199ba..f512d92 100644
--- a/src/com/android/settings/homepage/contextualcards/conditional/CellularDataConditionController.java
+++ b/src/com/android/settings/homepage/contextualcards/conditional/CellularDataConditionController.java
@@ -89,7 +89,7 @@
                 .setTitleText(mAppContext.getText(R.string.condition_cellular_title).toString())
                 .setSummaryText(mAppContext.getText(R.string.condition_cellular_summary).toString())
                 .setIconDrawable(mAppContext.getDrawable(R.drawable.ic_cellular_off))
-                .setIsHalfWidth(true)
+                .setViewType(ConditionContextualCardRenderer.VIEW_TYPE_HALF_WIDTH)
                 .build();
     }
 
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardController.java b/src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardController.java
index b477d52..25d1cda 100644
--- a/src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardController.java
+++ b/src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardController.java
@@ -168,7 +168,8 @@
             final int lastIndex = expandedCards.size() - 1;
             final ConditionalContextualCard card =
                     (ConditionalContextualCard) expandedCards.get(lastIndex);
-            expandedCards.set(lastIndex, card.mutate().setIsHalfWidth(false).build());
+            expandedCards.set(lastIndex, card.mutate().setViewType(
+                    ConditionContextualCardRenderer.VIEW_TYPE_FULL_WIDTH).build());
         }
         return expandedCards;
     }
@@ -180,6 +181,7 @@
             footerCards.add(new ConditionFooterContextualCard.Builder()
                     .setName(CONDITION_FOOTER)
                     .setRankingScore(UNSUPPORTED_RANKING)
+                    .setViewType(ConditionFooterContextualCardRenderer.VIEW_TYPE)
                     .build());
             return footerCards;
         }
@@ -194,6 +196,7 @@
                     .setConditionalCards(conditionCards)
                     .setName(CONDITION_HEADER)
                     .setRankingScore(UNSUPPORTED_RANKING)
+                    .setViewType(ConditionHeaderContextualCardRenderer.VIEW_TYPE)
                     .build());
             return headerCards;
         }
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardRenderer.java b/src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardRenderer.java
index 34f442c..fc936bc 100644
--- a/src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardRenderer.java
+++ b/src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardRenderer.java
@@ -39,9 +39,9 @@
  */
 public class ConditionContextualCardRenderer implements ContextualCardRenderer {
     @LayoutRes
-    public static final int HALF_WIDTH_VIEW_TYPE = R.layout.homepage_condition_half_tile;
+    public static final int VIEW_TYPE_HALF_WIDTH = R.layout.homepage_condition_half_tile;
     @LayoutRes
-    public static final int FULL_WIDTH_VIEW_TYPE = R.layout.homepage_condition_full_tile;
+    public static final int VIEW_TYPE_FULL_WIDTH = R.layout.homepage_condition_full_tile;
 
     private final Context mContext;
     private final ControllerRendererPool mControllerRendererPool;
@@ -53,16 +53,7 @@
     }
 
     @Override
-    public int getViewType(boolean isHalfWidth) {
-        if (isHalfWidth) {
-            return HALF_WIDTH_VIEW_TYPE;
-        } else {
-            return FULL_WIDTH_VIEW_TYPE;
-        }
-    }
-
-    @Override
-    public RecyclerView.ViewHolder createViewHolder(View view) {
+    public RecyclerView.ViewHolder createViewHolder(View view, @LayoutRes int viewType) {
         return new ConditionalCardHolder(view);
     }
 
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/ConditionFooterContextualCardRenderer.java b/src/com/android/settings/homepage/contextualcards/conditional/ConditionFooterContextualCardRenderer.java
index 2465ca4..53de541 100644
--- a/src/com/android/settings/homepage/contextualcards/conditional/ConditionFooterContextualCardRenderer.java
+++ b/src/com/android/settings/homepage/contextualcards/conditional/ConditionFooterContextualCardRenderer.java
@@ -20,6 +20,7 @@
 import android.content.Context;
 import android.view.View;
 
+import androidx.annotation.LayoutRes;
 import androidx.recyclerview.widget.RecyclerView;
 
 import com.android.internal.logging.nano.MetricsProto;
@@ -44,12 +45,7 @@
     }
 
     @Override
-    public int getViewType(boolean isHalfWidth) {
-        return VIEW_TYPE;
-    }
-
-    @Override
-    public RecyclerView.ViewHolder createViewHolder(View view) {
+    public RecyclerView.ViewHolder createViewHolder(View view, @LayoutRes int viewType) {
         return new ConditionFooterCardHolder(view);
     }
 
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/ConditionHeaderContextualCardRenderer.java b/src/com/android/settings/homepage/contextualcards/conditional/ConditionHeaderContextualCardRenderer.java
index a98c82d..d7fbee6 100644
--- a/src/com/android/settings/homepage/contextualcards/conditional/ConditionHeaderContextualCardRenderer.java
+++ b/src/com/android/settings/homepage/contextualcards/conditional/ConditionHeaderContextualCardRenderer.java
@@ -23,6 +23,7 @@
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 
+import androidx.annotation.LayoutRes;
 import androidx.recyclerview.widget.RecyclerView;
 
 import com.android.internal.logging.nano.MetricsProto;
@@ -47,12 +48,7 @@
     }
 
     @Override
-    public int getViewType(boolean isHalfWidth) {
-        return VIEW_TYPE;
-    }
-
-    @Override
-    public RecyclerView.ViewHolder createViewHolder(View view) {
+    public RecyclerView.ViewHolder createViewHolder(View view, @LayoutRes int viewType) {
         return new ConditionHeaderCardHolder(view);
     }
 
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/DndConditionCardController.java b/src/com/android/settings/homepage/contextualcards/conditional/DndConditionCardController.java
index cf91157..488280c 100644
--- a/src/com/android/settings/homepage/contextualcards/conditional/DndConditionCardController.java
+++ b/src/com/android/settings/homepage/contextualcards/conditional/DndConditionCardController.java
@@ -22,7 +22,6 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.provider.Settings;
-import android.service.notification.ZenModeConfig;
 
 import androidx.annotation.VisibleForTesting;
 
@@ -100,7 +99,7 @@
                 .setTitleText(mAppContext.getText(R.string.condition_zen_title).toString())
                 .setSummaryText(mAppContext.getText(R.string.condition_zen_summary).toString())
                 .setIconDrawable(mAppContext.getDrawable(R.drawable.ic_do_not_disturb_on_24dp))
-                .setIsHalfWidth(true)
+                .setViewType(ConditionContextualCardRenderer.VIEW_TYPE_HALF_WIDTH)
                 .build();
     }
 
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/HotspotConditionController.java b/src/com/android/settings/homepage/contextualcards/conditional/HotspotConditionController.java
index 862f828..1305c26 100644
--- a/src/com/android/settings/homepage/contextualcards/conditional/HotspotConditionController.java
+++ b/src/com/android/settings/homepage/contextualcards/conditional/HotspotConditionController.java
@@ -99,7 +99,7 @@
                 .setTitleText(mAppContext.getText(R.string.condition_hotspot_title).toString())
                 .setSummaryText(getSummary().toString())
                 .setIconDrawable(mAppContext.getDrawable(R.drawable.ic_hotspot))
-                .setIsHalfWidth(true)
+                .setViewType(ConditionContextualCardRenderer.VIEW_TYPE_HALF_WIDTH)
                 .build();
     }
 
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/NightDisplayConditionController.java b/src/com/android/settings/homepage/contextualcards/conditional/NightDisplayConditionController.java
index 249e4a0..09d3ba7 100644
--- a/src/com/android/settings/homepage/contextualcards/conditional/NightDisplayConditionController.java
+++ b/src/com/android/settings/homepage/contextualcards/conditional/NightDisplayConditionController.java
@@ -78,7 +78,7 @@
                 .setSummaryText(
                         mAppContext.getText(R.string.condition_night_display_summary).toString())
                 .setIconDrawable(mAppContext.getDrawable(R.drawable.ic_settings_night_display))
-                .setIsHalfWidth(true)
+                .setViewType(ConditionContextualCardRenderer.VIEW_TYPE_HALF_WIDTH)
                 .build();
     }
 
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/RingerMutedConditionController.java b/src/com/android/settings/homepage/contextualcards/conditional/RingerMutedConditionController.java
index 6dab6b8..38590f6 100644
--- a/src/com/android/settings/homepage/contextualcards/conditional/RingerMutedConditionController.java
+++ b/src/com/android/settings/homepage/contextualcards/conditional/RingerMutedConditionController.java
@@ -58,7 +58,7 @@
                 .setSummaryText(
                         mAppContext.getText(R.string.condition_device_muted_summary).toString())
                 .setIconDrawable(mAppContext.getDrawable(R.drawable.ic_notifications_off_24dp))
-                .setIsHalfWidth(true)
+                .setViewType(ConditionContextualCardRenderer.VIEW_TYPE_HALF_WIDTH)
                 .build();
     }
 }
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/RingerVibrateConditionController.java b/src/com/android/settings/homepage/contextualcards/conditional/RingerVibrateConditionController.java
index d8084b5..eee364f 100644
--- a/src/com/android/settings/homepage/contextualcards/conditional/RingerVibrateConditionController.java
+++ b/src/com/android/settings/homepage/contextualcards/conditional/RingerVibrateConditionController.java
@@ -60,7 +60,7 @@
                 .setSummaryText(
                         mAppContext.getText(R.string.condition_device_vibrate_summary).toString())
                 .setIconDrawable(mAppContext.getDrawable(R.drawable.ic_volume_ringer_vibrate))
-                .setIsHalfWidth(true)
+                .setViewType(ConditionContextualCardRenderer.VIEW_TYPE_HALF_WIDTH)
                 .build();
     }
 }
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/WorkModeConditionController.java b/src/com/android/settings/homepage/contextualcards/conditional/WorkModeConditionController.java
index 44b21bf..26616f0 100644
--- a/src/com/android/settings/homepage/contextualcards/conditional/WorkModeConditionController.java
+++ b/src/com/android/settings/homepage/contextualcards/conditional/WorkModeConditionController.java
@@ -93,7 +93,7 @@
                 .setTitleText(mAppContext.getText(R.string.condition_work_title).toString())
                 .setSummaryText(mAppContext.getText(R.string.condition_work_summary).toString())
                 .setIconDrawable(mAppContext.getDrawable(R.drawable.ic_signal_workmode_enable))
-                .setIsHalfWidth(true)
+                .setViewType(ConditionContextualCardRenderer.VIEW_TYPE_HALF_WIDTH)
                 .build();
     }
 
diff --git a/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardController.java b/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardController.java
index 7fa004a..bbcebbe 100644
--- a/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardController.java
+++ b/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardController.java
@@ -144,7 +144,8 @@
                             .setPendingIntent(suggestion.getPendingIntent())
                             .setName(suggestion.getId())
                             .setTitleText(suggestion.getTitle().toString())
-                            .setSummaryText(suggestion.getSummary().toString());
+                            .setSummaryText(suggestion.getSummary().toString())
+                            .setViewType(LegacySuggestionContextualCardRenderer.VIEW_TYPE);
 
                     cards.add(cardBuilder.build());
                 }
diff --git a/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRenderer.java b/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRenderer.java
index 3ce1883..20449f0 100644
--- a/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRenderer.java
+++ b/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRenderer.java
@@ -44,12 +44,7 @@
     }
 
     @Override
-    public int getViewType(boolean isHalfWidth) {
-        return VIEW_TYPE;
-    }
-
-    @Override
-    public RecyclerView.ViewHolder createViewHolder(View view) {
+    public RecyclerView.ViewHolder createViewHolder(View view, @LayoutRes int viewType) {
         return new LegacySuggestionViewHolder(view);
     }
 
diff --git a/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java b/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java
index 5a43f66..66e0465 100644
--- a/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java
+++ b/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java
@@ -26,6 +26,7 @@
 import android.widget.Button;
 import android.widget.ViewFlipper;
 
+import androidx.annotation.LayoutRes;
 import androidx.annotation.VisibleForTesting;
 import androidx.lifecycle.Lifecycle;
 import androidx.lifecycle.LifecycleObserver;
@@ -66,9 +67,6 @@
     private final SliceFullCardRendererHelper mFullCardHelper;
     private final SliceHalfCardRendererHelper mHalfCardHelper;
 
-    //TODO(b/121303357): Remove isHalfWidth field from SliceContextualCardRenderer class.
-    private boolean mIsHalfWidth;
-
     public SliceContextualCardRenderer(Context context, LifecycleOwner lifecycleOwner,
             ControllerRendererPool controllerRendererPool) {
         mContext = context;
@@ -83,17 +81,13 @@
     }
 
     @Override
-    public int getViewType(boolean isHalfWidth) {
-        mIsHalfWidth = isHalfWidth;
-        return isHalfWidth? VIEW_TYPE_HALF_WIDTH : VIEW_TYPE_FULL_WIDTH;
-    }
-
-    @Override
-    public RecyclerView.ViewHolder createViewHolder(View view) {
-        if (mIsHalfWidth) {
-            return mHalfCardHelper.createViewHolder(view);
+    public RecyclerView.ViewHolder createViewHolder(View view, @LayoutRes int viewType) {
+        switch (viewType) {
+            case VIEW_TYPE_HALF_WIDTH:
+                return mHalfCardHelper.createViewHolder(view);
+            default:
+                return mFullCardHelper.createViewHolder(view);
         }
-        return mFullCardHelper.createViewHolder(view);
     }
 
     @Override
diff --git a/src/com/android/settings/network/MobileNetworkListController.java b/src/com/android/settings/network/MobileNetworkListController.java
new file mode 100644
index 0000000..bd198e6
--- /dev/null
+++ b/src/com/android/settings/network/MobileNetworkListController.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2019 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 androidx.lifecycle.Lifecycle.Event.ON_PAUSE;
+import static androidx.lifecycle.Lifecycle.Event.ON_RESUME;
+
+import android.content.Context;
+import android.content.Intent;
+import android.provider.Settings;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.util.ArrayMap;
+
+import com.android.settings.R;
+import com.android.settings.network.telephony.MobileNetworkActivity;
+import com.android.settingslib.core.AbstractPreferenceController;
+
+import java.util.List;
+import java.util.Map;
+
+import androidx.lifecycle.Lifecycle;
+import androidx.lifecycle.LifecycleObserver;
+import androidx.lifecycle.OnLifecycleEvent;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+/**
+ * This populates the entries on a page which lists all available mobile subscriptions. Each entry
+ * has the name of the subscription with some subtext giving additional detail, and clicking on the
+ * entry brings you to a details page for that network.
+ */
+public class MobileNetworkListController extends AbstractPreferenceController implements
+        LifecycleObserver, SubscriptionsChangeListener.SubscriptionsChangeListenerClient {
+    private static final String TAG = "MobileNetworkListCtlr";
+
+    private SubscriptionManager mSubscriptionManager;
+    private SubscriptionsChangeListener mChangeListener;
+    private PreferenceScreen mPreferenceScreen;
+    private Map<Integer, Preference> mPreferences;
+
+    public MobileNetworkListController(Context context, Lifecycle lifecycle) {
+        super(context);
+        mSubscriptionManager = context.getSystemService(SubscriptionManager.class);
+        mChangeListener = new SubscriptionsChangeListener(context, this);
+        mPreferences = new ArrayMap<>();
+        lifecycle.addObserver(this);
+    }
+
+    @OnLifecycleEvent(ON_RESUME)
+    public void onResume() {
+        mChangeListener.start();
+        update();
+    }
+
+    @OnLifecycleEvent(ON_PAUSE)
+    public void onPause() {
+        mChangeListener.stop();
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        mPreferenceScreen = screen;
+        update();
+    }
+
+    private void update() {
+        if (mPreferenceScreen == null) {
+            return;
+        }
+
+        // Since we may already have created some preferences previously, we first grab the list of
+        // those, then go through the current available subscriptions making sure they are all
+        // present in the screen, and finally remove any now-outdated ones.
+        final Map<Integer, Preference> existingPreferences = mPreferences;
+        mPreferences = new ArrayMap<>();
+
+        final List<SubscriptionInfo> subscriptions = SubscriptionUtil.getAvailableSubscriptions(
+                mSubscriptionManager);
+        for (SubscriptionInfo info : subscriptions) {
+            int subId = info.getSubscriptionId();
+            Preference pref = existingPreferences.remove(subId);
+            if (pref == null) {
+                pref = new Preference(mPreferenceScreen.getContext());
+                mPreferenceScreen.addPreference(pref);
+            }
+            pref.setTitle(info.getDisplayName());
+
+            if (info.isEmbedded()) {
+                if (mSubscriptionManager.isActiveSubscriptionId(subId)) {
+                    pref.setSummary(R.string.mobile_network_active_esim);
+                } else {
+                    pref.setSummary(R.string.mobile_network_inactive_esim);
+                }
+            } else {
+                if (mSubscriptionManager.isActiveSubscriptionId(subId)) {
+                    pref.setSummary(R.string.mobile_network_active_sim);
+                } else {
+                    pref.setSummary(R.string.mobile_network_inactive_sim);
+                }
+            }
+
+            pref.setOnPreferenceClickListener(clickedPref -> {
+                final Intent intent = new Intent(mContext, MobileNetworkActivity.class);
+                intent.putExtra(Settings.EXTRA_SUB_ID, info.getSubscriptionId());
+                mContext.startActivity(intent);
+                return true;
+            });
+            mPreferences.put(subId, pref);
+        }
+        for (Preference pref : existingPreferences.values()) {
+            mPreferenceScreen.removePreference(pref);
+        }
+    }
+
+    @Override
+    public boolean isAvailable() {
+        return true;
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return null;
+    }
+
+    @Override
+    public void onAirplaneModeChanged(boolean airplaneModeEnabled) {
+    }
+
+    @Override
+    public void onSubscriptionsChanged() {
+        update();
+    }
+}
diff --git a/src/com/android/settings/network/MobileNetworkListFragment.java b/src/com/android/settings/network/MobileNetworkListFragment.java
new file mode 100644
index 0000000..8787378
--- /dev/null
+++ b/src/com/android/settings/network/MobileNetworkListFragment.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2019 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.provider.SearchIndexableResource;
+
+import com.android.settings.R;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.search.SearchIndexable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
+public class MobileNetworkListFragment extends DashboardFragment {
+    private static final String LOG_TAG = "NetworkListFragment";
+
+    @Override
+    protected int getPreferenceScreenResId() {
+        return R.xml.mobile_network_list;
+    }
+
+    @Override
+    protected String getLogTag() {
+        return LOG_TAG;
+    }
+
+    @Override
+    public int getMetricsCategory() {
+        // TODO(asargent) - return SettingsEnums.MOBILE_NETWORK_LIST once the CL defining it has
+        // landed.
+        return 0;
+    }
+
+    @Override
+    protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
+        final List<AbstractPreferenceController> controllers = new ArrayList<>();
+        controllers.add(new MobileNetworkListController(getContext(), getLifecycle()));
+        return controllers;
+    }
+
+    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+            new BaseSearchIndexProvider() {
+                @Override
+                public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
+                        boolean enabled) {
+                    final ArrayList<SearchIndexableResource> result = new ArrayList<>();
+                    final SearchIndexableResource sir = new SearchIndexableResource(context);
+                    sir.xmlResId = R.xml.mobile_network_list;
+                    result.add(sir);
+                    return result;
+                }
+            };
+}
diff --git a/src/com/android/settings/network/MobileNetworkSummaryController.java b/src/com/android/settings/network/MobileNetworkSummaryController.java
new file mode 100644
index 0000000..bbc4ea4
--- /dev/null
+++ b/src/com/android/settings/network/MobileNetworkSummaryController.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2019 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 androidx.lifecycle.Lifecycle.Event.ON_PAUSE;
+import static androidx.lifecycle.Lifecycle.Event.ON_RESUME;
+
+import android.content.Context;
+import android.content.Intent;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+
+import com.android.settings.R;
+import com.android.settings.network.telephony.MobileNetworkActivity;
+import com.android.settingslib.core.AbstractPreferenceController;
+
+import java.util.List;
+
+import androidx.lifecycle.Lifecycle;
+import androidx.lifecycle.LifecycleObserver;
+import androidx.lifecycle.OnLifecycleEvent;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+public class MobileNetworkSummaryController extends AbstractPreferenceController implements
+        SubscriptionsChangeListener.SubscriptionsChangeListenerClient, LifecycleObserver {
+    private static final String TAG = "MobileNetSummaryCtlr";
+
+    private static final String KEY = "mobile_network_list";
+
+    private SubscriptionManager mSubscriptionManager;
+    private SubscriptionsChangeListener mChangeListener;
+    private PreferenceScreen mScreen;
+
+    /**
+     * This controls the summary text and click behavior of the "Mobile network" item on the
+     * Network & internet page. There are 3 separate cases depending on the number of mobile network
+     * subscriptions:
+     * <ul>
+     * <li>No subscription: click action begins a UI flow to add a network subscription, and
+     * the summary text indicates this</li>
+     *
+     * <li>One subscription: click action takes you to details for that one network, and
+     * the summary text is the network name</li>
+     *
+     * <li>More than one subscription: click action takes you to a page listing the subscriptions,
+     * and the summary text gives the count of SIMs</li>
+     * </ul>
+     */
+    public MobileNetworkSummaryController(Context context, Lifecycle lifecycle) {
+        super(context);
+        mSubscriptionManager = context.getSystemService(SubscriptionManager.class);
+        mChangeListener = new SubscriptionsChangeListener(context, this);
+        lifecycle.addObserver(this);
+    }
+
+    @OnLifecycleEvent(ON_RESUME)
+    public void onResume() {
+        mChangeListener.start();
+        update();
+    }
+
+    @OnLifecycleEvent(ON_PAUSE)
+    public void onPause() {
+        mChangeListener.stop();
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        mScreen = screen;
+    }
+
+    @Override
+    public CharSequence getSummary() {
+        final List<SubscriptionInfo> subs = SubscriptionUtil.getAvailableSubscriptions(
+                mSubscriptionManager);
+        if (subs.isEmpty()) {
+            return mContext.getResources().getString(R.string.mobile_network_summary_add_a_network);
+        } else if (subs.size() == 1) {
+            return subs.get(0).getDisplayName();
+        } else {
+            final int count = subs.size();
+            return mContext.getResources().getQuantityString(R.plurals.mobile_network_summary_count,
+                    count, count);
+        }
+    }
+
+    private void update() {
+        if (mScreen != null) {
+            final Preference preference = mScreen.findPreference(getPreferenceKey());
+            refreshSummary(preference);
+            final List<SubscriptionInfo> subs = SubscriptionUtil.getAvailableSubscriptions(
+                    mSubscriptionManager);
+
+            preference.setOnPreferenceClickListener(null);
+            preference.setFragment(null);
+            if (subs.size() == 0) {
+                preference.setOnPreferenceClickListener((Preference pref) -> {
+                    // TODO(asargent) - need to get correct intent to fire here
+                    return true;
+                });
+            } else if (subs.size() == 1) {
+                preference.setOnPreferenceClickListener((Preference pref) -> {
+                    final Intent intent = new Intent(mContext, MobileNetworkActivity.class);
+                    mContext.startActivity(intent);
+                    return true;
+                });
+            } else {
+                preference.setFragment(MobileNetworkListFragment.class.getCanonicalName());
+            }
+        }
+    }
+
+    @Override
+    public boolean isAvailable() {
+        return true;
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return KEY;
+    }
+
+    @Override
+    public void onAirplaneModeChanged(boolean airplaneModeEnabled) {
+    }
+
+    @Override
+    public void onSubscriptionsChanged() {
+        update();
+    }
+}
diff --git a/src/com/android/settings/network/NetworkDashboardFragment.java b/src/com/android/settings/network/NetworkDashboardFragment.java
index c2b4a2b..efdb556 100644
--- a/src/com/android/settings/network/NetworkDashboardFragment.java
+++ b/src/com/android/settings/network/NetworkDashboardFragment.java
@@ -96,8 +96,11 @@
                 new MobilePlanPreferenceController(context, mobilePlanHost);
         final WifiMasterSwitchPreferenceController wifiPreferenceController =
                 new WifiMasterSwitchPreferenceController(context, metricsFeatureProvider);
-        final MobileNetworkPreferenceController mobileNetworkPreferenceController =
-                new MobileNetworkPreferenceController(context);
+        MobileNetworkPreferenceController mobileNetworkPreferenceController = null;
+        if (!FeatureFlagPersistent.isEnabled(context, FeatureFlags.NETWORK_INTERNET_V2)) {
+            mobileNetworkPreferenceController = new MobileNetworkPreferenceController(context);
+        }
+
         final VpnPreferenceController vpnPreferenceController =
                 new VpnPreferenceController(context);
         final PrivateDnsPreferenceController privateDnsPreferenceController =
@@ -106,13 +109,21 @@
         if (lifecycle != null) {
             lifecycle.addObserver(mobilePlanPreferenceController);
             lifecycle.addObserver(wifiPreferenceController);
-            lifecycle.addObserver(mobileNetworkPreferenceController);
+            if (mobileNetworkPreferenceController != null) {
+                lifecycle.addObserver(mobileNetworkPreferenceController);
+            }
             lifecycle.addObserver(vpnPreferenceController);
             lifecycle.addObserver(privateDnsPreferenceController);
         }
 
         final List<AbstractPreferenceController> controllers = new ArrayList<>();
-        controllers.add(mobileNetworkPreferenceController);
+
+        if (FeatureFlagPersistent.isEnabled(context, FeatureFlags.NETWORK_INTERNET_V2)) {
+            controllers.add(new MobileNetworkSummaryController(context, lifecycle));
+        }
+        if (mobileNetworkPreferenceController != null) {
+            controllers.add(mobileNetworkPreferenceController);
+        }
         controllers.add(new TetherPreferenceController(context, lifecycle));
         controllers.add(vpnPreferenceController);
         controllers.add(new ProxyPreferenceController(context));
diff --git a/src/com/android/settings/network/telephony/MobileNetworkActivity.java b/src/com/android/settings/network/telephony/MobileNetworkActivity.java
index c101db4..93ba918 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkActivity.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkActivity.java
@@ -37,7 +37,9 @@
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.util.CollectionUtils;
 import com.android.settings.R;
+import com.android.settings.core.FeatureFlags;
 import com.android.settings.core.SettingsBaseActivity;
+import com.android.settings.development.featureflags.FeatureFlagPersistent;
 
 import com.google.android.material.bottomnavigation.BottomNavigationView;
 
@@ -77,7 +79,11 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        setContentView(R.layout.mobile_network_settings_container);
+        if (FeatureFlagPersistent.isEnabled(this, FeatureFlags.NETWORK_INTERNET_V2)) {
+            setContentView(R.layout.mobile_network_settings_container_v2);
+        } else {
+            setContentView(R.layout.mobile_network_settings_container);
+        }
         setActionBar(findViewById(R.id.mobile_action_bar));
         mPhoneChangeReceiver = new PhoneChangeReceiver();
         mSubscriptionManager = getSystemService(SubscriptionManager.class);
@@ -132,7 +138,9 @@
     void updateSubscriptions(Bundle savedInstanceState) {
         mSubscriptionInfos = mSubscriptionManager.getActiveSubscriptionInfoList();
 
-        updateBottomNavigationView();
+        if (!FeatureFlagPersistent.isEnabled(this, FeatureFlags.NETWORK_INTERNET_V2)) {
+            updateBottomNavigationView();
+        }
 
         if (savedInstanceState == null) {
             switchFragment(new MobileNetworkSettings(), getSubscriptionId());
@@ -237,4 +245,4 @@
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/tests/robotests/src/com/android/settings/development/ForceMSAAPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/ForceMSAAPreferenceControllerTest.java
index 1cf58de..4e0e504 100644
--- a/tests/robotests/src/com/android/settings/development/ForceMSAAPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/ForceMSAAPreferenceControllerTest.java
@@ -22,7 +22,7 @@
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
-import android.os.SystemProperties;
+import android.sysprop.DisplayProperties;
 
 import androidx.preference.PreferenceScreen;
 import androidx.preference.SwitchPreference;
@@ -60,8 +60,7 @@
     public void onPreferenceChanged_settingEnabled_turnOnForceMsaa() {
         mController.onPreferenceChange(mPreference, true /* new value */);
 
-        final boolean mode = SystemProperties
-            .getBoolean(ForceMSAAPreferenceController.MSAA_PROPERTY, false /* default */);
+        final boolean mode = DisplayProperties.debug_force_msaa().orElse(false);
 
         assertThat(mode).isTrue();
     }
@@ -70,15 +69,14 @@
     public void onPreferenceChanged_settingDisabled_turnOffForceMsaa() {
         mController.onPreferenceChange(mPreference, false /* new value */);
 
-        final boolean mode = SystemProperties
-            .getBoolean(ForceMSAAPreferenceController.MSAA_PROPERTY, false /* default */);
+        final boolean mode = DisplayProperties.debug_force_msaa().orElse(false);
 
         assertThat(mode).isFalse();
     }
 
     @Test
     public void updateState_settingEnabled_preferenceShouldBeChecked() {
-        SystemProperties.set(ForceMSAAPreferenceController.MSAA_PROPERTY, Boolean.toString(true));
+        DisplayProperties.debug_force_msaa(true);
         mController.updateState(mPreference);
 
         verify(mPreference).setChecked(true);
@@ -86,7 +84,7 @@
 
     @Test
     public void updateState_settingDisabled_preferenceShouldNotBeChecked() {
-        SystemProperties.set(ForceMSAAPreferenceController.MSAA_PROPERTY, Boolean.toString(false));
+        DisplayProperties.debug_force_msaa(false);
         mController.updateState(mPreference);
 
         verify(mPreference).setChecked(false);
diff --git a/tests/robotests/src/com/android/settings/development/ShowLayoutBoundsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/ShowLayoutBoundsPreferenceControllerTest.java
index 5c5bc8b..8b6d65a 100644
--- a/tests/robotests/src/com/android/settings/development/ShowLayoutBoundsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/ShowLayoutBoundsPreferenceControllerTest.java
@@ -21,7 +21,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import android.os.SystemProperties;
+import android.sysprop.DisplayProperties;
 import android.view.View;
 
 import androidx.preference.PreferenceScreen;
@@ -58,8 +58,7 @@
     public void onPreferenceChanged_settingEnabled_turnOnShowLayoutBounds() {
         mController.onPreferenceChange(mPreference, true /* new value */);
 
-        final boolean mode =
-            SystemProperties.getBoolean(View.DEBUG_LAYOUT_PROPERTY, false /* default */);
+        final boolean mode = DisplayProperties.debug_layout().orElse(false);
 
         assertThat(mode).isTrue();
     }
@@ -68,15 +67,14 @@
     public void onPreferenceChanged_settingDisabled_turnOffShowLayoutBounds() {
         mController.onPreferenceChange(mPreference, false /* new value */);
 
-        final boolean mode =
-            SystemProperties.getBoolean(View.DEBUG_LAYOUT_PROPERTY, false /* default */);
+        final boolean mode = DisplayProperties.debug_layout().orElse(false);
 
         assertThat(mode).isFalse();
     }
 
     @Test
     public void updateState_settingEnabled_preferenceShouldBeChecked() {
-        SystemProperties.set(View.DEBUG_LAYOUT_PROPERTY, Boolean.toString(true));
+        DisplayProperties.debug_layout(true);
         mController.updateState(mPreference);
 
         verify(mPreference).setChecked(true);
@@ -84,7 +82,7 @@
 
     @Test
     public void updateState_settingDisabled_preferenceShouldNotBeChecked() {
-        SystemProperties.set(View.DEBUG_LAYOUT_PROPERTY, Boolean.toString(false));
+        DisplayProperties.debug_layout(false);
         mController.updateState(mPreference);
 
         verify(mPreference).setChecked(false);
@@ -94,8 +92,7 @@
     public void onDeveloperOptionsDisabled_shouldDisablePreference() {
         mController.onDeveloperOptionsDisabled();
 
-        final boolean mode =
-            SystemProperties.getBoolean(View.DEBUG_LAYOUT_PROPERTY, false /* default */);
+        final boolean mode = DisplayProperties.debug_layout().orElse(false);
 
         assertThat(mode).isFalse();
         verify(mPreference).setEnabled(false);
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardLookupTableTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardLookupTableTest.java
index eb558d8..36f9c96 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardLookupTableTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardLookupTableTest.java
@@ -18,17 +18,16 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import com.android.settings.homepage.contextualcards.ContextualCardLookupTable
-        .ControllerRendererMapping;
+import com.android.settings.homepage.contextualcards.ContextualCardLookupTable.ControllerRendererMapping;
 
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
 
 import java.util.ArrayList;
 import java.util.List;
-import org.robolectric.RobolectricTestRunner;
 
 @RunWith(RobolectricTestRunner.class)
 public class ContextualCardLookupTableTest {
@@ -98,18 +97,4 @@
 
         ContextualCardLookupTable.getCardRendererClassByViewType(UNSUPPORTED_VIEW_TYPE);
     }
-
-    @Test
-    public void getRendererClassByCardType_hasSupportedCardType_shouldGetCorrespondingRenderer() {
-        for (ControllerRendererMapping mapping : ContextualCardLookupTable.LOOKUP_TABLE) {
-            assertThat(ContextualCardLookupTable.getCardRendererClassByCardType(mapping.mCardType))
-                    .isEqualTo(mapping.mRendererClass);
-        }
-    }
-
-    @Test
-    public void getCardRendererClassByCardType_hasUnsupportedCardType_shouldAlwaysGetNull() {
-        assertThat(ContextualCardLookupTable.getCardRendererClassByCardType(UNSUPPORTED_CARD_TYPE))
-                .isNull();
-    }
 }
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardManagerTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardManagerTest.java
index 3fc8e06..3e6ba6c 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardManagerTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardManagerTest.java
@@ -16,6 +16,9 @@
 
 package com.android.settings.homepage.contextualcards;
 
+import static com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer.VIEW_TYPE_FULL_WIDTH;
+import static com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer.VIEW_TYPE_HALF_WIDTH;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.anyMap;
@@ -222,7 +225,7 @@
 
         assertThat(result).hasSize(5);
         for (ContextualCard card : result) {
-            assertThat(card.isHalfWidth()).isFalse();
+            assertThat(card.getViewType()).isEqualTo(VIEW_TYPE_FULL_WIDTH);
         }
     }
 
@@ -242,7 +245,7 @@
 
         assertThat(result).hasSize(5);
         for (ContextualCard card : result) {
-            assertThat(card.isHalfWidth()).isFalse();
+            assertThat(card.getViewType()).isEqualTo(VIEW_TYPE_FULL_WIDTH);
         }
     }
 
@@ -257,14 +260,16 @@
         );
         final List<ContextualCard> twoConsecutiveSuggestionCards = buildCategoriedCards(
                 getContextualCardList(), categories);
-        final List<Boolean> expectedValues = Arrays.asList(false, false, true, true, false);
+        final List<Integer> expectedValues = Arrays.asList(VIEW_TYPE_FULL_WIDTH,
+                VIEW_TYPE_FULL_WIDTH, VIEW_TYPE_HALF_WIDTH, VIEW_TYPE_HALF_WIDTH,
+                VIEW_TYPE_FULL_WIDTH);
 
         final List<ContextualCard> result = mManager.assignCardWidth(
                 twoConsecutiveSuggestionCards);
 
         assertThat(result).hasSize(5);
         for (int i = 0; i < result.size(); i++) {
-            assertThat(result.get(i).isHalfWidth()).isEqualTo(expectedValues.get(i));
+            assertThat(result.get(i).getViewType()).isEqualTo(expectedValues.get(i));
         }
     }
 
@@ -285,7 +290,7 @@
 
         assertThat(result).hasSize(5);
         for (ContextualCard card : result) {
-            assertThat(card.isHalfWidth()).isFalse();
+            assertThat(card.getViewType()).isEqualTo(VIEW_TYPE_FULL_WIDTH);
         }
     }
 
@@ -300,14 +305,16 @@
         );
         final List<ContextualCard> threeConsecutiveSuggestionCards = buildCategoriedCards(
                 getContextualCardList(), categories);
-        final List<Boolean> expectedValues = Arrays.asList(false, true, true, false, false);
+        final List<Integer> expectedValues = Arrays.asList(VIEW_TYPE_FULL_WIDTH,
+                VIEW_TYPE_HALF_WIDTH, VIEW_TYPE_HALF_WIDTH, VIEW_TYPE_FULL_WIDTH,
+                VIEW_TYPE_FULL_WIDTH);
 
         final List<ContextualCard> result = mManager.assignCardWidth(
                 threeConsecutiveSuggestionCards);
 
         assertThat(result).hasSize(5);
         for (int i = 0; i < result.size(); i++) {
-            assertThat(result.get(i).isHalfWidth()).isEqualTo(expectedValues.get(i));
+            assertThat(result.get(i).getViewType()).isEqualTo(expectedValues.get(i));
         }
     }
 
@@ -322,14 +329,16 @@
         );
         final List<ContextualCard> fourConsecutiveSuggestionCards = buildCategoriedCards(
                 getContextualCardList(), categories);
-        final List<Boolean> expectedValues = Arrays.asList(false, true, true, true, true);
+        final List<Integer> expectedValues = Arrays.asList(VIEW_TYPE_FULL_WIDTH,
+                VIEW_TYPE_HALF_WIDTH, VIEW_TYPE_HALF_WIDTH, VIEW_TYPE_HALF_WIDTH,
+                VIEW_TYPE_HALF_WIDTH);
 
         final List<ContextualCard> result = mManager.assignCardWidth(
                 fourConsecutiveSuggestionCards);
 
         assertThat(result).hasSize(5);
         for (int i = 0; i < result.size(); i++) {
-            assertThat(result.get(i).isHalfWidth()).isEqualTo(expectedValues.get(i));
+            assertThat(result.get(i).getViewType()).isEqualTo(expectedValues.get(i));
         }
     }
 
@@ -338,6 +347,7 @@
                 .setName(TEST_SLICE_NAME)
                 .setCardType(ContextualCard.CardType.SLICE)
                 .setSliceUri(Uri.parse(sliceUri))
+                .setViewType(VIEW_TYPE_FULL_WIDTH)
                 .build();
     }
 
@@ -356,28 +366,33 @@
                 .setName("test_wifi")
                 .setCardType(ContextualCard.CardType.SLICE)
                 .setSliceUri(CustomSliceRegistry.CONTEXTUAL_WIFI_SLICE_URI)
+                .setViewType(VIEW_TYPE_FULL_WIDTH)
                 .build());
         cards.add(new ContextualCard.Builder()
                 .setName("test_flashlight")
                 .setCardType(ContextualCard.CardType.SLICE)
                 .setSliceUri(
                         Uri.parse("content://com.android.settings.test.slices/action/flashlight"))
+                .setViewType(VIEW_TYPE_FULL_WIDTH)
                 .build());
         cards.add(new ContextualCard.Builder()
                 .setName("test_connected")
                 .setCardType(ContextualCard.CardType.SLICE)
                 .setSliceUri(CustomSliceRegistry.BLUETOOTH_DEVICES_SLICE_URI)
+                .setViewType(VIEW_TYPE_FULL_WIDTH)
                 .build());
         cards.add(new ContextualCard.Builder()
                 .setName("test_gesture")
                 .setCardType(ContextualCard.CardType.SLICE)
                 .setSliceUri(Uri.parse(
                         "content://com.android.settings.test.slices/action/gesture_pick_up"))
+                .setViewType(VIEW_TYPE_FULL_WIDTH)
                 .build());
         cards.add(new ContextualCard.Builder()
                 .setName("test_battery")
                 .setCardType(ContextualCard.CardType.SLICE)
                 .setSliceUri(CustomSliceRegistry.BATTERY_INFO_SLICE_URI)
+                .setViewType(VIEW_TYPE_FULL_WIDTH)
                 .build());
         return cards;
     }
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/ControllerRendererPoolTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/ControllerRendererPoolTest.java
index bf7c5e0..0cb0598 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/ControllerRendererPoolTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/ControllerRendererPoolTest.java
@@ -105,33 +105,4 @@
         assertThat(renderer).isNull();
         assertThat(mPool.getRenderers()).isEmpty();
     }
-
-    @Test
-    public void getRenderer_hasSupportedCardTypeAndWidth_shouldReturnCorrespondingRenderer() {
-        ContextualCardLookupTable.LOOKUP_TABLE.stream().forEach(mapping -> assertThat(
-                mPool.getRendererByCardType(mContext, mLifecycleOwner,
-                        mapping.mCardType).getClass()).isEqualTo(mapping.mRendererClass));
-    }
-
-    @Test
-    public void getRenderer_hasSupportedCardTypeAndWidth_shouldHaveDistinctRenderersInPool() {
-        final long count = ContextualCardLookupTable.LOOKUP_TABLE.stream().map(
-                mapping -> mapping.mRendererClass).distinct().count();
-
-        ContextualCardLookupTable.LOOKUP_TABLE.stream().forEach(
-                mapping -> mPool.getRendererByCardType(mContext, mLifecycleOwner,
-                        mapping.mCardType));
-
-        assertThat(mPool.getRenderers()).hasSize((int) count);
-    }
-
-    @Test
-    public void getRenderer_hasUnsupportedCardType_shouldReturnNullAndPoolIsEmpty() {
-        final ContextualCardRenderer renderer = mPool.getRendererByCardType(mContext,
-                mLifecycleOwner,
-                UNSUPPORTED_CARD_TYPE);
-
-        assertThat(renderer).isNull();
-        assertThat(mPool.getRenderers()).isEmpty();
-    }
 }
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardControllerTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardControllerTest.java
index 4553f7c..06f9b98 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardControllerTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardControllerTest.java
@@ -119,7 +119,8 @@
 
         assertThat(conditionalCards).hasSize(3);
         assertThat(conditionalCards.get(CardType.CONDITIONAL)).hasSize(1);
-        assertThat(conditionalCards.get(CardType.CONDITIONAL).get(0).isHalfWidth()).isFalse();
+        assertThat(conditionalCards.get(CardType.CONDITIONAL).get(0).getViewType()).isEqualTo(
+                ConditionContextualCardRenderer.VIEW_TYPE_FULL_WIDTH);
         assertThat(conditionalCards.get(CardType.CONDITIONAL_HEADER)).isEmpty();
         assertThat(conditionalCards.get(CardType.CONDITIONAL_FOOTER)).isNotEmpty();
     }
@@ -145,7 +146,8 @@
         assertThat(conditionalCards).hasSize(3);
         assertThat(conditionalCards.get(CardType.CONDITIONAL)).hasSize(2);
         for (ContextualCard card : conditionalCards.get(CardType.CONDITIONAL)) {
-            assertThat(card.isHalfWidth()).isTrue();
+            assertThat(card.getViewType()).isEqualTo(
+                    ConditionContextualCardRenderer.VIEW_TYPE_HALF_WIDTH);
         }
         assertThat(conditionalCards.get(CardType.CONDITIONAL_HEADER)).isEmpty();
         assertThat(conditionalCards.get(CardType.CONDITIONAL_FOOTER)).isNotEmpty();
@@ -197,7 +199,7 @@
                     .setName("test_name" + i)
                     .setTitleText("test_title" + i)
                     .setSummaryText("test_summary" + i)
-                    .setIsHalfWidth(true)
+                    .setViewType(ConditionContextualCardRenderer.VIEW_TYPE_HALF_WIDTH)
                     .build());
         }
         return conditionCards;
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardRendererTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardRendererTest.java
index c9b62ae..f29386f 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardRendererTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionContextualCardRendererTest.java
@@ -65,36 +65,40 @@
 
     @Test
     public void bindView_shouldSetListener() {
-        final int viewType = mRenderer.getViewType(false /* isHalfWidth */);
         final RecyclerView recyclerView = new RecyclerView(mActivity);
         recyclerView.setLayoutManager(new LinearLayoutManager(mActivity));
-        final View view = LayoutInflater.from(mActivity).inflate(viewType, recyclerView, false);
-        final RecyclerView.ViewHolder viewHolder = mRenderer.createViewHolder(view);
-        final View card = view.findViewById(R.id.content);
+        final ContextualCard card = buildConditionContextualCard();
+        final View view = LayoutInflater.from(mActivity).inflate(card.getViewType(), recyclerView,
+                false);
+        final RecyclerView.ViewHolder viewHolder = mRenderer.createViewHolder(view,
+                card.getViewType());
+        final View cardView = view.findViewById(R.id.content);
         when(mControllerRendererPool.getController(mActivity,
                 ContextualCard.CardType.CONDITIONAL)).thenReturn(mController);
 
-        mRenderer.bindView(viewHolder, buildConditionContextualCard());
+        mRenderer.bindView(viewHolder, card);
 
-        assertThat(card).isNotNull();
-        assertThat(card.hasOnClickListeners()).isTrue();
+        assertThat(cardView).isNotNull();
+        assertThat(cardView.hasOnClickListeners()).isTrue();
     }
 
     @Test
     public void viewClick_shouldInvokeControllerPrimaryClick() {
-        final int viewType = mRenderer.getViewType(false /* isHalfWidth */);
         final RecyclerView recyclerView = new RecyclerView(mActivity);
         recyclerView.setLayoutManager(new LinearLayoutManager(mActivity));
-        final View view = LayoutInflater.from(mActivity).inflate(viewType, recyclerView, false);
-        final RecyclerView.ViewHolder viewHolder = mRenderer.createViewHolder(view);
-        final View card = view.findViewById(R.id.content);
+        final ContextualCard card = buildConditionContextualCard();
+        final View view = LayoutInflater.from(mActivity).inflate(card.getViewType(), recyclerView,
+                false);
+        final RecyclerView.ViewHolder viewHolder = mRenderer.createViewHolder(view,
+                card.getViewType());
+        final View cardView = view.findViewById(R.id.content);
         when(mControllerRendererPool.getController(mActivity,
                 ContextualCard.CardType.CONDITIONAL)).thenReturn(mController);
 
-        mRenderer.bindView(viewHolder, buildConditionContextualCard());
+        mRenderer.bindView(viewHolder, card);
 
-        assertThat(card).isNotNull();
-        card.performClick();
+        assertThat(cardView).isNotNull();
+        cardView.performClick();
 
         verify(mController).onPrimaryClick(any(ContextualCard.class));
     }
@@ -108,7 +112,7 @@
                 .setTitleText("test_title")
                 .setSummaryText("test_summary")
                 .setIconDrawable(mActivity.getDrawable(R.drawable.ic_do_not_disturb_on_24dp))
-                .setIsHalfWidth(true)
+                .setViewType(ConditionContextualCardRenderer.VIEW_TYPE_FULL_WIDTH)
                 .build();
     }
 }
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionFooterContextualCardRendererTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionFooterContextualCardRendererTest.java
index fcb16f2..3cb6949 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionFooterContextualCardRendererTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionFooterContextualCardRendererTest.java
@@ -59,15 +59,17 @@
 
     @Test
     public void bindView_shouldSetClickListener() {
-        final int viewType = mRenderer.getViewType(false /* isHalfWidth */);
         final RecyclerView recyclerView = new RecyclerView(mContext);
         recyclerView.setLayoutManager(new LinearLayoutManager(mContext));
-        final View view = LayoutInflater.from(mContext).inflate(viewType, recyclerView, false);
-        final RecyclerView.ViewHolder viewHolder = mRenderer.createViewHolder(view);
+        final ContextualCard card = generateConditionFooterContextualCard();
+        final View view = LayoutInflater.from(mContext).inflate(card.getViewType(), recyclerView,
+                false);
+        final RecyclerView.ViewHolder viewHolder = mRenderer.createViewHolder(view,
+                card.getViewType());
         when(mControllerRendererPool.getController(mContext,
                 ContextualCard.CardType.CONDITIONAL_FOOTER)).thenReturn(mController);
 
-        mRenderer.bindView(viewHolder, generateConditionFooterContextualCard());
+        mRenderer.bindView(viewHolder, card);
 
         assertThat(viewHolder.itemView).isNotNull();
         assertThat(viewHolder.itemView.hasOnClickListeners()).isTrue();
@@ -75,15 +77,17 @@
 
     @Test
     public void bindView_clickView_shouldSetTrueToIsConditionExpanded() {
-        final int viewType = mRenderer.getViewType(false /* isHalfWidth */);
         final RecyclerView recyclerView = new RecyclerView(mContext);
         recyclerView.setLayoutManager(new LinearLayoutManager(mContext));
-        final View view = LayoutInflater.from(mContext).inflate(viewType, recyclerView, false);
-        final RecyclerView.ViewHolder viewHolder = mRenderer.createViewHolder(view);
+        final ContextualCard card = generateConditionFooterContextualCard();
+        final View view = LayoutInflater.from(mContext).inflate(card.getViewType(), recyclerView,
+                false);
+        final RecyclerView.ViewHolder viewHolder = mRenderer.createViewHolder(view,
+                card.getViewType());
         when(mControllerRendererPool.getController(mContext,
                 ContextualCard.CardType.CONDITIONAL_FOOTER)).thenReturn(mController);
 
-        mRenderer.bindView(viewHolder, generateConditionFooterContextualCard());
+        mRenderer.bindView(viewHolder, card);
 
         assertThat(viewHolder.itemView).isNotNull();
         viewHolder.itemView.performClick();
@@ -96,6 +100,7 @@
         return new ConditionFooterContextualCard.Builder()
                 .setName("test_condition_footer")
                 .setRankingScore(-9999.0)
+                .setViewType(ConditionFooterContextualCardRenderer.VIEW_TYPE)
                 .build();
     }
 }
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionHeaderContextualCardRendererTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionHeaderContextualCardRendererTest.java
index a4aa1d7..02dcecd 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionHeaderContextualCardRendererTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionHeaderContextualCardRendererTest.java
@@ -67,11 +67,13 @@
 
     @Test
     public void bindView_shouldSetClickListener() {
-        final int viewType = mRenderer.getViewType(false /* isHalfWidth */);
         final RecyclerView recyclerView = new RecyclerView(mActivity);
         recyclerView.setLayoutManager(new LinearLayoutManager(mActivity));
-        final View view = LayoutInflater.from(mActivity).inflate(viewType, recyclerView, false);
-        final RecyclerView.ViewHolder viewHolder = mRenderer.createViewHolder(view);
+        final ContextualCard card = generateConditionHeaderContextualCard();
+        final View view = LayoutInflater.from(mActivity).inflate(card.getViewType(), recyclerView,
+                false);
+        final RecyclerView.ViewHolder viewHolder = mRenderer.createViewHolder(view,
+                card.getViewType());
         when(mControllerRendererPool.getController(mActivity,
                 ContextualCard.CardType.CONDITIONAL_HEADER)).thenReturn(mController);
 
@@ -83,11 +85,13 @@
 
     @Test
     public void bindView_clickView_shouldSetTrueToIsConditionExpanded() {
-        final int viewType = mRenderer.getViewType(false /* isHalfWidth */);
         final RecyclerView recyclerView = new RecyclerView(mActivity);
         recyclerView.setLayoutManager(new LinearLayoutManager(mActivity));
-        final View view = LayoutInflater.from(mActivity).inflate(viewType, recyclerView, false);
-        final RecyclerView.ViewHolder viewHolder = mRenderer.createViewHolder(view);
+        final ContextualCard card = generateConditionHeaderContextualCard();
+        final View view = LayoutInflater.from(mActivity).inflate(card.getViewType(), recyclerView,
+                false);
+        final RecyclerView.ViewHolder viewHolder = mRenderer.createViewHolder(view,
+                card.getViewType());
         when(mControllerRendererPool.getController(mActivity,
                 ContextualCard.CardType.CONDITIONAL_HEADER)).thenReturn(mController);
 
@@ -105,6 +109,7 @@
                 .setConditionalCards(generateConditionCards(3))
                 .setName("test_condition_header")
                 .setRankingScore(-9999.0)
+                .setViewType(ConditionHeaderContextualCardRenderer.VIEW_TYPE)
                 .build();
     }
 
@@ -118,7 +123,7 @@
                     .setName("test_name" + i)
                     .setTitleText("test_title" + i)
                     .setSummaryText("test_summary" + i)
-                    .setIsHalfWidth(true)
+                    .setViewType(ConditionContextualCardRenderer.VIEW_TYPE_HALF_WIDTH)
                     .build());
         }
         return conditionCards;
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRendererTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRendererTest.java
index 2182794..596e95d6 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRendererTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRendererTest.java
@@ -66,35 +66,38 @@
 
     @Test
     public void bindView_shouldSetListener() {
-        final int viewType = mRenderer.getViewType(true /* isHalfWidth */);
         final RecyclerView recyclerView = new RecyclerView(mActivity);
         recyclerView.setLayoutManager(new LinearLayoutManager(mActivity));
-        final View card = LayoutInflater.from(mActivity).inflate(viewType, recyclerView, false);
-        final RecyclerView.ViewHolder viewHolder = mRenderer.createViewHolder(card);
-
+        final ContextualCard card = buildContextualCard();
+        final View cardView = LayoutInflater.from(mActivity).inflate(card.getViewType(),
+                recyclerView, false);
+        final RecyclerView.ViewHolder viewHolder = mRenderer.createViewHolder(cardView,
+                card.getViewType());
         when(mControllerRendererPool.getController(mActivity,
                 ContextualCard.CardType.LEGACY_SUGGESTION)).thenReturn(mController);
 
         mRenderer.bindView(viewHolder, buildContextualCard());
 
-        assertThat(card).isNotNull();
-        assertThat(card.hasOnClickListeners()).isTrue();
+        assertThat(cardView).isNotNull();
+        assertThat(cardView.hasOnClickListeners()).isTrue();
     }
 
     @Test
     public void viewClick_shouldInvokeControllerPrimaryClick() {
-        final int viewType = mRenderer.getViewType(true /* isHalfWidth */);
         final RecyclerView recyclerView = new RecyclerView(mActivity);
         recyclerView.setLayoutManager(new LinearLayoutManager(mActivity));
-        final View card = LayoutInflater.from(mActivity).inflate(viewType, recyclerView, false);
-        final RecyclerView.ViewHolder viewHolder = mRenderer.createViewHolder(card);
+        final ContextualCard card = buildContextualCard();
+        final View cardView = LayoutInflater.from(mActivity).inflate(card.getViewType(),
+                recyclerView, false);
+        final RecyclerView.ViewHolder viewHolder = mRenderer.createViewHolder(cardView,
+                card.getViewType());
         when(mControllerRendererPool.getController(mActivity,
                 ContextualCard.CardType.LEGACY_SUGGESTION)).thenReturn(mController);
 
         mRenderer.bindView(viewHolder, buildContextualCard());
 
-        assertThat(card).isNotNull();
-        card.performClick();
+        assertThat(cardView).isNotNull();
+        cardView.performClick();
 
         verify(mController).onPrimaryClick(any(ContextualCard.class));
     }
@@ -105,6 +108,7 @@
                 .setTitleText("test_title")
                 .setSummaryText("test_summary")
                 .setIconDrawable(mActivity.getDrawable(R.drawable.ic_do_not_disturb_on_24dp))
+                .setViewType(LegacySuggestionContextualCardRenderer.VIEW_TYPE)
                 .build();
     }
 }
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRendererTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRendererTest.java
index 4d9a21d..b156782 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRendererTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRendererTest.java
@@ -16,6 +16,8 @@
 
 package com.android.settings.homepage.contextualcards.slices;
 
+import static com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer.VIEW_TYPE_FULL_WIDTH;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.Mockito.doReturn;
@@ -211,12 +213,12 @@
     }
 
     private RecyclerView.ViewHolder getSliceViewHolder() {
-        final int viewType = mRenderer.getViewType(false /* isHalfWidth */);
         final RecyclerView recyclerView = new RecyclerView(mActivity);
         recyclerView.setLayoutManager(new LinearLayoutManager(mActivity));
-        final View view = LayoutInflater.from(mActivity).inflate(viewType, recyclerView, false);
+        final View view = LayoutInflater.from(mActivity).inflate(VIEW_TYPE_FULL_WIDTH, recyclerView,
+                false);
 
-        return mRenderer.createViewHolder(view);
+        return mRenderer.createViewHolder(view, VIEW_TYPE_FULL_WIDTH);
     }
 
     private ContextualCard buildContextualCard(Uri sliceUri) {
@@ -224,6 +226,7 @@
                 .setName("test_name")
                 .setCardType(ContextualCard.CardType.SLICE)
                 .setSliceUri(sliceUri)
+                .setViewType(VIEW_TYPE_FULL_WIDTH)
                 .build();
     }
 }
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceFullCardRendererHelperTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceFullCardRendererHelperTest.java
index 9172300d..8882009 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceFullCardRendererHelperTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceFullCardRendererHelperTest.java
@@ -127,7 +127,7 @@
                 .setCategory(ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE)
                 .setCardType(ContextualCard.CardType.SLICE)
                 .setSliceUri(TEST_SLICE_URI)
-                .setIsHalfWidth(false /* isHalfWidth */)
+                .setViewType(VIEW_TYPE_FULL_WIDTH)
                 .build();
     }
 
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceHalfCardRendererHelperTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceHalfCardRendererHelperTest.java
index c38697e..1286c27 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceHalfCardRendererHelperTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceHalfCardRendererHelperTest.java
@@ -95,7 +95,7 @@
                 .setCategory(ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE)
                 .setCardType(ContextualCard.CardType.SLICE)
                 .setSliceUri(TEST_SLICE_URI)
-                .setIsHalfWidth(false /* isHalfWidth */)
+                .setViewType(VIEW_TYPE_HALF_WIDTH)
                 .build();
     }
 
diff --git a/tests/robotests/src/com/android/settings/network/MobileNetworkListControllerTest.java b/tests/robotests/src/com/android/settings/network/MobileNetworkListControllerTest.java
new file mode 100644
index 0000000..1325650
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/network/MobileNetworkListControllerTest.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2019 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 android.provider.Settings.EXTRA_SUB_ID;
+import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.telephony.SubscriptionInfo;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
+import org.robolectric.RobolectricTestRunner;
+
+import java.util.Arrays;
+
+import androidx.lifecycle.Lifecycle;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+@RunWith(RobolectricTestRunner.class)
+public class MobileNetworkListControllerTest {
+    @Mock
+    private Lifecycle mLifecycle;
+
+    @Mock
+    private PreferenceScreen mPreferenceScreen;
+
+    private Context mContext;
+    private MobileNetworkListController mController;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = spy(Robolectric.setupActivity(Activity.class));
+        when(mPreferenceScreen.getContext()).thenReturn(mContext);
+        mController = new MobileNetworkListController(mContext, mLifecycle);
+    }
+
+    @After
+    public void tearDown() {
+        SubscriptionUtil.setAvailableSubscriptionsForTesting(null);
+    }
+
+    @Test
+    public void displayPreference_noSubscriptions_noCrash() {
+        mController.displayPreference(mPreferenceScreen);
+        mController.onResume();
+    }
+
+    @Test
+    public void displayPreference_twoSubscriptions_correctlySetup() {
+        final SubscriptionInfo sub1 = createMockSubscription(1, "sub1");
+        final SubscriptionInfo sub2 = createMockSubscription(2, "sub2");
+        SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2));
+        mController.displayPreference(mPreferenceScreen);
+        mController.onResume();
+
+        // Check that the preferences get created with the correct titles.
+        final ArgumentCaptor<Preference> preferenceCaptor = ArgumentCaptor.forClass(
+                Preference.class);
+        verify(mPreferenceScreen, times(2)).addPreference(preferenceCaptor.capture());
+        final Preference pref1 = preferenceCaptor.getAllValues().get(0);
+        final Preference pref2 = preferenceCaptor.getAllValues().get(1);
+        assertThat(pref1.getTitle()).isEqualTo("sub1");
+        assertThat(pref2.getTitle()).isEqualTo("sub2");
+
+        // Check that the onclick listeners are setup to fire with the right subscription id.
+        final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+        pref1.getOnPreferenceClickListener().onPreferenceClick(pref1);
+        pref2.getOnPreferenceClickListener().onPreferenceClick(pref2);
+        verify(mContext, times(2)).startActivity(intentCaptor.capture());
+        final Intent intent1 = intentCaptor.getAllValues().get(0);
+        final Intent intent2 = intentCaptor.getAllValues().get(1);
+        assertThat(intent1.getIntExtra(EXTRA_SUB_ID, INVALID_SUBSCRIPTION_ID)).isEqualTo(1);
+        assertThat(intent2.getIntExtra(EXTRA_SUB_ID, INVALID_SUBSCRIPTION_ID)).isEqualTo(2);
+    }
+
+    @Test
+    public void onSubscriptionsChanged_twoSubscriptionsOneChangesName_preferenceUpdated() {
+        final SubscriptionInfo sub1 = createMockSubscription(1, "sub1");
+        final SubscriptionInfo sub2 = createMockSubscription(2, "sub2");
+        SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2));
+        mController.displayPreference(mPreferenceScreen);
+        mController.onResume();
+        final ArgumentCaptor<Preference> preferenceCaptor = ArgumentCaptor.forClass(
+                Preference.class);
+        verify(mPreferenceScreen, times(2)).addPreference(preferenceCaptor.capture());
+
+        when(sub2.getDisplayName()).thenReturn("new name");
+        mController.onSubscriptionsChanged();
+        assertThat(preferenceCaptor.getAllValues().get(1).getTitle()).isEqualTo("new name");
+    }
+
+    @Test
+    public void onSubscriptionsChanged_startWithThreeSubsAndRemoveOne_correctPreferenceRemoved() {
+        final SubscriptionInfo sub1 = createMockSubscription(1, "sub1");
+        final SubscriptionInfo sub2 = createMockSubscription(2, "sub2");
+        final SubscriptionInfo sub3 = createMockSubscription(3, "sub3");
+        SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2, sub3));
+        mController.displayPreference(mPreferenceScreen);
+        mController.onResume();
+        final ArgumentCaptor<Preference> preferenceCaptor = ArgumentCaptor.forClass(
+                Preference.class);
+        verify(mPreferenceScreen, times(3)).addPreference(preferenceCaptor.capture());
+
+        // remove sub2, and check that the second pref was removed from the screen
+        SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub3));
+        mController.onSubscriptionsChanged();
+        final ArgumentCaptor<Preference> removedPrefCaptor = ArgumentCaptor.forClass(
+                Preference.class);
+        verify(mPreferenceScreen).removePreference(removedPrefCaptor.capture());
+        assertThat(removedPrefCaptor.getValue().getTitle()).isEqualTo("sub2");
+    }
+
+    private SubscriptionInfo createMockSubscription(int id, String displayName) {
+        final SubscriptionInfo sub = mock(SubscriptionInfo.class);
+        when(sub.getSubscriptionId()).thenReturn(id);
+        when(sub.getDisplayName()).thenReturn(displayName);
+        return sub;
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java b/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java
new file mode 100644
index 0000000..f0c012d
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2019 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.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.telephony.SubscriptionInfo;
+
+import com.android.settings.network.telephony.MobileNetworkActivity;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
+import org.robolectric.RobolectricTestRunner;
+
+import java.util.Arrays;
+
+import androidx.lifecycle.Lifecycle;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+@RunWith(RobolectricTestRunner.class)
+public class MobileNetworkSummaryControllerTest {
+    @Mock
+    private Lifecycle mLifecycle;
+    @Mock
+    PreferenceScreen mPreferenceScreen;
+
+    Preference mPreference;
+
+    private Context mContext;
+    private MobileNetworkSummaryController mController;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = spy(Robolectric.setupActivity(Activity.class));
+        mController = new MobileNetworkSummaryController(mContext, mLifecycle);
+        mPreference = new Preference(mContext);
+        mPreference.setKey(mController.getPreferenceKey());
+        when(mPreferenceScreen.findPreference(eq(mController.getPreferenceKey()))).thenReturn(
+                mPreference);
+    }
+
+    @After
+    public void tearDown() {
+        SubscriptionUtil.setAvailableSubscriptionsForTesting(null);
+    }
+
+    @Test
+    public void getSummary_noSubscriptions_correctSummary() {
+        mController.displayPreference(mPreferenceScreen);
+        mController.onResume();
+        assertThat(mController.getSummary()).isEqualTo("Add a network");
+    }
+
+    @Test
+    public void getSummary_oneSubscription_correctSummaryAndClickHandler() {
+        SubscriptionInfo sub1 = mock(SubscriptionInfo.class);
+        when(sub1.getSubscriptionId()).thenReturn(1);
+        when(sub1.getDisplayName()).thenReturn("sub1");
+        SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1));
+        mController.displayPreference(mPreferenceScreen);
+        mController.onResume();
+        assertThat(mController.getSummary()).isEqualTo("sub1");
+        assertThat(mPreference.getFragment()).isNull();
+        mPreference.getOnPreferenceClickListener().onPreferenceClick(mPreference);
+        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+        verify(mContext).startActivity(intentCaptor.capture());
+        assertThat(intentCaptor.getValue().getComponent().getClassName()).isEqualTo(
+                MobileNetworkActivity.class.getName());
+    }
+
+    @Test
+    public void getSummary_twoSubscriptions_correctSummaryAndFragment() {
+        SubscriptionInfo sub1 = mock(SubscriptionInfo.class);
+        SubscriptionInfo sub2 = mock(SubscriptionInfo.class);
+        when(sub1.getSubscriptionId()).thenReturn(1);
+        when(sub2.getSubscriptionId()).thenReturn(2);
+
+        SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2));
+        mController.displayPreference(mPreferenceScreen);
+        mController.onResume();
+        assertThat(mController.getSummary()).isEqualTo("2 SIMs");
+        assertThat(mPreference.getFragment()).isEqualTo(MobileNetworkListFragment.class.getName());
+    }
+
+    @Test
+    public void getSummaryAfterUpdate_twoSubscriptionsBecomesOne_correctSummaryAndFragment() {
+        SubscriptionInfo sub1 = mock(SubscriptionInfo.class);
+        SubscriptionInfo sub2 = mock(SubscriptionInfo.class);
+        when(sub1.getSubscriptionId()).thenReturn(1);
+        when(sub2.getSubscriptionId()).thenReturn(2);
+        when(sub1.getDisplayName()).thenReturn("sub1");
+        when(sub2.getDisplayName()).thenReturn("sub2");
+
+        SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2));
+        mController.displayPreference(mPreferenceScreen);
+        mController.onResume();
+        assertThat(mController.getSummary()).isEqualTo("2 SIMs");
+        assertThat(mPreference.getFragment()).isEqualTo(MobileNetworkListFragment.class.getName());
+
+        // Simulate sub2 having disappeared - the end result should change to be the same as
+        // if there were just one subscription.
+        SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1));
+        mController.onSubscriptionsChanged();
+        assertThat(mController.getSummary()).isEqualTo("sub1");
+        assertThat(mPreference.getFragment()).isNull();
+        mPreference.getOnPreferenceClickListener().onPreferenceClick(mPreference);
+        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+        verify(mContext).startActivity(intentCaptor.capture());
+        assertThat(intentCaptor.getValue().getComponent().getClassName()).isEqualTo(
+                MobileNetworkActivity.class.getName());
+    }
+
+    @Test
+    public void getSummaryAfterUpdate_oneSubscriptionBecomesTwo_correctSummaryAndFragment() {
+        SubscriptionInfo sub1 = mock(SubscriptionInfo.class);
+        SubscriptionInfo sub2 = mock(SubscriptionInfo.class);
+        when(sub1.getSubscriptionId()).thenReturn(1);
+        when(sub2.getSubscriptionId()).thenReturn(2);
+        when(sub1.getDisplayName()).thenReturn("sub1");
+        when(sub2.getDisplayName()).thenReturn("sub2");
+
+        SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1));
+        mController.displayPreference(mPreferenceScreen);
+        mController.onResume();
+        assertThat(mController.getSummary()).isEqualTo("sub1");
+        assertThat(mPreference.getFragment()).isNull();
+        mPreference.getOnPreferenceClickListener().onPreferenceClick(mPreference);
+        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+        verify(mContext).startActivity(intentCaptor.capture());
+        assertThat(intentCaptor.getValue().getComponent().getClassName()).isEqualTo(
+                MobileNetworkActivity.class.getName());
+
+        // Simulate sub2 appearing in the list of subscriptions and check the results.
+        SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2));
+        mController.displayPreference(mPreferenceScreen);
+        mController.onResume();
+        assertThat(mController.getSummary()).isEqualTo("2 SIMs");
+        assertThat(mPreference.getFragment()).isEqualTo(MobileNetworkListFragment.class.getName());
+    }
+}