From 227548d9271f4fe3588ebfaeae435bf297e771b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=ADas=20Hern=C3=A1ndez?= Date: Mon, 26 Aug 2024 15:42:58 +0200 Subject: [PATCH] Make ZenIconLoader injectable (in SystemUI) In settings, reduce calls to getInstance(), and pass it to preferences and their controllers instead. Bug: 360399800 Test: atest ZenModesListItemPreferenceTest ZenModesListPreferenceControllerTest Flag: android.app.modes_ui Change-Id: I318320575e3bd32b5d13a385fa644f8032484e1c --- .../AbstractZenModeHeaderController.java | 5 +++- .../ZenModeEditNameIconFragmentBase.java | 4 +++- .../notification/modes/ZenModeFragment.java | 4 +++- .../modes/ZenModeHeaderController.java | 9 ++++--- ...odeIconPickerIconPreferenceController.java | 6 +++-- .../modes/ZenModesListFragment.java | 3 ++- .../modes/ZenModesListItemPreference.java | 19 ++++++++++++--- .../ZenModesListPreferenceController.java | 10 +++++--- .../modes/ZenModesListItemPreferenceTest.java | 24 +++++++++---------- .../ZenModesListPreferenceControllerTest.java | 5 +++- 10 files changed, 59 insertions(+), 30 deletions(-) diff --git a/src/com/android/settings/notification/modes/AbstractZenModeHeaderController.java b/src/com/android/settings/notification/modes/AbstractZenModeHeaderController.java index af6423185e8..1d1b07d85a6 100644 --- a/src/com/android/settings/notification/modes/AbstractZenModeHeaderController.java +++ b/src/com/android/settings/notification/modes/AbstractZenModeHeaderController.java @@ -43,15 +43,18 @@ import java.util.function.Function; abstract class AbstractZenModeHeaderController extends AbstractZenModePreferenceController { private final DashboardFragment mFragment; + private final ZenIconLoader mIconLoader; private EntityHeaderController mHeaderController; @Nullable private ZenIcon.Key mCurrentIconKey; AbstractZenModeHeaderController( @NonNull Context context, + @NonNull ZenIconLoader iconLoader, @NonNull String key, @NonNull DashboardFragment fragment) { super(context, key); mFragment = fragment; + mIconLoader = iconLoader; } @Override @@ -90,7 +93,7 @@ abstract class AbstractZenModeHeaderController extends AbstractZenModePreference if (!Objects.equal(mCurrentIconKey, zenMode.getIconKey())) { mCurrentIconKey = zenMode.getIconKey(); FutureUtil.whenDone( - ZenIconLoader.getInstance().getIcon(mContext, zenMode), + mIconLoader.getIcon(mContext, zenMode), icon -> { checkNotNull(mHeaderController) .setIcon(iconStylist.apply(icon.drawable())) diff --git a/src/com/android/settings/notification/modes/ZenModeEditNameIconFragmentBase.java b/src/com/android/settings/notification/modes/ZenModeEditNameIconFragmentBase.java index 96cbf91b0d3..6dd90769645 100644 --- a/src/com/android/settings/notification/modes/ZenModeEditNameIconFragmentBase.java +++ b/src/com/android/settings/notification/modes/ZenModeEditNameIconFragmentBase.java @@ -30,6 +30,7 @@ import androidx.annotation.VisibleForTesting; import com.android.settings.R; import com.android.settings.dashboard.DashboardFragment; import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.notification.modes.ZenIconLoader; import com.android.settingslib.notification.modes.ZenMode; import com.android.settingslib.notification.modes.ZenModesBackend; @@ -102,7 +103,8 @@ public abstract class ZenModeEditNameIconFragmentBase extends DashboardFragment protected final List createPreferenceControllers( Context context) { return ImmutableList.of( - new ZenModeIconPickerIconPreferenceController(context, "chosen_icon", this), + new ZenModeIconPickerIconPreferenceController(context, ZenIconLoader.getInstance(), + "chosen_icon", this), new ZenModeEditNamePreferenceController(context, "name", this::setModeName), new ZenModeIconPickerListPreferenceController(context, "icon_list", this::setModeIcon), diff --git a/src/com/android/settings/notification/modes/ZenModeFragment.java b/src/com/android/settings/notification/modes/ZenModeFragment.java index 6889cac2e60..8eef7083995 100644 --- a/src/com/android/settings/notification/modes/ZenModeFragment.java +++ b/src/com/android/settings/notification/modes/ZenModeFragment.java @@ -32,6 +32,7 @@ import androidx.core.view.MenuProvider; import com.android.settings.R; import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.notification.modes.ZenIconLoader; import com.android.settingslib.notification.modes.ZenMode; import java.util.ArrayList; @@ -54,7 +55,8 @@ public class ZenModeFragment extends ZenModeFragmentBase { @Override protected List createPreferenceControllers(Context context) { List prefControllers = new ArrayList<>(); - prefControllers.add(new ZenModeHeaderController(context, "header", this)); + prefControllers.add( + new ZenModeHeaderController(context, ZenIconLoader.getInstance(), "header", this)); prefControllers.add(new ZenModeBlurbPreferenceController(context, "mode_blurb")); prefControllers.add( new ZenModeButtonPreferenceController(context, "activate", this, mBackend)); diff --git a/src/com/android/settings/notification/modes/ZenModeHeaderController.java b/src/com/android/settings/notification/modes/ZenModeHeaderController.java index ae6eacc52da..e901b9fb1a9 100644 --- a/src/com/android/settings/notification/modes/ZenModeHeaderController.java +++ b/src/com/android/settings/notification/modes/ZenModeHeaderController.java @@ -23,15 +23,14 @@ import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settings.dashboard.DashboardFragment; +import com.android.settingslib.notification.modes.ZenIconLoader; import com.android.settingslib.notification.modes.ZenMode; class ZenModeHeaderController extends AbstractZenModeHeaderController { - ZenModeHeaderController( - @NonNull Context context, - @NonNull String key, - @NonNull DashboardFragment fragment) { - super(context, key, fragment); + ZenModeHeaderController(@NonNull Context context, @NonNull ZenIconLoader iconLoader, + @NonNull String key, @NonNull DashboardFragment fragment) { + super(context, iconLoader, key, fragment); } @Override diff --git a/src/com/android/settings/notification/modes/ZenModeIconPickerIconPreferenceController.java b/src/com/android/settings/notification/modes/ZenModeIconPickerIconPreferenceController.java index 6c8d41f591a..dc0be100ae3 100644 --- a/src/com/android/settings/notification/modes/ZenModeIconPickerIconPreferenceController.java +++ b/src/com/android/settings/notification/modes/ZenModeIconPickerIconPreferenceController.java @@ -24,14 +24,16 @@ import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settings.dashboard.DashboardFragment; +import com.android.settingslib.notification.modes.ZenIconLoader; import com.android.settingslib.notification.modes.ZenMode; /** Controller used for displaying the currently-chosen icon at the top of the icon picker. */ class ZenModeIconPickerIconPreferenceController extends AbstractZenModeHeaderController { - ZenModeIconPickerIconPreferenceController(@NonNull Context context, @NonNull String key, + ZenModeIconPickerIconPreferenceController(@NonNull Context context, + @NonNull ZenIconLoader iconLoader, @NonNull String key, @NonNull DashboardFragment fragment) { - super(context, key, fragment); + super(context, iconLoader, key, fragment); } @Override diff --git a/src/com/android/settings/notification/modes/ZenModesListFragment.java b/src/com/android/settings/notification/modes/ZenModesListFragment.java index 588b3202bb6..37772b38eed 100644 --- a/src/com/android/settings/notification/modes/ZenModesListFragment.java +++ b/src/com/android/settings/notification/modes/ZenModesListFragment.java @@ -31,6 +31,7 @@ import com.android.settings.notification.modes.ZenModesListAddModePreferenceCont import com.android.settings.notification.modes.ZenModesListAddModePreferenceController.OnAddModeListener; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.notification.modes.ZenIconLoader; import com.android.settingslib.notification.modes.ZenMode; import com.android.settingslib.notification.modes.ZenModesBackend; import com.android.settingslib.search.SearchIndexable; @@ -56,7 +57,7 @@ public class ZenModesListFragment extends ZenModesFragmentBase { private static List buildPreferenceControllers(Context context, ZenModesBackend backend, OnAddModeListener onAddModeListener) { return ImmutableList.of( - new ZenModesListPreferenceController(context, backend), + new ZenModesListPreferenceController(context, backend, ZenIconLoader.getInstance()), new ZenModesListAddModePreferenceController(context, onAddModeListener) ); } diff --git a/src/com/android/settings/notification/modes/ZenModesListItemPreference.java b/src/com/android/settings/notification/modes/ZenModesListItemPreference.java index 0c31d8f0097..0909c6f5f2e 100644 --- a/src/com/android/settings/notification/modes/ZenModesListItemPreference.java +++ b/src/com/android/settings/notification/modes/ZenModesListItemPreference.java @@ -31,6 +31,8 @@ import com.android.settingslib.notification.modes.ZenMode; import com.google.common.base.Strings; +import java.util.concurrent.Executor; + /** * Preference representing a single mode item on the modes aggregator page. Clicking on this * preference leads to an individual mode's configuration page. @@ -38,18 +40,29 @@ import com.google.common.base.Strings; class ZenModesListItemPreference extends RestrictedPreference { private final Context mContext; + private final ZenIconLoader mIconLoader; + private final Executor mUiExecutor; private ZenMode mZenMode; private TextView mTitleView; private TextView mSummaryView; - ZenModesListItemPreference(Context context, ZenMode zenMode) { + ZenModesListItemPreference(Context context, ZenIconLoader iconLoader, ZenMode zenMode) { + this(context, iconLoader, context.getMainExecutor(), zenMode); + } + + @VisibleForTesting + ZenModesListItemPreference(Context context, ZenIconLoader iconLoader, Executor uiExecutor, + ZenMode zenMode) { super(context); mContext = context; + mIconLoader = iconLoader; + mUiExecutor = uiExecutor; setZenMode(zenMode); setKey(zenMode.getId()); } + @Override public void onBindViewHolder(PreferenceViewHolder holder) { super.onBindViewHolder(holder); @@ -93,12 +106,12 @@ class ZenModesListItemPreference extends RestrictedPreference { setIconSize(ICON_SIZE_SMALL); FutureUtil.whenDone( - ZenIconLoader.getInstance().getIcon(mContext, mZenMode), + mIconLoader.getIcon(mContext, mZenMode), icon -> setIcon( zenMode.isActive() ? IconUtil.applyAccentTint(mContext, icon.drawable()) : IconUtil.applyNormalTint(mContext, icon.drawable())), - mContext.getMainExecutor()); + mUiExecutor); updateTextColor(zenMode); } diff --git a/src/com/android/settings/notification/modes/ZenModesListPreferenceController.java b/src/com/android/settings/notification/modes/ZenModesListPreferenceController.java index 12b727862c1..5e36469f39c 100644 --- a/src/com/android/settings/notification/modes/ZenModesListPreferenceController.java +++ b/src/com/android/settings/notification/modes/ZenModesListPreferenceController.java @@ -25,6 +25,7 @@ import androidx.preference.PreferenceCategory; import com.android.settings.R; import com.android.settings.core.BasePreferenceController; +import com.android.settingslib.notification.modes.ZenIconLoader; import com.android.settingslib.notification.modes.ZenMode; import com.android.settingslib.notification.modes.ZenModesBackend; import com.android.settingslib.search.SearchIndexableRaw; @@ -42,11 +43,14 @@ class ZenModesListPreferenceController extends BasePreferenceController implements BasePreferenceController.UiBlocker { protected static final String KEY = "zen_modes_list"; - protected ZenModesBackend mBackend; + private final ZenModesBackend mBackend; + private final ZenIconLoader mIconLoader; - ZenModesListPreferenceController(Context context, @NonNull ZenModesBackend backend) { + ZenModesListPreferenceController(Context context, @NonNull ZenModesBackend backend, @NonNull + ZenIconLoader iconLoader) { super(context, KEY); mBackend = backend; + mIconLoader = iconLoader; } @Override @@ -82,7 +86,7 @@ class ZenModesListPreferenceController extends BasePreferenceController modePreference.setZenMode(mode); } else { // new rule; create a new ZenRulePreference & add it to the preference category - modePreference = new ZenModesListItemPreference(mContext, mode); + modePreference = new ZenModesListItemPreference(mContext, mIconLoader, mode); category.addPreference(modePreference); } modePreference.setOrder(modes.indexOf(mode)); diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModesListItemPreferenceTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModesListItemPreferenceTest.java index f5d5160c84b..3722e416061 100644 --- a/tests/robotests/src/com/android/settings/notification/modes/ZenModesListItemPreferenceTest.java +++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModesListItemPreferenceTest.java @@ -36,7 +36,6 @@ import org.junit.runner.RunWith; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; -import org.robolectric.shadows.ShadowLooper; @RunWith(RobolectricTestRunner.class) @EnableFlags(Flags.FLAG_MODES_UI) @@ -45,18 +44,18 @@ public class ZenModesListItemPreferenceTest { public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); private Context mContext; + private final ZenIconLoader mIconLoader = new ZenIconLoader( + MoreExecutors.newDirectExecutorService()); @Before public void setup() { MockitoAnnotations.initMocks(this); mContext = RuntimeEnvironment.application; - ZenIconLoader.setInstance(new ZenIconLoader(MoreExecutors.newDirectExecutorService())); } @Test public void constructor_setsMode() { - ZenModesListItemPreference preference = new ZenModesListItemPreference(mContext, - TestModeBuilder.EXAMPLE); + ZenModesListItemPreference preference = newPreference(TestModeBuilder.EXAMPLE); assertThat(preference.getKey()).isEqualTo(TestModeBuilder.EXAMPLE.getId()); assertThat(preference.getZenMode()).isEqualTo(TestModeBuilder.EXAMPLE); @@ -70,8 +69,7 @@ public class ZenModesListItemPreferenceTest { .setEnabled(true) .build(); - ZenModesListItemPreference preference = new ZenModesListItemPreference(mContext, mode); - ShadowLooper.idleMainLooper(); // To load icon. + ZenModesListItemPreference preference = newPreference(mode); assertThat(preference.getTitle()).isEqualTo("Enabled mode"); assertThat(preference.getSummary()).isEqualTo("When the thrush knocks"); @@ -87,8 +85,7 @@ public class ZenModesListItemPreferenceTest { .setActive(true) .build(); - ZenModesListItemPreference preference = new ZenModesListItemPreference(mContext, mode); - ShadowLooper.idleMainLooper(); + ZenModesListItemPreference preference = newPreference(mode); assertThat(preference.getTitle()).isEqualTo("Active mode"); assertThat(preference.getSummary()).isEqualTo("ON • When Birnam forest comes to Dunsinane"); @@ -103,8 +100,7 @@ public class ZenModesListItemPreferenceTest { .setEnabled(false, /* byUser= */ false) .build(); - ZenModesListItemPreference preference = new ZenModesListItemPreference(mContext, mode); - ShadowLooper.idleMainLooper(); + ZenModesListItemPreference preference = newPreference(mode); assertThat(preference.getTitle()).isEqualTo("Mode disabled by app"); assertThat(preference.getSummary()).isEqualTo("Not set"); @@ -119,11 +115,15 @@ public class ZenModesListItemPreferenceTest { .setEnabled(false, /* byUser= */ true) .build(); - ZenModesListItemPreference preference = new ZenModesListItemPreference(mContext, mode); - ShadowLooper.idleMainLooper(); + ZenModesListItemPreference preference = newPreference(mode); assertThat(preference.getTitle()).isEqualTo("Mode disabled by user"); assertThat(preference.getSummary()).isEqualTo("Disabled"); assertThat(preference.getIcon()).isNotNull(); } + + private ZenModesListItemPreference newPreference(ZenMode zenMode) { + return new ZenModesListItemPreference(mContext, mIconLoader, MoreExecutors.directExecutor(), + zenMode); + } } diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModesListPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModesListPreferenceControllerTest.java index 4fa8b8ac6c4..69568ce1434 100644 --- a/tests/robotests/src/com/android/settings/notification/modes/ZenModesListPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModesListPreferenceControllerTest.java @@ -40,11 +40,13 @@ import androidx.preference.PreferenceManager; import androidx.preference.PreferenceScreen; import com.android.settingslib.notification.modes.TestModeBuilder; +import com.android.settingslib.notification.modes.ZenIconLoader; import com.android.settingslib.notification.modes.ZenMode; import com.android.settingslib.notification.modes.ZenModesBackend; import com.android.settingslib.search.SearchIndexableRaw; import com.google.common.collect.ImmutableList; +import com.google.common.util.concurrent.MoreExecutors; import org.junit.Before; import org.junit.Rule; @@ -95,7 +97,8 @@ public class ZenModesListPreferenceControllerTest { PreferenceScreen preferenceScreen = preferenceManager.createPreferenceScreen(mContext); preferenceScreen.addPreference(mPreference); - mPrefController = new ZenModesListPreferenceController(mContext, mBackend); + mPrefController = new ZenModesListPreferenceController(mContext, mBackend, + new ZenIconLoader(MoreExecutors.newDirectExecutorService())); } @Test