First bits of "add a mode"
* Preference below the modes list. * Temporarily triggers addition of a mode with default name and type=SCHEDULE_TIME (type will be "manual only" later). * Fixed sorting of modes in the list when refreshing (new modes were added at the bottom instead of where they should, the same would've happened for renamed modes). * Minor polishes (extracted fragment launch to helper class, renamed item controller class for clarity). Test: atest com.android.settings.notification.modes Bug: 326442408 Fixes: 347198709 Flag: android.app.modes_ui Change-Id: Ie276c92181c5374faf74592433595e7e15a5efc0
This commit is contained in:
@@ -7906,7 +7906,7 @@
|
|||||||
<!-- Sound: Footer hyperlink text to launch the Connected devices settings page. [CHAR LIMIT=NONE]-->
|
<!-- Sound: Footer hyperlink text to launch the Connected devices settings page. [CHAR LIMIT=NONE]-->
|
||||||
<string name="spatial_audio_footer_learn_more_text">Connected devices settings</string>
|
<string name="spatial_audio_footer_learn_more_text">Connected devices settings</string>
|
||||||
|
|
||||||
<!-- Sound: Summary for the Do not Disturb option that describes how many automatic rules (schedules) are enabled [CHAR LIMIT=NONE]-->
|
<!-- Zen Modes: Summary for the Do not Disturb option that describes how many automatic rules (schedules) are enabled [CHAR LIMIT=NONE]-->
|
||||||
<string name="zen_mode_settings_schedules_summary">
|
<string name="zen_mode_settings_schedules_summary">
|
||||||
{count, plural,
|
{count, plural,
|
||||||
=0 {None}
|
=0 {None}
|
||||||
@@ -7915,13 +7915,16 @@
|
|||||||
}
|
}
|
||||||
</string>
|
</string>
|
||||||
|
|
||||||
<!-- Sound: Title for the Do not Disturb option and associated settings page. [CHAR LIMIT=50]-->
|
<!-- Zen Modes: Title for the Do not Disturb option and associated settings page. [CHAR LIMIT=50]-->
|
||||||
<string name="zen_mode_settings_title">Do Not Disturb</string>
|
<string name="zen_mode_settings_title">Do Not Disturb</string>
|
||||||
|
|
||||||
<!-- Sound: Title for the Modes option and associated settings page. [CHAR LIMIT=50]-->
|
<!-- Zen Modes: Title for the Modes option and associated settings page. [CHAR LIMIT=50]-->
|
||||||
<string name="zen_modes_list_title">Priority Modes</string>
|
<string name="zen_modes_list_title">Priority Modes</string>
|
||||||
|
|
||||||
<!-- Sound: Summary for the Do not Disturb option and associated settings page. [CHAR LIMIT=240]-->
|
<!-- Zen Modes: Caption of the "add a mode" item in the modes list -->
|
||||||
|
<string name="zen_modes_add_mode">Add a mode</string>
|
||||||
|
|
||||||
|
<!-- Zen Modes: Summary for the Do not Disturb option and associated settings page. [CHAR LIMIT=240]-->
|
||||||
<string name="zen_mode_settings_summary">Only get notified by important people and apps</string>
|
<string name="zen_mode_settings_summary">Only get notified by important people and apps</string>
|
||||||
|
|
||||||
<!-- Subtitle for the Do not Disturb slice. [CHAR LIMIT=50]-->
|
<!-- Subtitle for the Do not Disturb slice. [CHAR LIMIT=50]-->
|
||||||
|
@@ -15,8 +15,10 @@
|
|||||||
~ limitations under the License.
|
~ limitations under the License.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
<PreferenceScreen
|
||||||
android:title="@string/zen_modes_list_title" >
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:title="@string/zen_modes_list_title">
|
||||||
|
|
||||||
<!-- TODO: b/333682392 - add strings for summary as appropriate -->
|
<!-- TODO: b/333682392 - add strings for summary as appropriate -->
|
||||||
|
|
||||||
@@ -25,4 +27,10 @@
|
|||||||
<!-- Preferences leading to rules are added in this PreferenceCategory. -->
|
<!-- Preferences leading to rules are added in this PreferenceCategory. -->
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
|
<Preference
|
||||||
|
android:key="add_mode"
|
||||||
|
android:title="@string/zen_modes_add_mode"
|
||||||
|
android:icon="@drawable/ic_add_24dp"
|
||||||
|
settings:allowDividerAbove="false"/>
|
||||||
|
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
|
@@ -30,6 +30,8 @@ import android.provider.ContactsContract;
|
|||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.service.notification.Condition;
|
import android.service.notification.Condition;
|
||||||
import android.service.notification.ConversationChannelWrapper;
|
import android.service.notification.ConversationChannelWrapper;
|
||||||
|
import android.service.notification.SystemZenRules;
|
||||||
|
import android.service.notification.ZenAdapters;
|
||||||
import android.service.notification.ZenModeConfig;
|
import android.service.notification.ZenModeConfig;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
@@ -242,4 +244,32 @@ class ZenModesBackend {
|
|||||||
}
|
}
|
||||||
mNotificationManager.removeAutomaticZenRule(mode.getId(), /* fromUser= */ true);
|
mNotificationManager.removeAutomaticZenRule(mode.getId(), /* fromUser= */ true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new custom mode with the provided {@code name}. The mode will be "manual" (i.e.
|
||||||
|
* not have a schedule), this can be later updated by the user in the mode settings page.
|
||||||
|
*
|
||||||
|
* @return the created mode. Only {@code null} if creation failed due to an internal error
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
ZenMode addCustomMode(String name) {
|
||||||
|
ZenModeConfig.ScheduleInfo schedule = new ZenModeConfig.ScheduleInfo();
|
||||||
|
schedule.days = ZenModeConfig.ALL_DAYS;
|
||||||
|
schedule.startHour = 22;
|
||||||
|
schedule.endHour = 7;
|
||||||
|
|
||||||
|
// TODO: b/326442408 - Create as "manual" (i.e. no trigger) instead of schedule-time.
|
||||||
|
AutomaticZenRule rule = new AutomaticZenRule.Builder(name,
|
||||||
|
ZenModeConfig.toScheduleConditionId(schedule))
|
||||||
|
.setPackage(ZenModeConfig.getScheduleConditionProvider().getPackageName())
|
||||||
|
.setType(AutomaticZenRule.TYPE_SCHEDULE_CALENDAR)
|
||||||
|
.setOwner(ZenModeConfig.getScheduleConditionProvider())
|
||||||
|
.setTriggerDescription(SystemZenRules.getTriggerDescriptionForScheduleTime(
|
||||||
|
mContext, schedule))
|
||||||
|
.setManualInvocationAllowed(true)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
String ruleId = mNotificationManager.addAutomaticZenRule(rule);
|
||||||
|
return getMode(ruleId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* 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 android.content.Context;
|
||||||
|
|
||||||
|
import androidx.preference.Preference;
|
||||||
|
|
||||||
|
import com.android.settings.utils.ZenServiceListing;
|
||||||
|
import com.android.settingslib.core.AbstractPreferenceController;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
class ZenModesListAddModePreferenceController extends AbstractPreferenceController {
|
||||||
|
|
||||||
|
private final ZenModesBackend mBackend;
|
||||||
|
private final ZenServiceListing mServiceListing;
|
||||||
|
|
||||||
|
ZenModesListAddModePreferenceController(Context context, ZenModesBackend backend,
|
||||||
|
ZenServiceListing serviceListing) {
|
||||||
|
super(context);
|
||||||
|
mBackend = backend;
|
||||||
|
mServiceListing = serviceListing;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAvailable() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPreferenceKey() {
|
||||||
|
return "add_mode";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateState(Preference preference) {
|
||||||
|
preference.setOnPreferenceClickListener(pref -> {
|
||||||
|
// TODO: b/326442408 - Launch the proper mode creation flow (using mServiceListing).
|
||||||
|
ZenMode mode = mBackend.addCustomMode("New mode #" + new Random().nextInt(1000));
|
||||||
|
if (mode != null) {
|
||||||
|
ZenSubSettingLauncher.forMode(mContext, mode.getId()).launch();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@@ -31,12 +31,14 @@ import com.android.settings.utils.ZenServiceListing;
|
|||||||
import com.android.settingslib.core.AbstractPreferenceController;
|
import com.android.settingslib.core.AbstractPreferenceController;
|
||||||
import com.android.settingslib.search.SearchIndexable;
|
import com.android.settingslib.search.SearchIndexable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@SearchIndexable
|
@SearchIndexable
|
||||||
public class ZenModesListFragment extends ZenModesFragmentBase {
|
public class ZenModesListFragment extends ZenModesFragmentBase {
|
||||||
protected final ManagedServiceSettings.Config CONFIG = getConditionProviderConfig();
|
|
||||||
|
private static final ManagedServiceSettings.Config CONFIG = getConditionProviderConfig();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
|
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
|
||||||
@@ -50,13 +52,11 @@ public class ZenModesListFragment extends ZenModesFragmentBase {
|
|||||||
// We need to redefine ZenModesBackend here even though mBackend exists so that this method
|
// We need to redefine ZenModesBackend here even though mBackend exists so that this method
|
||||||
// can be static; it must be static to be able to be used in SEARCH_INDEX_DATA_PROVIDER.
|
// can be static; it must be static to be able to be used in SEARCH_INDEX_DATA_PROVIDER.
|
||||||
ZenModesBackend backend = ZenModesBackend.getInstance(context);
|
ZenModesBackend backend = ZenModesBackend.getInstance(context);
|
||||||
List<AbstractPreferenceController> controllers = new ArrayList<>();
|
|
||||||
controllers.add(new ZenModesListPreferenceController(
|
|
||||||
context, parent, backend));
|
|
||||||
|
|
||||||
// TODO: b/326442408 - Add controller for "Add Mode" preference/flow, which is what uses
|
return ImmutableList.of(
|
||||||
// the ZenServiceListing.
|
new ZenModesListPreferenceController(context, parent, backend),
|
||||||
return controllers;
|
new ZenModesListAddModePreferenceController(context, backend, serviceListing)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -77,7 +77,7 @@ public class ZenModesListFragment extends ZenModesFragmentBase {
|
|||||||
return SettingsEnums.NOTIFICATION_ZEN_MODE_AUTOMATION;
|
return SettingsEnums.NOTIFICATION_ZEN_MODE_AUTOMATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static ManagedServiceSettings.Config getConditionProviderConfig() {
|
private static ManagedServiceSettings.Config getConditionProviderConfig() {
|
||||||
return new ManagedServiceSettings.Config.Builder()
|
return new ManagedServiceSettings.Config.Builder()
|
||||||
.setTag(TAG)
|
.setTag(TAG)
|
||||||
.setIntentAction(ConditionProviderService.SERVICE_INTERFACE)
|
.setIntentAction(ConditionProviderService.SERVICE_INTERFACE)
|
||||||
@@ -87,8 +87,6 @@ public class ZenModesListFragment extends ZenModesFragmentBase {
|
|||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: b/322373473 - Add 3-dot options menu with capability to delete modes.
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For Search.
|
* For Search.
|
||||||
*/
|
*/
|
||||||
|
@@ -15,24 +15,19 @@
|
|||||||
*/
|
*/
|
||||||
package com.android.settings.notification.modes;
|
package com.android.settings.notification.modes;
|
||||||
|
|
||||||
import static com.android.settings.notification.modes.ZenModeFragmentBase.MODE_ID;
|
|
||||||
|
|
||||||
import android.app.settings.SettingsEnums;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
|
||||||
|
|
||||||
import com.android.settings.core.SubSettingLauncher;
|
|
||||||
import com.android.settingslib.RestrictedPreference;
|
import com.android.settingslib.RestrictedPreference;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Preference representing a single mode item on the modes aggregator page. Clicking on this
|
* Preference representing a single mode item on the modes aggregator page. Clicking on this
|
||||||
* preference leads to an individual mode's configuration page.
|
* preference leads to an individual mode's configuration page.
|
||||||
*/
|
*/
|
||||||
class ZenModeListPreference extends RestrictedPreference {
|
class ZenModesListItemPreference extends RestrictedPreference {
|
||||||
final Context mContext;
|
final Context mContext;
|
||||||
ZenMode mZenMode;
|
ZenMode mZenMode;
|
||||||
|
|
||||||
ZenModeListPreference(Context context, ZenMode zenMode) {
|
ZenModesListItemPreference(Context context, ZenMode zenMode) {
|
||||||
super(context);
|
super(context);
|
||||||
mContext = context;
|
mContext = context;
|
||||||
setZenMode(zenMode);
|
setZenMode(zenMode);
|
||||||
@@ -41,13 +36,7 @@ class ZenModeListPreference extends RestrictedPreference {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick() {
|
public void onClick() {
|
||||||
Bundle bundle = new Bundle();
|
ZenSubSettingLauncher.forMode(mContext, mZenMode.getId()).launch();
|
||||||
bundle.putString(MODE_ID, mZenMode.getId());
|
|
||||||
new SubSettingLauncher(mContext)
|
|
||||||
.setDestination(ZenModeFragment.class.getName())
|
|
||||||
.setArguments(bundle)
|
|
||||||
.setSourceMetricsCategory(SettingsEnums.NOTIFICATION_ZEN_MODE_AUTOMATION)
|
|
||||||
.launch();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setZenMode(ZenMode zenMode) {
|
public void setZenMode(ZenMode zenMode) {
|
@@ -15,7 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.android.settings.notification.modes;
|
package com.android.settings.notification.modes;
|
||||||
|
|
||||||
import android.app.AutomaticZenRule;
|
|
||||||
import android.app.Flags;
|
import android.app.Flags;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
@@ -74,24 +73,27 @@ class ZenModesListPreferenceController extends BasePreferenceController {
|
|||||||
// category for each rule that exists.
|
// category for each rule that exists.
|
||||||
PreferenceCategory category = (PreferenceCategory) preference;
|
PreferenceCategory category = (PreferenceCategory) preference;
|
||||||
|
|
||||||
Map<String, ZenModeListPreference> originalPreferences = new HashMap<>();
|
Map<String, ZenModesListItemPreference> originalPreferences = new HashMap<>();
|
||||||
for (int i = 0; i < category.getPreferenceCount(); i++) {
|
for (int i = 0; i < category.getPreferenceCount(); i++) {
|
||||||
ZenModeListPreference pref = (ZenModeListPreference) category.getPreference(i);
|
ZenModesListItemPreference pref = (ZenModesListItemPreference) category.getPreference(
|
||||||
|
i);
|
||||||
originalPreferences.put(pref.getKey(), pref);
|
originalPreferences.put(pref.getKey(), pref);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loop through each rule, either updating the existing rule or creating the rule's
|
// Loop through each rule, either updating the existing rule or creating the rule's
|
||||||
// preference
|
// preference
|
||||||
for (ZenMode mode : mBackend.getModes()) {
|
List<ZenMode> modes = mBackend.getModes();
|
||||||
if (originalPreferences.containsKey(mode.getId())) {
|
for (ZenMode mode : modes) {
|
||||||
|
ZenModesListItemPreference modePreference = originalPreferences.get(mode.getId());
|
||||||
|
if (modePreference != null) {
|
||||||
// existing rule; update its info if it's changed since the last display
|
// existing rule; update its info if it's changed since the last display
|
||||||
AutomaticZenRule rule = mode.getRule();
|
modePreference.setZenMode(mode);
|
||||||
originalPreferences.get(mode.getId()).setZenMode(mode);
|
|
||||||
} else {
|
} else {
|
||||||
// new rule; create a new ZenRulePreference & add it to the preference category
|
// new rule; create a new ZenRulePreference & add it to the preference category
|
||||||
Preference pref = new ZenModeListPreference(mContext, mode);
|
modePreference = new ZenModesListItemPreference(mContext, mode);
|
||||||
category.addPreference(pref);
|
category.addPreference(modePreference);
|
||||||
}
|
}
|
||||||
|
modePreference.setOrder(modes.indexOf(mode));
|
||||||
|
|
||||||
originalPreferences.remove(mode.getId());
|
originalPreferences.remove(mode.getId());
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* 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 android.app.settings.SettingsEnums;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import com.android.settings.core.SubSettingLauncher;
|
||||||
|
|
||||||
|
class ZenSubSettingLauncher {
|
||||||
|
|
||||||
|
static SubSettingLauncher forMode(Context context, String modeId) {
|
||||||
|
return forModeFragment(context, ZenModeFragment.class, modeId,
|
||||||
|
SettingsEnums.NOTIFICATION_ZEN_MODE_AUTOMATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SubSettingLauncher forModeFragment(Context context,
|
||||||
|
Class<? extends ZenModeFragmentBase> fragmentClass, String modeId,
|
||||||
|
int sourceMetricsCategory) {
|
||||||
|
Bundle bundle = new Bundle();
|
||||||
|
bundle.putString(ZenModeFragmentBase.MODE_ID, modeId);
|
||||||
|
|
||||||
|
return new SubSettingLauncher(context)
|
||||||
|
.setDestination(fragmentClass.getName())
|
||||||
|
.setArguments(bundle)
|
||||||
|
.setSourceMetricsCategory(sourceMetricsCategory);
|
||||||
|
}
|
||||||
|
}
|
@@ -31,8 +31,16 @@ import android.platform.test.annotations.EnableFlags;
|
|||||||
import android.platform.test.flag.junit.SetFlagsRule;
|
import android.platform.test.flag.junit.SetFlagsRule;
|
||||||
import android.service.notification.ZenPolicy;
|
import android.service.notification.ZenPolicy;
|
||||||
|
|
||||||
|
import androidx.preference.Preference;
|
||||||
|
import androidx.preference.PreferenceCategory;
|
||||||
|
import androidx.preference.PreferenceGroup;
|
||||||
|
import androidx.preference.PreferenceManager;
|
||||||
|
import androidx.preference.PreferenceScreen;
|
||||||
|
|
||||||
import com.android.settingslib.search.SearchIndexableRaw;
|
import com.android.settingslib.search.SearchIndexableRaw;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -43,6 +51,7 @@ import org.robolectric.RobolectricTestRunner;
|
|||||||
import org.robolectric.RuntimeEnvironment;
|
import org.robolectric.RuntimeEnvironment;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
@@ -75,15 +84,71 @@ public class ZenModesListPreferenceControllerTest {
|
|||||||
private ZenModesBackend mBackend;
|
private ZenModesBackend mBackend;
|
||||||
|
|
||||||
private ZenModesListPreferenceController mPrefController;
|
private ZenModesListPreferenceController mPrefController;
|
||||||
|
private PreferenceCategory mPreference;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
mContext = RuntimeEnvironment.application;
|
mContext = RuntimeEnvironment.application;
|
||||||
|
|
||||||
|
mPreference = new PreferenceCategory(mContext);
|
||||||
|
PreferenceManager preferenceManager = new PreferenceManager(mContext);
|
||||||
|
PreferenceScreen preferenceScreen = preferenceManager.createPreferenceScreen(mContext);
|
||||||
|
preferenceScreen.addPreference(mPreference);
|
||||||
|
|
||||||
mPrefController = new ZenModesListPreferenceController(mContext, null, mBackend);
|
mPrefController = new ZenModesListPreferenceController(mContext, null, mBackend);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@EnableFlags(Flags.FLAG_MODES_UI)
|
||||||
|
public void updateState_addsPreferences() {
|
||||||
|
ImmutableList<ZenMode> modes = ImmutableList.of(newMode("One"), newMode("Two"),
|
||||||
|
newMode("Three"), newMode("Four"), newMode("Five"));
|
||||||
|
when(mBackend.getModes()).thenReturn(modes);
|
||||||
|
|
||||||
|
mPrefController.updateState(mPreference);
|
||||||
|
|
||||||
|
assertThat(mPreference.getPreferenceCount()).isEqualTo(5);
|
||||||
|
List<ZenModesListItemPreference> itemPreferences = getModeListItems(mPreference);
|
||||||
|
assertThat(itemPreferences.stream().map(pref -> pref.mZenMode).toList())
|
||||||
|
.containsExactlyElementsIn(modes)
|
||||||
|
.inOrder();
|
||||||
|
|
||||||
|
for (int i = 0; i < modes.size(); i++) {
|
||||||
|
assertThat(((ZenModesListItemPreference) (mPreference.getPreference(i))).mZenMode)
|
||||||
|
.isEqualTo(modes.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@EnableFlags(Flags.FLAG_MODES_UI)
|
||||||
|
public void updateState_secondTime_updatesPreferences() {
|
||||||
|
ImmutableList<ZenMode> modes = ImmutableList.of(newMode("One"), newMode("Two"),
|
||||||
|
newMode("Three"), newMode("Four"), newMode("Five"));
|
||||||
|
when(mBackend.getModes()).thenReturn(modes);
|
||||||
|
mPrefController.updateState(mPreference);
|
||||||
|
|
||||||
|
assertThat(mPreference.getPreferenceCount()).isEqualTo(5);
|
||||||
|
List<ZenModesListItemPreference> oldPreferences = getModeListItems(mPreference);
|
||||||
|
|
||||||
|
ImmutableList<ZenMode> updatedModes = ImmutableList.of(modes.get(0), modes.get(1),
|
||||||
|
newMode("Two.1"), newMode("Two.2"), modes.get(2), /* deleted "Four" */
|
||||||
|
modes.get(4));
|
||||||
|
when(mBackend.getModes()).thenReturn(updatedModes);
|
||||||
|
mPrefController.updateState(mPreference);
|
||||||
|
|
||||||
|
List<ZenModesListItemPreference> newPreferences = getModeListItems(mPreference);
|
||||||
|
assertThat(newPreferences.stream().map(pref -> pref.mZenMode).toList())
|
||||||
|
.containsExactlyElementsIn(updatedModes)
|
||||||
|
.inOrder();
|
||||||
|
|
||||||
|
// Verify that the old preference controllers were reused instead of creating new ones.
|
||||||
|
assertThat(newPreferences.get(0)).isSameInstanceAs(oldPreferences.get(0));
|
||||||
|
assertThat(newPreferences.get(1)).isSameInstanceAs(oldPreferences.get(1));
|
||||||
|
assertThat(newPreferences.get(4)).isSameInstanceAs(oldPreferences.get(2));
|
||||||
|
assertThat(newPreferences.get(5)).isSameInstanceAs(oldPreferences.get(4));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisableFlags(Flags.FLAG_MODES_UI)
|
@DisableFlags(Flags.FLAG_MODES_UI)
|
||||||
public void testModesUiOff_notAvailableAndNoSearchData() {
|
public void testModesUiOff_notAvailableAndNoSearchData() {
|
||||||
@@ -151,4 +216,28 @@ public class ZenModesListPreferenceControllerTest {
|
|||||||
assertThat(item1.key).isEqualTo(TEST_MODE_ID);
|
assertThat(item1.key).isEqualTo(TEST_MODE_ID);
|
||||||
assertThat(item1.title).isEqualTo(TEST_MODE_NAME);
|
assertThat(item1.title).isEqualTo(TEST_MODE_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static ZenMode newMode(String id) {
|
||||||
|
return new ZenMode(
|
||||||
|
id,
|
||||||
|
new AutomaticZenRule.Builder("Mode " + id, Uri.parse("test_uri"))
|
||||||
|
.setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY)
|
||||||
|
.setZenPolicy(new ZenPolicy.Builder().allowAllSounds().build())
|
||||||
|
.build(),
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the child preferences of the {@code group}, sorted by their
|
||||||
|
* {@link Preference#getOrder} value (which is the order they will be sorted by and displayed
|
||||||
|
* in the UI).
|
||||||
|
*/
|
||||||
|
private List<ZenModesListItemPreference> getModeListItems(PreferenceGroup group) {
|
||||||
|
ArrayList<ZenModesListItemPreference> items = new ArrayList<>();
|
||||||
|
for (int i = 0; i < group.getPreferenceCount(); i++) {
|
||||||
|
items.add((ZenModesListItemPreference) group.getPreference(i));
|
||||||
|
}
|
||||||
|
items.sort(Comparator.comparing(Preference::getOrder));
|
||||||
|
return items;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user