A new attribute which can show the dynamic summary

For now, slice view shows screen title by default,
but it isn't approprate for some simple cases.
ie, device model, phone number, android version etc.

So, We create a new attribue which let BasePreferenceController
be more flxible. User can choose what they want to show
in summary text.

Fixes: 74900516
Test: make RunSettingsRoboTests

Change-Id: I2788c6edfaf8e656170a507607f22513841a3e0a
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index e729126..4247326 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -75,6 +75,8 @@
         <attr name="controller" format="string" />
         <!-- {@code true} when the controller declared represents a slice from {@link android.app.SettingsSliceContract} -->
         <attr name="platform_slice" format="boolean" />
+        <!-- Whether or not dynamic summary text from PreferenceController is allowed when creating slice object, by default it's false. -->
+        <attr name="allowDynamicSummaryInSlice" format="boolean" />
     </declare-styleable>
 
     <!-- For DotsPageIndicator -->
diff --git a/src/com/android/settings/core/PreferenceXmlParserUtils.java b/src/com/android/settings/core/PreferenceXmlParserUtils.java
index 8ef7f8d..9fdeeef 100644
--- a/src/com/android/settings/core/PreferenceXmlParserUtils.java
+++ b/src/com/android/settings/core/PreferenceXmlParserUtils.java
@@ -69,7 +69,8 @@
             MetadataFlag.FLAG_NEED_PREF_TITLE,
             MetadataFlag.FLAG_NEED_PREF_SUMMARY,
             MetadataFlag.FLAG_NEED_PREF_ICON,
-            MetadataFlag.FLAG_NEED_SEARCHABLE})
+            MetadataFlag.FLAG_NEED_SEARCHABLE,
+            MetadataFlag.FLAG_ALLOW_DYNAMIC_SUMMARY_IN_SLICE})
     @Retention(RetentionPolicy.SOURCE)
     public @interface MetadataFlag {
         int FLAG_INCLUDE_PREF_SCREEN = 1;
@@ -82,6 +83,7 @@
         int FLAG_NEED_PLATFORM_SLICE_FLAG = 1 << 7;
         int FLAG_NEED_KEYWORDS = 1 << 8;
         int FLAG_NEED_SEARCHABLE = 1 << 9;
+        int FLAG_ALLOW_DYNAMIC_SUMMARY_IN_SLICE = 1 << 10;
     }
 
     public static final String METADATA_PREF_TYPE = "type";
@@ -93,6 +95,8 @@
     public static final String METADATA_PLATFORM_SLICE_FLAG = "platform_slice";
     public static final String METADATA_KEYWORDS = "keywords";
     public static final String METADATA_SEARCHABLE = "searchable";
+    public static final String METADATA_ALLOW_DYNAMIC_SUMMARY_IN_SLICE =
+            "allow_dynamic_summary_in_slice";
 
     private static final String ENTRIES_SEPARATOR = "|";
 
@@ -228,6 +232,10 @@
                 preferenceMetadata.putBoolean(METADATA_SEARCHABLE,
                         isSearchable(preferenceAttributes));
             }
+            if (hasFlag(flags, MetadataFlag.FLAG_ALLOW_DYNAMIC_SUMMARY_IN_SLICE)) {
+                preferenceMetadata.putBoolean(METADATA_ALLOW_DYNAMIC_SUMMARY_IN_SLICE,
+                        isDynamicSummaryAllowed(preferenceAttributes));
+            }
             metadata.add(preferenceMetadata);
 
             preferenceAttributes.recycle();
@@ -312,6 +320,11 @@
         return styledAttributes.getBoolean(R.styleable.Preference_searchable, true /* default */);
     }
 
+    private static boolean isDynamicSummaryAllowed(TypedArray styledAttributes) {
+        return styledAttributes.getBoolean(R.styleable.Preference_allowDynamicSummaryInSlice,
+                false /* default */);
+    }
+
     private static String getKeywords(TypedArray styleAttributes) {
         return styleAttributes.getString(R.styleable.Preference_keywords);
     }
diff --git a/src/com/android/settings/slices/SliceBuilderUtils.java b/src/com/android/settings/slices/SliceBuilderUtils.java
index 0306fc9..a947fb2 100644
--- a/src/com/android/settings/slices/SliceBuilderUtils.java
+++ b/src/com/android/settings/slices/SliceBuilderUtils.java
@@ -184,12 +184,23 @@
      */
     public static CharSequence getSubtitleText(Context context,
             AbstractPreferenceController controller, SliceData sliceData) {
-        CharSequence summaryText = sliceData.getScreenTitle();
+        final boolean isDynamicSummaryAllowed = sliceData.isDynamicSummaryAllowed();
+        CharSequence summaryText = controller.getSummary();
+
+        // Priority 1 : User prefers showing the dynamic summary in slice view rather than static
+        // summary.
+        if (isDynamicSummaryAllowed && isValidSummary(context, summaryText)) {
+            return summaryText;
+        }
+
+        // Priority 2 : Show screen title.
+        summaryText = sliceData.getScreenTitle();
         if (isValidSummary(context, summaryText) && !TextUtils.equals(summaryText,
                 sliceData.getTitle())) {
             return summaryText;
         }
 
+        // Priority 3 : Show dynamic summary from preference controller.
         if (controller != null) {
             summaryText = controller.getSummary();
 
@@ -198,11 +209,13 @@
             }
         }
 
+        // Priority 4 : Show summary from slice data.
         summaryText = sliceData.getSummary();
         if (isValidSummary(context, summaryText)) {
             return summaryText;
         }
 
+        // Priority 5 : Show empty text.
         return "";
     }
 
@@ -217,7 +230,7 @@
                 .build();
     }
 
-    public static Intent  buildSearchResultPageIntent(Context context, String className, String key,
+    public static Intent buildSearchResultPageIntent(Context context, String className, String key,
             String screenTitle, int sourceMetricsCategory) {
         final Bundle args = new Bundle();
         args.putString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, key);
diff --git a/src/com/android/settings/slices/SliceData.java b/src/com/android/settings/slices/SliceData.java
index 72729a8..8705884 100644
--- a/src/com/android/settings/slices/SliceData.java
+++ b/src/com/android/settings/slices/SliceData.java
@@ -74,6 +74,8 @@
 
     private final boolean mIsPlatformDefined;
 
+    private final boolean mIsDynamicSummaryAllowed;
+
     public String getKey() {
         return mKey;
     }
@@ -118,6 +120,10 @@
         return mIsPlatformDefined;
     }
 
+    public boolean isDynamicSummaryAllowed() {
+        return mIsDynamicSummaryAllowed;
+    }
+
     private SliceData(Builder builder) {
         mKey = builder.mKey;
         mTitle = builder.mTitle;
@@ -130,6 +136,7 @@
         mPreferenceController = builder.mPrefControllerClassName;
         mSliceType = builder.mSliceType;
         mIsPlatformDefined = builder.mIsPlatformDefined;
+        mIsDynamicSummaryAllowed = builder.mIsDynamicSummaryAllowed;
     }
 
     @Override
@@ -169,6 +176,8 @@
 
         private boolean mIsPlatformDefined;
 
+        private boolean mIsDynamicSummaryAllowed;
+
         public Builder setKey(String key) {
             mKey = key;
             return this;
@@ -224,6 +233,11 @@
             return this;
         }
 
+        public Builder setDynamicSummaryAllowed(boolean isDynamicSummaryAllowed) {
+            mIsDynamicSummaryAllowed = isDynamicSummaryAllowed;
+            return this;
+        }
+
         public SliceData build() {
             if (TextUtils.isEmpty(mKey)) {
                 throw new InvalidSliceDataException("Key cannot be empty");
diff --git a/src/com/android/settings/slices/SliceDataConverter.java b/src/com/android/settings/slices/SliceDataConverter.java
index 7c233a6..29e3d6b 100644
--- a/src/com/android/settings/slices/SliceDataConverter.java
+++ b/src/com/android/settings/slices/SliceDataConverter.java
@@ -16,6 +16,8 @@
 
 package com.android.settings.slices;
 
+import static com.android.settings.core.PreferenceXmlParserUtils
+        .METADATA_ALLOW_DYNAMIC_SUMMARY_IN_SLICE;
 import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_CONTROLLER;
 import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_ICON;
 import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_KEY;
@@ -186,7 +188,8 @@
                             | MetadataFlag.FLAG_NEED_PREF_TITLE
                             | MetadataFlag.FLAG_NEED_PREF_ICON
                             | MetadataFlag.FLAG_NEED_PREF_SUMMARY
-                            | MetadataFlag.FLAG_NEED_PLATFORM_SLICE_FLAG);
+                            | MetadataFlag.FLAG_NEED_PLATFORM_SLICE_FLAG
+                            | MetadataFlag.FLAG_ALLOW_DYNAMIC_SUMMARY_IN_SLICE);
 
             for (Bundle bundle : metadata) {
                 // TODO (b/67996923) Non-controller Slices should become intent-only slices.
@@ -203,6 +206,8 @@
                 final int sliceType = SliceBuilderUtils.getSliceType(mContext, controllerClassName,
                         key);
                 final boolean isPlatformSlice = bundle.getBoolean(METADATA_PLATFORM_SLICE_FLAG);
+                final boolean isDynamicSummaryAllowed = bundle.getBoolean(
+                        METADATA_ALLOW_DYNAMIC_SUMMARY_IN_SLICE);
 
                 final SliceData xmlSlice = new SliceData.Builder()
                         .setKey(key)
@@ -214,6 +219,7 @@
                         .setFragmentName(fragmentName)
                         .setSliceType(sliceType)
                         .setPlatformDefined(isPlatformSlice)
+                        .setDynamicSummaryAllowed(isDynamicSummaryAllowed)
                         .build();
 
                 final BasePreferenceController controller =
diff --git a/src/com/android/settings/slices/SlicesDatabaseAccessor.java b/src/com/android/settings/slices/SlicesDatabaseAccessor.java
index 79d3bc6..35a0a5d 100644
--- a/src/com/android/settings/slices/SlicesDatabaseAccessor.java
+++ b/src/com/android/settings/slices/SlicesDatabaseAccessor.java
@@ -49,6 +49,7 @@
             IndexColumns.CONTROLLER,
             IndexColumns.PLATFORM_SLICE,
             IndexColumns.SLICE_TYPE,
+            IndexColumns.ALLOW_DYNAMIC_SUMMARY_IN_SLICE,
     };
 
     // Cursor value for boolean true
@@ -159,6 +160,8 @@
                 cursor.getColumnIndex(IndexColumns.CONTROLLER));
         final boolean isPlatformDefined = cursor.getInt(
                 cursor.getColumnIndex(IndexColumns.PLATFORM_SLICE)) == TRUE;
+        final boolean isDynamicSummaryAllowed = cursor.getInt(
+                cursor.getColumnIndex(IndexColumns.ALLOW_DYNAMIC_SUMMARY_IN_SLICE)) == TRUE;
         int sliceType = cursor.getInt(
                 cursor.getColumnIndex(IndexColumns.SLICE_TYPE));
 
@@ -178,6 +181,7 @@
                 .setUri(uri)
                 .setPlatformDefined(isPlatformDefined)
                 .setSliceType(sliceType)
+                .setDynamicSummaryAllowed(isDynamicSummaryAllowed)
                 .build();
     }
 
diff --git a/src/com/android/settings/slices/SlicesDatabaseHelper.java b/src/com/android/settings/slices/SlicesDatabaseHelper.java
index f1628e7..e463099 100644
--- a/src/com/android/settings/slices/SlicesDatabaseHelper.java
+++ b/src/com/android/settings/slices/SlicesDatabaseHelper.java
@@ -36,7 +36,7 @@
     private static final String DATABASE_NAME = "slices_index.db";
     private static final String SHARED_PREFS_TAG = "slices_shared_prefs";
 
-    private static final int DATABASE_VERSION = 2;
+    private static final int DATABASE_VERSION = 3;
 
     public interface Tables {
         String TABLE_SLICES_INDEX = "slices_index";
@@ -93,6 +93,12 @@
          * {@link SliceData.SliceType} representing the inline type of the result.
          */
         String SLICE_TYPE = "slice_type";
+
+        /**
+         * Boolean flag, {@code true} when the slice object prefers using the dynamic summary from
+         * preference controller.
+         */
+        String ALLOW_DYNAMIC_SUMMARY_IN_SLICE = "allow_dynamic_summary_in_slice";
     }
 
     private static final String CREATE_SLICES_TABLE =
@@ -117,6 +123,8 @@
                     IndexColumns.PLATFORM_SLICE +
                     ", " +
                     IndexColumns.SLICE_TYPE +
+                    ", " +
+                    IndexColumns.ALLOW_DYNAMIC_SUMMARY_IN_SLICE +
                     ");";
 
     private final Context mContext;
diff --git a/src/com/android/settings/slices/SlicesIndexer.java b/src/com/android/settings/slices/SlicesIndexer.java
index f88af8f..0ccd223 100644
--- a/src/com/android/settings/slices/SlicesIndexer.java
+++ b/src/com/android/settings/slices/SlicesIndexer.java
@@ -111,6 +111,8 @@
             values.put(IndexColumns.CONTROLLER, dataRow.getPreferenceController());
             values.put(IndexColumns.PLATFORM_SLICE, dataRow.isPlatformDefined());
             values.put(IndexColumns.SLICE_TYPE, dataRow.getSliceType());
+            values.put(IndexColumns.ALLOW_DYNAMIC_SUMMARY_IN_SLICE,
+                    dataRow.isDynamicSummaryAllowed());
 
             database.replaceOrThrow(Tables.TABLE_SLICES_INDEX, null /* nullColumnHack */,
                     values);
diff --git a/tests/robotests/res/xml-mcc998/location_settings.xml b/tests/robotests/res/xml-mcc998/location_settings.xml
index f61ca63..16f0d82 100644
--- a/tests/robotests/res/xml-mcc998/location_settings.xml
+++ b/tests/robotests/res/xml-mcc998/location_settings.xml
@@ -25,13 +25,15 @@
         android:title="title"
         android:icon="@drawable/ic_android"
         android:summary="summary1"
-        settings:controller="com.android.settings.core.BadPreferenceController"/>
+        settings:controller="com.android.settings.core.BadPreferenceController"
+        settings:allowDynamicSummaryInSlice="true"/>
 
     <Preference
         android:key="key2"
         android:title="title"
         android:icon="@drawable/ic_android"
         android:summary="summary2"
-        settings:controller="com.android.settings.slices.FakePreferenceController"/>
+        settings:controller="com.android.settings.slices.FakePreferenceController"
+        settings:allowDynamicSummaryInSlice="true"/>
 
 </PreferenceScreen>
\ No newline at end of file
diff --git a/tests/robotests/res/xml-mcc999/location_settings.xml b/tests/robotests/res/xml-mcc999/location_settings.xml
index da71a1e..91e4c41 100644
--- a/tests/robotests/res/xml-mcc999/location_settings.xml
+++ b/tests/robotests/res/xml-mcc999/location_settings.xml
@@ -26,6 +26,7 @@
         android:summary="summary"
         settings:controller="com.android.settings.slices.FakePreferenceController"
         settings:keywords="a, b, c"
-        settings:platform_slice="true"/>
+        settings:platform_slice="true"
+        settings:allowDynamicSummaryInSlice="true"/>
 
 </PreferenceScreen>
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/core/PreferenceXmlParserUtilsTest.java b/tests/robotests/src/com/android/settings/core/PreferenceXmlParserUtilsTest.java
index 06d75da..3b1b5af 100644
--- a/tests/robotests/src/com/android/settings/core/PreferenceXmlParserUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/core/PreferenceXmlParserUtilsTest.java
@@ -16,6 +16,8 @@
 
 package com.android.settings.core;
 
+import static com.android.settings.core.PreferenceXmlParserUtils
+        .METADATA_ALLOW_DYNAMIC_SUMMARY_IN_SLICE;
 import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_KEY;
 import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_KEYWORDS;
 import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_SEARCHABLE;
@@ -289,6 +291,30 @@
         assertThat(foundKey).isTrue();
     }
 
+    @Test
+    @Config(qualifiers = "mcc999")
+    public void extractMetadata_requestIsDynamicSummaryAllowed_shouldDefaultToFalse()
+            throws Exception {
+        final List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(mContext,
+                R.xml.display_settings, MetadataFlag.FLAG_ALLOW_DYNAMIC_SUMMARY_IN_SLICE);
+
+        for (Bundle bundle : metadata) {
+            assertThat(bundle.getBoolean(METADATA_ALLOW_DYNAMIC_SUMMARY_IN_SLICE)).isFalse();
+        }
+    }
+
+    @Test
+    @Config(qualifiers = "mcc998")
+    public void extractMetadata_requestIsDynamicSummaryAllowed_shouldReturnAttributeValue()
+            throws Exception {
+        final List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(mContext,
+                R.xml.location_settings, MetadataFlag.FLAG_ALLOW_DYNAMIC_SUMMARY_IN_SLICE);
+
+        for (Bundle bundle : metadata) {
+            assertThat(bundle.getBoolean(METADATA_ALLOW_DYNAMIC_SUMMARY_IN_SLICE)).isTrue();
+        }
+    }
+
     /**
      * @param resId the ID for the XML preference
      * @return an XML resource parser that points to the start tag
diff --git a/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java b/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java
index 705c0eb..16e9cb7 100644
--- a/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java
@@ -70,6 +70,7 @@
     private final Class TOGGLE_CONTROLLER = FakeToggleController.class;
     private final Class SLIDER_CONTROLLER = FakeSliderController.class;
     private final Class CONTEXT_CONTROLLER = FakeContextOnlyPreferenceController.class;
+    private final boolean IS_DYNAMIC_SUMMARY_ALLOWED = false;
 
     private final String INTENT_PATH = SettingsSlicesContract.PATH_SETTING_INTENT + "/" + KEY;
     private final String ACTION_PATH = SettingsSlicesContract.PATH_SETTING_ACTION + "/" + KEY;
@@ -206,6 +207,19 @@
     }
 
     @Test
+    public void getDynamicSummary_allowDynamicSummary_returnsControllerSummary() {
+        final SliceData data = getDummyData(true /*isDynamicSummaryAllowed*/);
+        final FakePreferenceController controller = spy(
+                new FakePreferenceController(mContext, KEY));
+        final String controllerSummary = "new_Summary";
+        doReturn(controllerSummary).when(controller).getSummary();
+
+        final CharSequence summary = SliceBuilderUtils.getSubtitleText(mContext, controller, data);
+
+        assertThat(summary).isEqualTo(controllerSummary);
+    }
+
+    @Test
     public void getDynamicSummary_returnsScreenTitle() {
         final SliceData data = getDummyData();
         final FakePreferenceController controller = new FakePreferenceController(mContext, KEY);
@@ -470,25 +484,31 @@
 
     private SliceData getDummyData() {
         return getDummyData(TOGGLE_CONTROLLER, SUMMARY, SliceData.SliceType.SWITCH, SCREEN_TITLE,
-                ICON);
+                ICON, IS_DYNAMIC_SUMMARY_ALLOWED);
+    }
+
+    private SliceData getDummyData(boolean isDynamicSummaryAllowed) {
+        return getDummyData(TOGGLE_CONTROLLER, SUMMARY, SliceData.SliceType.SWITCH, SCREEN_TITLE,
+                ICON, isDynamicSummaryAllowed);
     }
 
     private SliceData getDummyData(Class prefController, int sliceType, int icon) {
         return getDummyData(TOGGLE_CONTROLLER, SUMMARY, SliceData.SliceType.SWITCH, SCREEN_TITLE,
-                icon);
+                icon, IS_DYNAMIC_SUMMARY_ALLOWED);
     }
 
     private SliceData getDummyData(String summary, String screenTitle) {
         return getDummyData(TOGGLE_CONTROLLER, summary, SliceData.SliceType.SWITCH, screenTitle,
-                ICON);
+                ICON, IS_DYNAMIC_SUMMARY_ALLOWED);
     }
 
     private SliceData getDummyData(Class prefController, int sliceType) {
-        return getDummyData(prefController, SUMMARY, sliceType, SCREEN_TITLE, ICON);
+        return getDummyData(prefController, SUMMARY, sliceType, SCREEN_TITLE, ICON,
+                IS_DYNAMIC_SUMMARY_ALLOWED);
     }
 
     private SliceData getDummyData(Class prefController, String summary, int sliceType,
-            String screenTitle, int icon) {
+            String screenTitle, int icon, boolean isDynamicSummaryAllowed) {
         return new SliceData.Builder()
                 .setKey(KEY)
                 .setTitle(TITLE)
@@ -500,6 +520,7 @@
                 .setUri(URI)
                 .setPreferenceControllerClassName(prefController.getName())
                 .setSliceType(sliceType)
+                .setDynamicSummaryAllowed(isDynamicSummaryAllowed)
                 .build();
     }
 }
diff --git a/tests/robotests/src/com/android/settings/slices/SliceDataConverterTest.java b/tests/robotests/src/com/android/settings/slices/SliceDataConverterTest.java
index a7df5a7..83c35ba 100644
--- a/tests/robotests/src/com/android/settings/slices/SliceDataConverterTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SliceDataConverterTest.java
@@ -124,6 +124,7 @@
         assertThat(fakeSlice.getPreferenceController()).isEqualTo(FAKE_CONTROLLER_NAME);
         assertThat(fakeSlice.getSliceType()).isEqualTo(SliceData.SliceType.SLIDER);
         assertThat(fakeSlice.isPlatformDefined()).isTrue(); // from XML
+        assertThat(fakeSlice.isDynamicSummaryAllowed()).isTrue(); // from XML
     }
 
     private void assertFakeA11ySlice(SliceData fakeSlice) {
diff --git a/tests/robotests/src/com/android/settings/slices/SliceDataTest.java b/tests/robotests/src/com/android/settings/slices/SliceDataTest.java
index 0d91968..9adee07 100644
--- a/tests/robotests/src/com/android/settings/slices/SliceDataTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SliceDataTest.java
@@ -39,6 +39,7 @@
     private final String PREF_CONTROLLER = "com.android.settings.slices.tester";
     private final int SLICE_TYPE = SliceData.SliceType.SWITCH;
     private final boolean IS_PLATFORM_DEFINED = true;
+    private final boolean IS_DYNAMIC_SUMMARY_ALLOWED = true;
 
     @Test
     public void testBuilder_buildsMatchingObject() {
@@ -53,7 +54,8 @@
                 .setUri(URI)
                 .setPreferenceControllerClassName(PREF_CONTROLLER)
                 .setSliceType(SLICE_TYPE)
-                .setPlatformDefined(IS_PLATFORM_DEFINED);
+                .setPlatformDefined(IS_PLATFORM_DEFINED)
+                .setDynamicSummaryAllowed(IS_DYNAMIC_SUMMARY_ALLOWED);
 
         SliceData data = builder.build();
 
@@ -68,6 +70,7 @@
         assertThat(data.getPreferenceController()).isEqualTo(PREF_CONTROLLER);
         assertThat(data.getSliceType()).isEqualTo(SLICE_TYPE);
         assertThat(data.isPlatformDefined()).isEqualTo(IS_PLATFORM_DEFINED);
+        assertThat(data.isDynamicSummaryAllowed()).isEqualTo(IS_DYNAMIC_SUMMARY_ALLOWED);
     }
 
     @Test(expected = SliceData.InvalidSliceDataException.class)
@@ -216,7 +219,7 @@
     }
 
     @Test
-    public void testEquality_identicalObjects() {
+    public void testBuilder_noDynamicSummaryAllowed_buildsMatchingObject() {
         SliceData.Builder builder = new SliceData.Builder()
                 .setKey(KEY)
                 .setTitle(TITLE)
@@ -227,6 +230,32 @@
                 .setUri(URI)
                 .setPreferenceControllerClassName(PREF_CONTROLLER);
 
+        SliceData data = builder.build();
+
+        assertThat(data.getKey()).isEqualTo(KEY);
+        assertThat(data.getTitle()).isEqualTo(TITLE);
+        assertThat(data.getSummary()).isEqualTo(SUMMARY);
+        assertThat(data.getScreenTitle()).isEqualTo(SCREEN_TITLE);
+        assertThat(data.getIconResource()).isEqualTo(ICON);
+        assertThat(data.getFragmentClassName()).isEqualTo(FRAGMENT_NAME);
+        assertThat(data.getUri()).isEqualTo(URI);
+        assertThat(data.getPreferenceController()).isEqualTo(PREF_CONTROLLER);
+        assertThat(data.isDynamicSummaryAllowed()).isFalse();
+    }
+
+    @Test
+    public void testEquality_identicalObjects() {
+        SliceData.Builder builder = new SliceData.Builder()
+                .setKey(KEY)
+                .setTitle(TITLE)
+                .setSummary(SUMMARY)
+                .setScreenTitle(SCREEN_TITLE)
+                .setIcon(ICON)
+                .setFragmentName(FRAGMENT_NAME)
+                .setUri(URI)
+                .setPreferenceControllerClassName(PREF_CONTROLLER)
+                .setDynamicSummaryAllowed(IS_DYNAMIC_SUMMARY_ALLOWED);
+
         SliceData dataOne = builder.build();
         SliceData dataTwo = builder.build();
 
diff --git a/tests/robotests/src/com/android/settings/slices/SlicesDatabaseAccessorTest.java b/tests/robotests/src/com/android/settings/slices/SlicesDatabaseAccessorTest.java
index bea5e89..949d151 100644
--- a/tests/robotests/src/com/android/settings/slices/SlicesDatabaseAccessorTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SlicesDatabaseAccessorTest.java
@@ -97,6 +97,45 @@
         assertThat(data.getFragmentClassName()).isEqualTo(FAKE_FRAGMENT_NAME);
         assertThat(data.getUri()).isNull();
         assertThat(data.getPreferenceController()).isEqualTo(FAKE_CONTROLLER_NAME);
+        assertThat(data.isDynamicSummaryAllowed()).isFalse(); /* default value */
+    }
+
+    @Test
+    public void testGetSliceDataFromKey_allowDynamicSummary_validSliceReturned() {
+        String key = "key";
+        insertSpecialCase(key, true /* isPlatformSlice */, true /* isDynamicSummaryAllowed */);
+
+        SliceData data = mAccessor.getSliceDataFromKey(key);
+
+        assertThat(data.getKey()).isEqualTo(key);
+        assertThat(data.getTitle()).isEqualTo(FAKE_TITLE);
+        assertThat(data.getSummary()).isEqualTo(FAKE_SUMMARY);
+        assertThat(data.getScreenTitle()).isEqualTo(FAKE_SCREEN_TITLE);
+        assertThat(data.getKeywords()).isEqualTo(FAKE_KEYWORDS);
+        assertThat(data.getIconResource()).isEqualTo(FAKE_ICON);
+        assertThat(data.getFragmentClassName()).isEqualTo(FAKE_FRAGMENT_NAME);
+        assertThat(data.getUri()).isNull();
+        assertThat(data.getPreferenceController()).isEqualTo(FAKE_CONTROLLER_NAME);
+        assertThat(data.isDynamicSummaryAllowed()).isTrue();
+    }
+
+    @Test
+    public void testGetSliceDataFromKey_doNotAllowDynamicSummary_validSliceReturned() {
+        String key = "key";
+        insertSpecialCase(key, true /* isPlatformSlice */, false /* isDynamicSummaryAllowed */);
+
+        SliceData data = mAccessor.getSliceDataFromKey(key);
+
+        assertThat(data.getKey()).isEqualTo(key);
+        assertThat(data.getTitle()).isEqualTo(FAKE_TITLE);
+        assertThat(data.getSummary()).isEqualTo(FAKE_SUMMARY);
+        assertThat(data.getScreenTitle()).isEqualTo(FAKE_SCREEN_TITLE);
+        assertThat(data.getKeywords()).isEqualTo(FAKE_KEYWORDS);
+        assertThat(data.getIconResource()).isEqualTo(FAKE_ICON);
+        assertThat(data.getFragmentClassName()).isEqualTo(FAKE_FRAGMENT_NAME);
+        assertThat(data.getUri()).isNull();
+        assertThat(data.getPreferenceController()).isEqualTo(FAKE_CONTROLLER_NAME);
+        assertThat(data.isDynamicSummaryAllowed()).isFalse();
     }
 
     @Test(expected = IllegalStateException.class)
@@ -198,6 +237,11 @@
     }
 
     private void insertSpecialCase(String key, boolean isPlatformSlice) {
+        insertSpecialCase(key, isPlatformSlice, false /* isDynamicSummaryAllowed */);
+    }
+
+    private void insertSpecialCase(String key, boolean isPlatformSlice,
+            boolean isDynamicSummaryAllowed) {
         ContentValues values = new ContentValues();
         values.put(SlicesDatabaseHelper.IndexColumns.KEY, key);
         values.put(SlicesDatabaseHelper.IndexColumns.TITLE, FAKE_TITLE);
@@ -208,6 +252,8 @@
         values.put(SlicesDatabaseHelper.IndexColumns.FRAGMENT, FAKE_FRAGMENT_NAME);
         values.put(SlicesDatabaseHelper.IndexColumns.CONTROLLER, FAKE_CONTROLLER_NAME);
         values.put(SlicesDatabaseHelper.IndexColumns.PLATFORM_SLICE, isPlatformSlice);
+        values.put(SlicesDatabaseHelper.IndexColumns.ALLOW_DYNAMIC_SUMMARY_IN_SLICE,
+                isDynamicSummaryAllowed);
         values.put(SlicesDatabaseHelper.IndexColumns.SLICE_TYPE, SliceData.SliceType.INTENT);
 
         mDb.replaceOrThrow(SlicesDatabaseHelper.Tables.TABLE_SLICES_INDEX, null, values);
diff --git a/tests/robotests/src/com/android/settings/slices/SlicesDatabaseHelperTest.java b/tests/robotests/src/com/android/settings/slices/SlicesDatabaseHelperTest.java
index 602a7fd..a00d343 100644
--- a/tests/robotests/src/com/android/settings/slices/SlicesDatabaseHelperTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SlicesDatabaseHelperTest.java
@@ -73,6 +73,7 @@
                 IndexColumns.CONTROLLER,
                 IndexColumns.PLATFORM_SLICE,
                 IndexColumns.SLICE_TYPE,
+                IndexColumns.ALLOW_DYNAMIC_SUMMARY_IN_SLICE,
         };
 
         assertThat(columnNames).isEqualTo(expectedNames);
diff --git a/tests/robotests/src/com/android/settings/slices/SlicesIndexerTest.java b/tests/robotests/src/com/android/settings/slices/SlicesIndexerTest.java
index b823105..c92ee91 100644
--- a/tests/robotests/src/com/android/settings/slices/SlicesIndexerTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SlicesIndexerTest.java
@@ -53,6 +53,7 @@
     private final Uri URI = Uri.parse("content://com.android.settings.slices/test");
     private final String PREF_CONTROLLER = "com.android.settings.slices.tester";
     private final boolean PLATFORM_DEFINED = true;
+    private final boolean IS_DYNAMIC_SUMMARY_ALLOWED = true;
     private final int SLICE_TYPE = SliceData.SliceType.SLIDER;
 
     private Context mContext;
@@ -131,6 +132,9 @@
                     1 /* true */);
             assertThat(cursor.getInt(cursor.getColumnIndex(IndexColumns.SLICE_TYPE))).isEqualTo(
                     SLICE_TYPE);
+            assertThat(cursor.getInt(
+                    cursor.getColumnIndex(IndexColumns.ALLOW_DYNAMIC_SUMMARY_IN_SLICE))).isEqualTo(
+                    1 /* true */);
             cursor.moveToNext();
         }
     }
@@ -154,7 +158,8 @@
                 .setUri(URI)
                 .setPreferenceControllerClassName(PREF_CONTROLLER)
                 .setPlatformDefined(PLATFORM_DEFINED)
-                .setSliceType(SLICE_TYPE);
+                .setSliceType(SLICE_TYPE)
+                .setDynamicSummaryAllowed(IS_DYNAMIC_SUMMARY_ALLOWED);
 
         for (int i = 0; i < KEYS.length; i++) {
             builder.setKey(KEYS[i]).setTitle(TITLES[i]);