Loading src/com/android/settings/slices/SliceBroadcastReceiver.java +4 −4 Original line number Diff line number Diff line Loading @@ -71,7 +71,7 @@ public class SliceBroadcastReceiver extends BroadcastReceiver { throw new IllegalStateException("No key passed to Intent for toggle controller"); } BasePreferenceController controller = getBasePreferenceController(context, key); final BasePreferenceController controller = getPreferenceController(context, key); if (!(controller instanceof TogglePreferenceController)) { throw new IllegalStateException("Toggle action passed for a non-toggle key: " + key); Loading @@ -79,12 +79,12 @@ public class SliceBroadcastReceiver extends BroadcastReceiver { // TODO post context.getContentResolver().notifyChanged(uri, null) in the Toggle controller // so that it's automatically broadcast to any slice. TogglePreferenceController toggleController = (TogglePreferenceController) controller; boolean currentValue = toggleController.isChecked(); final TogglePreferenceController toggleController = (TogglePreferenceController) controller; final boolean currentValue = toggleController.isChecked(); toggleController.setChecked(!currentValue); } private BasePreferenceController getBasePreferenceController(Context context, String key) { private BasePreferenceController getPreferenceController(Context context, String key) { final SlicesDatabaseAccessor accessor = new SlicesDatabaseAccessor(context); final SliceData sliceData = accessor.getSliceDataFromKey(key); return SliceBuilderUtils.getPreferenceController(context, sliceData); Loading src/com/android/settings/slices/SliceBuilderUtils.java +39 −9 Original line number Diff line number Diff line Loading @@ -24,10 +24,13 @@ import android.content.Intent; import android.graphics.drawable.Icon; import android.text.TextUtils; import com.android.internal.annotations.VisibleForTesting; import com.android.settings.R; import com.android.settings.SubSettings; import com.android.settings.core.BasePreferenceController; import com.android.settings.core.TogglePreferenceController; import com.android.settings.search.DatabaseIndexingUtils; import com.android.settingslib.core.AbstractPreferenceController; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; Loading @@ -54,21 +57,17 @@ public class SliceBuilderUtils { public static Slice buildSlice(Context context, SliceData sliceData) { final PendingIntent contentIntent = getContentIntent(context, sliceData); final Icon icon = Icon.createWithResource(context, sliceData.getIconResource()); String summaryText = sliceData.getSummary(); String subtitleText = TextUtils.isEmpty(summaryText) ? sliceData.getScreenTitle() : summaryText; final BasePreferenceController controller = getPreferenceController(context, sliceData); final String subtitleText = getSubtitleText(context, controller, sliceData); RowBuilder builder = new RowBuilder(context, sliceData.getUri()) final RowBuilder builder = new RowBuilder(context, sliceData.getUri()) .setTitle(sliceData.getTitle()) .setTitleItem(icon) .setSubtitle(subtitleText) .setContentIntent(contentIntent); BasePreferenceController controller = getPreferenceController(context, sliceData); // TODO (b/71640747) Respect setting availability. // TODO (b/71640678) Add dynamic summary text. if (controller instanceof TogglePreferenceController) { addToggleAction(context, builder, ((TogglePreferenceController) controller).isChecked(), Loading @@ -82,7 +81,7 @@ public class SliceBuilderUtils { /** * Looks at the {@link SliceData#preferenceController} from {@param sliceData} and attempts to * build a {@link BasePreferenceController}. * build an {@link AbstractPreferenceController}. */ public static BasePreferenceController getPreferenceController(Context context, SliceData sliceData) { Loading Loading @@ -122,4 +121,35 @@ public class SliceBuilderUtils { intent.setClassName("com.android.settings", SubSettings.class.getName()); return PendingIntent.getActivity(context, 0 /* requestCode */, intent, 0 /* flags */); } @VisibleForTesting static String getSubtitleText(Context context, AbstractPreferenceController controller, SliceData sliceData) { String summaryText = sliceData.getSummary(); if (isValidSummary(context, summaryText)) { return summaryText; } if (controller != null) { summaryText = controller.getSummary(); if (isValidSummary(context, summaryText)) { return summaryText; } } return sliceData.getScreenTitle(); } private static boolean isValidSummary(Context context, String summary) { if (summary == null || TextUtils.isEmpty(summary.trim())) { return false; } final String placeHolder = context.getString(R.string.summary_placeholder); final String doublePlaceHolder = context.getString(R.string.summary_two_lines_placeholder); return !(TextUtils.equals(summary, placeHolder) || TextUtils.equals(summary, doublePlaceHolder)); } } src/com/android/settings/slices/SliceDataConverter.java +1 −1 Original line number Diff line number Diff line Loading @@ -163,7 +163,7 @@ class SliceDataConverter { // TODO (b/67996923) Non-controller Slices should become intent-only slices. // Note that without a controller, dynamic summaries are impossible. // TODO (b/67996923) This will not work if preferences have nested intens: // TODO (b/67996923) This will not work if preferences have nested intents: // <pref ....> // <intent action="blab"/> </pref> controllerClassName = XmlParserUtils.getController(mContext, attrs); Loading tests/robotests/src/com/android/settings/slices/SlicesDatabaseUtilsTest.java→tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java +65 −4 Original line number Diff line number Diff line Loading @@ -20,9 +20,13 @@ import static com.android.settings.TestConfig.SDK_VERSION; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; import android.content.Context; import android.net.Uri; import com.android.settings.R; import com.android.settings.TestConfig; import com.android.settings.core.BasePreferenceController; import com.android.settings.testutils.SettingsRobolectricTestRunner; Loading @@ -37,7 +41,7 @@ import androidx.app.slice.Slice; @RunWith(SettingsRobolectricTestRunner.class) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = SDK_VERSION) public class SlicesDatabaseUtilsTest { public class SliceBuilderUtilsTest { private final String KEY = "KEY"; private final String TITLE = "title"; Loading Loading @@ -65,17 +69,74 @@ public class SlicesDatabaseUtilsTest { @Test public void testGetPreferenceController_buildsMatchingController() { BasePreferenceController controller = SliceBuilderUtils.getPreferenceController(mContext, getDummyData()); BasePreferenceController controller = SliceBuilderUtils.getPreferenceController( mContext, getDummyData()); assertThat(controller).isInstanceOf(FakeToggleController.class); } @Test public void testDynamicSummary_returnsSliceSummary() { SliceData data = getDummyData(); FakePreferenceController controller = new FakePreferenceController(mContext, KEY); String summary = SliceBuilderUtils.getSubtitleText(mContext, controller, data); assertThat(summary).isEqualTo(data.getSummary()); } @Test public void testDynamicSummary_returnsFragmentSummary() { SliceData data = getDummyData(null); FakePreferenceController controller = spy(new FakePreferenceController(mContext, KEY)); String controllerSummary = "new_Summary"; doReturn(controllerSummary).when(controller).getSummary(); String summary = SliceBuilderUtils.getSubtitleText(mContext, controller, data); assertThat(summary).isEqualTo(controllerSummary); } @Test public void testDynamicSummary_returnsSliceScreenTitle() { SliceData data = getDummyData(null); FakePreferenceController controller = new FakePreferenceController(mContext, KEY); String summary = SliceBuilderUtils.getSubtitleText(mContext, controller, data); assertThat(summary).isEqualTo(data.getScreenTitle()); } @Test public void testDynamicSummary_placeHolderString_returnsScreenTitle() { SliceData data = getDummyData(mContext.getString(R.string.summary_placeholder)); FakePreferenceController controller = new FakePreferenceController(mContext, KEY); String summary = SliceBuilderUtils.getSubtitleText(mContext, controller, data); assertThat(summary).isEqualTo(data.getScreenTitle()); } @Test public void testDynamicSummary_sliceDataAndFragmentPlaceholder_returnsSliceScreenTitle() { String summaryPlaceholder = mContext.getString(R.string.summary_placeholder); SliceData data = getDummyData(summaryPlaceholder); FakePreferenceController controller = spy(new FakePreferenceController(mContext, KEY)); doReturn(summaryPlaceholder).when(controller).getSummary(); String summary = SliceBuilderUtils.getSubtitleText(mContext, controller, data); assertThat(summary).isEqualTo(data.getScreenTitle()); } private SliceData getDummyData() { return getDummyData(SUMMARY); } private SliceData getDummyData(String summary) { return new SliceData.Builder() .setKey(KEY) .setTitle(TITLE) .setSummary(SUMMARY) .setSummary(summary) .setScreenTitle(SCREEN_TITLE) .setIcon(ICON) .setFragmentName(FRAGMENT_NAME) Loading Loading
src/com/android/settings/slices/SliceBroadcastReceiver.java +4 −4 Original line number Diff line number Diff line Loading @@ -71,7 +71,7 @@ public class SliceBroadcastReceiver extends BroadcastReceiver { throw new IllegalStateException("No key passed to Intent for toggle controller"); } BasePreferenceController controller = getBasePreferenceController(context, key); final BasePreferenceController controller = getPreferenceController(context, key); if (!(controller instanceof TogglePreferenceController)) { throw new IllegalStateException("Toggle action passed for a non-toggle key: " + key); Loading @@ -79,12 +79,12 @@ public class SliceBroadcastReceiver extends BroadcastReceiver { // TODO post context.getContentResolver().notifyChanged(uri, null) in the Toggle controller // so that it's automatically broadcast to any slice. TogglePreferenceController toggleController = (TogglePreferenceController) controller; boolean currentValue = toggleController.isChecked(); final TogglePreferenceController toggleController = (TogglePreferenceController) controller; final boolean currentValue = toggleController.isChecked(); toggleController.setChecked(!currentValue); } private BasePreferenceController getBasePreferenceController(Context context, String key) { private BasePreferenceController getPreferenceController(Context context, String key) { final SlicesDatabaseAccessor accessor = new SlicesDatabaseAccessor(context); final SliceData sliceData = accessor.getSliceDataFromKey(key); return SliceBuilderUtils.getPreferenceController(context, sliceData); Loading
src/com/android/settings/slices/SliceBuilderUtils.java +39 −9 Original line number Diff line number Diff line Loading @@ -24,10 +24,13 @@ import android.content.Intent; import android.graphics.drawable.Icon; import android.text.TextUtils; import com.android.internal.annotations.VisibleForTesting; import com.android.settings.R; import com.android.settings.SubSettings; import com.android.settings.core.BasePreferenceController; import com.android.settings.core.TogglePreferenceController; import com.android.settings.search.DatabaseIndexingUtils; import com.android.settingslib.core.AbstractPreferenceController; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; Loading @@ -54,21 +57,17 @@ public class SliceBuilderUtils { public static Slice buildSlice(Context context, SliceData sliceData) { final PendingIntent contentIntent = getContentIntent(context, sliceData); final Icon icon = Icon.createWithResource(context, sliceData.getIconResource()); String summaryText = sliceData.getSummary(); String subtitleText = TextUtils.isEmpty(summaryText) ? sliceData.getScreenTitle() : summaryText; final BasePreferenceController controller = getPreferenceController(context, sliceData); final String subtitleText = getSubtitleText(context, controller, sliceData); RowBuilder builder = new RowBuilder(context, sliceData.getUri()) final RowBuilder builder = new RowBuilder(context, sliceData.getUri()) .setTitle(sliceData.getTitle()) .setTitleItem(icon) .setSubtitle(subtitleText) .setContentIntent(contentIntent); BasePreferenceController controller = getPreferenceController(context, sliceData); // TODO (b/71640747) Respect setting availability. // TODO (b/71640678) Add dynamic summary text. if (controller instanceof TogglePreferenceController) { addToggleAction(context, builder, ((TogglePreferenceController) controller).isChecked(), Loading @@ -82,7 +81,7 @@ public class SliceBuilderUtils { /** * Looks at the {@link SliceData#preferenceController} from {@param sliceData} and attempts to * build a {@link BasePreferenceController}. * build an {@link AbstractPreferenceController}. */ public static BasePreferenceController getPreferenceController(Context context, SliceData sliceData) { Loading Loading @@ -122,4 +121,35 @@ public class SliceBuilderUtils { intent.setClassName("com.android.settings", SubSettings.class.getName()); return PendingIntent.getActivity(context, 0 /* requestCode */, intent, 0 /* flags */); } @VisibleForTesting static String getSubtitleText(Context context, AbstractPreferenceController controller, SliceData sliceData) { String summaryText = sliceData.getSummary(); if (isValidSummary(context, summaryText)) { return summaryText; } if (controller != null) { summaryText = controller.getSummary(); if (isValidSummary(context, summaryText)) { return summaryText; } } return sliceData.getScreenTitle(); } private static boolean isValidSummary(Context context, String summary) { if (summary == null || TextUtils.isEmpty(summary.trim())) { return false; } final String placeHolder = context.getString(R.string.summary_placeholder); final String doublePlaceHolder = context.getString(R.string.summary_two_lines_placeholder); return !(TextUtils.equals(summary, placeHolder) || TextUtils.equals(summary, doublePlaceHolder)); } }
src/com/android/settings/slices/SliceDataConverter.java +1 −1 Original line number Diff line number Diff line Loading @@ -163,7 +163,7 @@ class SliceDataConverter { // TODO (b/67996923) Non-controller Slices should become intent-only slices. // Note that without a controller, dynamic summaries are impossible. // TODO (b/67996923) This will not work if preferences have nested intens: // TODO (b/67996923) This will not work if preferences have nested intents: // <pref ....> // <intent action="blab"/> </pref> controllerClassName = XmlParserUtils.getController(mContext, attrs); Loading
tests/robotests/src/com/android/settings/slices/SlicesDatabaseUtilsTest.java→tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java +65 −4 Original line number Diff line number Diff line Loading @@ -20,9 +20,13 @@ import static com.android.settings.TestConfig.SDK_VERSION; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; import android.content.Context; import android.net.Uri; import com.android.settings.R; import com.android.settings.TestConfig; import com.android.settings.core.BasePreferenceController; import com.android.settings.testutils.SettingsRobolectricTestRunner; Loading @@ -37,7 +41,7 @@ import androidx.app.slice.Slice; @RunWith(SettingsRobolectricTestRunner.class) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = SDK_VERSION) public class SlicesDatabaseUtilsTest { public class SliceBuilderUtilsTest { private final String KEY = "KEY"; private final String TITLE = "title"; Loading Loading @@ -65,17 +69,74 @@ public class SlicesDatabaseUtilsTest { @Test public void testGetPreferenceController_buildsMatchingController() { BasePreferenceController controller = SliceBuilderUtils.getPreferenceController(mContext, getDummyData()); BasePreferenceController controller = SliceBuilderUtils.getPreferenceController( mContext, getDummyData()); assertThat(controller).isInstanceOf(FakeToggleController.class); } @Test public void testDynamicSummary_returnsSliceSummary() { SliceData data = getDummyData(); FakePreferenceController controller = new FakePreferenceController(mContext, KEY); String summary = SliceBuilderUtils.getSubtitleText(mContext, controller, data); assertThat(summary).isEqualTo(data.getSummary()); } @Test public void testDynamicSummary_returnsFragmentSummary() { SliceData data = getDummyData(null); FakePreferenceController controller = spy(new FakePreferenceController(mContext, KEY)); String controllerSummary = "new_Summary"; doReturn(controllerSummary).when(controller).getSummary(); String summary = SliceBuilderUtils.getSubtitleText(mContext, controller, data); assertThat(summary).isEqualTo(controllerSummary); } @Test public void testDynamicSummary_returnsSliceScreenTitle() { SliceData data = getDummyData(null); FakePreferenceController controller = new FakePreferenceController(mContext, KEY); String summary = SliceBuilderUtils.getSubtitleText(mContext, controller, data); assertThat(summary).isEqualTo(data.getScreenTitle()); } @Test public void testDynamicSummary_placeHolderString_returnsScreenTitle() { SliceData data = getDummyData(mContext.getString(R.string.summary_placeholder)); FakePreferenceController controller = new FakePreferenceController(mContext, KEY); String summary = SliceBuilderUtils.getSubtitleText(mContext, controller, data); assertThat(summary).isEqualTo(data.getScreenTitle()); } @Test public void testDynamicSummary_sliceDataAndFragmentPlaceholder_returnsSliceScreenTitle() { String summaryPlaceholder = mContext.getString(R.string.summary_placeholder); SliceData data = getDummyData(summaryPlaceholder); FakePreferenceController controller = spy(new FakePreferenceController(mContext, KEY)); doReturn(summaryPlaceholder).when(controller).getSummary(); String summary = SliceBuilderUtils.getSubtitleText(mContext, controller, data); assertThat(summary).isEqualTo(data.getScreenTitle()); } private SliceData getDummyData() { return getDummyData(SUMMARY); } private SliceData getDummyData(String summary) { return new SliceData.Builder() .setKey(KEY) .setTitle(TITLE) .setSummary(SUMMARY) .setSummary(summary) .setScreenTitle(SCREEN_TITLE) .setIcon(ICON) .setFragmentName(FRAGMENT_NAME) Loading