From 37bdf39ad6767569438be4d95a5cc9b90c9e8961 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=ADas=20Hern=C3=A1ndez?= Date: Wed, 12 Jun 2024 19:33:12 +0200 Subject: [PATCH] Follow-up improvements to zen mode icon picker * Propose icons from com.android.internal.R instead of android.R (as a proof of concept) since this is what we'll be doing with the final icons. * Provide the icon options as a parameter to the controller (can also be used for testing). * Fix some Lint warnings. Test: atest ZenModeIconPickerListPreferenceControllerTest Bug: 333901673 Flag: android.app.modes_ui Change-Id: I023eed0fd5719c5c4540f8d145335f60d088e7fb --- .../modes/IconOptionsProvider.java | 28 +++++++++++ .../modes/TempIconOptionsProvider.java | 48 +++++++++++++++++++ .../ZenModeActionsPreferenceController.java | 2 - .../modes/ZenModeIconPickerFragment.java | 3 +- ...odeIconPickerListPreferenceController.java | 43 ++++------------- ...conPickerListPreferenceControllerTest.java | 18 ++++++- 6 files changed, 104 insertions(+), 38 deletions(-) create mode 100644 src/com/android/settings/notification/modes/IconOptionsProvider.java create mode 100644 src/com/android/settings/notification/modes/TempIconOptionsProvider.java diff --git a/src/com/android/settings/notification/modes/IconOptionsProvider.java b/src/com/android/settings/notification/modes/IconOptionsProvider.java new file mode 100644 index 00000000000..288aff258fc --- /dev/null +++ b/src/com/android/settings/notification/modes/IconOptionsProvider.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.notification.modes; + +import androidx.annotation.DrawableRes; + +import com.google.common.collect.ImmutableList; + +interface IconOptionsProvider { + + ImmutableList getIcons(); + + record IconInfo(@DrawableRes int resId, String description) { } +} diff --git a/src/com/android/settings/notification/modes/TempIconOptionsProvider.java b/src/com/android/settings/notification/modes/TempIconOptionsProvider.java new file mode 100644 index 00000000000..06c5c273ffe --- /dev/null +++ b/src/com/android/settings/notification/modes/TempIconOptionsProvider.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.notification.modes; + +import com.google.common.collect.ImmutableList; + +import java.lang.reflect.Modifier; +import java.util.Arrays; +import java.util.Comparator; +import java.util.Objects; + +/** Temporary implementation of {@link IconOptionsProvider} until we have the real list. */ +class TempIconOptionsProvider implements IconOptionsProvider { + @Override + public ImmutableList getIcons() { + return ImmutableList.copyOf( + Arrays.stream(com.android.internal.R.drawable.class.getFields()) + .filter( + f -> Modifier.isStatic(f.getModifiers()) + && Modifier.isFinal(f.getModifiers()) + && f.getName().startsWith("ic_")) + .limit(20) + .map(f -> { + try { + return new IconInfo(f.getInt(null), f.getName()); + } catch (IllegalAccessException e) { + return null; + } + }) + .filter(Objects::nonNull) + .sorted(Comparator.comparing(IconInfo::resId).reversed()) + .toList()); + } +} diff --git a/src/com/android/settings/notification/modes/ZenModeActionsPreferenceController.java b/src/com/android/settings/notification/modes/ZenModeActionsPreferenceController.java index 5695fbcbc47..8585234506f 100644 --- a/src/com/android/settings/notification/modes/ZenModeActionsPreferenceController.java +++ b/src/com/android/settings/notification/modes/ZenModeActionsPreferenceController.java @@ -31,8 +31,6 @@ import com.android.settingslib.widget.ActionButtonsPreference; class ZenModeActionsPreferenceController extends AbstractZenModePreferenceController { - private ActionButtonsPreference mPreference; - ZenModeActionsPreferenceController(@NonNull Context context, @NonNull String key, @Nullable ZenModesBackend backend) { super(context, key, backend); diff --git a/src/com/android/settings/notification/modes/ZenModeIconPickerFragment.java b/src/com/android/settings/notification/modes/ZenModeIconPickerFragment.java index 950849e0056..553d3ebc2e5 100644 --- a/src/com/android/settings/notification/modes/ZenModeIconPickerFragment.java +++ b/src/com/android/settings/notification/modes/ZenModeIconPickerFragment.java @@ -44,6 +44,7 @@ public class ZenModeIconPickerFragment extends ZenModeFragmentBase { new ZenModeIconPickerIconPreferenceController(context, "current_icon", this, mBackend), new ZenModeIconPickerListPreferenceController(context, "icon_list", this, - mBackend)); + // TODO: b/333901673 - Replace with correct icon list. + new TempIconOptionsProvider(), mBackend)); } } diff --git a/src/com/android/settings/notification/modes/ZenModeIconPickerListPreferenceController.java b/src/com/android/settings/notification/modes/ZenModeIconPickerListPreferenceController.java index b07c26f9e18..fc991dcfb19 100644 --- a/src/com/android/settings/notification/modes/ZenModeIconPickerListPreferenceController.java +++ b/src/com/android/settings/notification/modes/ZenModeIconPickerListPreferenceController.java @@ -37,22 +37,18 @@ import com.android.settingslib.widget.LayoutPreference; import com.google.common.collect.ImmutableList; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; -import java.util.Objects; - class ZenModeIconPickerListPreferenceController extends AbstractZenModePreferenceController { private final DashboardFragment mFragment; - private IconAdapter mAdapter; + private final IconOptionsProvider mIconOptionsProvider; + @Nullable private IconAdapter mAdapter; ZenModeIconPickerListPreferenceController(@NonNull Context context, @NonNull String key, - @NonNull DashboardFragment fragment, @Nullable ZenModesBackend backend) { + @NonNull DashboardFragment fragment, @NonNull IconOptionsProvider iconOptionsProvider, + @Nullable ZenModesBackend backend) { super(context, key, backend); mFragment = fragment; + mIconOptionsProvider = iconOptionsProvider; } @Override @@ -64,24 +60,7 @@ class ZenModeIconPickerListPreferenceController extends AbstractZenModePreferenc } if (mAdapter == null) { - // TODO: b/333901673 - This is just an example; replace with correct list. - List exampleIcons = - Arrays.stream(android.R.drawable.class.getFields()) - .filter( - f -> Modifier.isStatic(f.getModifiers()) - && f.getName().startsWith("ic_")) - .sorted(Comparator.comparing(Field::getName)) - .limit(20) - .map(f -> { - try { - return new IconInfo(f.getInt(null), f.getName()); - } catch (IllegalAccessException e) { - return null; - } - }) - .filter(Objects::nonNull) - .toList(); - mAdapter = new IconAdapter(exampleIcons); + mAdapter = new IconAdapter(mIconOptionsProvider); } RecyclerView recyclerView = pref.findViewById(R.id.icon_list); recyclerView.setLayoutManager(new AutoFitGridLayoutManager(mContext)); @@ -103,8 +82,6 @@ class ZenModeIconPickerListPreferenceController extends AbstractZenModePreferenc // Nothing to do, the current icon is shown in a different preference. } - private record IconInfo(@DrawableRes int resId, String description) { } - private class IconHolder extends RecyclerView.ViewHolder { private final ImageView mImageView; @@ -114,7 +91,7 @@ class ZenModeIconPickerListPreferenceController extends AbstractZenModePreferenc mImageView = itemView.findViewById(R.id.icon_image_view); } - void bindIcon(IconInfo icon) { + void bindIcon(IconOptionsProvider.IconInfo icon) { mImageView.setImageDrawable( IconUtil.makeIconCircle(itemView.getContext(), icon.resId())); itemView.setContentDescription(icon.description()); @@ -124,10 +101,10 @@ class ZenModeIconPickerListPreferenceController extends AbstractZenModePreferenc private class IconAdapter extends RecyclerView.Adapter { - private final ImmutableList mIconResources; + private final ImmutableList mIconResources; - private IconAdapter(List iconOptions) { - mIconResources = ImmutableList.copyOf(iconOptions); + private IconAdapter(IconOptionsProvider iconOptionsProvider) { + mIconResources = iconOptionsProvider.getIcons(); } @NonNull diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModeIconPickerListPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModeIconPickerListPreferenceControllerTest.java index c0fbe15a6c2..5f7ffa29ecc 100644 --- a/tests/robotests/src/com/android/settings/notification/modes/ZenModeIconPickerListPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModeIconPickerListPreferenceControllerTest.java @@ -34,6 +34,8 @@ import com.android.settings.R; import com.android.settings.dashboard.DashboardFragment; import com.android.settingslib.widget.LayoutPreference; +import com.google.common.collect.ImmutableList; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -61,7 +63,8 @@ public class ZenModeIconPickerListPreferenceControllerTest { DashboardFragment fragment = mock(DashboardFragment.class); mController = new ZenModeIconPickerListPreferenceController( - RuntimeEnvironment.getApplication(), "icon_list", fragment, mBackend); + RuntimeEnvironment.getApplication(), "icon_list", fragment, + new TestIconOptionsProvider(), mBackend); mRecyclerView = new RecyclerView(context); mRecyclerView.setId(R.id.icon_list); @@ -75,7 +78,7 @@ public class ZenModeIconPickerListPreferenceControllerTest { mController.displayPreference(mPreferenceScreen); assertThat(mRecyclerView.getAdapter()).isNotNull(); - assertThat(mRecyclerView.getAdapter().getItemCount()).isEqualTo(20); + assertThat(mRecyclerView.getAdapter().getItemCount()).isEqualTo(3); } @Test @@ -88,4 +91,15 @@ public class ZenModeIconPickerListPreferenceControllerTest { verify(mBackend).updateMode(captor.capture()); assertThat(captor.getValue().getRule().getIconResId()).isEqualTo(R.drawable.ic_android); } + + private static class TestIconOptionsProvider implements IconOptionsProvider { + + @Override + public ImmutableList getIcons() { + return ImmutableList.of( + new IconInfo(R.drawable.ic_android, "android"), + new IconInfo(R.drawable.ic_info, "info"), + new IconInfo(R.drawable.ic_hearing, "hearing")); + } + } }