From baeca6fb534a66e5e0878eb0e7a1569cbdb7cba1 Mon Sep 17 00:00:00 2001 From: Peter Zhang Date: Mon, 8 May 2023 16:59:01 +0200 Subject: [PATCH] Add the support of preference group / category to the Settings Tile API Test: robotest, manual Bug: 281517110 Change-Id: Ie36b0b3eb8ed80766efa050f1f0aee1f784a5949 --- .../settings/dashboard/DashboardFragment.java | 41 +++++++++---- .../dashboard/DashboardFragmentTest.java | 57 +++++++++++++++++++ 2 files changed, 86 insertions(+), 12 deletions(-) diff --git a/src/com/android/settings/dashboard/DashboardFragment.java b/src/com/android/settings/dashboard/DashboardFragment.java index f928d863858..dc4d5992b86 100644 --- a/src/com/android/settings/dashboard/DashboardFragment.java +++ b/src/com/android/settings/dashboard/DashboardFragment.java @@ -31,6 +31,7 @@ import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.lifecycle.LifecycleObserver; import androidx.preference.Preference; +import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceGroup; import androidx.preference.PreferenceManager; import androidx.preference.PreferenceScreen; @@ -46,7 +47,6 @@ import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.PrimarySwitchPreference; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.lifecycle.Lifecycle; -import com.android.settingslib.drawer.ActivityTile; import com.android.settingslib.drawer.DashboardCategory; import com.android.settingslib.drawer.Tile; import com.android.settingslib.search.Indexable; @@ -55,6 +55,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.Objects; @@ -504,6 +505,10 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment // Install dashboard tiles and collect pending observers. final boolean forceRoundedIcons = shouldForceRoundedIcon(); final List pendingObservers = new ArrayList<>(); + + // Move group tiles to the beginning of the list to ensure they are created before the + // other tiles. + tiles.sort(Comparator.comparingInt(tile -> tile.getType() == Tile.Type.GROUP ? 0 : 1)); for (Tile tile : tiles) { final String key = mDashboardFeatureProvider.getDashboardKeyForTile(tile); if (TextUtils.isEmpty(key)) { @@ -526,7 +531,14 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment observers = mDashboardFeatureProvider.bindPreferenceToTileAndGetObservers( getActivity(), this, forceRoundedIcons, pref, tile, key, mPlaceholderPreferenceController.getOrder()); - screen.addPreference(pref); + if (tile.hasGroupKey() && mDashboardTilePrefKeys.containsKey(tile.getGroupKey())) { + final Preference group = screen.findPreference(tile.getGroupKey()); + if (group instanceof PreferenceCategory) { + ((PreferenceCategory) group).addPreference(pref); + } + } else { + screen.addPreference(pref); + } registerDynamicDataObservers(observers); mDashboardTilePrefKeys.put(key, observers); } @@ -569,16 +581,21 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment } protected Preference createPreference(Tile tile) { - if (tile.hasSwitch()) { - return (tile instanceof ActivityTile || tile.hasPendingIntent()) - ? new PrimarySwitchPreference(getPrefContext()) - : new SwitchPreference(getPrefContext()); - } else if (tile.hasPendingIntent()) { - Preference preference = new Preference(getPrefContext()); - preference.setWidgetLayoutResource(R.layout.preference_external_action_icon); - return preference; - } else { - return new Preference(getPrefContext()); + switch (tile.getType()) { + case EXTERNAL_ACTION: + Preference externalActionPreference = new Preference(getPrefContext()); + externalActionPreference + .setWidgetLayoutResource(R.layout.preference_external_action_icon); + return externalActionPreference; + case SWITCH: + return new SwitchPreference(getPrefContext()); + case SWITCH_WITH_ACTION: + return new PrimarySwitchPreference(getPrefContext()); + case GROUP: + return new PreferenceCategory((getPrefContext())); + case ACTION: + default: + return new Preference(getPrefContext()); } } diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java index ae1997b380b..febc865136c 100644 --- a/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java +++ b/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java @@ -16,7 +16,9 @@ package com.android.settings.dashboard; import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.DASHBOARD_CONTAINER; +import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_GROUP_KEY; import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_KEYHINT; +import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_PENDING_INTENT; import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SWITCH_URI; import static com.google.common.truth.Truth.assertThat; @@ -43,6 +45,7 @@ import android.os.UserHandle; import android.preference.PreferenceManager.OnActivityResultListener; import androidx.preference.Preference; +import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceFragmentCompat; import androidx.preference.PreferenceManager; import androidx.preference.PreferenceScreen; @@ -60,6 +63,7 @@ import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin; import com.android.settingslib.drawer.ActivityTile; import com.android.settingslib.drawer.DashboardCategory; import com.android.settingslib.drawer.ProviderTile; +import com.android.settingslib.drawer.Tile; import org.junit.Before; import org.junit.Ignore; @@ -180,6 +184,43 @@ public class DashboardFragmentTest { verify(mTestFragment.mScreen, times(2)).addPreference(nullable(Preference.class)); } + @Test + public void displayTilesAsPreference_withGroup_shouldAddTilesIntoGroup() { + final ProviderInfo providerInfo = new ProviderInfo(); + providerInfo.packageName = "pkg"; + providerInfo.name = "provider"; + providerInfo.authority = "authority"; + final Bundle groupTileMetaData = new Bundle(); + groupTileMetaData.putString(META_DATA_PREFERENCE_KEYHINT, "injected_tile_group_key"); + ProviderTile groupTile = new ProviderTile(providerInfo, mDashboardCategory.key, + groupTileMetaData); + mDashboardCategory.addTile(groupTile); + + final Bundle subTileMetaData = new Bundle(); + subTileMetaData.putString(META_DATA_PREFERENCE_KEYHINT, "injected_tile_key3"); + subTileMetaData.putString(META_DATA_PREFERENCE_GROUP_KEY, "injected_tile_group_key"); + subTileMetaData.putParcelable( + META_DATA_PREFERENCE_PENDING_INTENT, + PendingIntent.getActivity(mContext, 0, new Intent(), 0)); + ProviderTile subTile = new ProviderTile(providerInfo, mDashboardCategory.key, + subTileMetaData); + mDashboardCategory.addTile(subTile); + + PreferenceCategory groupPreference = mock(PreferenceCategory.class); + when(mFakeFeatureFactory.dashboardFeatureProvider + .getTilesForCategory(nullable(String.class))) + .thenReturn(mDashboardCategory); + when(mFakeFeatureFactory.dashboardFeatureProvider + .getDashboardKeyForTile(any(Tile.class))) + .then(invocation -> ((Tile) invocation.getArgument(0)).getKey(mContext)); + when(mTestFragment.mScreen.findPreference("injected_tile_group_key")) + .thenReturn(groupPreference); + mTestFragment.onCreatePreferences(new Bundle(), "rootKey"); + + verify(mTestFragment.mScreen, times(3)).addPreference(nullable(Preference.class)); + verify(groupPreference).addPreference(nullable(Preference.class)); + } + @Test public void displayTilesAsPreference_shouldNotAddTilesWithoutIntent() { mTestFragment.onCreatePreferences(new Bundle(), "rootKey"); @@ -405,6 +446,22 @@ public class DashboardFragmentTest { assertThat(pref).isInstanceOf(PrimarySwitchPreference.class); } + @Test + public void createPreference_isGroupTile_returnPreferenceCategory() { + final ProviderInfo providerInfo = new ProviderInfo(); + providerInfo.packageName = "pkg"; + providerInfo.name = "provider"; + providerInfo.authority = "authority"; + final Bundle metaData = new Bundle(); + metaData.putString(META_DATA_PREFERENCE_KEYHINT, "injected_tile_key2"); + ProviderTile providerTile = + new ProviderTile(providerInfo, mDashboardCategory.key, metaData); + + final Preference pref = mTestFragment.createPreference(providerTile); + + assertThat(pref).isInstanceOf(PreferenceCategory.class); + } + @Test public void onActivityResult_test() { final int requestCode = 10;