Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b0e89cd1 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add dynamic summaries to Slices"

parents be090e9f 82254b08
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -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);
@@ -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);
+39 −9
Original line number Diff line number Diff line
@@ -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;
@@ -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(),
@@ -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) {
@@ -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));
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -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);
+65 −4
Original line number Diff line number Diff line
@@ -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;
@@ -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";
@@ -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)