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
This commit is contained in:
@@ -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<IconInfo> getIcons();
|
||||
|
||||
record IconInfo(@DrawableRes int resId, String description) { }
|
||||
}
|
@@ -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<IconInfo> 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());
|
||||
}
|
||||
}
|
@@ -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);
|
||||
|
@@ -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));
|
||||
}
|
||||
}
|
||||
|
@@ -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<IconInfo> 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<IconHolder> {
|
||||
|
||||
private final ImmutableList<IconInfo> mIconResources;
|
||||
private final ImmutableList<IconOptionsProvider.IconInfo> mIconResources;
|
||||
|
||||
private IconAdapter(List<IconInfo> iconOptions) {
|
||||
mIconResources = ImmutableList.copyOf(iconOptions);
|
||||
private IconAdapter(IconOptionsProvider iconOptionsProvider) {
|
||||
mIconResources = iconOptionsProvider.getIcons();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
@@ -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<IconInfo> 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"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user