Added zen settings messages and calls preferences.
- Made ZenModeSettings and ZenModeBehaviorSettings a DashboardFragment
- Switches in ZenModeBehaviorSettings all have their own preference controllers
- Instead of a dropdown, messages & calls have their own pages & preference controllers
- Added basic turn on/off DND button in settings (dialog not yet implemented)
Bug: 63077372
Fixes: 69057767
Test: make -j40 RunSettingsRoboTests
Change-Id: I1c70f77053713f66f873ee578477f23cfd7985bb
diff --git a/res/layout/zen_mode_button.xml b/res/layout/zen_mode_button.xml
new file mode 100644
index 0000000..af24fce
--- /dev/null
+++ b/res/layout/zen_mode_button.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+ -->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:gravity="bottom"
+ android:paddingTop="4dp"
+ android:paddingStart="72dp"
+ android:paddingEnd="72dp"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <Button
+ android:id="@+id/zen_mode_button"
+ android:layout_width="0dp"
+ android:layout_weight="1"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:paddingEnd="8dp" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/zen_mode_settings_button.xml b/res/layout/zen_mode_settings_button.xml
new file mode 100644
index 0000000..4d4b7d6
--- /dev/null
+++ b/res/layout/zen_mode_settings_button.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+ -->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:gravity="bottom"
+ android:paddingTop="4dp"
+ android:paddingStart="72dp"
+ android:paddingEnd="72dp"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <Button
+ android:id="@+id/zen_mode_settings_turn_on_button"
+ style="@style/ActionPrimaryButton"
+ android:layout_width="0dp"
+ android:layout_weight="1"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:text="@string/zen_mode_button_turn_on"
+ android:paddingEnd="8dp" />
+
+ <Button
+ android:id="@+id/zen_mode_settings_turn_off_button"
+ style="@style/ActionSecondaryButton"
+ android:layout_width="0dp"
+ android:layout_weight="1"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:text="@string/zen_mode_button_turn_off"
+ android:paddingEnd="8dp" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index 84f3722..aa8a586 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -1031,4 +1031,18 @@
<item>never</item>
</string-array>
+ <string-array name="zen_mode_contacts_entries" translatable="false">
+ <item>@string/zen_mode_from_anyone</item>
+ <item>@string/zen_mode_from_contacts</item>
+ <item>@string/zen_mode_from_starred</item>
+ <item>@string/zen_mode_from_none</item>
+ </string-array>
+
+ <string-array name="zen_mode_contacts_values" translatable="false">
+ <item>zen_mode_from_anyone</item>
+ <item>zen_mode_from_contacts</item>
+ <item>zen_mode_from_starred</item>
+ <item>zen_mode_from_none</item>
+ </string-array>
+
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 3b474ab..3654d85 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -6754,6 +6754,27 @@
<!-- Do not disturb: Button to add new automatic rule to DND. [CHAR LIMIT=30] -->
<string name="zen_mode_add">Add</string>
+ <!-- Do not disturb: Label for button that will turn on zen mode. [CHAR LIMIT=30] -->
+ <string name="zen_mode_button_turn_on">TURN ON NOW</string>
+
+ <!-- Do not disturb: Label for button that will turn off zen mode. [CHAR LIMIT=30] -->
+ <string name="zen_mode_button_turn_off">TURN OFF NOW</string>
+
+ <!-- [CHAR LIMIT=110] Zen mode settings footer: Footer showing end time of DND -->
+ <string name="zen_mode_settings_dnd_manual_end_time_next_day">Do Not Disturb is on until <xliff:g id="formatted_time" example="7:00 AM">%s</xliff:g></string>
+
+ <!-- [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>
+
+ <!-- [CHAR LIMIT=110] Zen mode settings footer: Footer showing how DND was triggered by an automatic DND rule -->
+ <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>
+
+ <!-- [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="Pixel Services">%s</xliff:g></string>
+
+ <!-- [CHAR LIMIT=110] Zen mode settings footer: Footer how DND was triggered by multiple rules and/or apps -->
+ <string name="zen_mode_settings_dnd_automatic_rule_multiple">Do Not Disturb was automatically turned on by a rule or app</string>
+
<!-- Work Sounds: Work sound settings section header. [CHAR LIMIT=50] -->
<string name="sound_work_settings">Work profile sounds</string>
diff --git a/res/xml/zen_mode_automation_settings.xml b/res/xml/zen_mode_automation_settings.xml
index 33842ec..99826ea 100644
--- a/res/xml/zen_mode_automation_settings.xml
+++ b/res/xml/zen_mode_automation_settings.xml
@@ -19,5 +19,15 @@
android:key="zen_mode_automation_settings_page"
android:title="@string/zen_mode_automation_settings_page_title" >
- <!-- Rules added at runtime -->
+
+ <PreferenceCategory
+ android:key="zen_mode_automatic_rules">
+ <!-- Rules added at runtime -->
+ </PreferenceCategory>
+
+ <Preference
+ android:key="zen_mode_add_automatic_rule"
+ android:icon="@drawable/ic_menu_add"
+ android:title="@string/zen_mode_add_rule"/>
+
</PreferenceScreen>
diff --git a/res/xml/zen_mode_behavior_settings.xml b/res/xml/zen_mode_behavior_settings.xml
index 999d6b4..7b5ed91 100644
--- a/res/xml/zen_mode_behavior_settings.xml
+++ b/res/xml/zen_mode_behavior_settings.xml
@@ -46,17 +46,16 @@
android:key="zen_mode_events"
android:title="@string/zen_mode_events"/>
- <!-- Messages -->
- <DropDownPreference
+ <Preference
android:key="zen_mode_messages"
android:title="@string/zen_mode_messages"
- android:summary="%s" />
+ android:fragment="com.android.settings.notification.ZenModeMessagesSettings" />
<!-- Calls -->
- <DropDownPreference
+ <Preference
android:key="zen_mode_calls"
android:title="@string/zen_mode_calls"
- android:summary="%s" />
+ android:fragment="com.android.settings.notification.ZenModeCallsSettings" />
<!-- Repeat callers -->
<SwitchPreference
diff --git a/res/xml/zen_mode_calls_settings.xml b/res/xml/zen_mode_calls_settings.xml
new file mode 100644
index 0000000..aa84216
--- /dev/null
+++ b/res/xml/zen_mode_calls_settings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+ -->
+
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:key="zen_mode_calls_settings"
+ android:title="@string/zen_mode_calls" />
diff --git a/res/xml/zen_mode_messages_settings.xml b/res/xml/zen_mode_messages_settings.xml
new file mode 100644
index 0000000..4b4a1e2
--- /dev/null
+++ b/res/xml/zen_mode_messages_settings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+ -->
+
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:key="zen_mode_messages_settings"
+ android:title="@string/zen_mode_messages" />
diff --git a/res/xml/zen_mode_settings.xml b/res/xml/zen_mode_settings.xml
index 92e2b7f..82bef4d 100644
--- a/res/xml/zen_mode_settings.xml
+++ b/res/xml/zen_mode_settings.xml
@@ -19,6 +19,7 @@
android:key="zen_mode_settings"
android:title="@string/zen_mode_settings_title">
+ <!-- Priority behavior settings -->
<Preference
android:key="zen_mode_behavior_settings"
android:title="@string/zen_mode_behavior_settings_title"
@@ -29,4 +30,14 @@
android:key="zen_mode_automation_settings"
android:title="@string/zen_mode_automation_settings_title"
android:fragment="com.android.settings.notification.ZenModeAutomationSettings" />
+
+ <!-- Turn on DND button -->
+ <!-- Layout preference doesn't obey allowDividerAbove, so put it in a PreferenceCategory -->
+ <PreferenceCategory>
+ <com.android.settings.applications.LayoutPreference
+ android:key="zen_mode_settings_button_container"
+ android:selectable="false"
+ android:layout="@layout/zen_mode_settings_button" />
+ </PreferenceCategory>
+
</PreferenceScreen>
diff --git a/src/com/android/settings/notification/AbstractZenModeAutomaticRulePreferenceController.java b/src/com/android/settings/notification/AbstractZenModeAutomaticRulePreferenceController.java
new file mode 100644
index 0000000..ec9cf2a
--- /dev/null
+++ b/src/com/android/settings/notification/AbstractZenModeAutomaticRulePreferenceController.java
@@ -0,0 +1,160 @@
+/*
+ * 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.app.AutomaticZenRule;
+import android.app.Fragment;
+import android.app.NotificationManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ServiceInfo;
+import android.provider.Settings;
+import android.service.notification.ConditionProviderService;
+import android.service.notification.ZenModeConfig;
+import android.support.v7.preference.Preference;
+
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.core.AbstractPreferenceController;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Map;
+import java.util.Set;
+
+abstract public class AbstractZenModeAutomaticRulePreferenceController extends
+ AbstractPreferenceController implements PreferenceControllerMixin {
+
+ private static final String TAG = "ZenModeAutomaticRule";
+ protected ZenModeBackend mBackend;
+ protected Fragment mParent;
+ protected Set<Map.Entry<String, AutomaticZenRule>> mRules;
+ protected PackageManager mPm;
+
+ public AbstractZenModeAutomaticRulePreferenceController(Context context, Fragment parent) {
+ super(context);
+ mBackend = ZenModeBackend.getInstance(context);
+ mParent = parent;
+ mPm = mContext.getPackageManager();
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+ mRules = getZenModeRules();
+ }
+
+ private Set<Map.Entry<String, AutomaticZenRule>> getZenModeRules() {
+ Map<String, AutomaticZenRule> ruleMap =
+ NotificationManager.from(mContext).getAutomaticZenRules();
+ return ruleMap.entrySet();
+ }
+
+ protected void showNameRuleDialog(final ZenRuleInfo ri) {
+ new ZenRuleNameDialog(mContext, null, ri.defaultConditionId) {
+ @Override
+ public void onOk(String ruleName) {
+ AutomaticZenRule rule = new AutomaticZenRule(ruleName, ri.serviceComponent,
+ ri.defaultConditionId, NotificationManager.INTERRUPTION_FILTER_PRIORITY,
+ true);
+ String savedRuleId = mBackend.addZenRule(rule);
+ if (savedRuleId != null) {
+ mParent.startActivity(getRuleIntent(ri.settingsAction, null, savedRuleId));
+ }
+ }
+ }.show();
+ }
+
+ protected Map.Entry<String, AutomaticZenRule>[] sortedRules() {
+ if (mRules == null) {
+ mRules = getZenModeRules();
+ }
+ final Map.Entry<String, AutomaticZenRule>[] rt =
+ mRules.toArray(new Map.Entry[mRules.size()]);
+ Arrays.sort(rt, RULE_COMPARATOR);
+ return rt;
+ }
+
+ protected static Intent getRuleIntent(String settingsAction,
+ ComponentName configurationActivity, String ruleId) {
+ final Intent intent = new Intent()
+ .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
+ .putExtra(ConditionProviderService.EXTRA_RULE_ID, ruleId);
+ if (configurationActivity != null) {
+ intent.setComponent(configurationActivity);
+ } else {
+ intent.setAction(settingsAction);
+ }
+ return intent;
+ }
+
+ private static final Comparator<Map.Entry<String, AutomaticZenRule>> RULE_COMPARATOR =
+ new Comparator<Map.Entry<String, AutomaticZenRule>>() {
+ @Override
+ public int compare(Map.Entry<String, AutomaticZenRule> lhs,
+ Map.Entry<String, AutomaticZenRule> rhs) {
+ int byDate = Long.compare(lhs.getValue().getCreationTime(),
+ rhs.getValue().getCreationTime());
+ if (byDate != 0) {
+ return byDate;
+ } else {
+ return key(lhs.getValue()).compareTo(key(rhs.getValue()));
+ }
+ }
+
+ private String key(AutomaticZenRule rule) {
+ final int type = ZenModeConfig.isValidScheduleConditionId(rule.getConditionId())
+ ? 1 : ZenModeConfig.isValidEventConditionId(rule.getConditionId())
+ ? 2 : 3;
+ return type + rule.getName().toString();
+ }
+ };
+
+ public static ZenRuleInfo getRuleInfo(PackageManager pm, ServiceInfo si) {
+ if (si == null || si.metaData == null) {
+ return null;
+ }
+ final String ruleType = si.metaData.getString(ConditionProviderService.META_DATA_RULE_TYPE);
+ final ComponentName configurationActivity = getSettingsActivity(si);
+ if (ruleType != null && !ruleType.trim().isEmpty() && configurationActivity != null) {
+ final ZenRuleInfo ri = new ZenRuleInfo();
+ ri.serviceComponent = new ComponentName(si.packageName, si.name);
+ ri.settingsAction = Settings.ACTION_ZEN_MODE_EXTERNAL_RULE_SETTINGS;
+ ri.title = ruleType;
+ ri.packageName = si.packageName;
+ ri.configurationActivity = getSettingsActivity(si);
+ ri.packageLabel = si.applicationInfo.loadLabel(pm);
+ ri.ruleInstanceLimit =
+ si.metaData.getInt(ConditionProviderService.META_DATA_RULE_INSTANCE_LIMIT, -1);
+ return ri;
+ }
+ return null;
+ }
+
+ protected static ComponentName getSettingsActivity(ServiceInfo si) {
+ if (si == null || si.metaData == null) {
+ return null;
+ }
+ final String configurationActivity =
+ si.metaData.getString(ConditionProviderService.META_DATA_CONFIGURATION_ACTIVITY);
+ if (configurationActivity != null) {
+ return ComponentName.unflattenFromString(configurationActivity);
+ }
+ return null;
+ }
+}
diff --git a/src/com/android/settings/notification/AbstractZenModePreferenceController.java b/src/com/android/settings/notification/AbstractZenModePreferenceController.java
new file mode 100644
index 0000000..ec275b2
--- /dev/null
+++ b/src/com/android/settings/notification/AbstractZenModePreferenceController.java
@@ -0,0 +1,117 @@
+/*
+ * 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.app.NotificationManager;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.provider.Settings;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.OnPause;
+import com.android.settingslib.core.lifecycle.events.OnResume;
+
+abstract public class AbstractZenModePreferenceController extends
+ AbstractPreferenceController implements PreferenceControllerMixin, LifecycleObserver,
+ OnResume, OnPause {
+
+ private SettingObserver mSettingObserver;
+ private final String KEY;
+ final private NotificationManager mNotificationManager;
+
+ public AbstractZenModePreferenceController(Context context, String key,
+ Lifecycle lifecycle) {
+ super(context);
+ if (lifecycle != null) {
+ lifecycle.addObserver(this);
+ }
+ KEY = key;
+ mNotificationManager = (NotificationManager) context.getSystemService(
+ Context.NOTIFICATION_SERVICE);
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mSettingObserver = new SettingObserver(screen.findPreference(KEY));
+ }
+
+ @Override
+ public void onResume() {
+ if (mSettingObserver != null) {
+ mSettingObserver.register(mContext.getContentResolver());
+ }
+ }
+
+ @Override
+ public void onPause() {
+ if (mSettingObserver != null) {
+ mSettingObserver.unregister(mContext.getContentResolver());
+ }
+ }
+
+ protected NotificationManager.Policy getPolicy() {
+ return mNotificationManager.getNotificationPolicy();
+ }
+
+ protected int getZenMode() {
+ return Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.ZEN_MODE, 0);
+ }
+
+ class SettingObserver extends ContentObserver {
+ private final Uri ZEN_MODE_URI = Settings.Global.getUriFor(Settings.Global.ZEN_MODE);
+ private final Uri ZEN_MODE_CONFIG_ETAG_URI = Settings.Global.getUriFor(
+ Settings.Global.ZEN_MODE_CONFIG_ETAG);
+
+ private final Preference mPreference;
+
+ public SettingObserver(Preference preference) {
+ super(new Handler());
+ mPreference = preference;
+ }
+
+ public void register(ContentResolver cr) {
+ cr.registerContentObserver(ZEN_MODE_URI, false, this);
+ cr.registerContentObserver(ZEN_MODE_CONFIG_ETAG_URI, false, this);
+ }
+
+ public void unregister(ContentResolver cr) {
+ cr.unregisterContentObserver(this);
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ super.onChange(selfChange, uri);
+ if (ZEN_MODE_URI.equals(uri)) {
+ updateState(mPreference);
+ }
+
+ if (ZEN_MODE_CONFIG_ETAG_URI.equals(uri)) {
+ updateState(mPreference);
+ }
+ }
+ }
+}
diff --git a/src/com/android/settings/notification/ZenModeAddAutomaticRulePreferenceController.java b/src/com/android/settings/notification/ZenModeAddAutomaticRulePreferenceController.java
new file mode 100644
index 0000000..a15536c
--- /dev/null
+++ b/src/com/android/settings/notification/ZenModeAddAutomaticRulePreferenceController.java
@@ -0,0 +1,75 @@
+/*
+ * 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.app.Fragment;
+import android.content.Context;
+import android.content.Intent;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.utils.ZenServiceListing;
+
+public class ZenModeAddAutomaticRulePreferenceController extends
+ AbstractZenModeAutomaticRulePreferenceController implements
+ Preference.OnPreferenceClickListener {
+
+ private final String KEY_ADD_RULE;
+ private final ZenServiceListing mZenServiceListing;
+
+ public ZenModeAddAutomaticRulePreferenceController(Context context, String key,
+ Fragment parent, ZenServiceListing serviceListing) {
+ super(context, parent);
+ KEY_ADD_RULE = key;
+ mZenServiceListing = serviceListing;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_ADD_RULE;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ Preference pref = screen.findPreference(KEY_ADD_RULE);
+ pref.setPersistent(false);
+ pref.setOnPreferenceClickListener(this);
+ }
+
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ new ZenRuleSelectionDialog(mContext, mZenServiceListing) {
+ @Override
+ public void onSystemRuleSelected(ZenRuleInfo ri) {
+ showNameRuleDialog(ri);
+ }
+
+ @Override
+ public void onExternalRuleSelected(ZenRuleInfo ri) {
+ Intent intent = new Intent().setComponent(ri.configurationActivity);
+ mParent.startActivity(intent);
+ }
+ }.show();
+ return true;
+ }
+}
diff --git a/src/com/android/settings/notification/ZenModeAlarmsPreferenceController.java b/src/com/android/settings/notification/ZenModeAlarmsPreferenceController.java
new file mode 100644
index 0000000..df9966d
--- /dev/null
+++ b/src/com/android/settings/notification/ZenModeAlarmsPreferenceController.java
@@ -0,0 +1,79 @@
+/*
+ * 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.app.NotificationManager.Policy;
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.Preference;
+import android.util.Log;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public class ZenModeAlarmsPreferenceController extends
+ AbstractZenModePreferenceController implements Preference.OnPreferenceChangeListener{
+
+ protected static final String KEY = "zen_mode_alarms";
+ private final ZenModeBackend mBackend;
+
+ public ZenModeAlarmsPreferenceController(Context context, Lifecycle lifecycle) {
+ super(context, KEY, lifecycle);
+ mBackend = ZenModeBackend.getInstance(context);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+
+ SwitchPreference pref = (SwitchPreference) preference;
+ switch (getZenMode()) {
+ case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
+ pref.setEnabled(false);
+ pref.setChecked(false);
+ break;
+ case Settings.Global.ZEN_MODE_ALARMS:
+ pref.setEnabled(false);
+ pref.setChecked(true);
+ break;
+ default:
+ pref.setEnabled(true);
+ pref.setChecked(mBackend.isPriorityCategoryEnabled(
+ Policy.PRIORITY_CATEGORY_ALARMS));
+ }
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ final boolean allowAlarms = (Boolean) newValue;
+ if (ZenModeSettingsBase.DEBUG) {
+ Log.d(TAG, "onPrefChange allowAlarms=" + allowAlarms);
+ }
+ mBackend.saveSoundPolicy(Policy.PRIORITY_CATEGORY_ALARMS, allowAlarms);
+ return true;
+ }
+}
diff --git a/src/com/android/settings/notification/ZenModeAutomaticRulesPreferenceController.java b/src/com/android/settings/notification/ZenModeAutomaticRulesPreferenceController.java
new file mode 100644
index 0000000..0ec5d69
--- /dev/null
+++ b/src/com/android/settings/notification/ZenModeAutomaticRulesPreferenceController.java
@@ -0,0 +1,100 @@
+/*
+ * 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.app.AutomaticZenRule;
+import android.app.Fragment;
+import android.content.Context;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceCategory;
+import android.support.v7.preference.PreferenceScreen;
+
+import java.util.Map;
+
+public class ZenModeAutomaticRulesPreferenceController extends
+ AbstractZenModeAutomaticRulePreferenceController {
+
+ private final String KEY_AUTOMATIC_RULES;
+ private PreferenceCategory mPreferenceCategory;
+ Map.Entry<String, AutomaticZenRule>[] mSortedRules;
+
+ public ZenModeAutomaticRulesPreferenceController(Context context, String key,
+ Fragment parent) {
+ super(context, parent);
+ KEY_AUTOMATIC_RULES = key;
+ mSortedRules = sortedRules();
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_AUTOMATIC_RULES;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mPreferenceCategory = (PreferenceCategory) screen.findPreference(getPreferenceKey());
+ mPreferenceCategory.setPersistent(false);
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+
+ // no need to update AutomaticRule if a rule was deleted
+ // (on rule deletion, the preference removes itself from its parent)
+ int oldRuleLength = mSortedRules.length;
+ mSortedRules = sortedRules();
+ if (!wasRuleDeleted(oldRuleLength)) {
+ updateAutomaticRules();
+ }
+ }
+
+ private boolean wasRuleDeleted(int oldRuleLength) {
+ int newRuleLength = mSortedRules.length;
+ int prefCount = mPreferenceCategory.getPreferenceCount();
+
+ return (prefCount == oldRuleLength -1) && (prefCount == newRuleLength);
+ }
+
+ private void updateAutomaticRules() {
+ for (Map.Entry<String, AutomaticZenRule> sortedRule : mSortedRules) {
+ ZenRulePreference currPref = (ZenRulePreference)
+ mPreferenceCategory.findPreference(sortedRule.getKey());
+ if (currPref != null && currPref.appExists) {
+ // rule already exists in preferences, update it
+ currPref.setAttributes(sortedRule.getValue());
+ } else {
+ // rule doesn't exist in preferences, add it
+ ZenRulePreference pref = new ZenRulePreference(mPreferenceCategory.getContext(),
+ sortedRule, mPreferenceCategory);
+ if (pref.appExists) {
+ mPreferenceCategory.addPreference(pref);
+ }
+ }
+ }
+
+ }
+}
+
+
+
diff --git a/src/com/android/settings/notification/ZenModeAutomationPreferenceController.java b/src/com/android/settings/notification/ZenModeAutomationPreferenceController.java
new file mode 100644
index 0000000..aa46d4e
--- /dev/null
+++ b/src/com/android/settings/notification/ZenModeAutomationPreferenceController.java
@@ -0,0 +1,34 @@
+package com.android.settings.notification;
+
+import android.content.Context;
+import android.support.v7.preference.Preference;
+
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.core.AbstractPreferenceController;
+
+public class ZenModeAutomationPreferenceController extends
+ AbstractPreferenceController implements PreferenceControllerMixin {
+
+ protected static final String KEY_ZEN_MODE_AUTOMATION = "zen_mode_automation_settings";
+ private final ZenModeSettings.SummaryBuilder mSummaryBuilder;
+
+ public ZenModeAutomationPreferenceController(Context context) {
+ super(context);
+ mSummaryBuilder = new ZenModeSettings.SummaryBuilder(context);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_ZEN_MODE_AUTOMATION;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ preference.setSummary(mSummaryBuilder.getAutomaticRulesSummary());
+ }
+}
diff --git a/src/com/android/settings/notification/ZenModeAutomationSettings.java b/src/com/android/settings/notification/ZenModeAutomationSettings.java
index 07e9228..ae75798 100644
--- a/src/com/android/settings/notification/ZenModeAutomationSettings.java
+++ b/src/com/android/settings/notification/ZenModeAutomationSettings.java
@@ -16,167 +16,47 @@
package com.android.settings.notification;
-import android.app.AlertDialog;
-import android.app.AutomaticZenRule;
-import android.app.NotificationManager;
-import android.content.ComponentName;
+import android.app.Fragment;
import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ServiceInfo;
-import android.content.res.Resources;
-import android.os.Bundle;
-import android.provider.SearchIndexableResource;
-import android.provider.Settings;
import android.service.notification.ConditionProviderService;
-import android.service.notification.ZenModeConfig;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.Preference.OnPreferenceClickListener;
-import android.support.v7.preference.PreferenceScreen;
-import android.support.v7.preference.PreferenceViewHolder;
-import android.view.View;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
-import com.android.settings.utils.ManagedServiceSettings.Config;
+import com.android.settings.utils.ManagedServiceSettings;
import com.android.settings.utils.ZenServiceListing;
-import com.android.settingslib.TwoTargetPreference;
+import com.android.settingslib.core.AbstractPreferenceController;
-import java.util.Arrays;
-import java.util.Comparator;
+import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
-public class ZenModeAutomationSettings extends ZenModeSettingsBase implements Indexable {
-
- static final Config CONFIG = getConditionProviderConfig();
-
- private PackageManager mPm;
- private ZenServiceListing mServiceListing;
+public class ZenModeAutomationSettings extends ZenModeSettingsBase {
+ private static final String KEY_ADD_RULE = "zen_mode_add_automatic_rule";
+ private static final String KEY_AUTOMATIC_RULES = "zen_mode_automatic_rules";
+ protected final ManagedServiceSettings.Config CONFIG = getConditionProviderConfig();
@Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
- addPreferencesFromResource(R.xml.zen_mode_automation_settings);
+ protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
+ ZenServiceListing serviceListing = new ZenServiceListing(getContext(), CONFIG);
+ serviceListing.reloadApprovedServices();
+ return buildPreferenceControllers(context, this, serviceListing);
+ }
- mPm = mContext.getPackageManager();
- mServiceListing = new ZenServiceListing(mContext, CONFIG);
- mServiceListing.reloadApprovedServices();
+ private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
+ Fragment parent, ZenServiceListing serviceListing) {
+ List<AbstractPreferenceController> controllers = new ArrayList<>();
+ controllers.add(new ZenModeAddAutomaticRulePreferenceController(context, KEY_ADD_RULE,
+ parent, serviceListing));
+ controllers.add(new ZenModeAutomaticRulesPreferenceController(context,
+ KEY_AUTOMATIC_RULES, parent));
+
+ return controllers;
}
@Override
- protected void onZenModeChanged() {
- // don't care
- }
-
- @Override
- protected void onZenModeConfigChanged() {
- updateControls();
- }
-
- @Override
- public void onResume() {
- super.onResume();
- if (isUiRestricted()) {
- return;
- }
- updateControls();
- }
-
- private void showAddRuleDialog() {
- new ZenRuleSelectionDialog(mContext, mServiceListing) {
- @Override
- public void onSystemRuleSelected(ZenRuleInfo ri) {
- showNameRuleDialog(ri);
- }
-
- @Override
- public void onExternalRuleSelected(ZenRuleInfo ri) {
- Intent intent = new Intent().setComponent(ri.configurationActivity);
- startActivity(intent);
- }
- }.show();
- }
-
- private void showNameRuleDialog(final ZenRuleInfo ri) {
- new ZenRuleNameDialog(mContext, null, ri.defaultConditionId) {
- @Override
- public void onOk(String ruleName) {
- mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_ZEN_ADD_RULE_OK);
- AutomaticZenRule rule = new AutomaticZenRule(ruleName, ri.serviceComponent,
- ri.defaultConditionId, NotificationManager.INTERRUPTION_FILTER_PRIORITY,
- true);
- String savedRuleId = addZenRule(rule);
- if (savedRuleId != null) {
- startActivity(getRuleIntent(ri.settingsAction, null, savedRuleId));
- }
- }
- }.show();
- }
-
- private void showDeleteRuleDialog(final String ruleId, final CharSequence ruleName) {
- new AlertDialog.Builder(mContext)
- .setMessage(getString(R.string.zen_mode_delete_rule_confirmation, ruleName))
- .setNegativeButton(R.string.cancel, null)
- .setPositiveButton(R.string.zen_mode_delete_rule_button,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- mMetricsFeatureProvider.action(mContext,
- MetricsEvent.ACTION_ZEN_DELETE_RULE_OK);
- removeZenRule(ruleId);
- }
- })
- .show();
- }
-
- private Intent getRuleIntent(String settingsAction, ComponentName configurationActivity,
- String ruleId) {
- final Intent intent = new Intent()
- .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
- .putExtra(ConditionProviderService.EXTRA_RULE_ID, ruleId);
- if (configurationActivity != null) {
- intent.setComponent(configurationActivity);
- } else {
- intent.setAction(settingsAction);
- }
- return intent;
- }
-
- private Map.Entry<String,AutomaticZenRule>[] sortedRules() {
- final Map.Entry<String,AutomaticZenRule>[] rt =
- mRules.toArray(new Map.Entry[mRules.size()]);
- Arrays.sort(rt, RULE_COMPARATOR);
- return rt;
- }
-
- private void updateControls() {
- final PreferenceScreen root = getPreferenceScreen();
- root.removeAll();
- final Map.Entry<String,AutomaticZenRule>[] sortedRules = sortedRules();
- for (Map.Entry<String,AutomaticZenRule> sortedRule : sortedRules) {
- ZenRulePreference pref = new ZenRulePreference(getPrefContext(), sortedRule);
- if (pref.appExists) {
- root.addPreference(pref);
- }
- }
- final Preference p = new Preference(getPrefContext());
- p.setIcon(R.drawable.ic_menu_add);
- p.setTitle(R.string.zen_mode_add_rule);
- p.setPersistent(false);
- p.setOnPreferenceClickListener(new OnPreferenceClickListener() {
- @Override
- public boolean onPreferenceClick(Preference preference) {
- mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_ZEN_ADD_RULE);
- showAddRuleDialog();
- return true;
- }
- });
- root.addPreference(p);
+ protected int getPreferenceScreenResId() {
+ return R.xml.zen_mode_automation_settings;
}
@Override
@@ -184,18 +64,8 @@
return MetricsEvent.NOTIFICATION_ZEN_MODE_AUTOMATION;
}
- private String computeRuleSummary(AutomaticZenRule rule, boolean isSystemRule,
- CharSequence providerLabel) {
- final String mode = computeZenModeCaption(getResources(), rule.getInterruptionFilter());
- final String ruleState = (rule == null || !rule.isEnabled())
- ? getString(R.string.switch_off_text)
- : getString(R.string.zen_mode_rule_summary_enabled_combination, mode);
-
- return ruleState;
- }
-
- private static Config getConditionProviderConfig() {
- final Config c = new Config();
+ protected static ManagedServiceSettings.Config getConditionProviderConfig() {
+ final ManagedServiceSettings.Config c = new ManagedServiceSettings.Config();
c.tag = TAG;
c.intentAction = ConditionProviderService.SERVICE_INTERFACE;
c.permission = android.Manifest.permission.BIND_CONDITION_PROVIDER_SERVICE;
@@ -203,146 +73,22 @@
return c;
}
- private static String computeZenModeCaption(Resources res, int zenMode) {
- switch (zenMode) {
- case NotificationManager.INTERRUPTION_FILTER_ALARMS:
- return res.getString(R.string.zen_mode_option_alarms);
- case NotificationManager.INTERRUPTION_FILTER_PRIORITY:
- return res.getString(R.string.zen_mode_option_important_interruptions);
- case NotificationManager.INTERRUPTION_FILTER_NONE:
- return res.getString(R.string.zen_mode_option_no_interruptions);
- default:
- return null;
- }
- }
-
- public static ZenRuleInfo getRuleInfo(PackageManager pm, ServiceInfo si) {
- if (si == null || si.metaData == null) {
- return null;
- }
- final String ruleType = si.metaData.getString(ConditionProviderService.META_DATA_RULE_TYPE);
- final ComponentName configurationActivity = getSettingsActivity(si);
- if (ruleType != null && !ruleType.trim().isEmpty() && configurationActivity != null) {
- final ZenRuleInfo ri = new ZenRuleInfo();
- ri.serviceComponent = new ComponentName(si.packageName, si.name);
- ri.settingsAction = Settings.ACTION_ZEN_MODE_EXTERNAL_RULE_SETTINGS;
- ri.title = ruleType;
- ri.packageName = si.packageName;
- ri.configurationActivity = getSettingsActivity(si);
- ri.packageLabel = si.applicationInfo.loadLabel(pm);
- ri.ruleInstanceLimit =
- si.metaData.getInt(ConditionProviderService.META_DATA_RULE_INSTANCE_LIMIT, -1);
- return ri;
- }
- return null;
- }
-
- private static ComponentName getSettingsActivity(ServiceInfo si) {
- if (si == null || si.metaData == null) {
- return null;
- }
- final String configurationActivity =
- si.metaData.getString(ConditionProviderService.META_DATA_CONFIGURATION_ACTIVITY);
- if (configurationActivity != null) {
- return ComponentName.unflattenFromString(configurationActivity);
- }
- return null;
- }
-
- private static final Comparator<Map.Entry<String,AutomaticZenRule>> RULE_COMPARATOR =
- new Comparator<Map.Entry<String,AutomaticZenRule>>() {
- @Override
- public int compare(Map.Entry<String,AutomaticZenRule> lhs,
- Map.Entry<String,AutomaticZenRule> rhs) {
- int byDate = Long.compare(lhs.getValue().getCreationTime(),
- rhs.getValue().getCreationTime());
- if (byDate != 0) {
- return byDate;
- } else {
- return key(lhs.getValue()).compareTo(key(rhs.getValue()));
- }
- }
-
- private String key(AutomaticZenRule rule) {
- final int type = ZenModeConfig.isValidScheduleConditionId(rule.getConditionId())
- ? 1 : ZenModeConfig.isValidEventConditionId(rule.getConditionId())
- ? 2 : 3;
- return type + rule.getName().toString();
- }
- };
-
- private class ZenRulePreference extends TwoTargetPreference {
- final CharSequence mName;
- final String mId;
- final boolean appExists;
-
- public ZenRulePreference(Context context,
- final Map.Entry<String, AutomaticZenRule> ruleEntry) {
- super(context);
-
- final AutomaticZenRule rule = ruleEntry.getValue();
- mName = rule.getName();
- mId = ruleEntry.getKey();
-
- final boolean isSchedule = ZenModeConfig.isValidScheduleConditionId(
- rule.getConditionId());
- final boolean isEvent = ZenModeConfig.isValidEventConditionId(rule.getConditionId());
- final boolean isSystemRule = isSchedule || isEvent;
-
- try {
- ApplicationInfo info = mPm.getApplicationInfo(rule.getOwner().getPackageName(), 0);
- setSummary(computeRuleSummary(rule, isSystemRule, info.loadLabel(mPm)));
- } catch (PackageManager.NameNotFoundException e) {
- appExists = false;
- return;
- }
-
- appExists = true;
- setTitle(rule.getName());
- setPersistent(false);
-
- final String action = isSchedule ? ZenModeScheduleRuleSettings.ACTION
- : isEvent ? ZenModeEventRuleSettings.ACTION : "";
- ServiceInfo si = mServiceListing.findService(rule.getOwner());
- ComponentName settingsActivity = getSettingsActivity(si);
- setIntent(getRuleIntent(action, settingsActivity, mId));
- setSelectable(settingsActivity != null || isSystemRule);
- }
-
- @Override
- protected int getSecondTargetResId() {
- return R.layout.zen_rule_widget;
- }
-
- @Override
- public void onBindViewHolder(PreferenceViewHolder view) {
- super.onBindViewHolder(view);
-
- View v = view.findViewById(R.id.delete_zen_rule);
- if (v != null) {
- v.setOnClickListener(mDeleteListener);
- }
- }
-
- private final View.OnClickListener mDeleteListener = new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- showDeleteRuleDialog(mId, mName);
- }
- };
- }
-
/**
* For Search.
*/
public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
- @Override
- public List<SearchIndexableResource> getXmlResourcesToIndex(
- Context context, boolean enabled) {
- final SearchIndexableResource sir = new SearchIndexableResource(context);
- sir.xmlResId = R.xml.zen_mode_automation_settings;
- return Arrays.asList(sir);
- }
- };
+ @Override
+ public List<String> getNonIndexableKeys(Context context) {
+ final List<String> keys = super.getNonIndexableKeys(context);
+ keys.add(KEY_ADD_RULE);
+ keys.add(KEY_AUTOMATIC_RULES);
+ return keys;
+ }
+
+ @Override
+ public List<AbstractPreferenceController> getPreferenceControllers(Context context) {
+ return buildPreferenceControllers(context, null, null);
+ }
+ };
}
diff --git a/src/com/android/settings/notification/ZenModeBackend.java b/src/com/android/settings/notification/ZenModeBackend.java
new file mode 100644
index 0000000..945da0b
--- /dev/null
+++ b/src/com/android/settings/notification/ZenModeBackend.java
@@ -0,0 +1,274 @@
+/*
+ * 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.app.AutomaticZenRule;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.provider.Settings;
+import android.service.notification.ZenModeConfig;
+import android.support.annotation.VisibleForTesting;
+import android.util.Log;
+
+import com.android.settings.R;
+
+public class ZenModeBackend {
+ @VisibleForTesting
+ protected static final String ZEN_MODE_FROM_ANYONE = "zen_mode_from_anyone";
+ @VisibleForTesting
+ protected static final String ZEN_MODE_FROM_CONTACTS = "zen_mode_from_contacts";
+ @VisibleForTesting
+ protected static final String ZEN_MODE_FROM_STARRED = "zen_mode_from_starred";
+ @VisibleForTesting
+ protected static final String ZEN_MODE_FROM_NONE = "zen_mode_from_none";
+ protected static final int SOURCE_NONE = -1;
+
+ private static ZenModeBackend sInstance;
+
+ protected int mZenMode;
+ /** gets policy last set by updatePolicy **/
+ protected NotificationManager.Policy mPolicy;
+ private final NotificationManager mNotificationManager;
+
+ private String TAG = "ZenModeSettingsBackend";
+ private final Context mContext;
+
+ public static ZenModeBackend getInstance(Context context) {
+ if (sInstance == null) {
+ sInstance = new ZenModeBackend(context);
+ }
+ return sInstance;
+ }
+
+ public ZenModeBackend(Context context) {
+ mContext = context;
+ mNotificationManager = (NotificationManager) context.getSystemService(
+ Context.NOTIFICATION_SERVICE);
+ updateZenMode();
+ updatePolicy();
+ }
+
+ protected void updatePolicy() {
+ if (mNotificationManager != null) {
+ mPolicy = mNotificationManager.getNotificationPolicy();
+ }
+ }
+
+ protected void updateZenMode() {
+ mZenMode = Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.ZEN_MODE, mZenMode);
+ }
+
+ protected boolean setZenRule(String id, AutomaticZenRule rule) {
+ return NotificationManager.from(mContext).updateAutomaticZenRule(id, rule);
+ }
+
+ protected void setZenMode(int zenMode) {
+ NotificationManager.from(mContext).setZenMode(zenMode, null, TAG);
+ mZenMode = zenMode;
+ }
+
+ /** gets last zen mode set by setZenMode or updateZenMode **/
+ protected int getZenMode() {
+ mZenMode = Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.ZEN_MODE, mZenMode);
+ return mZenMode;
+ }
+
+ protected boolean isPriorityCategoryEnabled(int categoryType) {
+ return (mPolicy.priorityCategories & categoryType) != 0;
+ }
+
+ protected int getNewPriorityCategories(boolean allow, int categoryType) {
+ int priorityCategories = mPolicy.priorityCategories;
+ if (allow) {
+ priorityCategories |= categoryType;
+ } else {
+ priorityCategories &= ~categoryType;
+ }
+ return priorityCategories;
+ }
+
+ protected int getPriorityCallSenders() {
+ return mPolicy.priorityCallSenders;
+ }
+
+ protected int getPriorityMessageSenders() {
+ return mPolicy.priorityMessageSenders;
+ }
+
+ protected void saveVisualEffectsPolicy(int category, boolean canBypass) {
+ int suppressedEffects = getNewSuppressedEffects(!canBypass, category);
+ savePolicy(mPolicy.priorityCategories, mPolicy.priorityCallSenders,
+ mPolicy.priorityMessageSenders, suppressedEffects);
+ }
+
+ protected void saveSoundPolicy(int category, boolean allow) {
+ int priorityCategories = getNewPriorityCategories(allow, category);
+ savePolicy(priorityCategories, mPolicy.priorityCallSenders,
+ mPolicy.priorityMessageSenders, mPolicy.suppressedVisualEffects);
+ }
+
+ protected void savePolicy(int priorityCategories, int priorityCallSenders,
+ int priorityMessageSenders, int suppressedVisualEffects) {
+ mPolicy = new NotificationManager.Policy(priorityCategories, priorityCallSenders,
+ priorityMessageSenders,
+ suppressedVisualEffects);
+ mNotificationManager.setNotificationPolicy(mPolicy);
+ }
+
+ protected int getNewSuppressedEffects(boolean suppress, int effectType) {
+ int effects = mPolicy.suppressedVisualEffects;
+ if (suppress) {
+ effects |= effectType;
+ } else {
+ effects &= ~effectType;
+ }
+ return effects;
+ }
+
+ protected boolean isEffectAllowed(int effect) {
+ return (mPolicy.suppressedVisualEffects & effect) == 0;
+ }
+
+ protected void saveSenders(int category, int val) {
+ int priorityCallSenders = getPriorityCallSenders();
+ int priorityMessagesSenders = getPriorityMessageSenders();
+ int categorySenders = getPrioritySenders(category);
+
+ final boolean allowSenders = val != SOURCE_NONE;
+ final int allowSendersFrom = val == SOURCE_NONE ? categorySenders : val;
+
+ String stringCategory = "";
+ if (category == NotificationManager.Policy.PRIORITY_CATEGORY_CALLS) {
+ stringCategory = "Calls";
+ priorityCallSenders = allowSendersFrom;
+ }
+
+ if (category == NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES) {
+ stringCategory = "Messages";
+ priorityMessagesSenders = allowSendersFrom;
+ }
+
+ savePolicy(getNewPriorityCategories(allowSenders, category),
+ priorityCallSenders, priorityMessagesSenders, mPolicy.suppressedVisualEffects);
+
+ if (ZenModeSettingsBase.DEBUG) Log.d(TAG, "onPrefChange allow=" +
+ stringCategory + allowSenders + " allow" + stringCategory + "From="
+ + ZenModeConfig.sourceToString(allowSendersFrom));
+ }
+
+ protected String getSendersKey(int category) {
+ switch (getZenMode()) {
+ case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
+ case Settings.Global.ZEN_MODE_ALARMS:
+ return getKeyFromSetting(SOURCE_NONE);
+ default:
+ int prioritySenders = getPrioritySenders(category);
+ return getKeyFromSetting(isPriorityCategoryEnabled(category)
+ ? prioritySenders : SOURCE_NONE);
+ }
+ }
+
+ private int getPrioritySenders(int category) {
+ int categorySenders = -1;
+
+ if (category == NotificationManager.Policy.PRIORITY_CATEGORY_CALLS) {
+ return getPriorityCallSenders();
+ }
+
+ if (category == NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES) {
+ return getPriorityMessageSenders();
+ }
+
+ return categorySenders;
+ }
+
+ protected static String getKeyFromSetting(int contactType) {
+ switch (contactType) {
+ case NotificationManager.Policy.PRIORITY_SENDERS_ANY:
+ return ZEN_MODE_FROM_ANYONE;
+ case NotificationManager.Policy.PRIORITY_SENDERS_CONTACTS:
+ return ZEN_MODE_FROM_CONTACTS;
+ case NotificationManager.Policy.PRIORITY_SENDERS_STARRED:
+ return ZEN_MODE_FROM_STARRED;
+ case SOURCE_NONE:
+ default:
+ return ZEN_MODE_FROM_NONE;
+ }
+ }
+
+ protected int getContactsSummary(int category) {
+ int contactType = -1;
+
+ // SOURCE_NONE can be used when in total silence or alarms only
+ // (policy is based on user's preferences but the UI displayed is based on zenMode)
+ if (category == SOURCE_NONE) {
+ return R.string.zen_mode_from_none;
+ }
+
+ if (category == NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES) {
+ if (isPriorityCategoryEnabled(category)) {
+ contactType = getPriorityMessageSenders();
+ }
+ } else if (category == NotificationManager.Policy.PRIORITY_CATEGORY_CALLS) {
+ if (isPriorityCategoryEnabled(category)) {
+ contactType = getPriorityCallSenders();
+ }
+ }
+
+ switch (contactType) {
+ case NotificationManager.Policy.PRIORITY_SENDERS_ANY:
+ return R.string.zen_mode_from_anyone;
+ case NotificationManager.Policy.PRIORITY_SENDERS_CONTACTS:
+ return R.string.zen_mode_from_contacts;
+ case NotificationManager.Policy.PRIORITY_SENDERS_STARRED:
+ return R.string.zen_mode_from_starred;
+ case SOURCE_NONE:
+ default:
+ return R.string.zen_mode_from_none;
+ }
+ }
+
+ protected static int getSettingFromPrefKey(String key) {
+ switch (key) {
+ case ZEN_MODE_FROM_ANYONE:
+ return NotificationManager.Policy.PRIORITY_SENDERS_ANY;
+ case ZEN_MODE_FROM_CONTACTS:
+ return NotificationManager.Policy.PRIORITY_SENDERS_CONTACTS;
+ case ZEN_MODE_FROM_STARRED:
+ return NotificationManager.Policy.PRIORITY_SENDERS_STARRED;
+ case ZEN_MODE_FROM_NONE:
+ default:
+ return SOURCE_NONE;
+ }
+ }
+
+ public boolean removeZenRule(String ruleId) {
+ return NotificationManager.from(mContext).removeAutomaticZenRule(ruleId);
+ }
+
+ protected String addZenRule(AutomaticZenRule rule) {
+ try {
+ String id = NotificationManager.from(mContext).addAutomaticZenRule(rule);
+ NotificationManager.from(mContext).getAutomaticZenRule(id);
+ return id;
+ } catch (Exception e) {
+ return null;
+ }
+ }
+}
diff --git a/src/com/android/settings/notification/ZenModeBehaviorPreferenceController.java b/src/com/android/settings/notification/ZenModeBehaviorPreferenceController.java
new file mode 100644
index 0000000..0e1f066
--- /dev/null
+++ b/src/com/android/settings/notification/ZenModeBehaviorPreferenceController.java
@@ -0,0 +1,37 @@
+package com.android.settings.notification;
+
+import android.content.Context;
+import android.support.v7.preference.Preference;
+
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public class ZenModeBehaviorPreferenceController extends
+ AbstractZenModePreferenceController implements PreferenceControllerMixin {
+
+ protected static final String KEY_BEHAVIOR_SETTINGS = "zen_mode_behavior_settings";
+ private final ZenModeSettings.SummaryBuilder mSummaryBuilder;
+
+ public ZenModeBehaviorPreferenceController(Context context, Lifecycle lifecycle) {
+ super(context, KEY_BEHAVIOR_SETTINGS, lifecycle);
+ mSummaryBuilder = new ZenModeSettings.SummaryBuilder(context);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_BEHAVIOR_SETTINGS;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+
+ preference.setSummary(mSummaryBuilder.getBehaviorSettingSummary(getPolicy(),
+ getZenMode()));
+ }
+}
diff --git a/src/com/android/settings/notification/ZenModeBehaviorSettings.java b/src/com/android/settings/notification/ZenModeBehaviorSettings.java
index 6fc97cf..dfe6786 100644
--- a/src/com/android/settings/notification/ZenModeBehaviorSettings.java
+++ b/src/com/android/settings/notification/ZenModeBehaviorSettings.java
@@ -16,303 +16,43 @@
package com.android.settings.notification;
-import android.app.NotificationManager;
-import android.app.NotificationManager.Policy;
import android.content.Context;
-import android.os.Bundle;
-import android.provider.SearchIndexableResource;
-import android.provider.Settings;
-import android.service.notification.ZenModeConfig;
-import android.support.v14.preference.SwitchPreference;
-import android.support.v7.preference.DropDownPreference;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.Preference.OnPreferenceChangeListener;
-import android.support.v7.preference.PreferenceScreen;
-import android.util.Log;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
-import java.util.Arrays;
+import java.util.ArrayList;
import java.util.List;
public class ZenModeBehaviorSettings extends ZenModeSettingsBase implements Indexable {
- private static final String KEY_ALARMS = "zen_mode_alarms";
- private static final String KEY_MEDIA = "zen_mode_media";
- private static final String KEY_REMINDERS = "zen_mode_reminders";
- private static final String KEY_EVENTS = "zen_mode_events";
- private static final String KEY_MESSAGES = "zen_mode_messages";
- private static final String KEY_CALLS = "zen_mode_calls";
- private static final String KEY_REPEAT_CALLERS = "zen_mode_repeat_callers";
- private static final String KEY_SCREEN_OFF = "zen_mode_screen_off";
- private static final String KEY_SCREEN_ON = "zen_mode_screen_on";
-
- private SwitchPreference mScreenOff;
- private SwitchPreference mScreenOn;
-
- private static final int SOURCE_NONE = -1;
-
- private boolean mDisableListeners;
- private SwitchPreference mReminders;
- private SwitchPreference mEvents;
- private DropDownPreference mMessages;
- private DropDownPreference mCalls;
- private SwitchPreference mRepeatCallers;
- private SwitchPreference mAlarms;
- private SwitchPreference mMediaSystemOther;
-
- private Policy mPolicy;
@Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- addPreferencesFromResource(R.xml.zen_mode_behavior_settings);
- final PreferenceScreen root = getPreferenceScreen();
+ protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
+ return buildPreferenceControllers(context, getLifecycle());
+ }
- mPolicy = NotificationManager.from(mContext).getNotificationPolicy();
-
- mReminders = (SwitchPreference) root.findPreference(KEY_REMINDERS);
- mReminders.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- if (mDisableListeners) return true;
- final boolean val = (Boolean) newValue;
- mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_ZEN_ALLOW_REMINDERS,
- val);
- if (DEBUG) Log.d(TAG, "onPrefChange allowReminders=" + val);
- savePolicy(getNewPriorityCategories(val, Policy.PRIORITY_CATEGORY_REMINDERS),
- mPolicy.priorityCallSenders, mPolicy.priorityMessageSenders,
- mPolicy.suppressedVisualEffects);
- return true;
- }
- });
-
- mEvents = (SwitchPreference) root.findPreference(KEY_EVENTS);
- mEvents.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- if (mDisableListeners) return true;
- final boolean val = (Boolean) newValue;
- mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_ZEN_ALLOW_EVENTS, val);
- if (DEBUG) Log.d(TAG, "onPrefChange allowEvents=" + val);
- savePolicy(getNewPriorityCategories(val, Policy.PRIORITY_CATEGORY_EVENTS),
- mPolicy.priorityCallSenders, mPolicy.priorityMessageSenders,
- mPolicy.suppressedVisualEffects);
- return true;
- }
- });
-
- mMessages = (DropDownPreference) root.findPreference(KEY_MESSAGES);
- addSources(mMessages);
- mMessages.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- if (mDisableListeners) return false;
- final int val = Integer.parseInt((String) newValue);
- final boolean allowMessages = val != SOURCE_NONE;
- final int allowMessagesFrom =
- val == SOURCE_NONE ? mPolicy.priorityMessageSenders : val;
- mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_ZEN_ALLOW_MESSAGES, val);
- if (DEBUG) Log.d(TAG, "onPrefChange allowMessages=" + allowMessages
- + " allowMessagesFrom=" + ZenModeConfig.sourceToString(allowMessagesFrom));
- savePolicy(
- getNewPriorityCategories(allowMessages, Policy.PRIORITY_CATEGORY_MESSAGES),
- mPolicy.priorityCallSenders, allowMessagesFrom,
- mPolicy.suppressedVisualEffects);
- return true;
- }
- });
-
- mCalls = (DropDownPreference) root.findPreference(KEY_CALLS);
- addSources(mCalls);
- mCalls.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- if (mDisableListeners) return false;
- final int val = Integer.parseInt((String) newValue);
- final boolean allowCalls = val != SOURCE_NONE;
- final int allowCallsFrom = val == SOURCE_NONE ? mPolicy.priorityCallSenders : val;
- mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_ZEN_ALLOW_CALLS, val);
- if (DEBUG) Log.d(TAG, "onPrefChange allowCalls=" + allowCalls
- + " allowCallsFrom=" + ZenModeConfig.sourceToString(allowCallsFrom));
- savePolicy(getNewPriorityCategories(allowCalls, Policy.PRIORITY_CATEGORY_CALLS),
- allowCallsFrom, mPolicy.priorityMessageSenders,
- mPolicy.suppressedVisualEffects);
- return true;
- }
- });
-
- mRepeatCallers = (SwitchPreference) root.findPreference(KEY_REPEAT_CALLERS);
- mRepeatCallers.setSummary(mContext.getString(R.string.zen_mode_repeat_callers_summary,
- mContext.getResources().getInteger(com.android.internal.R.integer
- .config_zen_repeat_callers_threshold)));
- mRepeatCallers.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- if (mDisableListeners) return true;
- final boolean val = (Boolean) newValue;
- mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_ZEN_ALLOW_REPEAT_CALLS,
- val);
- if (DEBUG) Log.d(TAG, "onPrefChange allowRepeatCallers=" + val);
- int priorityCategories = getNewPriorityCategories(val,
- Policy.PRIORITY_CATEGORY_REPEAT_CALLERS);
- savePolicy(priorityCategories, mPolicy.priorityCallSenders,
- mPolicy.priorityMessageSenders, mPolicy.suppressedVisualEffects);
- return true;
- }
- });
-
- mAlarms = (SwitchPreference) root.findPreference(KEY_ALARMS);
- mAlarms.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- if (mDisableListeners) return true;
- final boolean val = (Boolean) newValue;
- mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_ZEN_ALLOW_ALARMS, val);
- if (DEBUG) Log.d(TAG, "onPrefChange allowAlarms=" + val);
- savePolicy(getNewPriorityCategories(val, Policy.PRIORITY_CATEGORY_ALARMS),
- mPolicy.priorityCallSenders, mPolicy.priorityMessageSenders,
- mPolicy.suppressedVisualEffects);
- return true;
- }
- });
-
- mMediaSystemOther = (SwitchPreference) root.findPreference(KEY_MEDIA);
- mMediaSystemOther.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- if (mDisableListeners) return true;
- final boolean val = (Boolean) newValue;
- mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_ZEN_ALLOW_MEDIA, val);
- if (DEBUG) Log.d(TAG, "onPrefChange allowMediaSystemOther=" + val);
- savePolicy(getNewPriorityCategories(val,
- Policy.PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER),
- mPolicy.priorityCallSenders, mPolicy.priorityMessageSenders,
- mPolicy.suppressedVisualEffects);
- return true;
- }
- });
-
- mScreenOff = (SwitchPreference) root.findPreference(KEY_SCREEN_OFF);
- if (!getResources()
- .getBoolean(com.android.internal.R.bool.config_intrusiveNotificationLed)) {
- mScreenOff.setSummary(R.string.zen_mode_screen_off_summary_no_led);
- }
-
- mScreenOff.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- if (mDisableListeners) return true;
- final boolean bypass = (Boolean) newValue;
- mMetricsFeatureProvider.action(mContext,
- MetricsEvent.ACTION_ZEN_ALLOW_WHEN_SCREEN_OFF, !bypass);
- if (DEBUG) Log.d(TAG, "onPrefChange suppressWhenScreenOff=" + !bypass);
- savePolicy(mPolicy.priorityCategories,
- mPolicy.priorityCallSenders, mPolicy.priorityMessageSenders,
- getNewSuppressedEffects(!bypass, Policy.SUPPRESSED_EFFECT_SCREEN_OFF));
- return true;
- }
- });
-
- mScreenOn = (SwitchPreference) root.findPreference(KEY_SCREEN_ON);
- mScreenOn.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- if (mDisableListeners) return true;
- final boolean bypass = (Boolean) newValue;
- mMetricsFeatureProvider.action(mContext,
- MetricsEvent.ACTION_ZEN_ALLOW_WHEN_SCREEN_ON, bypass);
- if (DEBUG) Log.d(TAG, "onPrefChange allowWhenScreenOn=" + !bypass);
- savePolicy(mPolicy.priorityCategories,
- mPolicy.priorityCallSenders, mPolicy.priorityMessageSenders,
- getNewSuppressedEffects(!bypass, Policy.SUPPRESSED_EFFECT_SCREEN_ON));
- return true;
- }
- });
-
- updateControls();
+ private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
+ Lifecycle lifecycle) {
+ List<AbstractPreferenceController> controllers = new ArrayList<>();
+ controllers.add(new ZenModeAlarmsPreferenceController(context, lifecycle));
+ controllers.add(new ZenModeMediaSystemOtherPreferenceController(context, lifecycle));
+ controllers.add(new ZenModeEventsPreferenceController(context, lifecycle));
+ controllers.add(new ZenModeRemindersPreferenceController(context, lifecycle));
+ controllers.add(new ZenModeMessagesPreferenceController(context, lifecycle));
+ controllers.add(new ZenModeCallsPreferenceController(context, lifecycle));
+ controllers.add(new ZenModeRepeatCallersPreferenceController(context, lifecycle));
+ controllers.add(new ZenModeScreenOnPreferenceController(context, lifecycle));
+ controllers.add(new ZenModeScreenOffPreferenceController(context, lifecycle));
+ return controllers;
}
@Override
- protected void onZenModeChanged() {
- updateControls();
- }
-
- @Override
- protected void onZenModeConfigChanged() {
- mPolicy = NotificationManager.from(mContext).getNotificationPolicy();
- updateControls();
- }
-
- private void updateControlsPolicy() {
- if (mCalls != null) {
- mCalls.setValue(Integer.toString(
- isPriorityCategoryEnabled(Policy.PRIORITY_CATEGORY_CALLS)
- ? mPolicy.priorityCallSenders : SOURCE_NONE));
- }
- mMessages.setValue(Integer.toString(
- isPriorityCategoryEnabled(Policy.PRIORITY_CATEGORY_MESSAGES)
- ? mPolicy.priorityMessageSenders : SOURCE_NONE));
- mAlarms.setChecked(isPriorityCategoryEnabled(Policy.PRIORITY_CATEGORY_ALARMS));
- mMediaSystemOther.setChecked(isPriorityCategoryEnabled(
- Policy.PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER));
- mReminders.setChecked(isPriorityCategoryEnabled(Policy.PRIORITY_CATEGORY_REMINDERS));
- mEvents.setChecked(isPriorityCategoryEnabled(Policy.PRIORITY_CATEGORY_EVENTS));
- mRepeatCallers.setChecked(
- isPriorityCategoryEnabled(Policy.PRIORITY_CATEGORY_REPEAT_CALLERS));
- mRepeatCallers.setVisible(!isPriorityCategoryEnabled(Policy.PRIORITY_CATEGORY_CALLS)
- || mPolicy.priorityCallSenders != Policy.PRIORITY_SENDERS_ANY);
-
- }
-
- private void updateControls() {
- mDisableListeners = true;
- switch(mZenMode) {
- case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
- toggleBasicNoInterruptions();
- mAlarms.setChecked(false);
- mMediaSystemOther.setChecked(false);
- setTogglesEnabled(false);
- break;
- case Settings.Global.ZEN_MODE_ALARMS:
- toggleBasicNoInterruptions();
- mAlarms.setChecked(true);
- mMediaSystemOther.setChecked(true);
- setTogglesEnabled(false);
- break;
- default:
- updateControlsPolicy();
- setTogglesEnabled(true);
- }
-
- mScreenOff.setChecked(isEffectAllowed(Policy.SUPPRESSED_EFFECT_SCREEN_OFF));
- mScreenOn.setChecked(isEffectAllowed(Policy.SUPPRESSED_EFFECT_SCREEN_ON));
-
- mDisableListeners = false;
- }
-
- private void toggleBasicNoInterruptions() {
- if (mCalls != null) {
- mCalls.setValue(Integer.toString(SOURCE_NONE));
- }
- mMessages.setValue(Integer.toString(SOURCE_NONE));
- mReminders.setChecked(false);
- mEvents.setChecked(false);
- mRepeatCallers.setChecked(false);
- }
-
- private void setTogglesEnabled(boolean enable) {
- if (mCalls != null) {
- mCalls.setEnabled(enable);
- }
- mMessages.setEnabled(enable);
- mReminders.setEnabled(enable);
- mEvents.setEnabled(enable);
- mRepeatCallers.setEnabled(enable);
- mAlarms.setEnabled(enable);
- mMediaSystemOther.setEnabled(enable);
+ protected int getPreferenceScreenResId() {
+ return R.xml.zen_mode_behavior_settings;
}
@Override
@@ -320,67 +60,29 @@
return MetricsEvent.NOTIFICATION_ZEN_MODE_PRIORITY;
}
- private static void addSources(DropDownPreference pref) {
- pref.setEntries(new CharSequence[]{
- pref.getContext().getString(R.string.zen_mode_from_anyone),
- pref.getContext().getString(R.string.zen_mode_from_contacts),
- pref.getContext().getString(R.string.zen_mode_from_starred),
- pref.getContext().getString(R.string.zen_mode_from_none),
- });
- pref.setEntryValues(new CharSequence[] {
- Integer.toString(Policy.PRIORITY_SENDERS_ANY),
- Integer.toString(Policy.PRIORITY_SENDERS_CONTACTS),
- Integer.toString(Policy.PRIORITY_SENDERS_STARRED),
- Integer.toString(SOURCE_NONE),
- });
- }
-
- private boolean isPriorityCategoryEnabled(int categoryType) {
- return (mPolicy.priorityCategories & categoryType) != 0;
- }
-
- private int getNewPriorityCategories(boolean allow, int categoryType) {
- int priorityCategories = mPolicy.priorityCategories;
- if (allow) {
- priorityCategories |= categoryType;
- } else {
- priorityCategories &= ~categoryType;
- }
- return priorityCategories;
- }
-
- private void savePolicy(int priorityCategories, int priorityCallSenders,
- int priorityMessageSenders, int suppressedVisualEffects) {
- mPolicy = new Policy(priorityCategories, priorityCallSenders, priorityMessageSenders,
- suppressedVisualEffects);
- NotificationManager.from(mContext).setNotificationPolicy(mPolicy);
- }
-
/**
* For Search.
*/
public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
@Override
- public List<SearchIndexableResource> getXmlResourcesToIndex(
- Context context, boolean enabled) {
- final SearchIndexableResource sir = new SearchIndexableResource(context);
- sir.xmlResId = R.xml.zen_mode_behavior_settings;
- return Arrays.asList(sir);
+ public List<String> getNonIndexableKeys(Context context) {
+ final List<String> keys = super.getNonIndexableKeys(context);
+ keys.add(ZenModeAlarmsPreferenceController.KEY);
+ keys.add(ZenModeMediaSystemOtherPreferenceController.KEY);
+ keys.add(ZenModeEventsPreferenceController.KEY);
+ keys.add(ZenModeRemindersPreferenceController.KEY);
+ keys.add(ZenModeMessagesPreferenceController.KEY);
+ keys.add(ZenModeCallsPreferenceController.KEY);
+ keys.add(ZenModeRepeatCallersPreferenceController.KEY);
+ keys.add(ZenModeScreenOnPreferenceController.KEY);
+ keys.add(ZenModeScreenOffPreferenceController.KEY);
+ return keys;
}
- };
- private int getNewSuppressedEffects(boolean suppress, int effectType) {
- int effects = mPolicy.suppressedVisualEffects;
- if (suppress) {
- effects |= effectType;
- } else {
- effects &= ~effectType;
- }
- return effects;
- }
-
- private boolean isEffectAllowed(int effect) {
- return (mPolicy.suppressedVisualEffects & effect) == 0;
- }
+ @Override
+ public List<AbstractPreferenceController> getPreferenceControllers(Context context) {
+ return buildPreferenceControllers(context, null);
+ }
+ };
}
diff --git a/src/com/android/settings/notification/ZenModeButtonPreferenceController.java b/src/com/android/settings/notification/ZenModeButtonPreferenceController.java
new file mode 100644
index 0000000..79115f2
--- /dev/null
+++ b/src/com/android/settings/notification/ZenModeButtonPreferenceController.java
@@ -0,0 +1,88 @@
+/*
+ * 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.provider.Settings;
+import android.support.v7.preference.Preference;
+import android.view.View;
+import android.widget.Button;
+
+import com.android.settings.R;
+import com.android.settings.applications.LayoutPreference;
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public class ZenModeButtonPreferenceController extends AbstractZenModePreferenceController
+ implements PreferenceControllerMixin {
+
+ protected static final String KEY = "zen_mode_settings_button_container";
+ private Button mZenButtonOn;
+ private Button mZenButtonOff;
+ private ZenModeBackend mBackend;
+
+ public ZenModeButtonPreferenceController(Context context, Lifecycle lifecycle) {
+ super(context, KEY, lifecycle);
+ mBackend = ZenModeBackend.getInstance(context);
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+
+ if (null == mZenButtonOn) {
+ mZenButtonOn = (Button) ((LayoutPreference) preference)
+ .findViewById(R.id.zen_mode_settings_turn_on_button);
+ mZenButtonOn.setOnClickListener(v ->
+ mBackend.setZenMode(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS));
+ }
+
+ if (null == mZenButtonOff) {
+ mZenButtonOff = (Button) ((LayoutPreference) preference)
+ .findViewById(R.id.zen_mode_settings_turn_off_button);
+ mZenButtonOff.setOnClickListener(v ->
+ mBackend.setZenMode(Settings.Global.ZEN_MODE_OFF));
+ }
+
+ updateButtons();
+ }
+
+ private void updateButtons() {
+ switch (getZenMode()) {
+ case Settings.Global.ZEN_MODE_ALARMS:
+ case Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
+ case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
+ mZenButtonOff.setVisibility(View.VISIBLE);
+ mZenButtonOn.setVisibility(View.GONE);
+ break;
+ case Settings.Global.ZEN_MODE_OFF:
+ default:
+ mZenButtonOff.setVisibility(View.GONE);
+ mZenButtonOn.setVisibility(View.VISIBLE);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/notification/ZenModeCallsPreferenceController.java b/src/com/android/settings/notification/ZenModeCallsPreferenceController.java
new file mode 100644
index 0000000..48f9d1c
--- /dev/null
+++ b/src/com/android/settings/notification/ZenModeCallsPreferenceController.java
@@ -0,0 +1,64 @@
+/*
+ * 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.app.NotificationManager;
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v7.preference.Preference;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public class ZenModeCallsPreferenceController extends
+ AbstractZenModePreferenceController {
+
+ protected static final String KEY = "zen_mode_calls";
+ private final ZenModeBackend mBackend;
+
+ public ZenModeCallsPreferenceController(Context context, Lifecycle lifecycle) {
+ super(context, KEY, lifecycle);
+ mBackend = ZenModeBackend.getInstance(context);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+
+ switch (getZenMode()) {
+ case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
+ case Settings.Global.ZEN_MODE_ALARMS:
+ preference.setEnabled(false);
+ preference.setSummary(mBackend.getContactsSummary(mBackend.SOURCE_NONE));
+ break;
+ default:
+ preference.setEnabled(true);
+ preference.setSummary(mBackend.getContactsSummary(
+ NotificationManager.Policy.PRIORITY_CATEGORY_CALLS));
+ }
+
+ }
+}
diff --git a/src/com/android/settings/notification/ZenModeCallsSettings.java b/src/com/android/settings/notification/ZenModeCallsSettings.java
new file mode 100644
index 0000000..6874dc0
--- /dev/null
+++ b/src/com/android/settings/notification/ZenModeCallsSettings.java
@@ -0,0 +1,113 @@
+/*
+ * 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.app.NotificationManager;
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
+import com.android.settings.widget.RadioButtonPickerFragment;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ZenModeCallsSettings extends RadioButtonPickerFragment {
+ private ZenModeBackend mBackend;
+
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+ mBackend = ZenModeBackend.getInstance(context);
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsProto.MetricsEvent.NOTIFICATION_ZEN_MODE_CALLS;
+ }
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.zen_mode_calls_settings;
+ }
+
+ @Override
+ protected List<? extends RadioButtonPickerFragment.CandidateInfo> getCandidates() {
+ final String[] entries = entries();
+ final String[] values = keys();
+ final List<CallsCandidateInfo> candidates = new ArrayList<>();
+
+ if (entries == null || entries.length <= 0) return null;
+ if (values == null || values.length != entries.length) {
+ throw new IllegalArgumentException("Entries and values must be of the same length.");
+ }
+
+ for (int i = 0; i < entries.length; i++) {
+ candidates.add(new CallsCandidateInfo(entries[i], values[i]));
+ }
+
+ return candidates;
+ }
+
+ private String[] entries() {
+ return getResources().getStringArray(R.array.zen_mode_contacts_entries);
+ }
+
+ private String[] keys() {
+ return getResources().getStringArray(R.array.zen_mode_contacts_values);
+ }
+
+ @Override
+ protected String getDefaultKey() {
+ return mBackend.getSendersKey(NotificationManager.Policy.PRIORITY_CATEGORY_CALLS);
+ }
+
+ @Override
+ protected boolean setDefaultKey(String key) {
+ mBackend.saveSenders(NotificationManager.Policy.PRIORITY_CATEGORY_CALLS,
+ mBackend.getSettingFromPrefKey(key));
+ return true;
+ }
+
+ private static final class CallsCandidateInfo extends RadioButtonPickerFragment.CandidateInfo {
+ private final String name;
+ private final String key;
+
+ CallsCandidateInfo(String title, String value) {
+ super(true);
+
+ name = title;
+ key = value;
+ }
+
+ @Override
+ public CharSequence loadLabel() {
+ return name;
+ }
+
+ @Override
+ public Drawable loadIcon() {
+ return null;
+ }
+
+ @Override
+ public String getKey() {
+ return key;
+ }
+ }
+}
diff --git a/src/com/android/settings/notification/ZenModeEventRuleSettings.java b/src/com/android/settings/notification/ZenModeEventRuleSettings.java
index 3361734..aa2cc3f 100644
--- a/src/com/android/settings/notification/ZenModeEventRuleSettings.java
+++ b/src/com/android/settings/notification/ZenModeEventRuleSettings.java
@@ -33,6 +33,7 @@
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.Collections;
@@ -81,6 +82,16 @@
mCreate = false;
}
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.zen_mode_event_rule_settings;
+ }
+
+ @Override
+ protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
+ return null;
+ }
+
private void reloadCalendar() {
mCalendars = getCalendars(mContext);
ArrayList<CharSequence> entries = new ArrayList<>();
@@ -107,7 +118,6 @@
@Override
protected void onCreateInternal() {
mCreate = true;
- addPreferencesFromResource(R.xml.zen_mode_event_rule_settings);
final PreferenceScreen root = getPreferenceScreen();
mCalendar = (DropDownPreference) root.findPreference(KEY_CALENDAR);
@@ -243,5 +253,4 @@
public String name;
public int userId;
}
-
}
diff --git a/src/com/android/settings/notification/ZenModeEventsPreferenceController.java b/src/com/android/settings/notification/ZenModeEventsPreferenceController.java
new file mode 100644
index 0000000..335002c
--- /dev/null
+++ b/src/com/android/settings/notification/ZenModeEventsPreferenceController.java
@@ -0,0 +1,77 @@
+/*
+ * 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.app.NotificationManager.Policy;
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.Preference;
+import android.util.Log;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public class ZenModeEventsPreferenceController extends
+ AbstractZenModePreferenceController implements Preference.OnPreferenceChangeListener{
+
+ protected static final String KEY = "zen_mode_events";
+ private final ZenModeBackend mBackend;
+
+ public ZenModeEventsPreferenceController(Context context, Lifecycle lifecycle) {
+ super(context, KEY, lifecycle);
+ mBackend = ZenModeBackend.getInstance(context);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+
+ SwitchPreference pref = (SwitchPreference) preference;
+ switch (getZenMode()) {
+ case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
+ case Settings.Global.ZEN_MODE_ALARMS:
+ pref.setEnabled(false);
+ pref.setChecked(false);
+ break;
+ default:
+ pref.setChecked(mBackend.isPriorityCategoryEnabled(
+ Policy.PRIORITY_CATEGORY_EVENTS));
+ pref.setEnabled(true);
+ }
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ final boolean allowEvents = (Boolean) newValue;
+ if (ZenModeSettingsBase.DEBUG) {
+ Log.d(TAG, "onPrefChange allowEvents="
+ + allowEvents);
+ }
+ mBackend.saveSoundPolicy(Policy.PRIORITY_CATEGORY_EVENTS, allowEvents);
+ return true;
+ }
+}
diff --git a/src/com/android/settings/notification/ZenModeMediaSystemOtherPreferenceController.java b/src/com/android/settings/notification/ZenModeMediaSystemOtherPreferenceController.java
new file mode 100644
index 0000000..8893ff5
--- /dev/null
+++ b/src/com/android/settings/notification/ZenModeMediaSystemOtherPreferenceController.java
@@ -0,0 +1,80 @@
+/*
+ * 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.app.NotificationManager.Policy;
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.Preference;
+import android.util.Log;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public class ZenModeMediaSystemOtherPreferenceController extends
+ AbstractZenModePreferenceController implements Preference.OnPreferenceChangeListener{
+
+ protected static final String KEY = "zen_mode_media";
+ private final ZenModeBackend mBackend;
+
+ public ZenModeMediaSystemOtherPreferenceController(Context context, Lifecycle lifecycle) {
+ super(context, KEY, lifecycle);
+ mBackend = ZenModeBackend.getInstance(context);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+
+ SwitchPreference pref = (SwitchPreference) preference;
+ switch (getZenMode()) {
+ case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
+ pref.setEnabled(false);
+ pref.setChecked(false);
+ break;
+ case Settings.Global.ZEN_MODE_ALARMS:
+ pref.setEnabled(false);
+ pref.setChecked(true);
+ break;
+ default:
+ pref.setEnabled(true);
+ pref.setChecked(mBackend.isPriorityCategoryEnabled(
+ Policy.PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER));
+ }
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ final boolean allowMedia = (Boolean) newValue;
+ if (ZenModeSettingsBase.DEBUG) {
+ Log.d(TAG,
+ "onPrefChange allowMediaSystemOther=" + allowMedia);
+ }
+ mBackend.saveSoundPolicy(Policy.PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER, allowMedia);
+ return true;
+ }
+}
diff --git a/src/com/android/settings/notification/ZenModeMessagesPreferenceController.java b/src/com/android/settings/notification/ZenModeMessagesPreferenceController.java
new file mode 100644
index 0000000..257a7c9
--- /dev/null
+++ b/src/com/android/settings/notification/ZenModeMessagesPreferenceController.java
@@ -0,0 +1,47 @@
+package com.android.settings.notification;
+
+import android.app.NotificationManager;
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v7.preference.Preference;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public class ZenModeMessagesPreferenceController extends
+ AbstractZenModePreferenceController {
+
+ protected static final String KEY = "zen_mode_messages";
+ private final ZenModeBackend mBackend;
+
+ public ZenModeMessagesPreferenceController(Context context, Lifecycle lifecycle) {
+ super(context, KEY, lifecycle);
+ mBackend = ZenModeBackend.getInstance(context);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+
+ switch (getZenMode()) {
+ case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
+ case Settings.Global.ZEN_MODE_ALARMS:
+ preference.setEnabled(false);
+ preference.setSummary(mBackend.getContactsSummary(mBackend.SOURCE_NONE));
+ break;
+ default:
+ preference.setEnabled(true);
+ preference.setSummary(mBackend.getContactsSummary(
+ NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES));
+ }
+ }
+}
diff --git a/src/com/android/settings/notification/ZenModeMessagesSettings.java b/src/com/android/settings/notification/ZenModeMessagesSettings.java
new file mode 100644
index 0000000..9cbf248
--- /dev/null
+++ b/src/com/android/settings/notification/ZenModeMessagesSettings.java
@@ -0,0 +1,112 @@
+/*
+ * 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.app.NotificationManager;
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
+import com.android.settings.widget.RadioButtonPickerFragment;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ZenModeMessagesSettings extends RadioButtonPickerFragment {
+ private ZenModeBackend mBackend;
+
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+ mBackend = ZenModeBackend.getInstance(context);
+ }
+ @Override
+ public int getMetricsCategory() {
+ return MetricsProto.MetricsEvent.NOTIFICATION_ZEN_MODE_MESSAGES;
+ }
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.zen_mode_messages_settings;
+ }
+
+ @Override
+ protected List<? extends RadioButtonPickerFragment.CandidateInfo> getCandidates() {
+ final String[] entries = entries();
+ final String[] values = keys();
+ final List<MessagesCandidateInfo> candidates = new ArrayList<>();
+
+ if (entries == null || entries.length <= 0) return null;
+ if (values == null || values.length != entries.length) {
+ throw new IllegalArgumentException("Entries and values must be of the same length.");
+ }
+
+ for (int i = 0; i < entries.length; i++) {
+ candidates.add(new MessagesCandidateInfo(entries[i], values[i]));
+ }
+
+ return candidates;
+ }
+
+ private String[] entries() {
+ return getResources().getStringArray(R.array.zen_mode_contacts_entries);
+ }
+
+ private String[] keys() {
+ return getResources().getStringArray(R.array.zen_mode_contacts_values);
+ }
+
+ @Override
+ protected String getDefaultKey() {
+ return mBackend.getSendersKey(NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES);
+ }
+
+ @Override
+ protected boolean setDefaultKey(String key) {
+ mBackend.saveSenders(NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES,
+ mBackend.getSettingFromPrefKey(key));
+ return true;
+ }
+
+ private final class MessagesCandidateInfo extends RadioButtonPickerFragment.CandidateInfo {
+ private final String name;
+ private final String key;
+
+ MessagesCandidateInfo(String title, String value) {
+ super(true);
+
+ name = title;
+ key = value;
+ }
+
+ @Override
+ public CharSequence loadLabel() {
+ return name;
+ }
+
+ @Override
+ public Drawable loadIcon() {
+ return null;
+ }
+
+ @Override
+ public String getKey() {
+ return key;
+ }
+ }
+}
diff --git a/src/com/android/settings/notification/ZenModeRemindersPreferenceController.java b/src/com/android/settings/notification/ZenModeRemindersPreferenceController.java
new file mode 100644
index 0000000..a8fe220
--- /dev/null
+++ b/src/com/android/settings/notification/ZenModeRemindersPreferenceController.java
@@ -0,0 +1,76 @@
+/*
+ * 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.app.NotificationManager;
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.Preference;
+import android.util.Log;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public class ZenModeRemindersPreferenceController extends
+ AbstractZenModePreferenceController implements Preference.OnPreferenceChangeListener{
+
+ protected static final String KEY = "zen_mode_reminders";
+ private final ZenModeBackend mBackend;
+
+ public ZenModeRemindersPreferenceController(Context context, Lifecycle lifecycle) {
+ super(context, KEY, lifecycle);
+ mBackend = ZenModeBackend.getInstance(context);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+
+ SwitchPreference pref = (SwitchPreference) preference;
+ switch (getZenMode()) {
+ case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
+ case Settings.Global.ZEN_MODE_ALARMS:
+ pref.setEnabled(false);
+ pref.setChecked(false);
+ break;
+ default:
+ pref.setEnabled(true);
+ pref.setChecked(mBackend.isPriorityCategoryEnabled(
+ NotificationManager.Policy.PRIORITY_CATEGORY_REMINDERS));
+ }
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ final boolean allowReminders = (Boolean) newValue;
+ if (ZenModeSettingsBase.DEBUG) Log.d(TAG, "onPrefChange allowReminders="
+ + allowReminders);
+ mBackend.saveSoundPolicy(NotificationManager.Policy.PRIORITY_CATEGORY_REMINDERS,
+ allowReminders);
+ return true;
+ }
+}
diff --git a/src/com/android/settings/notification/ZenModeRepeatCallersPreferenceController.java b/src/com/android/settings/notification/ZenModeRepeatCallersPreferenceController.java
new file mode 100644
index 0000000..eb52d55
--- /dev/null
+++ b/src/com/android/settings/notification/ZenModeRepeatCallersPreferenceController.java
@@ -0,0 +1,86 @@
+/*
+ * 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.app.NotificationManager.Policy;
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.Preference;
+import android.util.Log;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public class ZenModeRepeatCallersPreferenceController extends
+ AbstractZenModePreferenceController implements Preference.OnPreferenceChangeListener{
+
+
+ protected static final String KEY = "zen_mode_repeat_callers";
+ private final ZenModeBackend mBackend;
+
+ public ZenModeRepeatCallersPreferenceController(Context context, Lifecycle lifecycle) {
+ super(context, KEY, lifecycle);
+ mBackend = ZenModeBackend.getInstance(context);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+
+ SwitchPreference pref = (SwitchPreference) preference;
+
+ switch (getZenMode()) {
+ case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
+ case Settings.Global.ZEN_MODE_ALARMS:
+ pref.setEnabled(false);
+ pref.setChecked(false);
+ break;
+ default:
+ boolean anyCallersCanBypassDnd = (mBackend.isPriorityCategoryEnabled(
+ Policy.PRIORITY_CATEGORY_CALLS)
+ && mBackend.getPriorityCallSenders() == Policy.PRIORITY_SENDERS_ANY);
+ // 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(mBackend.isPriorityCategoryEnabled(
+ Policy.PRIORITY_CATEGORY_REPEAT_CALLERS));
+ }
+ }
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ final boolean allowRepeatCallers = (Boolean) newValue;
+ if (ZenModeSettingsBase.DEBUG) Log.d(TAG, "onPrefChange allowRepeatCallers="
+ + allowRepeatCallers);
+ mBackend.saveSoundPolicy(Policy.PRIORITY_CATEGORY_REPEAT_CALLERS, allowRepeatCallers);
+ return true;
+ }
+}
diff --git a/src/com/android/settings/notification/ZenModeRuleSettingsBase.java b/src/com/android/settings/notification/ZenModeRuleSettingsBase.java
index 83c6753..b0715dc 100644
--- a/src/com/android/settings/notification/ZenModeRuleSettingsBase.java
+++ b/src/com/android/settings/notification/ZenModeRuleSettingsBase.java
@@ -26,6 +26,7 @@
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
+import android.provider.SearchIndexableResource;
import android.service.notification.ConditionProviderService;
import android.support.v7.preference.DropDownPreference;
import android.support.v7.preference.Preference;
@@ -43,8 +44,13 @@
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.search.Indexable;
import com.android.settings.widget.SwitchBar;
+import java.util.Arrays;
+import java.util.List;
+
public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase
implements SwitchBar.OnSwitchChangeListener {
protected static final String TAG = ZenModeSettingsBase.TAG;
@@ -52,6 +58,8 @@
private static final String KEY_RULE_NAME = "rule_name";
private static final String KEY_ZEN_MODE = "zen_mode";
+ private static final String KEY_EVENT_RULE_SETTINGS = "zen_mode_event_rule_settings";
+ private static final String KEY_SCHEDULE_RULE_SETTINGS = "zen_mode_schedule_rule_settings";
protected Context mContext;
protected boolean mDisableListeners;
@@ -72,8 +80,6 @@
@Override
public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
-
mContext = getActivity();
final Intent intent = getActivity().getIntent();
@@ -96,6 +102,8 @@
return;
}
+ super.onCreate(icicle);
+
setHasOptionsMenu(true);
onCreateInternal();
@@ -129,7 +137,7 @@
if (zenMode == mRule.getInterruptionFilter()) return false;
if (DEBUG) Log.d(TAG, "onPrefChange zenMode=" + zenMode);
mRule.setInterruptionFilter(zenMode);
- setZenRule(mId, mRule);
+ mBackend.setZenRule(mId, mRule);
return true;
}
});
@@ -172,7 +180,7 @@
mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_ZEN_ENABLE_RULE, enabled);
if (DEBUG) Log.d(TAG, "onSwitchChanged enabled=" + enabled);
mRule.setEnabled(enabled);
- setZenRule(mId, mRule);
+ mBackend.setZenRule(mId, mRule);
if (enabled) {
final int toastText = getEnabledToastText();
if (toastText != 0) {
@@ -188,16 +196,12 @@
protected void updateRule(Uri newConditionId) {
mRule.setConditionId(newConditionId);
- setZenRule(mId, mRule);
- }
-
- @Override
- protected void onZenModeChanged() {
- // noop
+ mBackend.setZenRule(mId, mRule);
}
@Override
protected void onZenModeConfigChanged() {
+ super.onZenModeConfigChanged();
if (!refreshRuleOrFinish()) {
updateControls();
}
@@ -225,7 +229,7 @@
@Override
public void onOk(String ruleName) {
mRule.setName(ruleName);
- setZenRule(mId, mRule);
+ mBackend.setZenRule(mId, mRule);
}
}.show();
}
@@ -250,7 +254,7 @@
mMetricsFeatureProvider.action(mContext,
MetricsEvent.ACTION_ZEN_DELETE_RULE_OK);
mDeleting = true;
- removeZenRule(mId);
+ mBackend.removeZenRule(mId);
}
})
.show();
@@ -294,4 +298,25 @@
mDisableListeners = false;
}
+ /**
+ * For Search.
+ */
+ public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+ new BaseSearchIndexProvider() {
+ @Override
+ public List<SearchIndexableResource> getXmlResourcesToIndex(
+ Context context, boolean enabled) {
+ final SearchIndexableResource sir = new SearchIndexableResource(context);
+ // not indexable
+ return Arrays.asList(sir);
+ }
+
+ @Override
+ public List<String> getNonIndexableKeys(Context context) {
+ final List<String> keys = super.getNonIndexableKeys(context);
+ keys.add(KEY_SCHEDULE_RULE_SETTINGS);
+ keys.add(KEY_EVENT_RULE_SETTINGS);
+ return keys;
+ }
+ };
}
diff --git a/src/com/android/settings/notification/ZenModeScheduleRuleSettings.java b/src/com/android/settings/notification/ZenModeScheduleRuleSettings.java
index 72f6567..ab0349e 100644
--- a/src/com/android/settings/notification/ZenModeScheduleRuleSettings.java
+++ b/src/com/android/settings/notification/ZenModeScheduleRuleSettings.java
@@ -19,7 +19,6 @@
import android.app.AlertDialog;
import android.app.AutomaticZenRule;
import android.app.Dialog;
-import android.app.DialogFragment;
import android.app.FragmentManager;
import android.app.TimePickerDialog;
import android.content.Context;
@@ -40,10 +39,12 @@
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+import com.android.settingslib.core.AbstractPreferenceController;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
+import java.util.List;
public class ZenModeScheduleRuleSettings extends ZenModeRuleSettingsBase {
private static final String KEY_DAYS = "days";
@@ -71,6 +72,16 @@
}
@Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.zen_mode_schedule_rule_settings;
+ }
+
+ @Override
+ protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
+ return null;
+ }
+
+ @Override
protected String getZenModeDependency() {
return mDays.getKey();
}
@@ -82,7 +93,6 @@
@Override
protected void onCreateInternal() {
- addPreferencesFromResource(R.xml.zen_mode_schedule_rule_settings);
final PreferenceScreen root = getPreferenceScreen();
mDays = root.findPreference(KEY_DAYS);
@@ -306,5 +316,4 @@
boolean onSetTime(int hour, int minute);
}
}
-
}
diff --git a/src/com/android/settings/notification/ZenModeScreenOffPreferenceController.java b/src/com/android/settings/notification/ZenModeScreenOffPreferenceController.java
new file mode 100644
index 0000000..8099691
--- /dev/null
+++ b/src/com/android/settings/notification/ZenModeScreenOffPreferenceController.java
@@ -0,0 +1,64 @@
+/*
+ * 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.app.NotificationManager.Policy;
+import android.content.Context;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.Preference;
+import android.util.Log;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public class ZenModeScreenOffPreferenceController extends
+ AbstractZenModePreferenceController implements Preference.OnPreferenceChangeListener{
+
+ protected static final String KEY = "zen_mode_screen_off";
+ private final ZenModeBackend mBackend;
+
+ public ZenModeScreenOffPreferenceController(Context context, Lifecycle lifecycle) {
+ super(context, KEY, lifecycle);
+ mBackend = ZenModeBackend.getInstance(context);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+
+ SwitchPreference pref = (SwitchPreference) preference;
+ pref.setChecked(mBackend.isEffectAllowed(Policy.SUPPRESSED_EFFECT_SCREEN_OFF));
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ final boolean bypass = (Boolean) newValue;
+ if (ZenModeSettingsBase.DEBUG) Log.d(TAG, "onPrefChange allowWhenScreenOff="
+ + !bypass);
+ mBackend.saveVisualEffectsPolicy(Policy.SUPPRESSED_EFFECT_SCREEN_OFF, bypass);
+ return true;
+ }
+}
diff --git a/src/com/android/settings/notification/ZenModeScreenOnPreferenceController.java b/src/com/android/settings/notification/ZenModeScreenOnPreferenceController.java
new file mode 100644
index 0000000..fac9bfd
--- /dev/null
+++ b/src/com/android/settings/notification/ZenModeScreenOnPreferenceController.java
@@ -0,0 +1,65 @@
+/*
+ * 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.app.NotificationManager.Policy;
+import android.content.Context;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.Preference;
+import android.util.Log;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public class ZenModeScreenOnPreferenceController extends
+ AbstractZenModePreferenceController implements Preference.OnPreferenceChangeListener{
+
+ protected static final String KEY = "zen_mode_screen_on";
+ private final ZenModeBackend mBackend;
+
+ public ZenModeScreenOnPreferenceController(Context context, Lifecycle lifecycle) {
+ super(context, KEY, lifecycle);
+ mBackend = ZenModeBackend.getInstance(context);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+
+ SwitchPreference pref = (SwitchPreference) preference;
+ pref.setChecked(mBackend.isEffectAllowed(Policy.SUPPRESSED_EFFECT_SCREEN_ON));
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ final boolean bypass = (Boolean) newValue;
+ if (ZenModeSettingsBase.DEBUG) Log.d(TAG, "onPrefChange allowWhenScreenOn="
+ + !bypass);
+
+ mBackend.saveVisualEffectsPolicy(Policy.SUPPRESSED_EFFECT_SCREEN_ON, bypass);
+ return true;
+ }
+}
diff --git a/src/com/android/settings/notification/ZenModeSettings.java b/src/com/android/settings/notification/ZenModeSettings.java
index 2699cfd..6cdf00b 100644
--- a/src/com/android/settings/notification/ZenModeSettings.java
+++ b/src/com/android/settings/notification/ZenModeSettings.java
@@ -20,56 +20,28 @@
import android.app.NotificationManager;
import android.app.NotificationManager.Policy;
import android.content.Context;
-import android.os.Bundle;
import android.provider.SearchIndexableResource;
import android.provider.Settings;
-import android.service.notification.ZenModeConfig;
import android.support.annotation.VisibleForTesting;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceScreen;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
-public class ZenModeSettings extends ZenModeSettingsBase implements Indexable {
-
- private static final String KEY_BEHAVIOR_SETTINGS = "zen_mode_behavior_settings";
- private static final String KEY_AUTOMATION_SETTINGS = "zen_mode_automation_settings";
-
- private Preference mBehaviorSettings;
- private Preference mAutomationSettings;
- private Policy mPolicy;
- private SummaryBuilder mSummaryBuilder;
+public class ZenModeSettings extends ZenModeSettingsBase {
@Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- addPreferencesFromResource(R.xml.zen_mode_settings);
- final PreferenceScreen root = getPreferenceScreen();
-
- mBehaviorSettings = root.findPreference(KEY_BEHAVIOR_SETTINGS);
- mAutomationSettings = root.findPreference(KEY_AUTOMATION_SETTINGS);
- mPolicy = NotificationManager.from(mContext).getNotificationPolicy();
- mSummaryBuilder = new SummaryBuilder(getContext());
- }
-
- @Override
- public void onResume() {
- super.onResume();
- if (isUiRestricted()) {
- return;
- }
- updateControls();
+ protected int getPreferenceScreenResId() {
+ return R.xml.zen_mode_settings;
}
@Override
@@ -78,27 +50,8 @@
}
@Override
- protected void onZenModeChanged() {
- updateControls();
- }
-
- @Override
- protected void onZenModeConfigChanged() {
- mPolicy = NotificationManager.from(mContext).getNotificationPolicy();
- updateControls();
- }
-
- private void updateControls() {
- updateBehaviorSettingsSummary();
- updateAutomationSettingsSummary();
- }
-
- private void updateBehaviorSettingsSummary() {
- mBehaviorSettings.setSummary(mSummaryBuilder.getBehaviorSettingSummary(mPolicy, mZenMode));
- }
-
- private void updateAutomationSettingsSummary() {
- mAutomationSettings.setSummary(mSummaryBuilder.getAutomaticRulesSummary());
+ protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
+ return buildPreferenceControllers(context, getLifecycle());
}
@Override
@@ -106,6 +59,16 @@
return R.string.help_uri_interruptions;
}
+
+ private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
+ Lifecycle lifecycle) {
+ List<AbstractPreferenceController> controllers = new ArrayList<>();
+ controllers.add(new ZenModeBehaviorPreferenceController(context, lifecycle));
+ controllers.add(new ZenModeAutomationPreferenceController(context));
+ controllers.add(new ZenModeButtonPreferenceController(context, lifecycle));
+ return controllers;
+ }
+
public static class SummaryBuilder {
private Context mContext;
@@ -227,42 +190,29 @@
}
}
- private static final Comparator<Entry<String,AutomaticZenRule>> RULE_COMPARATOR =
- new Comparator<Map.Entry<String,AutomaticZenRule>>() {
- @Override
- public int compare(Map.Entry<String,AutomaticZenRule> lhs,
- Map.Entry<String,AutomaticZenRule> rhs) {
- int byDate = Long.compare(lhs.getValue().getCreationTime(),
- rhs.getValue().getCreationTime());
- if (byDate != 0) {
- return byDate;
- } else {
- return key(lhs.getValue()).compareTo(key(rhs.getValue()));
- }
- }
-
- private String key(AutomaticZenRule rule) {
- final int type = ZenModeConfig.isValidScheduleConditionId(rule.getConditionId())
- ? 1
- : ZenModeConfig.isValidEventConditionId(rule.getConditionId())
- ? 2
- : 3;
- return type + rule.getName().toString();
- }
- };
-
/**
* For Search.
*/
public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
- @Override
- public List<SearchIndexableResource> getXmlResourcesToIndex(
- Context context, boolean enabled) {
- final SearchIndexableResource sir = new SearchIndexableResource(context);
- sir.xmlResId = R.xml.zen_mode_settings;
- return Arrays.asList(sir);
- }
- };
+ @Override
+ public List<SearchIndexableResource> getXmlResourcesToIndex(
+ Context context, boolean enabled) {
+ final SearchIndexableResource sir = new SearchIndexableResource(context);
+ sir.xmlResId = R.xml.zen_mode_settings;
+ return Arrays.asList(sir);
+ }
+ @Override
+ public List<String> getNonIndexableKeys(Context context) {
+ List<String> keys = super.getNonIndexableKeys(context);
+ keys.add(ZenModeButtonPreferenceController.KEY);
+ return keys;
+ }
+
+ @Override
+ public List<AbstractPreferenceController> getPreferenceControllers(Context context) {
+ return buildPreferenceControllers(context, null);
+ }
+ };
}
diff --git a/src/com/android/settings/notification/ZenModeSettingsBase.java b/src/com/android/settings/notification/ZenModeSettingsBase.java
index 6a9431e..2aecae4 100644
--- a/src/com/android/settings/notification/ZenModeSettingsBase.java
+++ b/src/com/android/settings/notification/ZenModeSettingsBase.java
@@ -16,8 +16,6 @@
package com.android.settings.notification;
-import android.app.AutomaticZenRule;
-import android.app.NotificationManager;
import android.content.Context;
import android.database.ContentObserver;
import android.net.Uri;
@@ -26,17 +24,11 @@
import android.os.UserManager;
import android.provider.Settings;
import android.provider.Settings.Global;
-import android.service.notification.ZenModeConfig;
import android.util.Log;
-import com.android.settings.RestrictedSettingsFragment;
+import com.android.settings.dashboard.RestrictedDashboardFragment;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-abstract public class ZenModeSettingsBase extends RestrictedSettingsFragment {
+abstract public class ZenModeSettingsBase extends RestrictedDashboardFragment {
protected static final String TAG = "ZenModeSettings";
protected static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
@@ -44,30 +36,33 @@
private final SettingsObserver mSettingsObserver = new SettingsObserver();
protected Context mContext;
- protected Set<Map.Entry<String, AutomaticZenRule>> mRules;
protected int mZenMode;
- abstract protected void onZenModeChanged();
- abstract protected void onZenModeConfigChanged();
+ protected ZenModeBackend mBackend;
+
+ protected void onZenModeConfigChanged() {};
public ZenModeSettingsBase() {
super(UserManager.DISALLOW_ADJUST_VOLUME);
}
@Override
+ protected String getLogTag() {
+ return TAG;
+ }
+
+ @Override
public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
mContext = getActivity();
+ mBackend = ZenModeBackend.getInstance(mContext);
+ super.onCreate(icicle);
updateZenMode(false /*fireChanged*/);
- maybeRefreshRules(true, false /*fireChanged*/);
- if (DEBUG) Log.d(TAG, "Loaded mRules=" + mRules);
}
@Override
public void onResume() {
super.onResume();
updateZenMode(true /*fireChanged*/);
- maybeRefreshRules(true, true /*fireChanged*/);
mSettingsObserver.register();
if (isUiRestricted()) {
if (isUiRestrictedByOnlyAdmin()) {
@@ -89,56 +84,7 @@
final int zenMode = Settings.Global.getInt(getContentResolver(), Global.ZEN_MODE, mZenMode);
if (zenMode == mZenMode) return;
mZenMode = zenMode;
- if (DEBUG) Log.d(TAG, "updateZenMode mZenMode=" + mZenMode);
- if (fireChanged) {
- onZenModeChanged();
- }
- }
-
- protected String addZenRule(AutomaticZenRule rule) {
- try {
- String id = NotificationManager.from(mContext).addAutomaticZenRule(rule);
- final AutomaticZenRule savedRule =
- NotificationManager.from(mContext).getAutomaticZenRule(id);
- maybeRefreshRules(savedRule != null, true);
- return id;
- } catch (Exception e) {
- return null;
- }
- }
-
- protected boolean setZenRule(String id, AutomaticZenRule rule) {
- final boolean success =
- NotificationManager.from(mContext).updateAutomaticZenRule(id, rule);
- maybeRefreshRules(success, true);
- return success;
- }
-
- protected boolean removeZenRule(String id) {
- final boolean success =
- NotificationManager.from(mContext).removeAutomaticZenRule(id);
- maybeRefreshRules(success, true);
- return success;
- }
-
- protected void maybeRefreshRules(boolean success, boolean fireChanged) {
- if (success) {
- mRules = getZenModeRules();
- if (DEBUG) Log.d(TAG, "Refreshed mRules=" + mRules);
- if (fireChanged) {
- onZenModeConfigChanged();
- }
- }
- }
-
- protected void setZenMode(int zenMode, Uri conditionId) {
- NotificationManager.from(mContext).setZenMode(zenMode, conditionId, TAG);
- }
-
- private Set<Map.Entry<String, AutomaticZenRule>> getZenModeRules() {
- Map<String, AutomaticZenRule> ruleMap
- = NotificationManager.from(mContext).getAutomaticZenRules();
- return ruleMap.entrySet();
+ if (DEBUG) Log.d(TAG, "updateZenMode mZenMode=" + mZenMode + " " + fireChanged);
}
private final class SettingsObserver extends ContentObserver {
@@ -165,7 +111,8 @@
updateZenMode(true /*fireChanged*/);
}
if (ZEN_MODE_CONFIG_ETAG_URI.equals(uri)) {
- maybeRefreshRules(true, true /*fireChanged*/);
+ mBackend.updatePolicy();
+ onZenModeConfigChanged();
}
}
}
diff --git a/src/com/android/settings/notification/ZenRulePreference.java b/src/com/android/settings/notification/ZenRulePreference.java
new file mode 100644
index 0000000..a838f29
--- /dev/null
+++ b/src/com/android/settings/notification/ZenRulePreference.java
@@ -0,0 +1,166 @@
+/*
+ * 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.app.AlertDialog;
+import android.app.AutomaticZenRule;
+import android.app.NotificationManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ServiceInfo;
+import android.content.res.Resources;
+import android.service.notification.ZenModeConfig;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceCategory;
+import android.support.v7.preference.PreferenceViewHolder;
+import android.view.View;
+
+import com.android.settings.R;
+import com.android.settings.utils.ManagedServiceSettings;
+import com.android.settings.utils.ZenServiceListing;
+import com.android.settingslib.TwoTargetPreference;
+
+import java.util.Map;
+
+public class ZenRulePreference extends TwoTargetPreference {
+ protected final ManagedServiceSettings.Config CONFIG =
+ ZenModeAutomationSettings.getConditionProviderConfig();
+ final CharSequence mName;
+ final String mId;
+ boolean appExists;
+ final PreferenceCategory mParent;
+ final Preference mPref;
+ final Context mContext;
+ final ZenModeBackend mBackend;
+ final ZenServiceListing mServiceListing;
+ final PackageManager mPm;
+
+ public ZenRulePreference(Context context,
+ final Map.Entry<String, AutomaticZenRule> ruleEntry,
+ PreferenceCategory prefCategory) {
+ super(context);
+
+ mBackend = ZenModeBackend.getInstance(context);
+ mContext = context;
+ final AutomaticZenRule rule = ruleEntry.getValue();
+ mName = rule.getName();
+ mId = ruleEntry.getKey();
+ mParent = prefCategory;
+ mPm = mContext.getPackageManager();
+ mServiceListing = new ZenServiceListing(mContext, CONFIG);
+ mServiceListing.reloadApprovedServices();
+ mPref = this;
+
+ setAttributes(rule);
+ }
+
+ @Override
+ protected int getSecondTargetResId() {
+ return R.layout.zen_rule_widget;
+ }
+
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder view) {
+ super.onBindViewHolder(view);
+
+ View v = view.findViewById(R.id.delete_zen_rule);
+ if (v != null) {
+ v.setOnClickListener(mDeleteListener);
+ }
+ }
+
+ private final View.OnClickListener mDeleteListener = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ showDeleteRuleDialog(mId, mName, mParent, mPref);
+ }
+ };
+
+ private void showDeleteRuleDialog(final String ruleId, final CharSequence ruleName,
+ PreferenceCategory parent, Preference pref) {
+ new AlertDialog.Builder(mContext)
+ .setMessage(mContext.getResources().getString(
+ R.string.zen_mode_delete_rule_confirmation, ruleName))
+ .setNegativeButton(R.string.cancel, null)
+ .setPositiveButton(R.string.zen_mode_delete_rule_button,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ mBackend.removeZenRule(ruleId);
+ parent.removePreference(pref);
+ }
+ })
+ .show();
+ }
+
+ protected void setAttributes(AutomaticZenRule rule) {
+ final boolean isSchedule = ZenModeConfig.isValidScheduleConditionId(
+ rule.getConditionId());
+ final boolean isEvent = ZenModeConfig.isValidEventConditionId(rule.getConditionId());
+ final boolean isSystemRule = isSchedule || isEvent;
+
+ try {
+ ApplicationInfo info = mPm.getApplicationInfo(rule.getOwner().getPackageName(), 0);
+ setSummary(computeRuleSummary(rule, isSystemRule, info.loadLabel(mPm)));
+ } catch (PackageManager.NameNotFoundException e) {
+ appExists = false;
+ return;
+ }
+
+ appExists = true;
+ setTitle(rule.getName());
+ setPersistent(false);
+
+ final String action = isSchedule ? ZenModeScheduleRuleSettings.ACTION
+ : isEvent ? ZenModeEventRuleSettings.ACTION : "";
+ ServiceInfo si = mServiceListing.findService(rule.getOwner());
+ ComponentName settingsActivity = AbstractZenModeAutomaticRulePreferenceController.
+ getSettingsActivity(si);
+ setIntent(AbstractZenModeAutomaticRulePreferenceController.getRuleIntent(action,
+ settingsActivity, mId));
+ setSelectable(settingsActivity != null || isSystemRule);
+ setKey(mId);
+ }
+
+ private String computeRuleSummary(AutomaticZenRule rule, boolean isSystemRule,
+ CharSequence providerLabel) {
+ final String mode = computeZenModeCaption(mContext.getResources(),
+ rule.getInterruptionFilter());
+ final String ruleState = (rule == null || !rule.isEnabled())
+ ? mContext.getResources().getString(R.string.switch_off_text)
+ : mContext.getResources().getString(
+ R.string.zen_mode_rule_summary_enabled_combination, mode);
+
+ return ruleState;
+ }
+
+ private static String computeZenModeCaption(Resources res, int zenMode) {
+ switch (zenMode) {
+ case NotificationManager.INTERRUPTION_FILTER_ALARMS:
+ return res.getString(R.string.zen_mode_option_alarms);
+ case NotificationManager.INTERRUPTION_FILTER_PRIORITY:
+ return res.getString(R.string.zen_mode_option_important_interruptions);
+ case NotificationManager.INTERRUPTION_FILTER_NONE:
+ return res.getString(R.string.zen_mode_option_no_interruptions);
+ default:
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/notification/ZenRuleSelectionDialog.java b/src/com/android/settings/notification/ZenRuleSelectionDialog.java
index 3c49dcb..0c725ed 100644
--- a/src/com/android/settings/notification/ZenRuleSelectionDialog.java
+++ b/src/com/android/settings/notification/ZenRuleSelectionDialog.java
@@ -164,7 +164,8 @@
if (DEBUG) Log.d(TAG, "Services reloaded: count=" + services.size());
Set<ZenRuleInfo> externalRuleTypes = new TreeSet<>(RULE_TYPE_COMPARATOR);
for (ServiceInfo serviceInfo : services) {
- final ZenRuleInfo ri = ZenModeAutomationSettings.getRuleInfo(mPm, serviceInfo);
+ final ZenRuleInfo ri = AbstractZenModeAutomaticRulePreferenceController.
+ getRuleInfo(mPm, serviceInfo);
if (ri != null && ri.configurationActivity != null
&& mNm.isNotificationPolicyAccessGrantedForPackage(ri.packageName)
&& (ri.ruleInstanceLimit <= 0 || ri.ruleInstanceLimit
diff --git a/src/com/android/settings/search/SearchIndexableResources.java b/src/com/android/settings/search/SearchIndexableResources.java
index 46e693d..0aa2ab7 100644
--- a/src/com/android/settings/search/SearchIndexableResources.java
+++ b/src/com/android/settings/search/SearchIndexableResources.java
@@ -69,6 +69,8 @@
import com.android.settings.notification.SoundSettings;
import com.android.settings.notification.ZenModeAutomationSettings;
import com.android.settings.notification.ZenModeBehaviorSettings;
+import com.android.settings.notification.ZenModeEventRuleSettings;
+import com.android.settings.notification.ZenModeScheduleRuleSettings;
import com.android.settings.notification.ZenModeSettings;
import com.android.settings.print.PrintSettingsFragment;
import com.android.settings.security.EncryptionAndCredential;
@@ -168,6 +170,8 @@
addIndex(LockscreenDashboardFragment.class);
addIndex(ZenModeBehaviorSettings.class);
addIndex(ZenModeAutomationSettings.class);
+ addIndex(ZenModeEventRuleSettings.class);
+ addIndex(ZenModeScheduleRuleSettings.class);
}
private SearchIndexableResources() {
diff --git a/tests/robotests/assets/grandfather_not_implementing_indexable b/tests/robotests/assets/grandfather_not_implementing_indexable
index 8c44112..46414c7 100644
--- a/tests/robotests/assets/grandfather_not_implementing_indexable
+++ b/tests/robotests/assets/grandfather_not_implementing_indexable
@@ -3,7 +3,6 @@
com.android.settings.deviceinfo.PrivateVolumeForget
com.android.settings.inputmethod.SpellCheckersSettings
com.android.settings.inputmethod.KeyboardLayoutPickerFragment
-com.android.settings.notification.ZenModeEventRuleSettings
com.android.settings.fuelgauge.InactiveApps
com.android.settings.accessibility.CaptionPropertiesFragment
com.android.settings.accessibility.AccessibilitySettingsForSetupWizard
@@ -30,7 +29,6 @@
com.android.settings.accessibility.ToggleAutoclickPreferenceFragment
com.android.settings.applications.AppLaunchSettings
com.android.settings.applications.ProcessStatsUi
-com.android.settings.notification.ZenModeScheduleRuleSettings
com.android.settings.datausage.BillingCycleSettings
com.android.settings.notification.NotificationStation
com.android.settings.print.PrintJobSettingsFragment
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeAlarmsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeAlarmsPreferenceControllerTest.java
new file mode 100644
index 0000000..06ca70a
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/ZenModeAlarmsPreferenceControllerTest.java
@@ -0,0 +1,143 @@
+/*
+ * 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 static android.provider.Settings.Global.ZEN_MODE;
+import static android.provider.Settings.Global.ZEN_MODE_ALARMS;
+import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+import static android.provider.Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
+
+import static junit.framework.Assert.assertEquals;
+
+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.ContentResolver;
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
+public class ZenModeAlarmsPreferenceControllerTest {
+ private ZenModeAlarmsPreferenceController 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;
+ private ContentResolver mContentResolver;
+
+ private final boolean ALARMS_SETTINGS = true;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
+
+ mContext = shadowApplication.getApplicationContext();
+ mContentResolver = RuntimeEnvironment.application.getContentResolver();
+ when(mNotificationManager.getNotificationPolicy()).thenReturn(mPolicy);
+ mController = new ZenModeAlarmsPreferenceController(mContext, mock(Lifecycle.class));
+ ReflectionHelpers.setField(mController, "mBackend", mBackend);
+
+ when(mPreferenceScreen.findPreference(mController.getPreferenceKey())).thenReturn(
+ mockPref);
+ mController.displayPreference(mPreferenceScreen);
+ }
+
+ @Test
+ public void updateState_TotalSilence() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_NO_INTERRUPTIONS);
+
+ final SwitchPreference mockPref = mock(SwitchPreference.class);
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(false);
+ verify(mockPref).setChecked(false);
+ }
+
+ @Test
+ public void updateState_AlarmsOnly() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_ALARMS);
+
+ final SwitchPreference mockPref = mock(SwitchPreference.class);
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(false);
+ verify(mockPref).setChecked(true);
+ }
+
+ @Test
+ public void updateState_Priority() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
+
+ when(mBackend.isPriorityCategoryEnabled(
+ NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS)).thenReturn(ALARMS_SETTINGS);
+
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(true);
+ verify(mockPref).setChecked(ALARMS_SETTINGS);
+ }
+
+ @Test
+ public void onPreferenceChanged_EnableAlarms() {
+ boolean allowAlarms = true;
+ mController.onPreferenceChange(mockPref, allowAlarms);
+
+ verify(mBackend).saveSoundPolicy(NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS,
+ allowAlarms);
+ }
+
+ @Test
+ public void onPreferenceChanged_DisableAlarms() {
+ boolean allowAlarms = false;
+ mController.onPreferenceChange(mockPref, allowAlarms);
+
+ verify(mBackend).saveSoundPolicy(NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS,
+ allowAlarms);
+ }
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeButtonPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeButtonPreferenceControllerTest.java
new file mode 100644
index 0000000..a1b4dab
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/ZenModeButtonPreferenceControllerTest.java
@@ -0,0 +1,133 @@
+/*
+ * 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 static android.provider.Settings.Global.ZEN_MODE;
+import static android.provider.Settings.Global.ZEN_MODE_ALARMS;
+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_OFF;
+
+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.ContentResolver;
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+import android.view.View;
+import android.widget.Button;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
+public class ZenModeButtonPreferenceControllerTest {
+ private ZenModeButtonPreferenceController mController;
+
+ @Mock
+ private ZenModeBackend mBackend;
+ @Mock
+ private NotificationManager mNotificationManager;
+ @Mock
+ private Preference mockPref;
+ @Mock
+ private NotificationManager.Policy mPolicy;
+ @Mock
+ private Button mZenButtonOn;
+ @Mock
+ private Button mZenButtonOff;
+ @Mock
+ private PreferenceScreen mPreferenceScreen;
+ private ContentResolver mContentResolver;
+ private Context mContext;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
+
+ mContext = shadowApplication.getApplicationContext();
+ mContentResolver = RuntimeEnvironment.application.getContentResolver();
+ mController = new ZenModeButtonPreferenceController(mContext, mock(Lifecycle.class));
+ when(mNotificationManager.getNotificationPolicy()).thenReturn(mPolicy);
+ ReflectionHelpers.setField(mController, "mBackend", mBackend);
+ ReflectionHelpers.setField(mController, "mZenButtonOn", mZenButtonOn);
+ ReflectionHelpers.setField(mController, "mZenButtonOff", mZenButtonOff);
+
+ when(mPreferenceScreen.findPreference(mController.getPreferenceKey())).thenReturn(
+ mockPref);
+ mController.displayPreference(mPreferenceScreen);
+ }
+
+ @Test
+ public void updateState_TotalSilence() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_NO_INTERRUPTIONS);
+ final Preference mockPref = mock(Preference.class);
+ mController.updateState(mockPref);
+
+ verify(mZenButtonOn).setVisibility(View.GONE);
+ verify(mZenButtonOff).setVisibility(View.VISIBLE);
+ }
+
+ @Test
+ public void updateState_AlarmsOnly() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_ALARMS);
+ final Preference mockPref = mock(Preference.class);
+ mController.updateState(mockPref);
+
+ verify(mZenButtonOn).setVisibility(View.GONE);
+ verify(mZenButtonOff).setVisibility(View.VISIBLE);
+ }
+
+ @Test
+ public void updateState_Priority() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
+ final Preference mockPref = mock(Preference.class);
+ mController.updateState(mockPref);
+
+ verify(mZenButtonOn).setVisibility(View.GONE);
+ verify(mZenButtonOff).setVisibility(View.VISIBLE);
+ }
+
+ @Test
+ public void updateState_ZenOff() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_OFF);
+ final Preference mockPref = mock(Preference.class);
+ mController.updateState(mockPref);
+
+ verify(mZenButtonOn).setVisibility(View.VISIBLE);
+ verify(mZenButtonOff).setVisibility(View.GONE);
+ }
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeCallsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeCallsPreferenceControllerTest.java
new file mode 100644
index 0000000..ea7e9f5
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/ZenModeCallsPreferenceControllerTest.java
@@ -0,0 +1,135 @@
+/*
+ * 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 static android.provider.Settings.Global.ZEN_MODE;
+import static android.provider.Settings.Global.ZEN_MODE_ALARMS;
+import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+import static android.provider.Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
+
+import static junit.framework.Assert.assertEquals;
+
+import static org.mockito.ArgumentMatchers.any;
+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.ContentResolver;
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
+public class ZenModeCallsPreferenceControllerTest {
+ private ZenModeCallsPreferenceController mController;
+
+ @Mock
+ private ZenModeBackend mBackend;
+ @Mock
+ private NotificationManager mNotificationManager;
+ @Mock
+ private Preference mockPref;
+ @Mock
+ private NotificationManager.Policy mPolicy;
+ @Mock
+ private PreferenceScreen mPreferenceScreen;
+ private ContentResolver mContentResolver;
+ private Context mContext;
+
+ private final boolean CALLS_SETTINGS = true;
+ private final int MOCK_CALLS_SENDERS = NotificationManager.Policy.PRIORITY_SENDERS_STARRED;
+ private final int SUMMARY_ID_MOCK_CALLS_SENDERS = R.string.zen_mode_from_starred;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
+
+ mContext = shadowApplication.getApplicationContext();
+ mContentResolver = RuntimeEnvironment.application.getContentResolver();
+ when(mNotificationManager.getNotificationPolicy()).thenReturn(mPolicy);
+ when(mBackend.getContactsSummary(ZenModeBackend.SOURCE_NONE))
+ .thenCallRealMethod();
+ when(mBackend.getContactsSummary(NotificationManager.Policy.PRIORITY_CATEGORY_CALLS))
+ .thenCallRealMethod();
+
+ mController = new ZenModeCallsPreferenceController(mContext, mock(Lifecycle.class));
+ ReflectionHelpers.setField(mController, "mBackend", mBackend);
+
+ when(mPreferenceScreen.findPreference(mController.getPreferenceKey())).thenReturn(
+ mockPref);
+ mController.displayPreference(mPreferenceScreen);
+ }
+
+ @Test
+ public void updateState_TotalSilence() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_NO_INTERRUPTIONS);
+ when(mBackend.isPriorityCategoryEnabled(
+ NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES))
+ .thenReturn(false);
+ final Preference mockPref = mock(Preference.class);
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(false);
+ verify(mockPref).setSummary(R.string.zen_mode_from_none);
+ }
+
+ @Test
+ public void updateState_AlarmsOnly() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_ALARMS);
+
+ final Preference mockPref = mock(Preference.class);
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(false);
+ verify(mockPref).setSummary(R.string.zen_mode_from_none);
+ }
+
+ @Test
+ public void updateState_Priority() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
+ when(mBackend.isPriorityCategoryEnabled(
+ NotificationManager.Policy.PRIORITY_CATEGORY_CALLS))
+ .thenReturn(CALLS_SETTINGS);
+ when(mBackend.getPriorityCallSenders()).thenReturn(MOCK_CALLS_SENDERS);
+
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(true);
+ verify(mockPref).setSummary(SUMMARY_ID_MOCK_CALLS_SENDERS);
+ }
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeCallsTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeCallsTest.java
new file mode 100644
index 0000000..3cc87a8
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/ZenModeCallsTest.java
@@ -0,0 +1,126 @@
+/*
+ * 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 static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.Activity;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.os.UserManager;
+import android.provider.Settings;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class ZenModeCallsTest {
+ private ZenModeCallsSettings mCalls;
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private ZenModeBackend mBackend;
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private Activity mActivity;
+ @Mock
+ private UserManager mUserManager;
+ @Mock
+ private NotificationManager mNotificationManager;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ when(mActivity.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
+ when(mActivity.getSystemService(Context.NOTIFICATION_SERVICE))
+ .thenReturn(mNotificationManager);
+ FakeFeatureFactory.setupForTest(mActivity);
+
+ mCalls = new ZenModeCallsSettings();
+ mCalls.onAttach((Context)mActivity);
+
+ ReflectionHelpers.setField(mCalls, "mBackend", mBackend);
+ }
+
+ @Test
+ public void getDefaultKeyReturnsBasedOnZen() {
+ when(mBackend.getSendersKey(NotificationManager.Policy.PRIORITY_CATEGORY_CALLS))
+ .thenCallRealMethod();
+ when(mBackend.getZenMode()).thenReturn(Settings.Global.ZEN_MODE_NO_INTERRUPTIONS);
+ assertThat(mCalls.getDefaultKey())
+ .isEqualTo(mBackend.getKeyFromSetting(mBackend.SOURCE_NONE));
+
+ when(mBackend.getZenMode()).thenReturn(Settings.Global.ZEN_MODE_ALARMS);
+ assertThat(mCalls.getDefaultKey())
+ .isEqualTo(mBackend.getKeyFromSetting(mBackend.SOURCE_NONE));
+
+ when(mBackend.getZenMode()).thenReturn(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS);
+ when(mBackend.isPriorityCategoryEnabled(
+ NotificationManager.Policy.PRIORITY_CATEGORY_CALLS))
+ .thenReturn(true);
+ when(mBackend.getPriorityMessageSenders())
+ .thenReturn(NotificationManager.Policy.PRIORITY_SENDERS_ANY);
+ assertThat(mCalls.getDefaultKey())
+ .isEqualTo(mBackend.getKeyFromSetting(
+ NotificationManager.Policy.PRIORITY_SENDERS_ANY));
+ }
+
+ @Test
+ public void setAnySender() {
+ String key = mBackend.getKeyFromSetting(NotificationManager.Policy.PRIORITY_SENDERS_ANY);
+ mCalls.setDefaultKey(key);
+ verify(mBackend).saveSenders(NotificationManager.Policy.PRIORITY_CATEGORY_CALLS,
+ mBackend.getSettingFromPrefKey(key));
+ }
+
+ @Test
+ public void setNoSender() {
+ String key = mBackend.getKeyFromSetting(ZenModeBackend.SOURCE_NONE);
+ mCalls.setDefaultKey(key);
+ verify(mBackend).saveSenders(NotificationManager.Policy.PRIORITY_CATEGORY_CALLS,
+ mBackend.getSettingFromPrefKey(key));
+ }
+
+ @Test
+ public void setStarredSenders() {
+ String key = mBackend.getKeyFromSetting(
+ NotificationManager.Policy.PRIORITY_SENDERS_STARRED);
+ mCalls.setDefaultKey(key);
+ verify(mBackend).saveSenders(NotificationManager.Policy.PRIORITY_CATEGORY_CALLS,
+ mBackend.getSettingFromPrefKey(key));
+ }
+
+ @Test
+ public void setContactsOnlySenders() {
+ String key = mBackend.getKeyFromSetting(
+ NotificationManager.Policy.PRIORITY_SENDERS_CONTACTS);
+ mCalls.setDefaultKey(key);
+ verify(mBackend).saveSenders(NotificationManager.Policy.PRIORITY_CATEGORY_CALLS,
+ mBackend.getSettingFromPrefKey(key));
+ }
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeEventsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeEventsPreferenceControllerTest.java
new file mode 100644
index 0000000..b527abf
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/ZenModeEventsPreferenceControllerTest.java
@@ -0,0 +1,142 @@
+/*
+ * 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 static android.provider.Settings.Global.ZEN_MODE;
+import static android.provider.Settings.Global.ZEN_MODE_ALARMS;
+import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+import static android.provider.Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
+
+import static junit.framework.Assert.assertEquals;
+
+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.ContentResolver;
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.annotation.Config;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
+public class ZenModeEventsPreferenceControllerTest {
+ private ZenModeEventsPreferenceController mController;
+
+ @Mock
+ private ZenModeBackend mBackend;
+ @Mock
+ private NotificationManager mNotificationManager;
+ @Mock
+ private SwitchPreference mockPref;
+ @Mock
+ private NotificationManager.Policy mPolicy;
+ @Mock
+ private PreferenceScreen mPreferenceScreen;
+ private ContentResolver mContentResolver;
+ private Context mContext;
+
+ private final boolean EVENTS_SETTINGS = true;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
+
+ mContext = shadowApplication.getApplicationContext();
+ mContentResolver = RuntimeEnvironment.application.getContentResolver();
+ when(mNotificationManager.getNotificationPolicy()).thenReturn(mPolicy);
+
+ mController = new ZenModeEventsPreferenceController(mContext, mock(Lifecycle.class));
+ ReflectionHelpers.setField(mController, "mBackend", mBackend);
+
+ when(mPreferenceScreen.findPreference(mController.getPreferenceKey())).thenReturn(
+ mockPref);
+ mController.displayPreference(mPreferenceScreen);
+ }
+
+ @Test
+ public void updateState_TotalSilence() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_NO_INTERRUPTIONS);
+
+ final SwitchPreference mockPref = mock(SwitchPreference.class);
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(false);
+ verify(mockPref).setChecked(false);
+ }
+
+ @Test
+ public void updateState_AlarmsOnly() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_ALARMS);
+
+ final SwitchPreference mockPref = mock(SwitchPreference.class);
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(false);
+ verify(mockPref).setChecked(false);
+ }
+
+ @Test
+ public void updateState_Priority() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
+
+ when(mBackend.isPriorityCategoryEnabled(
+ NotificationManager.Policy.PRIORITY_CATEGORY_EVENTS)).thenReturn(EVENTS_SETTINGS);
+
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(true);
+ verify(mockPref).setChecked(EVENTS_SETTINGS);
+ }
+
+ @Test
+ public void onPreferenceChanged_EnableEvents() {
+ boolean allow = true;
+ mController.onPreferenceChange(mockPref, allow);
+
+ verify(mBackend).saveSoundPolicy(NotificationManager.Policy.PRIORITY_CATEGORY_EVENTS,
+ allow);
+ }
+
+ @Test
+ public void onPreferenceChanged_DisableEvents() {
+ boolean allow = false;
+ mController.onPreferenceChange(mockPref, allow);
+
+ verify(mBackend).saveSoundPolicy(NotificationManager.Policy.PRIORITY_CATEGORY_EVENTS,
+ allow);
+ }
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeMediaPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeMediaPreferenceControllerTest.java
new file mode 100644
index 0000000..976d6d4
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/ZenModeMediaPreferenceControllerTest.java
@@ -0,0 +1,145 @@
+/*
+ * 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 static android.provider.Settings.Global.ZEN_MODE;
+import static android.provider.Settings.Global.ZEN_MODE_ALARMS;
+import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+import static android.provider.Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
+
+import static junit.framework.Assert.assertEquals;
+
+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.ContentResolver;
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
+public class ZenModeMediaPreferenceControllerTest {
+ private ZenModeMediaSystemOtherPreferenceController mController;
+
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private Context mContext;
+ @Mock
+ private ZenModeBackend mBackend;
+ @Mock
+ private NotificationManager mNotificationManager;
+ @Mock
+ private SwitchPreference mockPref;
+ @Mock
+ private NotificationManager.Policy mPolicy;
+ @Mock
+ private PreferenceScreen mPreferenceScreen;
+ private ContentResolver mContentResolver;
+
+ private final boolean MEDIA_SETTINGS = true;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
+
+ mContext = shadowApplication.getApplicationContext();
+ mContentResolver = RuntimeEnvironment.application.getContentResolver();
+ when(mNotificationManager.getNotificationPolicy()).thenReturn(mPolicy);
+
+ mController = new ZenModeMediaSystemOtherPreferenceController(mContext,
+ mock(Lifecycle.class));
+ ReflectionHelpers.setField(mController, "mBackend", mBackend);
+
+ when(mPreferenceScreen.findPreference(mController.getPreferenceKey())).thenReturn(
+ mockPref);
+ mController.displayPreference(mPreferenceScreen);
+ }
+
+ @Test
+ public void updateState_TotalSilence() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_NO_INTERRUPTIONS);
+
+ final SwitchPreference mockPref = mock(SwitchPreference.class);
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(false);
+ verify(mockPref).setChecked(false);
+ }
+
+ @Test
+ public void updateState_AlarmsOnly() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_ALARMS);
+
+ final SwitchPreference mockPref = mock(SwitchPreference.class);
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(false);
+ verify(mockPref).setChecked(true);
+ }
+
+ @Test
+ public void updateState_Priority() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
+
+ when(mBackend.isPriorityCategoryEnabled(
+ NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER)).
+ thenReturn(MEDIA_SETTINGS);
+
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(true);
+ verify(mockPref).setChecked(MEDIA_SETTINGS);
+ }
+
+ @Test
+ public void onPreferenceChanged_EnableEvents() {
+ boolean allow = true;
+ mController.onPreferenceChange(mockPref, allow);
+
+ verify(mBackend).saveSoundPolicy(
+ NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER, allow);
+ }
+
+ @Test
+ public void onPreferenceChanged_DisableEvents() {
+ boolean allow = false;
+ mController.onPreferenceChange(mockPref, allow);
+
+ verify(mBackend).saveSoundPolicy(
+ NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER, allow);
+ }
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeMessagesPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeMessagesPreferenceControllerTest.java
new file mode 100644
index 0000000..c06f93f
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/ZenModeMessagesPreferenceControllerTest.java
@@ -0,0 +1,140 @@
+/*
+ * 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 static android.provider.Settings.Global.ZEN_MODE;
+import static android.provider.Settings.Global.ZEN_MODE_ALARMS;
+import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+import static android.provider.Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
+
+import static junit.framework.Assert.assertEquals;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationManager;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
+public class ZenModeMessagesPreferenceControllerTest {
+ private ZenModeMessagesPreferenceController mController;
+
+ @Mock
+ private ZenModeBackend mBackend;
+ @Mock
+ private NotificationManager mNotificationManager;
+ @Mock
+ private Preference mockPref;
+ @Mock
+ private NotificationManager.Policy mPolicy;
+ @Mock
+ private PreferenceScreen mPreferenceScreen;
+ private ContentResolver mContentResolver;
+ private Context mContext;
+
+ private final boolean MESSAGES_SETTINGS = true;
+ private final int MOCK_MESSAGES_SENDERS = NotificationManager.Policy.PRIORITY_SENDERS_STARRED;
+ private final int SUMMARY_ID_MOCK_MESSAGES_SENDERS = R.string.zen_mode_from_starred;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
+
+ mContext = shadowApplication.getApplicationContext();
+ mContentResolver = RuntimeEnvironment.application.getContentResolver();
+ when(mNotificationManager.getNotificationPolicy()).thenReturn(mPolicy);
+
+ when(mBackend.getPriorityMessageSenders()).thenReturn(MOCK_MESSAGES_SENDERS);
+ when(mBackend.getContactsSummary(ZenModeBackend.SOURCE_NONE))
+ .thenCallRealMethod();
+ when(mBackend.getContactsSummary(NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES))
+ .thenCallRealMethod();
+
+ mController = new ZenModeMessagesPreferenceController(mContext, mock(Lifecycle.class));
+ ReflectionHelpers.setField(mController, "mBackend", mBackend);
+
+ when(mPreferenceScreen.findPreference(mController.getPreferenceKey())).thenReturn(
+ mockPref);
+ mController.displayPreference(mPreferenceScreen);
+ }
+
+ @Test
+ public void updateState_TotalSilence() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_NO_INTERRUPTIONS);
+
+ when(mBackend.isPriorityCategoryEnabled(
+ NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES))
+ .thenReturn(false);
+ final Preference mockPref = mock(Preference.class);
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(false);
+ verify(mockPref).setSummary(R.string.zen_mode_from_none);
+ }
+
+ @Test
+ public void updateState_AlarmsOnly() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_ALARMS);
+
+ final Preference mockPref = mock(Preference.class);
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(false);
+ verify(mockPref).setSummary(R.string.zen_mode_from_none);
+ }
+
+ @Test
+ public void updateState_Priority() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
+
+ when(mBackend.isPriorityCategoryEnabled(
+ NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES))
+ .thenReturn(MESSAGES_SETTINGS);
+
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(true);
+ verify(mockPref).setSummary(SUMMARY_ID_MOCK_MESSAGES_SENDERS);
+ }
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeMessagesTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeMessagesTest.java
new file mode 100644
index 0000000..fe92570
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/ZenModeMessagesTest.java
@@ -0,0 +1,126 @@
+/*
+ * 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 static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.Activity;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.os.UserManager;
+import android.provider.Settings;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class ZenModeMessagesTest {
+ private ZenModeMessagesSettings mMessages;
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private ZenModeBackend mBackend;
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private Activity mActivity;
+ @Mock
+ private UserManager mUserManager;
+ @Mock
+ private NotificationManager mNotificationManager;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ when(mActivity.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
+ when(mActivity.getSystemService(Context.NOTIFICATION_SERVICE))
+ .thenReturn(mNotificationManager);
+ FakeFeatureFactory.setupForTest(mActivity);
+
+ mMessages = new ZenModeMessagesSettings();
+ mMessages.onAttach((Context)mActivity);
+
+ ReflectionHelpers.setField(mMessages, "mBackend", mBackend);
+ }
+
+ @Test
+ public void getDefaultKeyReturnsBasedOnZen() {
+ when(mBackend.getSendersKey(NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES))
+ .thenCallRealMethod();
+ when(mBackend.getZenMode()).thenReturn(Settings.Global.ZEN_MODE_NO_INTERRUPTIONS);
+ assertThat(mMessages.getDefaultKey())
+ .isEqualTo(mBackend.getKeyFromSetting(mBackend.SOURCE_NONE));
+
+ when(mBackend.getZenMode()).thenReturn(Settings.Global.ZEN_MODE_ALARMS);
+ assertThat(mMessages.getDefaultKey())
+ .isEqualTo(mBackend.getKeyFromSetting(mBackend.SOURCE_NONE));
+
+ when(mBackend.getZenMode()).thenReturn(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS);
+ when(mBackend.isPriorityCategoryEnabled(
+ NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES))
+ .thenReturn(true);
+ when(mBackend.getPriorityMessageSenders())
+ .thenReturn(NotificationManager.Policy.PRIORITY_SENDERS_ANY);
+ assertThat(mMessages.getDefaultKey())
+ .isEqualTo(mBackend.getKeyFromSetting(
+ NotificationManager.Policy.PRIORITY_SENDERS_ANY));
+ }
+
+ @Test
+ public void setAnySender() {
+ String key = mBackend.getKeyFromSetting(NotificationManager.Policy.PRIORITY_SENDERS_ANY);
+ mMessages.setDefaultKey(key);
+ verify(mBackend).saveSenders(NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES,
+ mBackend.getSettingFromPrefKey(key));
+ }
+
+ @Test
+ public void setNoSender() {
+ String key = mBackend.getKeyFromSetting(ZenModeBackend.SOURCE_NONE);
+ mMessages.setDefaultKey(key);
+ verify(mBackend).saveSenders(NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES,
+ mBackend.getSettingFromPrefKey(key));
+ }
+
+ @Test
+ public void setStarredSenders() {
+ String key = mBackend.getKeyFromSetting(
+ NotificationManager.Policy.PRIORITY_SENDERS_STARRED);
+ mMessages.setDefaultKey(key);
+ verify(mBackend).saveSenders(NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES,
+ mBackend.getSettingFromPrefKey(key));
+ }
+
+ @Test
+ public void setContactsOnlySenders() {
+ String key = mBackend.getKeyFromSetting(
+ NotificationManager.Policy.PRIORITY_SENDERS_CONTACTS);
+ mMessages.setDefaultKey(key);
+ verify(mBackend).saveSenders(NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES,
+ mBackend.getSettingFromPrefKey(key));
+ }
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenModePreferenceControllerTest.java
index 1d71a8a..0a28673 100644
--- a/tests/robotests/src/com/android/settings/notification/ZenModePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/ZenModePreferenceControllerTest.java
@@ -43,7 +43,7 @@
import static org.mockito.Mockito.when;
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
public class ZenModePreferenceControllerTest {
@Mock
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeRemindersPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeRemindersPreferenceControllerTest.java
new file mode 100644
index 0000000..9d8b011
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/ZenModeRemindersPreferenceControllerTest.java
@@ -0,0 +1,144 @@
+/*
+ * 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 static android.provider.Settings.Global.ZEN_MODE;
+import static android.provider.Settings.Global.ZEN_MODE_ALARMS;
+import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+import static android.provider.Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
+
+import static junit.framework.Assert.assertEquals;
+
+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.ContentResolver;
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
+public class ZenModeRemindersPreferenceControllerTest {
+ private ZenModeRemindersPreferenceController mController;
+
+ @Mock
+ private ZenModeBackend mBackend;
+ @Mock
+ private NotificationManager mNotificationManager;
+ @Mock
+ private SwitchPreference mockPref;
+ @Mock
+ private NotificationManager.Policy mPolicy;
+ @Mock
+ private PreferenceScreen mPreferenceScreen;
+
+ private ContentResolver mContentResolver;
+ private Context mContext;
+ private final boolean REMINDERS_SETTINGS = true;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
+
+ mContext = shadowApplication.getApplicationContext();
+ mContentResolver = RuntimeEnvironment.application.getContentResolver();
+ when(mNotificationManager.getNotificationPolicy()).thenReturn(mPolicy);
+
+ mController = new ZenModeRemindersPreferenceController(mContext, mock(Lifecycle.class));
+ ReflectionHelpers.setField(mController, "mBackend", mBackend);
+
+ when(mPreferenceScreen.findPreference(mController.getPreferenceKey())).thenReturn(
+ mockPref);
+ mController.displayPreference(mPreferenceScreen);
+ }
+
+
+ @Test
+ public void updateState_TotalSilence() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_NO_INTERRUPTIONS);
+
+ final SwitchPreference mockPref = mock(SwitchPreference.class);
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(false);
+ verify(mockPref).setChecked(false);
+ }
+
+ @Test
+ public void updateState_AlarmsOnly() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_ALARMS);
+
+ final SwitchPreference mockPref = mock(SwitchPreference.class);
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(false);
+ verify(mockPref).setChecked(false);
+ }
+
+ @Test
+ public void updateState_Priority() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
+
+ when(mBackend.isPriorityCategoryEnabled(
+ NotificationManager.Policy.PRIORITY_CATEGORY_REMINDERS)).
+ thenReturn(REMINDERS_SETTINGS);
+
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(true);
+ verify(mockPref).setChecked(REMINDERS_SETTINGS);
+ }
+
+ @Test
+ public void onPreferenceChanged_EnableReminders() {
+ boolean allow = true;
+ mController.onPreferenceChange(mockPref, allow);
+
+ verify(mBackend).saveSoundPolicy(NotificationManager.Policy.PRIORITY_CATEGORY_REMINDERS,
+ allow);
+ }
+
+ @Test
+ public void onPreferenceChanged_DisableReminders() {
+ boolean allow = false;
+ mController.onPreferenceChange(mockPref, allow);
+
+ verify(mBackend).saveSoundPolicy(NotificationManager.Policy.PRIORITY_CATEGORY_REMINDERS,
+ allow);
+ }
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeRepeatCallersPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeRepeatCallersPreferenceControllerTest.java
new file mode 100644
index 0000000..d4ee9bc
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/ZenModeRepeatCallersPreferenceControllerTest.java
@@ -0,0 +1,160 @@
+/*
+ * 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 static android.provider.Settings.Global.ZEN_MODE;
+import static android.provider.Settings.Global.ZEN_MODE_ALARMS;
+import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+import static android.provider.Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
+
+import static junit.framework.Assert.assertEquals;
+
+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.ContentResolver;
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
+public class ZenModeRepeatCallersPreferenceControllerTest {
+ private ZenModeRepeatCallersPreferenceController mController;
+
+ @Mock
+ private ZenModeBackend mBackend;
+ @Mock
+ private NotificationManager mNotificationManager;
+ @Mock
+ private SwitchPreference mockPref;
+ @Mock
+ private NotificationManager.Policy mPolicy;
+ @Mock
+ private PreferenceScreen mPreferenceScreen;
+ private ContentResolver mContentResolver;
+ private Context mContext;
+
+ private final boolean REPEAT_CALLERS_SETTINGS = true;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
+
+ mContext = shadowApplication.getApplicationContext();
+ mContentResolver = RuntimeEnvironment.application.getContentResolver();
+ when(mNotificationManager.getNotificationPolicy()).thenReturn(mPolicy);
+
+ mController = new ZenModeRepeatCallersPreferenceController(mContext, mock(Lifecycle.class));
+ ReflectionHelpers.setField(mController, "mBackend", mBackend);
+
+ when(mPreferenceScreen.findPreference(mController.getPreferenceKey())).thenReturn(
+ mockPref);
+ mController.displayPreference(mPreferenceScreen);
+ }
+
+ @Test
+ public void updateState_TotalSilence() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_NO_INTERRUPTIONS);
+ final SwitchPreference mockPref = mock(SwitchPreference.class);
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(false);
+ verify(mockPref).setChecked(false);
+ }
+
+ @Test
+ public void updateState_AlarmsOnly() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_ALARMS);
+
+ final SwitchPreference mockPref = mock(SwitchPreference.class);
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(false);
+ verify(mockPref).setChecked(false);
+ }
+
+ @Test
+ public void updateState_Priority() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
+
+ when(mBackend.isPriorityCategoryEnabled(
+ NotificationManager.Policy.PRIORITY_CATEGORY_REPEAT_CALLERS)).
+ thenReturn(REPEAT_CALLERS_SETTINGS);
+
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(true);
+ verify(mockPref).setChecked(REPEAT_CALLERS_SETTINGS);
+ }
+
+ @Test
+ public void updateState_Priority_anyCallers() {
+ boolean mockPriorityState = false;
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
+ when(mBackend.isPriorityCategoryEnabled(NotificationManager.Policy.PRIORITY_CATEGORY_CALLS))
+ .thenReturn(true);
+ when(mBackend.getPriorityCallSenders()).thenReturn(
+ NotificationManager.Policy.PRIORITY_SENDERS_ANY);
+ when(mBackend.isPriorityCategoryEnabled(
+ NotificationManager.Policy.PRIORITY_CATEGORY_REPEAT_CALLERS))
+ .thenReturn(mockPriorityState);
+
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(false);
+ verify(mockPref).setChecked(true);
+ }
+
+ @Test
+ public void onPreferenceChanged_EnableRepeatCallers() {
+ boolean allow = true;
+ mController.onPreferenceChange(mockPref, allow);
+
+ verify(mBackend).saveSoundPolicy(
+ NotificationManager.Policy.PRIORITY_CATEGORY_REPEAT_CALLERS, allow);
+ }
+
+ @Test
+ public void onPreferenceChanged_DisableRepeatCallers() {
+ boolean allow = false;
+ mController.onPreferenceChange(mockPref, allow);
+
+ verify(mBackend).saveSoundPolicy(
+ NotificationManager.Policy.PRIORITY_CATEGORY_REPEAT_CALLERS, allow);
+ }
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeScheduleRuleSettingsTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeScheduleRuleSettingsTest.java
index f8e5775..89b3f2a 100644
--- a/tests/robotests/src/com/android/settings/notification/ZenModeScheduleRuleSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/notification/ZenModeScheduleRuleSettingsTest.java
@@ -105,11 +105,6 @@
protected Object getSystemService(final String name) {
return null;
}
-
- @Override
- protected void maybeRefreshRules(boolean success, boolean fireChanged) {
- //do nothing
- }
}
}
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeScreenOffPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeScreenOffPreferenceControllerTest.java
new file mode 100644
index 0000000..3fe1eab
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/ZenModeScreenOffPreferenceControllerTest.java
@@ -0,0 +1,99 @@
+/*
+ * 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 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.provider.Settings;
+import android.support.v14.preference.SwitchPreference;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
+public class ZenModeScreenOffPreferenceControllerTest {
+ private ZenModeScreenOffPreferenceController mController;
+
+ @Mock
+ private ZenModeBackend mBackend;
+ @Mock
+ private NotificationManager mNotificationManager;
+ @Mock
+ private SwitchPreference mockPref;
+ @Mock
+ private NotificationManager.Policy mPolicy;
+
+ private Context mContext;
+ private final boolean MOCK_PRIORITY_SCREEN_OFF_SETTING = false;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
+
+ mContext = shadowApplication.getApplicationContext();
+ when(mNotificationManager.getNotificationPolicy()).thenReturn(mPolicy);
+
+ mController = new ZenModeScreenOffPreferenceController(mContext, mock(Lifecycle.class));
+ ReflectionHelpers.setField(mController, "mBackend", mBackend);
+ }
+
+ @Test
+ public void updateState() {
+ final SwitchPreference mockPref = mock(SwitchPreference.class);
+ when(mBackend.isEffectAllowed(NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OFF))
+ .thenReturn(MOCK_PRIORITY_SCREEN_OFF_SETTING);
+ mController.updateState(mockPref);
+
+ verify(mockPref).setChecked(MOCK_PRIORITY_SCREEN_OFF_SETTING);
+ }
+
+ @Test
+ public void onPreferenceChanged_EnableScreenOff() {
+ boolean allow = true;
+ mController.onPreferenceChange(mockPref, allow);
+
+ verify(mBackend).saveVisualEffectsPolicy(
+ NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OFF, allow);
+ }
+
+ @Test
+ public void onPreferenceChanged_DisableScreenOff() {
+ boolean allow = false;
+ mController.onPreferenceChange(mockPref, allow);
+
+ verify(mBackend).saveVisualEffectsPolicy(
+ NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OFF, allow);
+ }
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeScreenOnPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeScreenOnPreferenceControllerTest.java
new file mode 100644
index 0000000..24e3ce3
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/ZenModeScreenOnPreferenceControllerTest.java
@@ -0,0 +1,99 @@
+/*
+ * 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 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.provider.Settings;
+import android.support.v14.preference.SwitchPreference;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
+public class ZenModeScreenOnPreferenceControllerTest {
+ private ZenModeScreenOnPreferenceController mController;
+
+ @Mock
+ private ZenModeBackend mBackend;
+ @Mock
+ private NotificationManager mNotificationManager;
+ @Mock
+ private SwitchPreference mockPref;
+ @Mock
+ private NotificationManager.Policy mPolicy;
+
+ private Context mContext;
+ private final boolean MOCK_PRIORITY_SCREEN_ON_SETTING = false;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
+
+ mContext = shadowApplication.getApplicationContext();
+ when(mNotificationManager.getNotificationPolicy()).thenReturn(mPolicy);
+
+ mController = new ZenModeScreenOnPreferenceController(mContext, mock(Lifecycle.class));
+ ReflectionHelpers.setField(mController, "mBackend", mBackend);
+ }
+
+ @Test
+ public void updateState() {
+ final SwitchPreference mockPref = mock(SwitchPreference.class);
+ when(mBackend.isEffectAllowed(NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_ON))
+ .thenReturn(MOCK_PRIORITY_SCREEN_ON_SETTING);
+ mController.updateState(mockPref);
+
+ verify(mockPref).setChecked(MOCK_PRIORITY_SCREEN_ON_SETTING);
+ }
+
+ @Test
+ public void onPreferenceChanged_EnableScreenOn() {
+ boolean allow = true;
+ mController.onPreferenceChange(mockPref, allow);
+
+ verify(mBackend).saveVisualEffectsPolicy(
+ NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_ON, allow);
+ }
+
+ @Test
+ public void onPreferenceChanged_DisableScreenOn() {
+ boolean allow = false;
+ mController.onPreferenceChange(mockPref, allow);
+
+ verify(mBackend).saveVisualEffectsPolicy(
+ NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_ON, allow);
+ }
+}
\ No newline at end of file