Add custom dnd pages for each dnd auto rule

- Fix strings
- Add zen custom settings dialog when custom settings are being applied
Test: make RunSettingsRoboTests -j40
Bug: 111475013
Fixes: 120787133
Fixes: 120796642
Fixes: 120865472
Change-Id: I34d6b4b23d36277e3704416d65e2418418c124e1
This commit is contained in:
Beverly
2018-12-11 16:19:33 -05:00
parent f30fb4b20b
commit b9f38af689
50 changed files with 3582 additions and 159 deletions

View File

@@ -0,0 +1,171 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2018 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.
-->
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fadeScrollbars="false"
android:scrollIndicators="top|bottom">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingStart="24dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="14dp">
<TextView
android:id="@+id/zen_custom_settings_dialog_calls"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/zen_mode_calls" />
<TextView
android:id="@+id/zen_custom_settings_dialog_calls_allow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItem" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="14dp">
<TextView
android:id="@+id/zen_custom_settings_dialog_messages"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/zen_mode_messages" />
<TextView
android:id="@+id/zen_custom_settings_dialog_messages_allow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItem" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="14dp">
<TextView
android:id="@+id/zen_custom_settings_dialog_alarms"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/zen_mode_alarms" />
<TextView
android:id="@+id/zen_custom_settings_dialog_alarms_allow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItem" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="14dp">
<TextView
android:id="@+id/zen_custom_settings_dialog_media"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/zen_mode_media" />
<TextView
android:id="@+id/zen_custom_settings_dialog_media_allow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItem" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="14dp">
<TextView
android:id="@+id/zen_custom_settings_dialog_system"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/zen_mode_system" />
<TextView
android:id="@+id/zen_custom_settings_dialog_system_allow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItem" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="14dp">
<TextView
android:id="@+id/zen_custom_settings_dialog_reminders"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/zen_mode_reminders"/>
<TextView
android:id="@+id/zen_custom_settings_dialog_reminders_allow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItem" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="14dp">
<TextView
android:id="@+id/zen_custom_settings_dialog_events"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/zen_mode_events"/>
<TextView
android:id="@+id/zen_custom_settings_dialog_events_allow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItem" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="14dp">
<TextView
android:id="@+id/zen_custom_settings_dialog_notifications"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/zen_custom_settings_notifications_header" />
<TextView
android:id="@+id/zen_custom_settings_dialog_show_notifications"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItem" />
</LinearLayout>
</LinearLayout>
</ScrollView>

View File

@@ -1081,14 +1081,14 @@
<item>@string/zen_mode_from_anyone</item> <item>@string/zen_mode_from_anyone</item>
<item>@string/zen_mode_from_contacts</item> <item>@string/zen_mode_from_contacts</item>
<item>@string/zen_mode_from_starred</item> <item>@string/zen_mode_from_starred</item>
<item>@string/zen_mode_from_none_calls</item> <item>@string/zen_mode_from_none_messages</item>
</string-array> </string-array>
<string-array name="zen_mode_contacts_calls_entries" translatable="false"> <string-array name="zen_mode_contacts_calls_entries" translatable="false">
<item>@string/zen_mode_from_anyone</item> <item>@string/zen_mode_from_anyone</item>
<item>@string/zen_mode_from_contacts</item> <item>@string/zen_mode_from_contacts</item>
<item>@string/zen_mode_from_starred</item> <item>@string/zen_mode_from_starred</item>
<item>@string/zen_mode_from_none_messages</item> <item>@string/zen_mode_from_none_calls</item>
</string-array> </string-array>
<string-array name="zen_mode_contacts_values" translatable="false"> <string-array name="zen_mode_contacts_values" translatable="false">

View File

@@ -7328,8 +7328,8 @@
<!-- [CHAR LIMIT=110] Zen mode settings footer: Footer showing length of DND --> <!-- [CHAR LIMIT=110] Zen mode settings footer: Footer showing length of DND -->
<string name="zen_mode_settings_dnd_manual_indefinite">Do Not Disturb will stay on until you turn it off</string> <string name="zen_mode_settings_dnd_manual_indefinite">Do Not Disturb will stay on until you turn it off</string>
<!-- [CHAR LIMIT=110] Zen mode settings footer: Footer showing how DND was triggered by an automatic DND rule --> <!-- [CHAR LIMIT=110] Zen mode settings footer: Footer showing how DND was triggered by an automatic DND schedule -->
<string name="zen_mode_settings_dnd_automatic_rule">Do Not Disturb was automatically turned on by a rule (<xliff:g id="rule_name" example="Weeknights">%s</xliff:g>)</string> <string name="zen_mode_settings_dnd_automatic_rule">Do Not Disturb was automatically turned on by a schedule (<xliff:g id="rule_name" example="Weeknights">%s</xliff:g>)</string>
<!-- [CHAR LIMIT=110] Zen mode settings footer: Footer how DND was triggered by an app --> <!-- [CHAR LIMIT=110] Zen mode settings footer: Footer how DND was triggered by an app -->
<string name="zen_mode_settings_dnd_automatic_rule_app">Do Not Disturb was automatically turned on by an app (<xliff:g id="app_name" example="Android Services">%s</xliff:g>)</string> <string name="zen_mode_settings_dnd_automatic_rule_app">Do Not Disturb was automatically turned on by an app (<xliff:g id="app_name" example="Android Services">%s</xliff:g>)</string>
@@ -7337,6 +7337,9 @@
<!-- [CHAR LIMIT=120] Zen mode settings footer: Footer informing user DND has custom settings. --> <!-- [CHAR LIMIT=120] Zen mode settings footer: Footer informing user DND has custom settings. -->
<string name="zen_mode_settings_dnd_custom_settings_footer">Do Not Disturb is on for <xliff:g id="rule_names" example="Sleeping and Work">%s</xliff:g> with custom settings.</string> <string name="zen_mode_settings_dnd_custom_settings_footer">Do Not Disturb is on for <xliff:g id="rule_names" example="Sleeping and Work">%s</xliff:g> with custom settings.</string>
<!-- [CHAR LIMIT=120] Zen mode settings footer: Link following zen_mode_settings_dnd_custom_settings_footer to see the currently applied custom dnd settings. -->
<string name="zen_mode_settings_dnd_custom_settings_footer_link"><annotation id="link"> View custom settings</annotation></string>
<!--[CHAR LIMIT=40] Zen Interruption level: Priority. --> <!--[CHAR LIMIT=40] Zen Interruption level: Priority. -->
<string name="zen_interruption_level_priority">Priority only</string> <string name="zen_interruption_level_priority">Priority only</string>
@@ -7400,6 +7403,17 @@
<!-- Do not disturb settings, sound and vibrations summary [CHAR LIMIT=100]--> <!-- Do not disturb settings, sound and vibrations summary [CHAR LIMIT=100]-->
<string name="zen_sound_three_allowed">Muted, but allow <xliff:g id="sound_type" example="alarms">%1$s</xliff:g>, <xliff:g id="sound_type" example="alarms">%2$s</xliff:g>, and <xliff:g id="sound_type" example="media">%3$s</xliff:g></string> <string name="zen_sound_three_allowed">Muted, but allow <xliff:g id="sound_type" example="alarms">%1$s</xliff:g>, <xliff:g id="sound_type" example="alarms">%2$s</xliff:g>, and <xliff:g id="sound_type" example="media">%3$s</xliff:g></string>
<!-- Do not disturb custom settings dialog title [CHAR LIMIT=40]-->
<string name="zen_custom_settings_dialog_title">Custom settings</string>
<!-- Do not disturb custom settings dialog button label [CHAR LIMIT=40]-->
<string name="zen_custom_settings_dialog_review_schedule">Review schedule</string>
<!-- Do not disturb custom settings dialog button label [CHAR LIMIT=40]-->
<string name="zen_custom_settings_dialog_ok">Got it</string>
<!-- Do not disturb custom settings notifications header [CHAR LIMIT=40]-->
<string name="zen_custom_settings_notifications_header">Notifications</string>
<!-- Do not disturb custom settings duration header [CHAR LIMIT=40]-->
<string name="zen_custom_settings_duration_header">Duration</string>
<!-- Do not disturb settings, messages, events and reminders title [CHAR LIMIT=100]--> <!-- Do not disturb settings, messages, events and reminders title [CHAR LIMIT=100]-->
<string name="zen_msg_event_reminder_title">Messages, events &amp; reminders</string> <string name="zen_msg_event_reminder_title">Messages, events &amp; reminders</string>
<!-- Do not disturb settings, messages, events and reminders footer [CHAR LIMIT=NONE]--> <!-- Do not disturb settings, messages, events and reminders footer [CHAR LIMIT=NONE]-->
@@ -7941,6 +7955,9 @@
<!-- [CHAR LIMIT=120] Zen mode settings: Summay text indicating the currenty dnd schedule is using custom behavior --> <!-- [CHAR LIMIT=120] Zen mode settings: Summay text indicating the currenty dnd schedule is using custom behavior -->
<string name="zen_mode_custom_behavior_summary">Create custom settings for this schedule</string> <string name="zen_mode_custom_behavior_summary">Create custom settings for this schedule</string>
<!-- [CHAR LIMIT=100] Zen mode settings: Category text indicating the schedule this custom behavior will be configured for-->
<string name="zen_mode_custom_behavior_category_title">For \u2018<xliff:g id="schedule_name" example="Schedule 1">%1$s</xliff:g>\u2019</string>
<!-- [CHAR LIMIT=40] General divider text when concatenating multiple items in a text summary --> <!-- [CHAR LIMIT=40] General divider text when concatenating multiple items in a text summary -->
<string name="summary_divider_text">,\u0020</string> <string name="summary_divider_text">,\u0020</string>
@@ -7956,9 +7973,12 @@
<!-- [CHAR LIMIT=40] Zen mode settings: Allow calls toggle title --> <!-- [CHAR LIMIT=40] Zen mode settings: Allow calls toggle title -->
<string name="zen_mode_calls_title">Calls</string> <string name="zen_mode_calls_title">Calls</string>
<!-- [CHAR LIMIT=20] Zen mode settings: Calls screen footer --> <!-- [CHAR LIMIT=NONE] Zen mode settings: Calls screen footer -->
<string name="zen_mode_calls_footer">When Do Not Disturb is on, incoming calls are blocked. You can adjust settings to allow your friends, family, or other contacts to reach you.</string> <string name="zen_mode_calls_footer">When Do Not Disturb is on, incoming calls are blocked. You can adjust settings to allow your friends, family, or other contacts to reach you.</string>
<!-- [CHAR LIMIT=NONE] Zen mode custom rule settings: Calls screen footer -->
<string name="zen_mode_custom_calls_footer">For \u2018<xliff:g id="schedule_name" example="Schedule 1">%1$s</xliff:g>\u2019 incoming calls are blocked. You can adjust settings to allow your friends, family, or other contacts to reach you.</string>
<!-- [CHAR LIMIT=50] Zen mode settings: Starred contacts preference title --> <!-- [CHAR LIMIT=50] Zen mode settings: Starred contacts preference title -->
<string name="zen_mode_starred_contacts_title">Starred contacts</string> <string name="zen_mode_starred_contacts_title">Starred contacts</string>
@@ -7974,6 +7994,9 @@
<!-- Do not disturb settings, messages, events and reminders footer [CHAR LIMIT=NONE]--> <!-- Do not disturb settings, messages, events and reminders footer [CHAR LIMIT=NONE]-->
<string name="zen_mode_messages_footer">When Do Not Disturb is on, incoming text messages are blocked. You can adjust settings to allow your friends, family, or other contacts to reach you.</string> <string name="zen_mode_messages_footer">When Do Not Disturb is on, incoming text messages are blocked. You can adjust settings to allow your friends, family, or other contacts to reach you.</string>
<!-- [CHAR LIMIT=NONE] Zen mode custom rule settings: Messages screen footer -->
<string name="zen_mode_custom_messages_footer">For \u2018<xliff:g id="schedule_name" example="Schedule 1">%1$s</xliff:g>\u2019 incoming text messages are blocked. You can adjust settings to allow your friends, family, or other contacts to reach you.</string>
<!-- [CHAR LIMIT=40] Zen mode settings: Allow messages to bypass DND title --> <!-- [CHAR LIMIT=40] Zen mode settings: Allow messages to bypass DND title -->
<string name="zen_mode_messages_title">Text messages</string> <string name="zen_mode_messages_title">Text messages</string>
@@ -8037,11 +8060,11 @@
<!-- [CHAR LIMIT=100] Zen mode settings: Allow apps to bypass DND title--> <!-- [CHAR LIMIT=100] Zen mode settings: Allow apps to bypass DND title-->
<string name="zen_mode_bypassing_apps_title">App exceptions</string> <string name="zen_mode_bypassing_apps_title">App exceptions</string>
<!-- [CHAR LIMIT=80] Zen mode settings: Allow apps to bypass DND --> <!-- [CHAR LIMIT=120] Zen mode settings: Allow apps to bypass DND -->
<plurals name="zen_mode_bypassing_apps_subtext"> <plurals name="zen_mode_bypassing_apps_subtext">
<item quantity="zero">No apps can override Do Not Disturb</item> <item quantity="zero">No apps can override Do Not Disturb</item>
<item quantity="one">1 app can override Do Not Disturb</item> <item quantity="one">Notifications from 1 app can override Do Not Disturb</item>
<item quantity="other"><xliff:g id="number" example="2">%1$d</xliff:g> apps can override Do Not Disturb</item> <item quantity="other">Notifications from <xliff:g id="number" example="2">%1$d</xliff:g> apps can override Do Not Disturb</item>
</plurals> </plurals>
<!-- [CHAR LIMIT=50] Zen mode settings: Events (ie: calendar events) --> <!-- [CHAR LIMIT=50] Zen mode settings: Events (ie: calendar events) -->

View File

@@ -0,0 +1,66 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2018 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.
-->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:key="zen_custom_rule_configuration_page"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:title="@string/zen_mode_settings_title">
<PreferenceCategory
android:key="zen_custom_rule_configuration_category">
<!-- Calls -->
<Preference
android:key="zen_rule_calls_settings"
android:title="@string/zen_mode_calls" />
<!-- Messages -->
<Preference
android:key="zen_rule_messages_settings"
android:title="@string/zen_mode_messages" />
<!-- Alarms -->
<SwitchPreference
android:key="zen_rule_alarms"
android:title="@string/zen_mode_alarms"/>
<!-- Media -->
<SwitchPreference
android:key="zen_rule_media"
android:title="@string/zen_mode_media"/>
<!-- System -->
<SwitchPreference
android:key="zen_rule_system"
android:title="@string/zen_mode_system"/>
<!-- Reminders -->
<SwitchPreference
android:key="zen_rule_reminders"
android:title="@string/zen_mode_reminders"/>
<!-- Events -->
<SwitchPreference
android:key="zen_rule_events"
android:title="@string/zen_mode_events"/>
</PreferenceCategory>
<Preference
android:key="zen_rule_notifications"
android:title="@string/zen_mode_restrict_notifications_title"
settings:allowDividerAbove="true"/>
</PreferenceScreen>

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2018 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.
-->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:key="zen_custom_rule_settings_page"
android:title="@string/zen_mode_custom_behavior_title">
<PreferenceCategory
android:key="zen_custom_rule_category">
<com.android.settings.notification.ZenCustomRadioButtonPreference
android:key="zen_custom_rule_setting_default"
android:title="@string/zen_mode_custom_behavior_summary_default"/>
<com.android.settings.notification.ZenCustomRadioButtonPreference
android:key="zen_custom_rule_setting"
android:title="@string/zen_mode_custom_behavior_summary" />
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -45,4 +45,10 @@
android:title="@string/zen_mode_event_rule_reply" android:title="@string/zen_mode_event_rule_reply"
android:summary="%s" /> android:summary="%s" />
<!-- Custom Do Not Disturb Setting-->
<Preference
android:key="zen_custom_setting"
android:title="@string/zen_mode_custom_behavior_title"
android:order="100" />
</PreferenceScreen> </PreferenceScreen>

View File

@@ -50,7 +50,7 @@
<!-- Custom Do Not Disturb Setting--> <!-- Custom Do Not Disturb Setting-->
<Preference <Preference
android:key="zen_schedule_custom_setting" android:key="zen_custom_setting"
android:title="@string/zen_mode_custom_behavior_title" android:title="@string/zen_mode_custom_behavior_title"
android:order="100" /> android:order="100" />

View File

@@ -0,0 +1,61 @@
/*
* Copyright (C) 2018 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;
import android.app.AutomaticZenRule;
import android.content.Context;
import android.os.Bundle;
import androidx.preference.Preference;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.core.lifecycle.Lifecycle;
abstract class AbstractZenCustomRulePreferenceController extends
AbstractZenModePreferenceController implements PreferenceControllerMixin {
String mId;
AutomaticZenRule mRule;
AbstractZenCustomRulePreferenceController(Context context, String key,
Lifecycle lifecycle) {
super(context, key, lifecycle);
}
@Override
public void updateState(Preference preference) {
if (mId != null) {
mRule = mBackend.getAutomaticZenRule(mId);
}
}
@Override
public boolean isAvailable() {
return mRule != null;
}
public void onResume(AutomaticZenRule rule, String id) {
mId = id;
mRule = rule;
}
Bundle createBundle() {
Bundle bundle = new Bundle();
bundle.putString(ZenCustomRuleSettings.RULE_ID, mId);
return bundle;
}
}

View File

@@ -50,7 +50,7 @@ abstract public class AbstractZenModePreferenceController extends
@VisibleForTesting @VisibleForTesting
protected SettingObserver mSettingObserver; protected SettingObserver mSettingObserver;
private final String KEY; final String KEY;
final private NotificationManager mNotificationManager; final private NotificationManager mNotificationManager;
protected static ZenModeConfigWrapper mZenModeConfigWrapper; protected static ZenModeConfigWrapper mZenModeConfigWrapper;
protected MetricsFeatureProvider mMetricsFeatureProvider; protected MetricsFeatureProvider mMetricsFeatureProvider;

View File

@@ -0,0 +1,81 @@
/*
* Copyright (C) 2018 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;
import android.content.Context;
import android.os.Bundle;
import android.service.notification.ZenPolicy;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settingslib.core.AbstractPreferenceController;
import java.util.ArrayList;
import java.util.List;
public class ZenCustomRuleBlockedEffectsSettings extends ZenCustomRuleSettingsBase {
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
mFooterPreferenceMixin.createFooterPreference().setTitle(
R.string.zen_mode_blocked_effects_footer);
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.zen_mode_block_settings;
}
@Override
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
mControllers = new ArrayList<>();
mControllers.add(new ZenRuleVisEffectPreferenceController(context, getSettingsLifecycle(),
"zen_effect_intent", ZenPolicy.VISUAL_EFFECT_FULL_SCREEN_INTENT,
MetricsEvent.ACTION_ZEN_BLOCK_FULL_SCREEN_INTENTS, null));
mControllers.add(new ZenRuleVisEffectPreferenceController(context, getSettingsLifecycle(),
"zen_effect_light", ZenPolicy.VISUAL_EFFECT_LIGHTS,
MetricsEvent.ACTION_ZEN_BLOCK_LIGHT, null));
mControllers.add(new ZenRuleVisEffectPreferenceController(context, getSettingsLifecycle(),
"zen_effect_peek", ZenPolicy.VISUAL_EFFECT_PEEK,
MetricsEvent.ACTION_ZEN_BLOCK_PEEK, null));
mControllers.add(new ZenRuleVisEffectPreferenceController(context, getSettingsLifecycle(),
"zen_effect_status", ZenPolicy.VISUAL_EFFECT_STATUS_BAR,
MetricsEvent.ACTION_ZEN_BLOCK_STATUS,
new int[] {ZenPolicy.VISUAL_EFFECT_NOTIFICATION_LIST}));
mControllers.add(new ZenRuleVisEffectPreferenceController(context, getSettingsLifecycle(),
"zen_effect_badge", ZenPolicy.VISUAL_EFFECT_BADGE,
MetricsEvent.ACTION_ZEN_BLOCK_BADGE, null));
mControllers.add(new ZenRuleVisEffectPreferenceController(context, getSettingsLifecycle(),
"zen_effect_ambient", ZenPolicy.VISUAL_EFFECT_AMBIENT,
MetricsEvent.ACTION_ZEN_BLOCK_AMBIENT, null));
mControllers.add(new ZenRuleVisEffectPreferenceController(context, getSettingsLifecycle(),
"zen_effect_list", ZenPolicy.VISUAL_EFFECT_NOTIFICATION_LIST,
MetricsEvent.ACTION_ZEN_BLOCK_NOTIFICATION_LIST, null));
return mControllers;
}
@Override
String getPreferenceCategoryKey() {
return null;
}
@Override
public int getMetricsCategory() {
return MetricsEvent.ZEN_CUSTOM_RULE_VIS_EFFECTS;
}
}

View File

@@ -0,0 +1,81 @@
/*
* Copyright (C) 2018 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;
import android.content.Context;
import android.os.Bundle;
import android.service.notification.ZenPolicy;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.widget.FooterPreference;
import java.util.ArrayList;
import java.util.List;
public class ZenCustomRuleCallsSettings extends ZenCustomRuleSettingsBase {
private static final String CALLS_KEY = "zen_mode_calls";
private static final String REPEAT_CALLERS_KEY = "zen_mode_repeat_callers";
private static final String STARRED_CONTACTS_KEY = "zen_mode_starred_contacts_callers";
private static final String PREFERENCE_CATEGORY_KEY = "zen_mode_settings_category_calls";
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
}
@Override
protected int getPreferenceScreenResId() {
return com.android.settings.R.xml.zen_mode_calls_settings;
}
@Override
public int getMetricsCategory() {
return MetricsProto.MetricsEvent.ZEN_CUSTOM_RULE_CALLS;
}
@Override
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
mControllers = new ArrayList<>();
mControllers.add(new ZenRuleCallsPreferenceController(context, CALLS_KEY,
getSettingsLifecycle()));
mControllers.add(new ZenRuleRepeatCallersPreferenceController(context,
REPEAT_CALLERS_KEY, getSettingsLifecycle(), context.getResources()
.getInteger(com.android.internal.R.integer.config_zen_repeat_callers_threshold)));
mControllers.add(new ZenRuleStarredContactsPreferenceController(context,
getSettingsLifecycle(), ZenPolicy.PRIORITY_CATEGORY_CALLS, STARRED_CONTACTS_KEY));
return mControllers;
}
@Override
String getPreferenceCategoryKey() {
return PREFERENCE_CATEGORY_KEY;
}
@Override
public void updatePreferences() {
super.updatePreferences();
PreferenceScreen screen = getPreferenceScreen();
Preference footerPreference = screen.findPreference(FooterPreference.KEY_FOOTER);
footerPreference.setTitle(mContext.getResources().getString(
R.string.zen_mode_custom_calls_footer, mRule.getName()));
}
}

View File

@@ -0,0 +1,160 @@
/*
* Copyright (C) 2018 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;
import android.app.NotificationManager;
import android.content.Context;
import android.os.Bundle;
import android.service.notification.ZenPolicy;
import androidx.preference.Preference;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.core.SubSettingLauncher;
import com.android.settingslib.core.AbstractPreferenceController;
import java.util.ArrayList;
import java.util.List;
public class ZenCustomRuleConfigSettings extends ZenCustomRuleSettingsBase {
private static final String CALLS_KEY = "zen_rule_calls_settings";
private static final String MESSAGES_KEY = "zen_rule_messages_settings";
private static final String ALARMS_KEY = "zen_rule_alarms";
private static final String MEDIA_KEY = "zen_rule_media";
private static final String SYSTEM_KEY = "zen_rule_system";
private static final String REMINDERS_KEY = "zen_rule_reminders";
private static final String EVENTS_KEY = "zen_rule_events";
private static final String NOTIFICATIONS_KEY = "zen_rule_notifications";
private static final String PREFERENCE_CATEGORY_KEY = "zen_custom_rule_configuration_category";
private Preference mCallsPreference;
private Preference mMessagesPreference;
private Preference mNotificationsPreference;
private ZenModeSettings.SummaryBuilder mSummaryBuilder;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
mSummaryBuilder = new ZenModeSettings.SummaryBuilder(mContext);
mCallsPreference = getPreferenceScreen().findPreference(CALLS_KEY);
mCallsPreference.setOnPreferenceClickListener(
new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
new SubSettingLauncher(mContext)
.setDestination(ZenCustomRuleCallsSettings.class.getName())
.setArguments(createZenRuleBundle())
.setSourceMetricsCategory(MetricsEvent.ZEN_CUSTOM_RULE_CALLS)
.launch();
return true;
}
});
mMessagesPreference = getPreferenceScreen().findPreference(MESSAGES_KEY);
mMessagesPreference.setOnPreferenceClickListener(
new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
new SubSettingLauncher(mContext)
.setDestination(ZenCustomRuleMessagesSettings.class.getName())
.setArguments(createZenRuleBundle())
.setSourceMetricsCategory(MetricsEvent.ZEN_CUSTOM_RULE_MESSAGES)
.launch();
return true;
}
});
mNotificationsPreference = getPreferenceScreen().findPreference(NOTIFICATIONS_KEY);
mNotificationsPreference.setOnPreferenceClickListener(
new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
new SubSettingLauncher(mContext)
.setDestination(ZenCustomRuleNotificationsSettings.class.getName())
.setArguments(createZenRuleBundle())
.setSourceMetricsCategory
(MetricsEvent.ZEN_CUSTOM_RULE_NOTIFICATION_RESTRICTIONS)
.launch();
return true;
}
});
updateSummaries();
}
@Override
public void onZenModeConfigChanged() {
super.onZenModeConfigChanged();
updateSummaries();
}
/**
* Updates summaries of preferences without preference controllers
*/
private void updateSummaries() {
NotificationManager.Policy noManPolicy = mBackend.toNotificationPolicy(
mRule.getZenPolicy());
mCallsPreference.setSummary(mSummaryBuilder.getCallsSettingSummary(noManPolicy));
mMessagesPreference.setSummary(mSummaryBuilder.getMessagesSettingSummary(noManPolicy));
mNotificationsPreference.setSummary(mSummaryBuilder.getBlockedEffectsSummary(noManPolicy));
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.zen_mode_custom_rule_configuration;
}
@Override
public int getMetricsCategory() {
return MetricsEvent.ZEN_CUSTOM_RULE_SOUND_SETTINGS;
}
@Override
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
mControllers = new ArrayList<>();
mControllers.add(new ZenRuleCustomSwitchPreferenceController(context,
getSettingsLifecycle(), ALARMS_KEY, ZenPolicy.PRIORITY_CATEGORY_ALARMS,
MetricsEvent.ACTION_ZEN_ALLOW_ALARMS));
mControllers.add(new ZenRuleCustomSwitchPreferenceController(context,
getSettingsLifecycle(), MEDIA_KEY, ZenPolicy.PRIORITY_CATEGORY_MEDIA,
MetricsEvent.ACTION_ZEN_ALLOW_MEDIA));
mControllers.add(new ZenRuleCustomSwitchPreferenceController(context,
getSettingsLifecycle(), SYSTEM_KEY, ZenPolicy.PRIORITY_CATEGORY_SYSTEM,
MetricsEvent.ACTION_ZEN_ALLOW_SYSTEM));
mControllers.add(new ZenRuleCustomSwitchPreferenceController(context,
getSettingsLifecycle(), REMINDERS_KEY, ZenPolicy.PRIORITY_CATEGORY_REMINDERS,
MetricsEvent.ACTION_ZEN_ALLOW_REMINDERS));
mControllers.add(new ZenRuleCustomSwitchPreferenceController(context,
getSettingsLifecycle(), EVENTS_KEY, ZenPolicy.PRIORITY_CATEGORY_EVENTS,
MetricsEvent.ACTION_ZEN_ALLOW_EVENTS));
return mControllers;
}
@Override
String getPreferenceCategoryKey() {
return PREFERENCE_CATEGORY_KEY;
}
@Override
public void onResume() {
super.onResume();
updateSummaries();
}
}

View File

@@ -0,0 +1,72 @@
/*
* Copyright (C) 2018 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;
import android.content.Context;
import android.service.notification.ZenPolicy;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.widget.FooterPreference;
import java.util.ArrayList;
import java.util.List;
public class ZenCustomRuleMessagesSettings extends ZenCustomRuleSettingsBase {
private static final String MESSAGES_KEY = "zen_mode_messages";
private static final String STARRED_CONTACTS_KEY = "zen_mode_starred_contacts_messages";
private static final String PREFERENCE_CATEGORY_KEY = "zen_mode_settings_category_messages";
@Override
protected int getPreferenceScreenResId() {
return com.android.settings.R.xml.zen_mode_messages_settings;
}
@Override
public int getMetricsCategory() {
return MetricsProto.MetricsEvent.ZEN_CUSTOM_RULE_MESSAGES;
}
@Override
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
mControllers = new ArrayList<>();
mControllers.add(new ZenRuleMessagesPreferenceController(context, MESSAGES_KEY,
getSettingsLifecycle()));
mControllers.add(new ZenRuleStarredContactsPreferenceController(context,
getSettingsLifecycle(), ZenPolicy.PRIORITY_CATEGORY_MESSAGES,
STARRED_CONTACTS_KEY));
return mControllers;
}
@Override
String getPreferenceCategoryKey() {
return PREFERENCE_CATEGORY_KEY;
}
@Override
public void updatePreferences() {
super.updatePreferences();
PreferenceScreen screen = getPreferenceScreen();
Preference footerPreference = screen.findPreference(FooterPreference.KEY_FOOTER);
footerPreference.setTitle(mContext.getResources().getString(
R.string.zen_mode_custom_messages_footer, mRule.getName()));
}
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright (C) 2018 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;
import android.content.Context;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.widget.FooterPreference;
import java.util.ArrayList;
import java.util.List;
public class ZenCustomRuleNotificationsSettings extends ZenCustomRuleSettingsBase {
private static final String VIS_EFFECTS_ALL_KEY = "zen_mute_notifications";
private static final String VIS_EFFECTS_NONE_KEY = "zen_hide_notifications";
private static final String VIS_EFFECTS_CUSTOM_KEY = "zen_custom";
private static final String PREFERENCE_CATEGORY_KEY = "restrict_category";
@Override
protected int getPreferenceScreenResId() {
return R.xml.zen_mode_restrict_notifications_settings;
}
@Override
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
mControllers = new ArrayList<>();
mControllers.add(new ZenRuleVisEffectsAllPreferenceController(
context, getSettingsLifecycle(), VIS_EFFECTS_ALL_KEY));
mControllers.add(new ZenRuleVisEffectsNonePreferenceController(
context, getSettingsLifecycle(), VIS_EFFECTS_NONE_KEY));
mControllers.add(new ZenRuleVisEffectsCustomPreferenceController(
context, getSettingsLifecycle(), VIS_EFFECTS_CUSTOM_KEY));
mControllers.add(new ZenRuleNotifFooterPreferenceController(context, getSettingsLifecycle(),
FooterPreference.KEY_FOOTER));
return mControllers;
}
@Override
String getPreferenceCategoryKey() {
return PREFERENCE_CATEGORY_KEY;
}
@Override
public int getMetricsCategory() {
return MetricsProto.MetricsEvent.ZEN_CUSTOM_RULE_NOTIFICATION_RESTRICTIONS;
}
}

View File

@@ -0,0 +1,57 @@
/*
* Copyright (C) 2018 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;
import android.content.Context;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settingslib.core.AbstractPreferenceController;
import java.util.ArrayList;
import java.util.List;
public class ZenCustomRuleSettings extends ZenCustomRuleSettingsBase {
private static final String RULE_DEFAULT_POLICY_KEY = "zen_custom_rule_setting_default";
private static final String CUSTOM_RULE_POLICY_KEY = "zen_custom_rule_setting";
private static final String PREFERENCE_CATEGORY_KEY = "zen_custom_rule_category";
@Override
protected int getPreferenceScreenResId() {
return R.xml.zen_mode_custom_rule_settings;
}
@Override
public int getMetricsCategory() {
return MetricsProto.MetricsEvent.ZEN_CUSTOM_RULE_SETTINGS;
}
@Override
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
mControllers = new ArrayList<>();
mControllers.add(new ZenRuleDefaultPolicyPreferenceController(
context, getSettingsLifecycle(), RULE_DEFAULT_POLICY_KEY));
mControllers.add(new ZenRuleCustomPolicyPreferenceController(
context, getSettingsLifecycle(), CUSTOM_RULE_POLICY_KEY));
return mControllers;
}
@Override
String getPreferenceCategoryKey() {
return PREFERENCE_CATEGORY_KEY;
}
}

View File

@@ -0,0 +1,103 @@
/*
* Copyright (C) 2018 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;
import android.app.AutomaticZenRule;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settingslib.core.AbstractPreferenceController;
import java.util.ArrayList;
import java.util.List;
abstract class ZenCustomRuleSettingsBase extends ZenModeSettingsBase {
static final String TAG = "ZenCustomRuleSettings";
static final String RULE_ID = "RULE_ID";
String mId;
AutomaticZenRule mRule;
List<AbstractPreferenceController> mControllers = new ArrayList<>();
/**
* @return null if no preference category exists
*/
abstract String getPreferenceCategoryKey();
@Override
public void onAttach(Context context) {
super.onAttach(context);
Bundle bundle = getArguments();
if (bundle != null && bundle.containsKey(RULE_ID)) {
mId = bundle.getString(RULE_ID);
mRule = mBackend.getAutomaticZenRule(mId);
} else {
Log.d(TAG, "Rule id required to set custom dnd rule config settings");
this.finish();
}
}
@Override
public void onZenModeConfigChanged() {
super.onZenModeConfigChanged();
updatePreferences();
}
public void updatePreferences() {
mRule = mBackend.getAutomaticZenRule(mId);
final PreferenceScreen screen = getPreferenceScreen();
String categoryKey = getPreferenceCategoryKey();
if (categoryKey != null) {
Preference prefCategory = screen.findPreference(categoryKey);
if (prefCategory != null) {
prefCategory.setTitle(mContext.getResources().getString(
com.android.settings.R.string.zen_mode_custom_behavior_category_title,
mRule.getName()));
}
}
for (AbstractPreferenceController controller : mControllers) {
AbstractZenCustomRulePreferenceController zenRuleController =
(AbstractZenCustomRulePreferenceController) controller;
zenRuleController.onResume(mRule, mId);
zenRuleController.displayPreference(screen);
updatePreference(zenRuleController);
}
}
@Override
public int getHelpResource() {
return R.string.help_uri_interruptions;
}
@Override
public void onResume() {
super.onResume();
updatePreferences();
}
Bundle createZenRuleBundle() {
Bundle bundle = new Bundle();
bundle.putString(RULE_ID, mId);
return bundle;
}
}

View File

@@ -23,15 +23,20 @@ import android.app.ActivityManager;
import android.app.AutomaticZenRule; import android.app.AutomaticZenRule;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.content.Context; import android.content.Context;
import android.database.Cursor;
import android.icu.text.ListFormatter;
import android.net.Uri; import android.net.Uri;
import android.provider.ContactsContract;
import android.provider.Settings; import android.provider.Settings;
import android.service.notification.ZenModeConfig; import android.service.notification.ZenModeConfig;
import android.service.notification.ZenPolicy;
import android.util.Log; import android.util.Log;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import com.android.settings.R; import com.android.settings.R;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
@@ -116,7 +121,7 @@ public class ZenModeBackend {
return (mPolicy.priorityCategories & categoryType) != 0; return (mPolicy.priorityCategories & categoryType) != 0;
} }
protected int getNewPriorityCategories(boolean allow, int categoryType) { protected int getNewDefaultPriorityCategories(boolean allow, int categoryType) {
int priorityCategories = mPolicy.priorityCategories; int priorityCategories = mPolicy.priorityCategories;
if (allow) { if (allow) {
priorityCategories |= categoryType; priorityCategories |= categoryType;
@@ -135,7 +140,8 @@ public class ZenModeBackend {
} }
protected int getPriorityMessageSenders() { protected int getPriorityMessageSenders() {
if (isPriorityCategoryEnabled(NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES)) { if (isPriorityCategoryEnabled(
NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES)) {
return mPolicy.priorityMessageSenders; return mPolicy.priorityMessageSenders;
} }
return SOURCE_NONE; return SOURCE_NONE;
@@ -151,7 +157,7 @@ public class ZenModeBackend {
} }
protected void saveSoundPolicy(int category, boolean allow) { protected void saveSoundPolicy(int category, boolean allow) {
int priorityCategories = getNewPriorityCategories(allow, category); int priorityCategories = getNewDefaultPriorityCategories(allow, category);
savePolicy(priorityCategories, mPolicy.priorityCallSenders, savePolicy(priorityCategories, mPolicy.priorityCallSenders,
mPolicy.priorityMessageSenders, mPolicy.suppressedVisualEffects); mPolicy.priorityMessageSenders, mPolicy.suppressedVisualEffects);
} }
@@ -163,6 +169,7 @@ public class ZenModeBackend {
mNotificationManager.setNotificationPolicy(mPolicy); mNotificationManager.setNotificationPolicy(mPolicy);
} }
private int getNewSuppressedEffects(boolean suppress, int effectType) { private int getNewSuppressedEffects(boolean suppress, int effectType) {
int effects = mPolicy.suppressedVisualEffects; int effects = mPolicy.suppressedVisualEffects;
@@ -202,7 +209,7 @@ public class ZenModeBackend {
priorityMessagesSenders = allowSendersFrom; priorityMessagesSenders = allowSendersFrom;
} }
savePolicy(getNewPriorityCategories(allowSenders, category), savePolicy(getNewDefaultPriorityCategories(allowSenders, category),
priorityCallSenders, priorityMessagesSenders, mPolicy.suppressedVisualEffects); priorityCallSenders, priorityMessagesSenders, mPolicy.suppressedVisualEffects);
if (ZenModeSettingsBase.DEBUG) Log.d(TAG, "onPrefChange allow" + if (ZenModeSettingsBase.DEBUG) Log.d(TAG, "onPrefChange allow" +
@@ -236,6 +243,20 @@ public class ZenModeBackend {
return categorySenders; return categorySenders;
} }
protected static String getKeyFromZenPolicySetting(int contactType) {
switch (contactType) {
case ZenPolicy.PEOPLE_TYPE_ANYONE:
return ZEN_MODE_FROM_ANYONE;
case ZenPolicy.PEOPLE_TYPE_CONTACTS:
return ZEN_MODE_FROM_CONTACTS;
case ZenPolicy.PEOPLE_TYPE_STARRED:
return ZEN_MODE_FROM_STARRED;
case ZenPolicy.PEOPLE_TYPE_NONE:
default:
return ZEN_MODE_FROM_NONE;
}
}
protected static String getKeyFromSetting(int contactType) { protected static String getKeyFromSetting(int contactType) {
switch (contactType) { switch (contactType) {
case NotificationManager.Policy.PRIORITY_SENDERS_ANY: case NotificationManager.Policy.PRIORITY_SENDERS_ANY:
@@ -288,6 +309,50 @@ public class ZenModeBackend {
} }
} }
protected int getContactsCallsSummary(ZenPolicy policy) {
int peopleType = policy.getPriorityCallSenders();
switch (peopleType) {
case ZenPolicy.PEOPLE_TYPE_ANYONE:
return R.string.zen_mode_from_anyone;
case ZenPolicy.PEOPLE_TYPE_CONTACTS:
return R.string.zen_mode_from_contacts;
case ZenPolicy.PEOPLE_TYPE_STARRED:
return R.string.zen_mode_from_starred;
case ZenPolicy.PEOPLE_TYPE_NONE:
default:
return R.string.zen_mode_from_none_calls;
}
}
protected int getContactsMessagesSummary(ZenPolicy policy) {
int peopleType = policy.getPriorityMessageSenders();
switch (peopleType) {
case ZenPolicy.PEOPLE_TYPE_ANYONE:
return R.string.zen_mode_from_anyone;
case ZenPolicy.PEOPLE_TYPE_CONTACTS:
return R.string.zen_mode_from_contacts;
case ZenPolicy.PEOPLE_TYPE_STARRED:
return R.string.zen_mode_from_starred;
case ZenPolicy.PEOPLE_TYPE_NONE:
default:
return R.string.zen_mode_from_none_messages;
}
}
protected static int getZenPolicySettingFromPrefKey(String key) {
switch (key) {
case ZEN_MODE_FROM_ANYONE:
return ZenPolicy.PEOPLE_TYPE_ANYONE;
case ZEN_MODE_FROM_CONTACTS:
return ZenPolicy.PEOPLE_TYPE_CONTACTS;
case ZEN_MODE_FROM_STARRED:
return ZenPolicy.PEOPLE_TYPE_STARRED;
case ZEN_MODE_FROM_NONE:
default:
return ZenPolicy.PEOPLE_TYPE_NONE;
}
}
protected static int getSettingFromPrefKey(String key) { protected static int getSettingFromPrefKey(String key) {
switch (key) { switch (key) {
case ZEN_MODE_FROM_ANYONE: case ZEN_MODE_FROM_ANYONE:
@@ -318,6 +383,40 @@ public class ZenModeBackend {
} }
} }
ZenPolicy setDefaultZenPolicy(ZenPolicy zenPolicy) {
int calls;
if (mPolicy.allowCalls()) {
calls = ZenModeConfig.getZenPolicySenders(mPolicy.allowCallsFrom());
} else {
calls = ZenPolicy.PEOPLE_TYPE_NONE;
}
int messages;
if (mPolicy.allowMessages()) {
messages = ZenModeConfig.getZenPolicySenders(mPolicy.allowMessagesFrom());
} else {
messages = ZenPolicy.PEOPLE_TYPE_NONE;
}
return new ZenPolicy.Builder(zenPolicy)
.allowAlarms(mPolicy.allowAlarms())
.allowCalls(calls)
.allowEvents(mPolicy.allowEvents())
.allowMedia(mPolicy.allowMedia())
.allowMessages(messages)
.allowReminders(mPolicy.allowReminders())
.allowRepeatCallers(mPolicy.allowRepeatCallers())
.allowSystem(mPolicy.allowSystem())
.showFullScreenIntent(mPolicy.showFullScreenIntents())
.showLights(mPolicy.showLights())
.showInAmbientDisplay(mPolicy.showAmbient())
.showInNotificationList(mPolicy.showInNotificationList())
.showBadges(mPolicy.showBadges())
.showPeeking(mPolicy.showPeeking())
.showStatusBarIcons(mPolicy.showStatusBarIcons())
.build();
}
protected Map.Entry<String, AutomaticZenRule>[] getAutomaticZenRules() { protected Map.Entry<String, AutomaticZenRule>[] getAutomaticZenRules() {
Map<String, AutomaticZenRule> ruleMap = Map<String, AutomaticZenRule> ruleMap =
NotificationManager.from(mContext).getAutomaticZenRules(); NotificationManager.from(mContext).getAutomaticZenRules();
@@ -338,6 +437,70 @@ public class ZenModeBackend {
return mDefaultRuleIds; return mDefaultRuleIds;
} }
NotificationManager.Policy toNotificationPolicy(ZenPolicy policy) {
ZenModeConfig config = new ZenModeConfig();
return config.toNotificationPolicy(policy);
}
@VisibleForTesting
List<String> getStarredContacts(Cursor cursor) {
List<String> starredContacts = new ArrayList<>();
if (cursor != null && cursor.moveToFirst()) {
do {
String contact = cursor.getString(0);
if (contact != null) {
starredContacts.add(contact);
}
} while (cursor.moveToNext());
}
return starredContacts;
}
private List<String> getStarredContacts() {
Cursor cursor = null;
try {
cursor = queryData();
return getStarredContacts(cursor);
} finally {
if (cursor != null) {
cursor.close();
}
}
}
public String getStarredContactsSummary() {
List<String> starredContacts = getStarredContacts();
int numStarredContacts = starredContacts.size();
List<String> displayContacts = new ArrayList<>();
if (numStarredContacts == 0) {
displayContacts.add(mContext.getString(R.string.zen_mode_from_none));
} else {
for (int i = 0; i < 2 && i < numStarredContacts; i++) {
displayContacts.add(starredContacts.get(i));
}
if (numStarredContacts == 3) {
displayContacts.add(starredContacts.get(2));
} else if (numStarredContacts > 2) {
displayContacts.add(mContext.getResources().getQuantityString(
R.plurals.zen_mode_starred_contacts_summary_additional_contacts,
numStarredContacts - 2, numStarredContacts - 2));
}
}
// values in displayContacts must not be null
return ListFormatter.getInstance().format(displayContacts);
}
private Cursor queryData() {
return mContext.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,
new String[]{ContactsContract.Contacts.DISPLAY_NAME_PRIMARY},
ContactsContract.Data.STARRED + "=1", null,
ContactsContract.Data.TIMES_CONTACTED);
}
@VisibleForTesting @VisibleForTesting
public static final Comparator<Map.Entry<String, AutomaticZenRule>> RULE_COMPARATOR = public static final Comparator<Map.Entry<String, AutomaticZenRule>> RULE_COMPARATOR =
new Comparator<Map.Entry<String, AutomaticZenRule>>() { new Comparator<Map.Entry<String, AutomaticZenRule>>() {

View File

@@ -30,13 +30,15 @@ import androidx.preference.Preference;
import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceScreen;
import com.android.settings.R; import com.android.settings.R;
import com.android.settingslib.core.AbstractPreferenceController; import com.android.settings.core.SubSettingLauncher;
public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase { public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase {
protected static final String TAG = ZenModeSettingsBase.TAG; protected static final String TAG = ZenModeSettingsBase.TAG;
protected static final boolean DEBUG = ZenModeSettingsBase.DEBUG; protected static final boolean DEBUG = ZenModeSettingsBase.DEBUG;
private final String CUSTOM_BEHAVIOR_KEY = "zen_custom_setting";
protected Context mContext; protected Context mContext;
protected boolean mDisableListeners; protected boolean mDisableListeners;
protected AutomaticZenRule mRule; protected AutomaticZenRule mRule;
@@ -45,6 +47,7 @@ public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase {
protected ZenAutomaticRuleHeaderPreferenceController mHeader; protected ZenAutomaticRuleHeaderPreferenceController mHeader;
protected ZenRuleButtonsPreferenceController mActionButtons; protected ZenRuleButtonsPreferenceController mActionButtons;
protected ZenAutomaticRuleSwitchPreferenceController mSwitch; protected ZenAutomaticRuleSwitchPreferenceController mSwitch;
protected Preference mCustomBehaviorPreference;
abstract protected void onCreateInternal(); abstract protected void onCreateInternal();
abstract protected boolean setRule(AutomaticZenRule rule); abstract protected boolean setRule(AutomaticZenRule rule);
@@ -75,6 +78,21 @@ public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase {
} }
super.onCreate(icicle); super.onCreate(icicle);
mCustomBehaviorPreference = getPreferenceScreen().findPreference(CUSTOM_BEHAVIOR_KEY);
mCustomBehaviorPreference.setOnPreferenceClickListener(
new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
Bundle bundle = new Bundle();
bundle.putString(ZenCustomRuleSettings.RULE_ID, mId);
new SubSettingLauncher(mContext)
.setDestination(ZenCustomRuleSettings.class.getName())
.setArguments(bundle)
.setSourceMetricsCategory(0) // TODO
.launch();
return true;
}
});
onCreateInternal(); onCreateInternal();
} }
@@ -84,7 +102,9 @@ public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase {
if (isUiRestricted()) { if (isUiRestricted()) {
return; return;
} }
updateControls(); if (!refreshRuleOrFinish()) {
updateControls();
}
} }
@Override @Override
@@ -111,22 +131,6 @@ public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase {
updatePreference(mActionButtons); updatePreference(mActionButtons);
} }
private void updatePreference(AbstractPreferenceController controller) {
final PreferenceScreen screen = getPreferenceScreen();
if (!controller.isAvailable()) {
return;
}
final String key = controller.getPreferenceKey();
final Preference preference = screen.findPreference(key);
if (preference == null) {
Log.d(TAG, String.format("Cannot find preference with key %s in Controller %s",
key, controller.getClass().getSimpleName()));
return;
}
controller.updateState(preference);
}
protected void updateRule(Uri newConditionId) { protected void updateRule(Uri newConditionId) {
mRule.setConditionId(newConditionId); mRule.setConditionId(newConditionId);
mBackend.updateZenRule(mId, mRule); mBackend.updateZenRule(mId, mRule);
@@ -165,6 +169,11 @@ public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase {
mDisableListeners = true; mDisableListeners = true;
updateControlsInternal(); updateControlsInternal();
updateHeader(); updateHeader();
if (mRule.getZenPolicy() == null) {
mCustomBehaviorPreference.setSummary(R.string.zen_mode_custom_behavior_summary_default);
} else {
mCustomBehaviorPreference.setSummary(R.string.zen_mode_custom_behavior_summary);
}
mDisableListeners = false; mDisableListeners = false;
} }
} }

View File

@@ -90,7 +90,8 @@ public class ZenModeSettings extends ZenModeSettingsBase {
controllers.add(new ZenModeDurationPreferenceController(context, lifecycle)); controllers.add(new ZenModeDurationPreferenceController(context, lifecycle));
controllers.add(new ZenModeAutomationPreferenceController(context)); controllers.add(new ZenModeAutomationPreferenceController(context));
controllers.add(new ZenModeButtonPreferenceController(context, lifecycle, fragmentManager)); controllers.add(new ZenModeButtonPreferenceController(context, lifecycle, fragmentManager));
controllers.add(new ZenModeSettingsFooterPreferenceController(context, lifecycle)); controllers.add(new ZenModeSettingsFooterPreferenceController(context, lifecycle,
fragmentManager));
return controllers; return controllers;
} }

View File

@@ -26,7 +26,11 @@ import android.provider.Settings;
import android.provider.Settings.Global; import android.provider.Settings.Global;
import android.util.Log; import android.util.Log;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settings.dashboard.RestrictedDashboardFragment; import com.android.settings.dashboard.RestrictedDashboardFragment;
import com.android.settingslib.core.AbstractPreferenceController;
abstract public class ZenModeSettingsBase extends RestrictedDashboardFragment { abstract public class ZenModeSettingsBase extends RestrictedDashboardFragment {
protected static final String TAG = "ZenModeSettings"; protected static final String TAG = "ZenModeSettings";
@@ -121,4 +125,20 @@ abstract public class ZenModeSettingsBase extends RestrictedDashboardFragment {
} }
} }
} }
void updatePreference(AbstractPreferenceController controller) {
final PreferenceScreen screen = getPreferenceScreen();
if (!controller.isAvailable()) {
return;
}
final String key = controller.getPreferenceKey();
final Preference preference = screen.findPreference(key);
if (preference == null) {
Log.d(TAG, String.format("Cannot find preference with key %s in Controller %s",
key, controller.getClass().getSimpleName()));
return;
}
controller.updateState(preference);
}
} }

View File

@@ -16,17 +16,29 @@
package com.android.settings.notification; package com.android.settings.notification;
import android.app.Dialog;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.icu.text.ListFormatter; import android.icu.text.ListFormatter;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings; import android.provider.Settings;
import android.service.notification.ZenModeConfig; import android.service.notification.ZenModeConfig;
import android.util.Log; import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.FragmentManager;
import androidx.preference.Preference; import androidx.preference.Preference;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settings.utils.AnnotationSpan;
import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.Lifecycle;
import java.util.ArrayList; import java.util.ArrayList;
@@ -34,11 +46,13 @@ import java.util.List;
import java.util.Objects; import java.util.Objects;
public class ZenModeSettingsFooterPreferenceController extends AbstractZenModePreferenceController { public class ZenModeSettingsFooterPreferenceController extends AbstractZenModePreferenceController {
static final String KEY = "footer_preference";
private FragmentManager mFragment;
protected static final String KEY = "footer_preference"; public ZenModeSettingsFooterPreferenceController(Context context, Lifecycle lifecycle,
FragmentManager fragment) {
public ZenModeSettingsFooterPreferenceController(Context context, Lifecycle lifecycle) {
super(context, KEY, lifecycle); super(context, KEY, lifecycle);
mFragment = fragment;
} }
@Override @Override
@@ -70,7 +84,7 @@ public class ZenModeSettingsFooterPreferenceController extends AbstractZenModePr
} }
} }
protected String getFooterText() { protected CharSequence getFooterText() {
ZenModeConfig config = getZenModeConfig(); ZenModeConfig config = getZenModeConfig();
NotificationManager.Policy appliedPolicy = mBackend.getConsolidatedPolicy(); NotificationManager.Policy appliedPolicy = mBackend.getConsolidatedPolicy();
@@ -88,15 +102,25 @@ public class ZenModeSettingsFooterPreferenceController extends AbstractZenModePr
if (rulesNames.size() > 0) { if (rulesNames.size() > 0) {
String rules = ListFormatter.getInstance().format(rulesNames); String rules = ListFormatter.getInstance().format(rulesNames);
if (!rules.isEmpty()) { if (!rules.isEmpty()) {
return mContext.getString(R.string.zen_mode_settings_dnd_custom_settings_footer, final AnnotationSpan.LinkInfo linkInfo = new AnnotationSpan.LinkInfo(
rules); AnnotationSpan.LinkInfo.DEFAULT_ANNOTATION, new View.OnClickListener() {
@Override
public void onClick(View v) {
showCustomSettingsDialog();
}
});
return TextUtils.concat(mContext.getResources().getString(
R.string.zen_mode_settings_dnd_custom_settings_footer, rules),
AnnotationSpan.linkify(mContext.getResources().getText(
R.string.zen_mode_settings_dnd_custom_settings_footer_link),
linkInfo));
} }
} }
} }
return getFooterUsingDefaultPolicy(config); return getDefaultPolicyFooter(config);
} }
private String getFooterUsingDefaultPolicy(ZenModeConfig config) { private String getDefaultPolicyFooter(ZenModeConfig config) {
String footerText = ""; String footerText = "";
long latestEndTime = -1; long latestEndTime = -1;
@@ -162,4 +186,101 @@ public class ZenModeSettingsFooterPreferenceController extends AbstractZenModePr
} }
return zenRules; return zenRules;
} }
private void showCustomSettingsDialog() {
ZenCustomSettingsDialog dialog = new ZenCustomSettingsDialog();
dialog.setNotificationPolicy(mBackend.getConsolidatedPolicy());
dialog.show(mFragment, ZenCustomSettingsDialog.class.getName());
}
public static class ZenCustomSettingsDialog extends InstrumentedDialogFragment {
private String KEY_POLICY = "policy";
private NotificationManager.Policy mPolicy;
private ZenModeSettings.SummaryBuilder mSummaryBuilder;
public void setNotificationPolicy(NotificationManager.Policy policy) {
mPolicy = policy;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Context context = getActivity();
if (savedInstanceState != null) {
NotificationManager.Policy policy = savedInstanceState.getParcelable(KEY_POLICY);
if (policy != null) {
mPolicy = policy;
}
}
mSummaryBuilder = new ZenModeSettings.SummaryBuilder(context);
AlertDialog customSettingsDialog = new AlertDialog.Builder(context)
.setTitle(R.string.zen_custom_settings_dialog_title)
.setNeutralButton(R.string.zen_custom_settings_dialog_review_schedule,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
new SubSettingLauncher(context)
.setDestination(
ZenModeAutomationSettings.class.getName())
.setSourceMetricsCategory(
MetricsEvent.NOTIFICATION_ZEN_MODE_AUTOMATION)
.launch();
}
})
.setPositiveButton(R.string.zen_custom_settings_dialog_ok, null)
.setView(LayoutInflater.from(context).inflate(context.getResources().getLayout(
R.layout.zen_custom_settings_dialog), null, false))
.create();
customSettingsDialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
TextView allowCallsText = customSettingsDialog.findViewById(
R.id.zen_custom_settings_dialog_calls_allow);
TextView allowMessagesText = customSettingsDialog.findViewById(
R.id.zen_custom_settings_dialog_messages_allow);
TextView allowAlarmsText = customSettingsDialog.findViewById(
R.id.zen_custom_settings_dialog_alarms_allow);
TextView allowMediaText = customSettingsDialog.findViewById(
R.id.zen_custom_settings_dialog_media_allow);
TextView allowSystemText = customSettingsDialog.findViewById(
R.id.zen_custom_settings_dialog_system_allow);
TextView allowRemindersText = customSettingsDialog.findViewById(
R.id.zen_custom_settings_dialog_reminders_allow);
TextView allowEventsText = customSettingsDialog.findViewById(
R.id.zen_custom_settings_dialog_events_allow);
TextView notificationsText = customSettingsDialog.findViewById(
R.id.zen_custom_settings_dialog_show_notifications);
allowCallsText.setText(mSummaryBuilder.getCallsSettingSummary(mPolicy));
allowMessagesText.setText(mSummaryBuilder.getMessagesSettingSummary(mPolicy));
allowAlarmsText.setText(getAllowRes(mPolicy.allowAlarms()));
allowMediaText.setText(getAllowRes(mPolicy.allowMedia()));
allowSystemText.setText(getAllowRes(mPolicy.allowSystem()));
allowRemindersText.setText(getAllowRes(mPolicy.allowReminders()));
allowEventsText.setText(getAllowRes(mPolicy.allowEvents()));
notificationsText.setText(mSummaryBuilder.getBlockedEffectsSummary(mPolicy));
}
});
return customSettingsDialog;
}
@Override
public int getMetricsCategory() {
return MetricsEvent.ZEN_CUSTOM_SETTINGS_DIALOG;
}
private int getAllowRes(boolean allow) {
return allow ? R.string.zen_mode_sound_summary_on : R.string.zen_mode_sound_summary_off;
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable(KEY_POLICY, mPolicy);
}
}
} }

View File

@@ -23,25 +23,15 @@ import static android.app.NotificationManager.Policy.PRIORITY_SENDERS_STARRED;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.database.Cursor;
import android.icu.text.ListFormatter;
import android.provider.Contacts; import android.provider.Contacts;
import android.provider.ContactsContract;
import com.android.settings.R;
import com.android.settingslib.core.lifecycle.Lifecycle;
import java.util.ArrayList;
import java.util.List;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference; import androidx.preference.Preference;
import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceScreen;
import com.android.settingslib.core.lifecycle.Lifecycle;
public class ZenModeStarredContactsPreferenceController extends public class ZenModeStarredContactsPreferenceController extends
AbstractZenModePreferenceController implements Preference.OnPreferenceClickListener { AbstractZenModePreferenceController implements Preference.OnPreferenceClickListener {
protected static String KEY;
private Preference mPreference; private Preference mPreference;
private final int mPriorityCategory; private final int mPriorityCategory;
private final PackageManager mPackageManager; private final PackageManager mPackageManager;
@@ -52,8 +42,6 @@ public class ZenModeStarredContactsPreferenceController extends
public ZenModeStarredContactsPreferenceController(Context context, Lifecycle lifecycle, int public ZenModeStarredContactsPreferenceController(Context context, Lifecycle lifecycle, int
priorityCategory, String key) { priorityCategory, String key) {
super(context, key, lifecycle); super(context, key, lifecycle);
KEY = key;
mPriorityCategory = priorityCategory; mPriorityCategory = priorityCategory;
mPackageManager = mContext.getPackageManager(); mPackageManager = mContext.getPackageManager();
@@ -96,29 +84,7 @@ public class ZenModeStarredContactsPreferenceController extends
@Override @Override
public CharSequence getSummary() { public CharSequence getSummary() {
List<String> starredContacts = getStarredContacts(); return mBackend.getStarredContactsSummary();
int numStarredContacts = starredContacts.size();
List<String> displayContacts = new ArrayList<>();
if (numStarredContacts == 0) {
displayContacts.add(mContext.getString(R.string.zen_mode_from_none));
} else {
for (int i = 0; i < 2 && i < numStarredContacts; i++) {
displayContacts.add(starredContacts.get(i));
}
if (numStarredContacts == 3) {
displayContacts.add(starredContacts.get(2));
} else if (numStarredContacts > 2) {
displayContacts.add(mContext.getResources().getQuantityString(
R.plurals.zen_mode_starred_contacts_summary_additional_contacts,
numStarredContacts - 2, numStarredContacts - 2));
}
}
// values in displayContacts must not be null
return ListFormatter.getInstance().format(displayContacts);
} }
@Override @Override
@@ -131,39 +97,6 @@ public class ZenModeStarredContactsPreferenceController extends
return true; return true;
} }
@VisibleForTesting
List<String> getStarredContacts(Cursor cursor) {
List<String> starredContacts = new ArrayList<>();
if (cursor.moveToFirst()) {
do {
String contact = cursor.getString(0);
if (contact != null) {
starredContacts.add(contact);
}
} while (cursor.moveToNext());
}
return starredContacts;
}
private List<String> getStarredContacts() {
Cursor cursor = null;
try {
cursor = queryData();
return getStarredContacts(cursor);
} finally {
if (cursor != null) {
cursor.close();
}
}
}
private Cursor queryData() {
return mContext.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,
new String[]{ContactsContract.Contacts.DISPLAY_NAME_PRIMARY},
ContactsContract.Data.STARRED + "=1", null,
ContactsContract.Data.TIMES_CONTACTED);
}
private boolean isIntentValid() { private boolean isIntentValid() {
return mStarredContactsIntent.resolveActivity(mPackageManager) != null return mStarredContactsIntent.resolveActivity(mPackageManager) != null
|| mFallbackIntent.resolveActivity(mPackageManager) != null; || mFallbackIntent.resolveActivity(mPackageManager) != null;

View File

@@ -0,0 +1,86 @@
/*
* Copyright (C) 2018 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;
import android.content.Context;
import android.service.notification.ZenPolicy;
import android.text.TextUtils;
import android.util.Pair;
import androidx.annotation.VisibleForTesting;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settingslib.core.lifecycle.Lifecycle;
public class ZenRuleCallsPreferenceController extends AbstractZenCustomRulePreferenceController
implements Preference.OnPreferenceChangeListener {
private final String[] mListValues;
public ZenRuleCallsPreferenceController(Context context, String key, Lifecycle lifecycle) {
super(context, key, lifecycle);
mListValues = context.getResources().getStringArray(
com.android.settings.R.array.zen_mode_contacts_values);
}
@Override
public void updateState(Preference preference) {
super.updateState(preference);
updateFromContactsValue(preference);
}
@Override
public boolean onPreferenceChange(Preference preference, Object selectedContactsFrom) {
int allowCalls = ZenModeBackend.getZenPolicySettingFromPrefKey(
selectedContactsFrom.toString());
mMetricsFeatureProvider.action(mContext, MetricsProto.MetricsEvent.ACTION_ZEN_ALLOW_CALLS,
Pair.create(MetricsProto.MetricsEvent.FIELD_ZEN_TOGGLE_EXCEPTION, allowCalls),
Pair.create(MetricsProto.MetricsEvent.FIELD_ZEN_RULE_ID, mId));
mRule.setZenPolicy(new ZenPolicy.Builder(mRule.getZenPolicy())
.allowCalls(allowCalls)
.build());
mBackend.updateZenRule(mId, mRule);
updateFromContactsValue(preference);
return true;
}
private void updateFromContactsValue(Preference preference) {
if (mRule == null || mRule.getZenPolicy() == null) {
return;
}
ListPreference listPreference = (ListPreference) preference;
listPreference.setSummary(mBackend.getContactsCallsSummary(mRule.getZenPolicy()));
final String currentVal = ZenModeBackend.getKeyFromZenPolicySetting(
mRule.getZenPolicy().getPriorityCallSenders());
listPreference.setValue(mListValues[getIndexOfSendersValue(currentVal)]);
}
@VisibleForTesting
protected int getIndexOfSendersValue(String currentVal) {
int index = 3; // defaults to "none" based on R.array.zen_mode_contacts_values
for (int i = 0; i < mListValues.length; i++) {
if (TextUtils.equals(currentVal, mListValues[i])) {
return i;
}
}
return index;
}
}

View File

@@ -0,0 +1,81 @@
/*
* Copyright (C) 2018 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;
import android.content.Context;
import android.service.notification.ZenPolicy;
import android.util.Log;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.core.SubSettingLauncher;
import com.android.settingslib.core.lifecycle.Lifecycle;
public class ZenRuleCustomPolicyPreferenceController extends
AbstractZenCustomRulePreferenceController {
private ZenCustomRadioButtonPreference mPreference;
public ZenRuleCustomPolicyPreferenceController(Context context, Lifecycle lifecycle,
String key) {
super(context, key, lifecycle);
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mPreference = (ZenCustomRadioButtonPreference) screen.findPreference(getPreferenceKey());
mPreference.setOnGearClickListener(p -> {
setCustomPolicy();
launchCustomSettings();
});
mPreference.setOnRadioButtonClickListener(p -> {
setCustomPolicy();
launchCustomSettings();
});
}
@Override
public void updateState(Preference preference) {
super.updateState(preference);
if (mId == null || mRule == null) {
return;
}
mPreference.setChecked(mRule.getZenPolicy() != null);
}
private void setCustomPolicy() {
if (mRule.getZenPolicy() == null) {
mRule.setZenPolicy(mBackend.setDefaultZenPolicy(new ZenPolicy()));
mBackend.updateZenRule(mId, mRule);
}
}
private void launchCustomSettings() {
new SubSettingLauncher(mContext)
.setDestination(ZenCustomRuleConfigSettings.class.getName())
.setArguments(createBundle())
.setSourceMetricsCategory(MetricsProto.MetricsEvent.ZEN_CUSTOM_RULE_SOUND_SETTINGS)
.launch();
}
}

View File

@@ -0,0 +1,70 @@
/*
* Copyright (C) 2017 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;
import android.content.Context;
import android.service.notification.ZenPolicy;
import android.util.Log;
import android.util.Pair;
import androidx.preference.Preference;
import androidx.preference.SwitchPreference;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settingslib.core.lifecycle.Lifecycle;
public class ZenRuleCustomSwitchPreferenceController extends
AbstractZenCustomRulePreferenceController implements Preference.OnPreferenceChangeListener {
private @ZenPolicy.PriorityCategory int mCategory;
private int mMetricsCategory;
public ZenRuleCustomSwitchPreferenceController(Context context, Lifecycle lifecycle,
String key, @ZenPolicy.PriorityCategory int category, int metricsCategory) {
super(context, key, lifecycle);
mCategory = category;
mMetricsCategory = metricsCategory;
}
@Override
public void updateState(Preference preference) {
super.updateState(preference);
if (mRule == null || mRule.getZenPolicy() == null) {
return;
}
SwitchPreference pref = (SwitchPreference) preference;
pref.setChecked(mRule.getZenPolicy().isCategoryAllowed(mCategory, false));
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
final boolean allow = (Boolean) newValue;
if (ZenModeSettingsBase.DEBUG) {
Log.d(TAG, KEY + " onPrefChange mRule=" + mRule + " mCategory=" + mCategory
+ " allow=" + allow);
}
mMetricsFeatureProvider.action(mContext, mMetricsCategory,
Pair.create(MetricsProto.MetricsEvent.FIELD_ZEN_TOGGLE_EXCEPTION, allow ? 1 : 0),
Pair.create(MetricsProto.MetricsEvent.FIELD_ZEN_RULE_ID, mId));
mRule.setZenPolicy(new ZenPolicy.Builder(mRule.getZenPolicy())
.allowCategory(mCategory, allow)
.build());
mBackend.updateZenRule(mId, mRule);
return true;
}
}

View File

@@ -0,0 +1,60 @@
/*
* Copyright (C) 2018 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;
import android.content.Context;
import android.util.Pair;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.core.lifecycle.Lifecycle;
public class ZenRuleDefaultPolicyPreferenceController extends
AbstractZenCustomRulePreferenceController implements PreferenceControllerMixin {
private ZenCustomRadioButtonPreference mPreference;
public ZenRuleDefaultPolicyPreferenceController(Context context, Lifecycle lifecycle,
String key) {
super(context, key, lifecycle);
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mPreference = (ZenCustomRadioButtonPreference) screen.findPreference(getPreferenceKey());
mPreference.setOnRadioButtonClickListener(p -> {
mRule.setZenPolicy(null);
mBackend.updateZenRule(mId, mRule);
});
}
@Override
public void updateState(Preference preference) {
super.updateState(preference);
if (mId == null || mRule == null) {
return;
}
mMetricsFeatureProvider.action(mContext, MetricsEvent.ZEN_CUSTOM_RULE_DEFAULT_SETTINGS,
Pair.create(MetricsEvent.FIELD_ZEN_RULE_ID, mId));
mPreference.setChecked(mRule.getZenPolicy() == null);
}
}

View File

@@ -0,0 +1,87 @@
/*
* Copyright (C) 2018 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;
import android.content.Context;
import android.service.notification.ZenPolicy;
import android.text.TextUtils;
import android.util.Pair;
import androidx.annotation.VisibleForTesting;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settingslib.core.lifecycle.Lifecycle;
public class ZenRuleMessagesPreferenceController extends AbstractZenCustomRulePreferenceController
implements Preference.OnPreferenceChangeListener {
private final String[] mListValues;
public ZenRuleMessagesPreferenceController(Context context, String key, Lifecycle lifecycle) {
super(context, key, lifecycle);
mListValues = context.getResources().getStringArray(
com.android.settings.R.array.zen_mode_contacts_values);
}
@Override
public void updateState(Preference preference) {
super.updateState(preference);
updateFromContactsValue(preference);
}
@Override
public boolean onPreferenceChange(Preference preference, Object selectedContactsFrom) {
int allowMessages = ZenModeBackend.getZenPolicySettingFromPrefKey(
selectedContactsFrom.toString());
mMetricsFeatureProvider.action(mContext,
MetricsProto.MetricsEvent.ACTION_ZEN_ALLOW_MESSAGES,
Pair.create(MetricsProto.MetricsEvent.FIELD_ZEN_TOGGLE_EXCEPTION, allowMessages),
Pair.create(MetricsProto.MetricsEvent.FIELD_ZEN_RULE_ID, mId));
mRule.setZenPolicy(new ZenPolicy.Builder(mRule.getZenPolicy())
.allowMessages(allowMessages)
.build());
mBackend.updateZenRule(mId, mRule);
updateFromContactsValue(preference);
return true;
}
private void updateFromContactsValue(Preference preference) {
if (mRule == null || mRule.getZenPolicy() == null) {
return;
}
ListPreference listPreference = (ListPreference) preference;
listPreference.setSummary(mBackend.getContactsMessagesSummary(mRule.getZenPolicy()));
final String currentVal = ZenModeBackend.getKeyFromZenPolicySetting(
mRule.getZenPolicy().getPriorityMessageSenders());
listPreference.setValue(mListValues[getIndexOfSendersValue(currentVal)]);
}
@VisibleForTesting
protected int getIndexOfSendersValue(String currentVal) {
int index = 3; // defaults to "none" based on R.array.zen_mode_contacts_values
for (int i = 0; i < mListValues.length; i++) {
if (TextUtils.equals(currentVal, mListValues[i])) {
return i;
}
}
return index;
}
}

View File

@@ -0,0 +1,60 @@
/*
* Copyright (C) 2018 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;
import android.content.Context;
import androidx.preference.Preference;
import com.android.settings.R;
import com.android.settingslib.core.lifecycle.Lifecycle;
public class ZenRuleNotifFooterPreferenceController extends
AbstractZenCustomRulePreferenceController {
public ZenRuleNotifFooterPreferenceController(Context context, Lifecycle lifecycle,
String key) {
super(context, key, lifecycle);
}
@Override
public boolean isAvailable() {
if (!super.isAvailable() || mRule.getZenPolicy() == null) {
return false;
}
return mRule.getZenPolicy().shouldHideAllVisualEffects()
|| mRule.getZenPolicy().shouldShowAllVisualEffects();
}
@Override
public void updateState(Preference preference) {
super.updateState(preference);
if (mRule == null || mRule.getZenPolicy() == null) {
return;
}
if (mRule.getZenPolicy().shouldShowAllVisualEffects()) {
preference.setTitle(R.string.zen_mode_restrict_notifications_mute_footer);
} else if (mRule.getZenPolicy().shouldHideAllVisualEffects()) {
preference.setTitle(R.string.zen_mode_restrict_notifications_hide_footer);
} else {
preference.setTitle(null);
}
}
}

View File

@@ -0,0 +1,91 @@
/*
* Copyright (C) 2018 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;
import android.content.Context;
import android.service.notification.ZenPolicy;
import android.util.Log;
import android.util.Pair;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settingslib.core.lifecycle.Lifecycle;
public class ZenRuleRepeatCallersPreferenceController extends
AbstractZenCustomRulePreferenceController implements Preference.OnPreferenceChangeListener {
private final int mRepeatCallersThreshold;
public ZenRuleRepeatCallersPreferenceController(Context context,
String key, Lifecycle lifecycle, int repeatCallersThreshold) {
super(context, key, lifecycle);
mRepeatCallersThreshold = repeatCallersThreshold;
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
setRepeatCallerSummary(screen.findPreference(KEY));
}
@Override
public void updateState(Preference preference) {
super.updateState(preference);
if (mRule == null || mRule.getZenPolicy() == null) {
return;
}
SwitchPreference pref = (SwitchPreference) preference;
boolean anyCallersCanBypassDnd = mRule.getZenPolicy().getPriorityCallSenders()
== ZenPolicy.PEOPLE_TYPE_ANYONE;
// if any caller can bypass dnd then repeat callers preference is disabled
if (anyCallersCanBypassDnd) {
pref.setEnabled(false);
pref.setChecked(true);
} else {
pref.setEnabled(true);
pref.setChecked(mRule.getZenPolicy().getPriorityCategoryRepeatCallers()
== ZenPolicy.STATE_ALLOW);
}
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
final boolean allow = (Boolean) newValue;
if (ZenModeSettingsBase.DEBUG) {
Log.d(TAG, KEY + " onPrefChange mRule=" + mRule + " mCategory="
+ ZenPolicy.PRIORITY_CATEGORY_REPEAT_CALLERS + " allow=" + allow);
}
mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_ZEN_ALLOW_REPEAT_CALLS,
Pair.create(MetricsEvent.FIELD_ZEN_TOGGLE_EXCEPTION, allow ? 1 : 0),
Pair.create(MetricsEvent.FIELD_ZEN_RULE_ID, mId));
mRule.setZenPolicy(new ZenPolicy.Builder(mRule.getZenPolicy())
.allowRepeatCallers(allow)
.build());
mBackend.updateZenRule(mId, mRule);
return true;
}
private void setRepeatCallerSummary(Preference preference) {
preference.setSummary(mContext.getString(
com.android.settings.R.string.zen_mode_repeat_callers_summary,
mRepeatCallersThreshold));
}
}

View File

@@ -0,0 +1,103 @@
/*
* Copyright (C) 2018 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;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.provider.Contacts;
import android.service.notification.ZenPolicy;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settingslib.core.lifecycle.Lifecycle;
public class ZenRuleStarredContactsPreferenceController extends
AbstractZenCustomRulePreferenceController implements Preference.OnPreferenceClickListener {
private Preference mPreference;
private final @ZenPolicy.PriorityCategory int mPriorityCategory;
private final PackageManager mPackageManager;
private Intent mStarredContactsIntent;
private Intent mFallbackIntent;
public ZenRuleStarredContactsPreferenceController(Context context, Lifecycle lifecycle,
@ZenPolicy.PriorityCategory int priorityCategory, String key) {
super(context, key, lifecycle);
mPriorityCategory = priorityCategory;
mPackageManager = mContext.getPackageManager();
mStarredContactsIntent = new Intent(Contacts.Intents.UI.LIST_STARRED_ACTION);
mFallbackIntent = new Intent(Intent.ACTION_MAIN);
mFallbackIntent.addCategory(Intent.CATEGORY_APP_CONTACTS);
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mPreference = screen.findPreference(KEY);
if (mPreference != null) {
mPreference.setOnPreferenceClickListener(this);
}
}
@Override
public String getPreferenceKey() {
return KEY;
}
@Override
public boolean isAvailable() {
if (!super.isAvailable() || mRule.getZenPolicy() == null || !isIntentValid()) {
return false;
}
if (mPriorityCategory == ZenPolicy.PRIORITY_CATEGORY_CALLS) {
return mRule.getZenPolicy().getPriorityCallSenders() == ZenPolicy.PEOPLE_TYPE_STARRED;
} else if (mPriorityCategory == ZenPolicy.PRIORITY_CATEGORY_MESSAGES) {
return mRule.getZenPolicy().getPriorityMessageSenders()
== ZenPolicy.PEOPLE_TYPE_STARRED;
} else {
// invalid category
return false;
}
}
@Override
public CharSequence getSummary() {
return mBackend.getStarredContactsSummary();
}
@Override
public boolean onPreferenceClick(Preference preference) {
if (mStarredContactsIntent.resolveActivity(mPackageManager) != null) {
mContext.startActivity(mStarredContactsIntent);
} else {
mContext.startActivity(mFallbackIntent);
}
return true;
}
private boolean isIntentValid() {
return mStarredContactsIntent.resolveActivity(mPackageManager) != null
|| mFallbackIntent.resolveActivity(mPackageManager) != null;
}
}

View File

@@ -0,0 +1,104 @@
/*
* Copyright (C) 2018 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;
import android.content.Context;
import android.service.notification.ZenPolicy;
import android.util.Log;
import android.util.Pair;
import androidx.annotation.VisibleForTesting;
import androidx.preference.CheckBoxPreference;
import androidx.preference.Preference;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.widget.DisabledCheckBoxPreference;
import com.android.settingslib.core.lifecycle.Lifecycle;
public class ZenRuleVisEffectPreferenceController extends AbstractZenCustomRulePreferenceController
implements Preference.OnPreferenceChangeListener {
private final int mMetricsCategory;
@VisibleForTesting protected @ZenPolicy.VisualEffect int mEffect;
// if any of these effects are suppressed, this effect must be too
@VisibleForTesting protected @ZenPolicy.VisualEffect int[] mParentSuppressedEffects;
public ZenRuleVisEffectPreferenceController(Context context, Lifecycle lifecycle, String key,
@ZenPolicy.VisualEffect int visualEffect, int metricsCategory,
@ZenPolicy.VisualEffect int[] parentSuppressedEffects) {
super(context, key, lifecycle);
mEffect = visualEffect;
mMetricsCategory = metricsCategory;
mParentSuppressedEffects = parentSuppressedEffects;
}
@Override
public boolean isAvailable() {
if (!super.isAvailable()) {
return false;
}
if (mEffect == ZenPolicy.VISUAL_EFFECT_LIGHTS) {
return mContext.getResources()
.getBoolean(com.android.internal.R.bool.config_intrusiveNotificationLed);
}
return true;
}
@Override
public void updateState(Preference preference) {
super.updateState(preference);
if (mRule == null || mRule.getZenPolicy() == null) {
return;
}
boolean suppressed = !mRule.getZenPolicy().isVisualEffectAllowed(mEffect, false);
boolean parentSuppressed = false;
if (mParentSuppressedEffects != null) {
for (@ZenPolicy.VisualEffect int parentEffect : mParentSuppressedEffects) {
if (!mRule.getZenPolicy().isVisualEffectAllowed(parentEffect, true)) {
parentSuppressed = true;
}
}
}
if (parentSuppressed) {
((CheckBoxPreference) preference).setChecked(parentSuppressed);
onPreferenceChange(preference, parentSuppressed);
((DisabledCheckBoxPreference) preference).enableCheckbox(false);
} else {
((DisabledCheckBoxPreference) preference).enableCheckbox(true);
((CheckBoxPreference) preference).setChecked(suppressed);
}
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
final boolean suppressEffect = (Boolean) newValue;
mMetricsFeatureProvider.action(mContext, mMetricsCategory,
Pair.create(MetricsProto.MetricsEvent.FIELD_ZEN_TOGGLE_EXCEPTION,
suppressEffect ? 1 : 0),
Pair.create(MetricsProto.MetricsEvent.FIELD_ZEN_RULE_ID, mId));
mRule.setZenPolicy(new ZenPolicy.Builder(mRule.getZenPolicy())
.showVisualEffect(mEffect, !suppressEffect)
.build());
mBackend.updateZenRule(mId, mRule);
return true;
}
}

View File

@@ -0,0 +1,64 @@
/*
* Copyright (C) 2018 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;
import android.content.Context;
import android.service.notification.ZenPolicy;
import android.util.Log;
import android.util.Pair;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.core.lifecycle.Lifecycle;
public class ZenRuleVisEffectsAllPreferenceController extends
AbstractZenCustomRulePreferenceController implements PreferenceControllerMixin {
private ZenCustomRadioButtonPreference mPreference;
public ZenRuleVisEffectsAllPreferenceController(Context context, Lifecycle lifecycle,
String key) {
super(context, key, lifecycle);
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mPreference = (ZenCustomRadioButtonPreference) screen.findPreference(getPreferenceKey());
mPreference.setOnRadioButtonClickListener(p -> {
mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_ZEN_SOUND_ONLY,
Pair.create(MetricsEvent.FIELD_ZEN_RULE_ID, mId));
mRule.setZenPolicy(new ZenPolicy.Builder(mRule.getZenPolicy())
.showAllVisualEffects()
.build());
mBackend.updateZenRule(mId, mRule);
});
}
@Override
public void updateState(Preference preference) {
super.updateState(preference);
if (mId == null || mRule == null || mRule.getZenPolicy() == null) {
return;
}
mPreference.setChecked(mRule.getZenPolicy().shouldShowAllVisualEffects());
}
}

View File

@@ -0,0 +1,75 @@
/*
* Copyright (C) 2018 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;
import android.content.Context;
import android.util.Pair;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.core.SubSettingLauncher;
import com.android.settingslib.core.lifecycle.Lifecycle;
public class ZenRuleVisEffectsCustomPreferenceController extends
AbstractZenCustomRulePreferenceController implements PreferenceControllerMixin {
private ZenCustomRadioButtonPreference mPreference;
public ZenRuleVisEffectsCustomPreferenceController(Context context, Lifecycle lifecycle,
String key) {
super(context, key, lifecycle);
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mPreference = (ZenCustomRadioButtonPreference) screen.findPreference(getPreferenceKey());
mPreference.setOnGearClickListener(p -> {
launchCustomSettings();
});
mPreference.setOnRadioButtonClickListener(p -> {
launchCustomSettings();
});
}
@Override
public void updateState(Preference preference) {
super.updateState(preference);
if (mId == null || mRule == null || mRule.getZenPolicy() == null) {
return;
}
mPreference.setChecked(!mRule.getZenPolicy().shouldHideAllVisualEffects()
&& !mRule.getZenPolicy().shouldShowAllVisualEffects());
}
private void launchCustomSettings() {
mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_ZEN_SHOW_CUSTOM,
Pair.create(MetricsEvent.FIELD_ZEN_RULE_ID, mId));
new SubSettingLauncher(mContext)
.setDestination(ZenCustomRuleBlockedEffectsSettings.class.getName())
.setArguments(createBundle())
.setSourceMetricsCategory(MetricsEvent.ZEN_CUSTOM_RULE_VIS_EFFECTS)
.launch();
}
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright (C) 2018 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;
import android.content.Context;
import android.service.notification.ZenPolicy;
import android.util.Log;
import android.util.Pair;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.core.lifecycle.Lifecycle;
public class ZenRuleVisEffectsNonePreferenceController extends
AbstractZenCustomRulePreferenceController implements PreferenceControllerMixin {
private ZenCustomRadioButtonPreference mPreference;
public ZenRuleVisEffectsNonePreferenceController(Context context, Lifecycle lifecycle,
String key) {
super(context, key, lifecycle);
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mPreference = (ZenCustomRadioButtonPreference) screen.findPreference(getPreferenceKey());
mPreference.setOnRadioButtonClickListener(p -> {
mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_ZEN_SOUND_AND_VIS_EFFECTS,
Pair.create(MetricsEvent.FIELD_ZEN_RULE_ID, mId));
mRule.setZenPolicy(new ZenPolicy.Builder(mRule.getZenPolicy())
.hideAllVisualEffects()
.build());
mBackend.updateZenRule(mId, mRule);
});
}
@Override
public void updateState(Preference preference) {
super.updateState(preference);
if (mId == null || mRule == null || mRule.getZenPolicy() == null) {
return;
}
mPreference.setChecked(mRule.getZenPolicy().shouldHideAllVisualEffects());
}
}

View File

@@ -54,6 +54,12 @@ com.android.settings.notification.NotificationStation
com.android.settings.notification.RedactionInterstitial$RedactionInterstitialFragment com.android.settings.notification.RedactionInterstitial$RedactionInterstitialFragment
com.android.settings.notification.ZenModeEventRuleSettings com.android.settings.notification.ZenModeEventRuleSettings
com.android.settings.notification.ZenModeScheduleRuleSettings com.android.settings.notification.ZenModeScheduleRuleSettings
com.android.settings.notification.ZenCustomRuleNotificationsSettings
com.android.settings.notification.ZenCustomRuleCallsSettings
com.android.settings.notification.ZenCustomRuleConfigSettings
com.android.settings.notification.ZenCustomRuleSettings
com.android.settings.notification.ZenCustomRuleBlockedEffectsSettings
com.android.settings.notification.ZenCustomRuleMessagesSettings
com.android.settings.password.ChooseLockGeneric$ChooseLockGenericFragment com.android.settings.password.ChooseLockGeneric$ChooseLockGenericFragment
com.android.settings.password.SetupChooseLockGeneric$InternalActivity$InternalSetupChooseLockGenericFragment com.android.settings.password.SetupChooseLockGeneric$InternalActivity$InternalSetupChooseLockGenericFragment
com.android.settings.password.SetupChooseLockGeneric$SetupChooseLockGenericFragment com.android.settings.password.SetupChooseLockGeneric$SetupChooseLockGenericFragment

View File

@@ -1,26 +1,58 @@
package com.android.settings.notification; package com.android.settings.notification;
import static com.google.common.truth.Truth.assertThat;
import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertEquals;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import android.app.AutomaticZenRule; import android.app.AutomaticZenRule;
import android.app.NotificationManager;
import android.content.Context;
import android.database.Cursor;
import android.provider.Settings; import android.provider.Settings;
import android.service.notification.ZenModeConfig; import android.service.notification.ZenModeConfig;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.shadows.ShadowApplication;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import org.robolectric.RobolectricTestRunner;
@RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class)
public class ZenModeBackendTest { public class ZenModeBackendTest {
@Mock
private NotificationManager mNotificationManager;
private static final String GENERIC_RULE_NAME = "test"; private static final String GENERIC_RULE_NAME = "test";
private static final String DEFAULT_ID_1 = ZenModeConfig.EVENTS_DEFAULT_RULE_ID; private static final String DEFAULT_ID_1 = ZenModeConfig.EVENTS_DEFAULT_RULE_ID;
private static final String DEFAULT_ID_2 = ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID; private static final String DEFAULT_ID_2 = ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID;
private Context mContext;
private ZenModeBackend mBackend;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
ShadowApplication shadowApplication = ShadowApplication.getInstance();
shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
mContext = RuntimeEnvironment.application;
mBackend = new ZenModeBackend(mContext);
}
@Test @Test
public void updateState_checkRuleOrderingDescending() { public void updateState_checkRuleOrderingDescending() {
final int NUM_RULES = 4; final int NUM_RULES = 4;
@@ -63,6 +95,39 @@ public class ZenModeBackendTest {
} }
} }
@Test
public void updateSummary_nullCursorValues() {
Cursor testCursorWithNullValues = createMockCursor(3);
when(testCursorWithNullValues.getString(0)).thenReturn(null);
// expected - no null values
List<String> contacts = mBackend.getStarredContacts(testCursorWithNullValues);
for (String contact : contacts) {
assertThat(contact).isNotNull();
}
}
private Cursor createMockCursor(int size) {
Cursor mockCursor = mock(Cursor.class);
when(mockCursor.moveToFirst()).thenReturn(true);
doAnswer(new Answer<Boolean>() {
int count = 0;
@Override
public Boolean answer(InvocationOnMock invocation) throws Throwable {
if (count < size) {
count++;
return true;
}
return false;
}
}).when(mockCursor).moveToNext();
return mockCursor;
}
private Map.Entry<String, AutomaticZenRule>[] populateAutoZenRulesAscendingCreationTime( private Map.Entry<String, AutomaticZenRule>[] populateAutoZenRulesAscendingCreationTime(
int numRules, boolean addDefaultRules) { int numRules, boolean addDefaultRules) {
Map<String, AutomaticZenRule> ruleMap = new HashMap<>(); Map<String, AutomaticZenRule> ruleMap = new HashMap<>();

View File

@@ -17,12 +17,16 @@
package com.android.settings.notification; package com.android.settings.notification;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.content.Context; import android.content.Context;
import androidx.preference.Preference;
import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before; import org.junit.Before;
@@ -67,11 +71,10 @@ public final class ZenModeMessagesPreferenceControllerTest {
assertTrue(mController.isAvailable()); assertTrue(mController.isAvailable());
} }
// TODO: (b/111475013 - beverlyt) set messages summary @Test
// @Test public void testHasSummary() {
// public void testHasSummary() { Preference pref = mock(Preference.class);
// Preference pref = mock(Preference.class); mController.updateState(pref);
// mController.updateState(pref); verify(pref).setSummary(any());
// verify(pref).setSummary(any()); }
// }
} }

View File

@@ -22,9 +22,8 @@ import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
import static android.provider.Settings.Global.ZEN_MODE_NO_INTERRUPTIONS; import static android.provider.Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
import static android.provider.Settings.Global.ZEN_MODE_OFF; import static android.provider.Settings.Global.ZEN_MODE_OFF;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy; import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
@@ -40,6 +39,7 @@ import android.service.notification.ZenModeConfig;
import android.service.notification.ZenModeConfig.ZenRule; import android.service.notification.ZenModeConfig.ZenRule;
import android.util.ArrayMap; import android.util.ArrayMap;
import androidx.fragment.app.FragmentManager;
import androidx.preference.Preference; import androidx.preference.Preference;
import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceScreen;
@@ -92,8 +92,8 @@ public class ZenModeSettingsFooterPreferenceControllerTest {
mContentResolver = RuntimeEnvironment.application.getContentResolver(); mContentResolver = RuntimeEnvironment.application.getContentResolver();
when(mNotificationManager.getZenModeConfig()).thenReturn(mZenModeConfig); when(mNotificationManager.getZenModeConfig()).thenReturn(mZenModeConfig);
mController = mController = new ZenModeSettingsFooterPreferenceController(mContext, mock(Lifecycle.class),
new ZenModeSettingsFooterPreferenceController(mContext, mock(Lifecycle.class)); mock(FragmentManager.class));
ReflectionHelpers.setField(mZenModeConfig, AUTOMATIC_RULES_FIELD, mInjectedAutomaticRules); ReflectionHelpers.setField(mZenModeConfig, AUTOMATIC_RULES_FIELD, mInjectedAutomaticRules);
ReflectionHelpers.setField(mController, "mZenModeConfigWrapper", mConfigWrapper); ReflectionHelpers.setField(mController, "mZenModeConfigWrapper", mConfigWrapper);

View File

@@ -30,7 +30,6 @@ import android.app.NotificationManager;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.database.Cursor;
import androidx.preference.Preference; import androidx.preference.Preference;
import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceScreen;
@@ -49,7 +48,6 @@ import org.robolectric.RuntimeEnvironment;
import org.robolectric.shadows.ShadowApplication; import org.robolectric.shadows.ShadowApplication;
import org.robolectric.util.ReflectionHelpers; import org.robolectric.util.ReflectionHelpers;
import java.util.List;
@RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class)
public class ZenModeStarredContactsPreferenceControllerTest { public class ZenModeStarredContactsPreferenceControllerTest {
@@ -156,18 +154,6 @@ public class ZenModeStarredContactsPreferenceControllerTest {
assertThat(mMessagesController.isAvailable()).isTrue(); assertThat(mMessagesController.isAvailable()).isTrue();
} }
@Test
public void updateSummary_nullCursorValues() {
Cursor testCursorWithNullValues = createMockCursor(3);
when(testCursorWithNullValues.getString(0)).thenReturn(null);
// expected - no null values
List<String> contacts = mMessagesController.getStarredContacts(testCursorWithNullValues);
for (String contact : contacts) {
assertThat(contact).isNotNull();
}
}
@Test @Test
public void nullPreference_displayPreference() { public void nullPreference_displayPreference() {
when(mPreferenceScreen.findPreference(mMessagesController.getPreferenceKey())) when(mPreferenceScreen.findPreference(mMessagesController.getPreferenceKey()))
@@ -176,25 +162,4 @@ public class ZenModeStarredContactsPreferenceControllerTest {
// should not throw a null pointer // should not throw a null pointer
mMessagesController.displayPreference(mPreferenceScreen); mMessagesController.displayPreference(mPreferenceScreen);
} }
private Cursor createMockCursor(int size) {
Cursor mockCursor = mock(Cursor.class);
when(mockCursor.moveToFirst()).thenReturn(true);
doAnswer(new Answer<Boolean>() {
int count = 0;
@Override
public Boolean answer(InvocationOnMock invocation) {
if (count < size) {
count++;
return true;
}
return false;
}
}).when(mockCursor).moveToNext();
return mockCursor;
}
} }

View File

@@ -0,0 +1,90 @@
/*
* Copyright (C) 2018 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;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.NotificationManager;
import android.content.Context;
import android.service.notification.ZenPolicy;
import androidx.preference.PreferenceScreen;
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.shadows.ShadowApplication;
import org.robolectric.util.ReflectionHelpers;
@RunWith(RobolectricTestRunner.class)
public class ZenRuleCustomPolicyPreferenceControllerTest extends
ZenRuleCustomPrefContrTestBase {
@Mock
private ZenModeBackend mBackend;
@Mock
private NotificationManager mNotificationManager;
@Mock
private ZenCustomRadioButtonPreference mockPref;
@Mock
private PreferenceScreen mScreen;
private Context mContext;
private ZenRuleCustomPolicyPreferenceController mController;
@Override
AbstractZenCustomRulePreferenceController getController() {
return mController;
}
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
ShadowApplication shadowApplication = ShadowApplication.getInstance();
shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
mContext = RuntimeEnvironment.application;
mController = new ZenRuleCustomPolicyPreferenceController(mContext, mock(Lifecycle.class),
PREF_KEY);
ReflectionHelpers.setField(mController, "mBackend", mBackend);
when(mBackend.getAutomaticZenRule(RULE_ID)).thenReturn(mRule);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mockPref);
mController.displayPreference(mScreen);
}
@Test
public void updateState_nullZenPolicy() {
updateControllerZenPolicy(null);
mController.updateState(mockPref);
verify(mockPref).setChecked(false);
}
@Test
public void updateState_hasZenPolicy() {
updateControllerZenPolicy(new ZenPolicy.Builder().build());
mController.updateState(mockPref);
verify(mockPref).setChecked(true);
}
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright (C) 2018 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;
import android.app.AutomaticZenRule;
import android.app.NotificationManager;
import android.service.notification.ZenPolicy;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
@RunWith(RobolectricTestRunner.class)
abstract class ZenRuleCustomPrefContrTestBase {
public static final String RULE_ID = "test_rule_id";
public static final String PREF_KEY = "main_pref";
AutomaticZenRule mRule = new AutomaticZenRule("test", null, null, null, null,
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
abstract AbstractZenCustomRulePreferenceController getController();
void updateControllerZenPolicy(ZenPolicy policy) {
mRule.setZenPolicy(policy);
getController().onResume(mRule, RULE_ID);
}
}

View File

@@ -0,0 +1,108 @@
/*
* Copyright (C) 2018 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;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.NotificationManager;
import android.content.Context;
import android.service.notification.ZenPolicy;
import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.shadows.ShadowApplication;
import org.robolectric.util.ReflectionHelpers;
@RunWith(RobolectricTestRunner.class)
public class ZenRuleCustomSwitchPreferenceControllerTest extends ZenRuleCustomPrefContrTestBase {
private ZenRuleCustomSwitchPreferenceController mController;
@Mock
private ZenModeBackend mBackend;
@Mock
private NotificationManager mNotificationManager;
@Mock
private SwitchPreference mockPref;
@Mock
private NotificationManager.Policy mPolicy;
@Mock
private PreferenceScreen mPreferenceScreen;
private Context mContext;
@Override
AbstractZenCustomRulePreferenceController getController() {
return mController;
}
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
ShadowApplication shadowApplication = ShadowApplication.getInstance();
shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
mContext = RuntimeEnvironment.application;
when(mNotificationManager.getNotificationPolicy()).thenReturn(mPolicy);
mController = new ZenRuleCustomSwitchPreferenceController(mContext, mock(Lifecycle.class),
PREF_KEY, ZenPolicy.PRIORITY_CATEGORY_ALARMS, 0);
ReflectionHelpers.setField(mController, "mBackend", mBackend);
when(mPreferenceScreen.findPreference(mController.getPreferenceKey()))
.thenReturn(mockPref);
mController.displayPreference(mPreferenceScreen);
}
@Test
public void onPreferenceChanged_enable() {
updateControllerZenPolicy(new ZenPolicy.Builder()
.allowMedia(false)
.allowAlarms(false)
.build());
mController.onPreferenceChange(mockPref, true);
mRule.setZenPolicy(new ZenPolicy.Builder()
.allowMedia(false)
.allowAlarms(true)
.build());
verify(mBackend).updateZenRule(RULE_ID, mRule);
}
@Test
public void onPreferenceChanged_disable() {
updateControllerZenPolicy(new ZenPolicy.Builder()
.allowMedia(false)
.allowAlarms(true)
.build());
mController.onPreferenceChange(mockPref, false);
mRule.setZenPolicy(new ZenPolicy.Builder()
.allowMedia(false)
.allowAlarms(false)
.build());
verify(mBackend).updateZenRule(RULE_ID, mRule);
}
}

View File

@@ -0,0 +1,90 @@
/*
* Copyright (C) 2018 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;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.NotificationManager;
import android.content.Context;
import android.service.notification.ZenPolicy;
import androidx.preference.PreferenceScreen;
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.shadows.ShadowApplication;
import org.robolectric.util.ReflectionHelpers;
@RunWith(RobolectricTestRunner.class)
public class ZenRuleDefaultPolicyPreferenceControllerTest extends
ZenRuleCustomPrefContrTestBase {
@Mock
private ZenModeBackend mBackend;
@Mock
private NotificationManager mNotificationManager;
@Mock
private ZenCustomRadioButtonPreference mockPref;
@Mock
private PreferenceScreen mScreen;
private Context mContext;
private ZenRuleDefaultPolicyPreferenceController mController;
@Override
AbstractZenCustomRulePreferenceController getController() {
return mController;
}
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
ShadowApplication shadowApplication = ShadowApplication.getInstance();
shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
mContext = RuntimeEnvironment.application;
mController = new ZenRuleDefaultPolicyPreferenceController(mContext, mock(Lifecycle.class),
PREF_KEY);
ReflectionHelpers.setField(mController, "mBackend", mBackend);
when(mBackend.getAutomaticZenRule(RULE_ID)).thenReturn(mRule);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mockPref);
mController.displayPreference(mScreen);
}
@Test
public void updateState_nullZenPolicy() {
updateControllerZenPolicy(null);
mController.updateState(mockPref);
verify(mockPref).setChecked(true);
}
@Test
public void updateState_hasZenPolicy() {
updateControllerZenPolicy(new ZenPolicy.Builder().build());
mController.updateState(mockPref);
verify(mockPref).setChecked(false);
}
}

View File

@@ -0,0 +1,92 @@
/*
* Copyright (C) 2018 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;
import static junit.framework.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import android.app.AutomaticZenRule;
import android.app.NotificationManager;
import android.content.Context;
import androidx.preference.PreferenceScreen;
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.shadows.ShadowApplication;
import org.robolectric.util.ReflectionHelpers;
@RunWith(RobolectricTestRunner.class)
public class ZenRulePreferenceControllerTest {
@Mock
private ZenModeBackend mBackend;
@Mock
private NotificationManager mNotificationManager;
@Mock
private ZenCustomRadioButtonPreference mockPref;
@Mock
private PreferenceScreen mScreen;
private Context mContext;
private TestablePreferenceController mController;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
ShadowApplication shadowApplication = ShadowApplication.getInstance();
shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
mContext = RuntimeEnvironment.application;
mController = new TestablePreferenceController(mContext,"test", mock(Lifecycle.class));
ReflectionHelpers.setField(mController, "mBackend", mBackend);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mockPref);
mController.displayPreference(mScreen);
}
@Test
public void onResumeTest() {
final String id = "testid";
final AutomaticZenRule rule = new AutomaticZenRule("test", null, null,
null, null, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
assertTrue(mController.mRule == null);
assertTrue(mController.mId == null);
mController.onResume(rule, id);
assertEquals(mController.mId, id);
assertEquals(mController.mRule, rule);
}
class TestablePreferenceController extends AbstractZenCustomRulePreferenceController {
TestablePreferenceController(Context context, String key,
Lifecycle lifecycle) {
super(context, key, lifecycle);
}
}
}

View File

@@ -0,0 +1,123 @@
/*
* Copyright (C) 2018 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;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.NotificationManager;
import android.content.Context;
import android.service.notification.ZenPolicy;
import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.shadows.ShadowApplication;
import org.robolectric.util.ReflectionHelpers;
@RunWith(RobolectricTestRunner.class)
public class ZenRuleRepeatCallersPreferenceControllerTest extends ZenRuleCustomPrefContrTestBase {
private ZenRuleRepeatCallersPreferenceController mController;
@Mock
private ZenModeBackend mBackend;
@Mock
private NotificationManager mNotificationManager;
@Mock
private SwitchPreference mockPref;
@Mock
private NotificationManager.Policy mPolicy;
@Mock
private PreferenceScreen mPreferenceScreen;
private Context mContext;
@Override
AbstractZenCustomRulePreferenceController getController() {
return mController;
}
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
ShadowApplication shadowApplication = ShadowApplication.getInstance();
shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
mContext = RuntimeEnvironment.application;
when(mNotificationManager.getNotificationPolicy()).thenReturn(mPolicy);
mController = new ZenRuleRepeatCallersPreferenceController(mContext, PREF_KEY,
mock(Lifecycle.class), 15);
ReflectionHelpers.setField(mController, "mBackend", mBackend);
when(mBackend.getAutomaticZenRule(anyString())).thenReturn(mRule);
when(mPreferenceScreen.findPreference(mController.getPreferenceKey())).thenReturn(
mockPref);
mController.displayPreference(mPreferenceScreen);
}
@Test
public void updateState_Priority_anyCallers() {
updateControllerZenPolicy(new ZenPolicy.Builder()
.allowCalls(ZenPolicy.PEOPLE_TYPE_ANYONE)
.allowRepeatCallers(false)
.build());
mController.updateState(mockPref);
verify(mockPref).setEnabled(false);
verify(mockPref).setChecked(true);
}
@Test
public void onPreferenceChanged_EnableRepeatCallers() {
updateControllerZenPolicy(new ZenPolicy.Builder()
.allowCalls(ZenPolicy.PEOPLE_TYPE_CONTACTS)
.allowRepeatCallers(false)
.build());
mController.updateState(mockPref);
mController.onPreferenceChange(mockPref, true);
mRule.setZenPolicy(new ZenPolicy.Builder()
.allowCalls(ZenPolicy.PEOPLE_TYPE_CONTACTS)
.allowRepeatCallers(true)
.build());
verify(mBackend).updateZenRule(RULE_ID, mRule);
}
@Test
public void onPreferenceChanged_DisableRepeatCallers() {
updateControllerZenPolicy(new ZenPolicy.Builder()
.allowCalls(ZenPolicy.PEOPLE_TYPE_CONTACTS)
.allowRepeatCallers(true)
.build());
mController.updateState(mockPref);
mController.onPreferenceChange(mockPref, false);
mRule.setZenPolicy(new ZenPolicy.Builder()
.allowCalls(ZenPolicy.PEOPLE_TYPE_CONTACTS)
.allowRepeatCallers(false)
.build());
verify(mBackend).updateZenRule(RULE_ID, mRule);
}
}

View File

@@ -0,0 +1,171 @@
/*
* Copyright (C) 2018 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;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import android.app.NotificationManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.service.notification.ZenPolicy;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.shadows.ShadowApplication;
import org.robolectric.util.ReflectionHelpers;
@RunWith(RobolectricTestRunner.class)
public class ZenRuleStarredContactsPreferenceControllerTest extends ZenRuleCustomPrefContrTestBase {
private ZenRuleStarredContactsPreferenceController mCallsController;
private ZenRuleStarredContactsPreferenceController mMessagesController;
private static int CURR_CONTROLLER = ZenPolicy.PRIORITY_CATEGORY_CALLS;
@Mock
private ZenModeBackend mBackend;
@Mock
private NotificationManager mNotificationManager;
@Mock
private Preference mockPref;
@Mock
private PreferenceScreen mPreferenceScreen;
@Mock
private Intent testIntent;
@Mock
private ComponentName mComponentName;
private Context mContext;
@Override
AbstractZenCustomRulePreferenceController getController() {
if (CURR_CONTROLLER == ZenPolicy.PRIORITY_CATEGORY_MESSAGES) {
return mMessagesController;
} else {
return mCallsController;
}
}
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
ShadowApplication shadowApplication = ShadowApplication.getInstance();
shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
mContext = RuntimeEnvironment.application;
when(testIntent.resolveActivity(any())).thenReturn(mComponentName);
mCallsController = new ZenRuleStarredContactsPreferenceController(
mContext, mock(Lifecycle.class), ZenPolicy.PRIORITY_CATEGORY_CALLS,
"zen_mode_starred_contacts_callers");
when(mBackend.getAutomaticZenRule(RULE_ID)).thenReturn(mRule);
ReflectionHelpers.setField(mCallsController, "mBackend", mBackend);
ReflectionHelpers.setField(mCallsController, "mStarredContactsIntent", testIntent);
when(mPreferenceScreen.findPreference(mCallsController.getPreferenceKey()))
.thenReturn(mockPref);
mCallsController.displayPreference(mPreferenceScreen);
mMessagesController = new ZenRuleStarredContactsPreferenceController(
mContext, mock(Lifecycle.class), ZenPolicy.PRIORITY_CATEGORY_MESSAGES,
"zen_mode_starred_contacts_messages");
ReflectionHelpers.setField(mMessagesController, "mBackend", mBackend);
ReflectionHelpers.setField(mMessagesController, "mStarredContactsIntent", testIntent);
when(mPreferenceScreen.findPreference(mMessagesController.getPreferenceKey()))
.thenReturn(mockPref);
mMessagesController.displayPreference(mPreferenceScreen);
}
@Test
public void isAvailable_noCallers() {
CURR_CONTROLLER = ZenPolicy.PRIORITY_CATEGORY_CALLS;
updateControllerZenPolicy(new ZenPolicy.Builder()
.allowCalls(ZenPolicy.PEOPLE_TYPE_NONE)
.build());
assertThat(mCallsController.isAvailable()).isFalse();
}
@Test
public void isAvailable_anyCallers() {
CURR_CONTROLLER = ZenPolicy.PRIORITY_CATEGORY_CALLS;
updateControllerZenPolicy(new ZenPolicy.Builder()
.allowCalls(ZenPolicy.PEOPLE_TYPE_ANYONE)
.build());
assertThat(mCallsController.isAvailable()).isFalse();
}
@Test
public void isAvailable_starredCallers() {
CURR_CONTROLLER = ZenPolicy.PRIORITY_CATEGORY_CALLS;
updateControllerZenPolicy(new ZenPolicy.Builder()
.allowCalls(ZenPolicy.PEOPLE_TYPE_STARRED)
.build());
assertThat(mCallsController.isAvailable()).isTrue();
}
@Test
public void isAvailable_noMessages() {
CURR_CONTROLLER = ZenPolicy.PRIORITY_CATEGORY_MESSAGES;
updateControllerZenPolicy(new ZenPolicy.Builder()
.allowMessages(ZenPolicy.PEOPLE_TYPE_NONE)
.build());
assertThat(mCallsController.isAvailable()).isFalse();
}
@Test
public void isAvailable_anyMessages() {
CURR_CONTROLLER = ZenPolicy.PRIORITY_CATEGORY_MESSAGES;
updateControllerZenPolicy(new ZenPolicy.Builder()
.allowMessages(ZenPolicy.PEOPLE_TYPE_ANYONE)
.build());
assertThat(mMessagesController.isAvailable()).isFalse();
}
@Test
public void isAvailable_starredMessageContacts() {
CURR_CONTROLLER = ZenPolicy.PRIORITY_CATEGORY_MESSAGES;
updateControllerZenPolicy(new ZenPolicy.Builder()
.allowMessages(ZenPolicy.PEOPLE_TYPE_STARRED)
.build());
assertThat(mMessagesController.isAvailable()).isTrue();
}
@Test
public void nullPreference_displayPreference() {
when(mPreferenceScreen.findPreference(mMessagesController.getPreferenceKey()))
.thenReturn(null);
// should not throw a null pointer
mMessagesController.displayPreference(mPreferenceScreen);
}
}

View File

@@ -0,0 +1,187 @@
/*
* Copyright (C) 2018 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;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.NotificationManager;
import android.content.Context;
import android.content.res.Resources;
import android.service.notification.ZenPolicy;
import androidx.preference.PreferenceScreen;
import com.android.settings.widget.DisabledCheckBoxPreference;
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.shadows.ShadowApplication;
import org.robolectric.util.ReflectionHelpers;
@RunWith(RobolectricTestRunner.class)
public class ZenRuleVisEffectPreferenceControllerTest extends ZenRuleCustomPrefContrTestBase {
private static final @ZenPolicy.VisualEffect int EFFECT_PEEK = ZenPolicy.VISUAL_EFFECT_PEEK;
private static final @ZenPolicy.VisualEffect int PARENT_EFFECT1 = ZenPolicy.VISUAL_EFFECT_BADGE;
private static final @ZenPolicy.VisualEffect int PARENT_EFFECT2 =
ZenPolicy.VISUAL_EFFECT_NOTIFICATION_LIST;
private static final int PREF_METRICS = 1;
@Mock
private ZenModeBackend mBackend;
@Mock
private DisabledCheckBoxPreference mockPref;
@Mock
private PreferenceScreen mScreen;
@Mock
NotificationManager mNotificationManager;
private Context mContext;
private ZenRuleVisEffectPreferenceController mController;
@Override
AbstractZenCustomRulePreferenceController getController() {
return mController;
}
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
ShadowApplication shadowApplication = ShadowApplication.getInstance();
shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
when(mNotificationManager.getNotificationPolicy()).thenReturn(
mock(NotificationManager.Policy.class));
mContext = RuntimeEnvironment.application;
mController = new ZenRuleVisEffectPreferenceController(mContext, mock(Lifecycle.class),
PREF_KEY, EFFECT_PEEK, PREF_METRICS, null);
ReflectionHelpers.setField(mController, "mBackend", mBackend);
when(mBackend.getAutomaticZenRule(RULE_ID)).thenReturn(mRule);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mockPref);
mController.displayPreference(mScreen);
}
@Test
public void isAvailable() {
// VISUAL_EFFECT_PEEK isn't available until after onResume is called
assertFalse(mController.isAvailable());
updateControllerZenPolicy(new ZenPolicy()); // calls onResume
assertTrue(mController.isAvailable());
// VISUAL_EFFECT_LIGHTS is only available if the device has an LED:
Context mockContext = mock(Context.class);
mController = new ZenRuleVisEffectPreferenceController(mockContext, mock(Lifecycle.class),
PREF_KEY, ZenPolicy.VISUAL_EFFECT_LIGHTS, PREF_METRICS, null);
updateControllerZenPolicy(new ZenPolicy()); // calls onResume
Resources mockResources = mock(Resources.class);
when(mockContext.getResources()).thenReturn(mockResources);
when(mockResources.getBoolean(com.android.internal.R.bool.config_intrusiveNotificationLed))
.thenReturn(false); // no light
assertFalse(mController.isAvailable());
when(mockResources.getBoolean(com.android.internal.R.bool.config_intrusiveNotificationLed))
.thenReturn(true); // has light
assertTrue(mController.isAvailable());
}
@Test
public void updateState_notChecked() {
updateControllerZenPolicy(new ZenPolicy.Builder()
.showPeeking(true)
.build());
mController.updateState(mockPref);
verify(mockPref).setChecked(false);
verify(mockPref).enableCheckbox(true);
}
@Test
public void updateState_checked() {
updateControllerZenPolicy(new ZenPolicy.Builder()
.showPeeking(false)
.build());
mController.updateState(mockPref);
verify(mockPref).setChecked(true);
verify(mockPref).enableCheckbox(true);
}
@Test
public void updateState_checkedFalse_parentChecked() {
mController.mParentSuppressedEffects = new int[]{PARENT_EFFECT1, PARENT_EFFECT2};
updateControllerZenPolicy(new ZenPolicy.Builder()
.showVisualEffect(EFFECT_PEEK, true)
.showVisualEffect(PARENT_EFFECT1, true)
.showVisualEffect(PARENT_EFFECT2, false)
.build());
mController.updateState(mockPref);
verify(mockPref).setChecked(true);
verify(mockPref).enableCheckbox(false);
}
@Test
public void updateState_checkedFalse_parentNotChecked() {
mController.mParentSuppressedEffects = new int[]{PARENT_EFFECT1, PARENT_EFFECT2};
updateControllerZenPolicy(new ZenPolicy.Builder()
.showVisualEffect(EFFECT_PEEK, true)
.showVisualEffect(PARENT_EFFECT1, true)
.showVisualEffect(PARENT_EFFECT2, true)
.build());
mController.updateState(mockPref);
verify(mockPref).setChecked(false);
verify(mockPref).enableCheckbox(true);
}
@Test
public void onPreferenceChanged_checkedFalse() {
updateControllerZenPolicy(new ZenPolicy.Builder()
.showPeeking(false)
.build());
mController.onPreferenceChange(mockPref, false);
mRule.setZenPolicy(new ZenPolicy.Builder(mRule.getZenPolicy())
.showPeeking(true)
.build());
verify(mBackend).updateZenRule(RULE_ID, mRule);
}
@Test
public void onPreferenceChanged_checkedTrue() {
updateControllerZenPolicy(new ZenPolicy.Builder()
.showPeeking(true)
.build());
mController.onPreferenceChange(mockPref, true);
mRule.setZenPolicy(new ZenPolicy.Builder(mRule.getZenPolicy())
.showPeeking(false)
.build());
verify(mBackend).updateZenRule(RULE_ID, mRule);
}
}

View File

@@ -0,0 +1,104 @@
/*
* Copyright (C) 2018 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;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.NotificationManager;
import android.content.Context;
import android.service.notification.ZenPolicy;
import androidx.preference.PreferenceScreen;
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.shadows.ShadowApplication;
import org.robolectric.util.ReflectionHelpers;
@RunWith(RobolectricTestRunner.class)
public class ZenRuleVisEffectsAllPreferenceControllerTest extends
ZenRuleCustomPrefContrTestBase {
@Mock
private ZenModeBackend mBackend;
@Mock
private NotificationManager mNotificationManager;
@Mock
private ZenCustomRadioButtonPreference mockPref;
@Mock
private PreferenceScreen mScreen;
private ZenRuleVisEffectsAllPreferenceController mController;
private Context mContext;
@Override
AbstractZenCustomRulePreferenceController getController() {
return mController;
}
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
ShadowApplication shadowApplication = ShadowApplication.getInstance();
shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
mContext = RuntimeEnvironment.application;
mController = new ZenRuleVisEffectsAllPreferenceController(mContext, mock(Lifecycle.class),
PREF_KEY);
ReflectionHelpers.setField(mController, "mBackend", mBackend);
when(mBackend.getAutomaticZenRule(RULE_ID)).thenReturn(mRule);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mockPref);
mController.displayPreference(mScreen);
}
@Test
public void updateState_noVisEffects() {
updateControllerZenPolicy(new ZenPolicy.Builder()
.hideAllVisualEffects()
.build());
mController.updateState(mockPref);
verify(mockPref).setChecked(false);
}
@Test
public void updateState_showAllVisualEffects() {
updateControllerZenPolicy(new ZenPolicy.Builder()
.showAllVisualEffects()
.build());
mController.updateState(mockPref);
verify(mockPref).setChecked(true);
}
@Test
public void updateState_customEffects() {
updateControllerZenPolicy(new ZenPolicy.Builder()
.showPeeking(true)
.showBadges(false)
.build());
mController.updateState(mockPref);
verify(mockPref).setChecked(false);
}
}

View File

@@ -0,0 +1,104 @@
/*
* Copyright (C) 2018 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;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.NotificationManager;
import android.content.Context;
import android.service.notification.ZenPolicy;
import androidx.preference.PreferenceScreen;
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.shadows.ShadowApplication;
import org.robolectric.util.ReflectionHelpers;
@RunWith(RobolectricTestRunner.class)
public class ZenRuleVisEffectsCustomPreferenceControllerTest extends
ZenRuleCustomPrefContrTestBase {
@Mock
private ZenModeBackend mBackend;
@Mock
private NotificationManager mNotificationManager;
@Mock
private ZenCustomRadioButtonPreference mockPref;
@Mock
private PreferenceScreen mScreen;
private ZenRuleVisEffectsCustomPreferenceController mController;
private Context mContext;
@Override
AbstractZenCustomRulePreferenceController getController() {
return mController;
}
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
ShadowApplication shadowApplication = ShadowApplication.getInstance();
shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
mContext = RuntimeEnvironment.application;
mController = new ZenRuleVisEffectsCustomPreferenceController(mContext, mock(Lifecycle.class),
PREF_KEY);
ReflectionHelpers.setField(mController, "mBackend", mBackend);
when(mBackend.getAutomaticZenRule(RULE_ID)).thenReturn(mRule);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mockPref);
mController.displayPreference(mScreen);
}
@Test
public void updateState_noVisEffects() {
updateControllerZenPolicy(new ZenPolicy.Builder()
.hideAllVisualEffects()
.build());
mController.updateState(mockPref);
verify(mockPref).setChecked(false);
}
@Test
public void updateState_showAllVisualEffects() {
updateControllerZenPolicy(new ZenPolicy.Builder()
.showAllVisualEffects()
.build());
mController.updateState(mockPref);
verify(mockPref).setChecked(false);
}
@Test
public void updateState_customEffects() {
updateControllerZenPolicy(new ZenPolicy.Builder()
.showPeeking(true)
.showBadges(false)
.build());
mController.updateState(mockPref);
verify(mockPref).setChecked(true);
}
}

View File

@@ -0,0 +1,104 @@
/*
* Copyright (C) 2018 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;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.NotificationManager;
import android.content.Context;
import android.service.notification.ZenPolicy;
import androidx.preference.PreferenceScreen;
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.shadows.ShadowApplication;
import org.robolectric.util.ReflectionHelpers;
@RunWith(RobolectricTestRunner.class)
public class ZenRuleVisEffectsNonePreferenceControllerTest extends
ZenRuleCustomPrefContrTestBase {
@Mock
private ZenModeBackend mBackend;
@Mock
private NotificationManager mNotificationManager;
@Mock
private ZenCustomRadioButtonPreference mockPref;
@Mock
private PreferenceScreen mScreen;
private ZenRuleVisEffectsNonePreferenceController mController;
private Context mContext;
@Override
AbstractZenCustomRulePreferenceController getController() {
return mController;
}
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
ShadowApplication shadowApplication = ShadowApplication.getInstance();
shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
mContext = RuntimeEnvironment.application;
mController = new ZenRuleVisEffectsNonePreferenceController(mContext, mock(Lifecycle.class),
PREF_KEY);
ReflectionHelpers.setField(mController, "mBackend", mBackend);
when(mBackend.getAutomaticZenRule(RULE_ID)).thenReturn(mRule);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mockPref);
mController.displayPreference(mScreen);
}
@Test
public void updateState_noVisEffects() {
updateControllerZenPolicy(new ZenPolicy.Builder()
.hideAllVisualEffects()
.build());
mController.updateState(mockPref);
verify(mockPref).setChecked(true);
}
@Test
public void updateState_showAllVisualEffects() {
updateControllerZenPolicy(new ZenPolicy.Builder()
.showAllVisualEffects()
.build());
mController.updateState(mockPref);
verify(mockPref).setChecked(false);
}
@Test
public void updateState_custom() {
updateControllerZenPolicy(new ZenPolicy.Builder()
.showPeeking(true)
.showBadges(false)
.build());
mController.updateState(mockPref);
verify(mockPref).setChecked(false);
}
}