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
This commit is contained in:
Beverly
2017-10-27 14:44:23 -04:00
parent a40f6a2a45
commit a58e52a0be
53 changed files with 3888 additions and 815 deletions

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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

View File

@@ -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" />

View File

@@ -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" />

View File

@@ -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>

View File

@@ -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;
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}
}
}
}

View File

@@ -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());
}
}

View File

@@ -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 @@ public class ZenModeAutomationSettings extends ZenModeSettingsBase implements In
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 @@ public class ZenModeAutomationSettings extends ZenModeSettingsBase implements In
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);
}
};
}

View File

@@ -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;
}
}
}

View File

@@ -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()));
}
}

View File

@@ -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 @@ public class ZenModeBehaviorSettings extends ZenModeSettingsBase implements Inde
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);
}
};
}

View File

@@ -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);
}
}
}

View File

@@ -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));
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -33,6 +33,7 @@ import android.support.v7.preference.PreferenceScreen;
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 @@ public class ZenModeEventRuleSettings extends ZenModeRuleSettingsBase {
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 @@ public class ZenModeEventRuleSettings extends ZenModeRuleSettingsBase {
@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 class ZenModeEventRuleSettings extends ZenModeRuleSettingsBase {
public String name;
public int userId;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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));
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -26,6 +26,7 @@ import android.content.DialogInterface.OnClickListener;
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 android.widget.Toast;
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 @@ public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase
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 @@ public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
mContext = getActivity();
final Intent intent = getActivity().getIntent();
@@ -96,6 +102,8 @@ public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase
return;
}
super.onCreate(icicle);
setHasOptionsMenu(true);
onCreateInternal();
@@ -129,7 +137,7 @@ public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase
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 @@ public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase
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 @@ public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase
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 @@ public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase
@Override
public void onOk(String ruleName) {
mRule.setName(ruleName);
setZenRule(mId, mRule);
mBackend.setZenRule(mId, mRule);
}
}.show();
}
@@ -250,7 +254,7 @@ public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase
mMetricsFeatureProvider.action(mContext,
MetricsEvent.ACTION_ZEN_DELETE_RULE_OK);
mDeleting = true;
removeZenRule(mId);
mBackend.removeZenRule(mId);
}
})
.show();
@@ -294,4 +298,25 @@ public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase
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;
}
};
}

View File

@@ -19,7 +19,6 @@ package com.android.settings.notification;
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 android.widget.TimePicker;
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";
@@ -70,6 +71,16 @@ public class ZenModeScheduleRuleSettings extends ZenModeRuleSettingsBase {
return mSchedule != null;
}
@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 @@ public class ZenModeScheduleRuleSettings extends ZenModeRuleSettingsBase {
@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 @@ public class ZenModeScheduleRuleSettings extends ZenModeRuleSettingsBase {
boolean onSetTime(int hour, int minute);
}
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -20,56 +20,28 @@ import android.app.AutomaticZenRule;
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 @@ public class ZenModeSettings extends ZenModeSettingsBase implements Indexable {
}
@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 @@ public class ZenModeSettings extends ZenModeSettingsBase implements Indexable {
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 @@ public class ZenModeSettings extends ZenModeSettingsBase implements Indexable {
}
}
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);
}
};
}

View File

@@ -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.Handler;
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 @@ abstract public class ZenModeSettingsBase extends RestrictedSettingsFragment {
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 @@ abstract public class ZenModeSettingsBase extends RestrictedSettingsFragment {
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 @@ abstract public class ZenModeSettingsBase extends RestrictedSettingsFragment {
updateZenMode(true /*fireChanged*/);
}
if (ZEN_MODE_CONFIG_ETAG_URI.equals(uri)) {
maybeRefreshRules(true, true /*fireChanged*/);
mBackend.updatePolicy();
onZenModeConfigChanged();
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -164,7 +164,8 @@ public abstract class ZenRuleSelectionDialog {
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

View File

@@ -69,6 +69,8 @@ import com.android.settings.notification.ConfigureNotificationSettings;
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 @@ public final class SearchIndexableResources {
addIndex(LockscreenDashboardFragment.class);
addIndex(ZenModeBehaviorSettings.class);
addIndex(ZenModeAutomationSettings.class);
addIndex(ZenModeEventRuleSettings.class);
addIndex(ZenModeScheduleRuleSettings.class);
}
private SearchIndexableResources() {

View File

@@ -3,7 +3,6 @@ com.android.settings.deviceinfo.SimStatus
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.accounts.ManagedProfileSettings
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

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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));
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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));
}
}

View File

@@ -43,7 +43,7 @@ import static org.mockito.Mockito.verify;
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

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -105,11 +105,6 @@ public class ZenModeScheduleRuleSettingsTest {
protected Object getSystemService(final String name) {
return null;
}
@Override
protected void maybeRefreshRules(boolean success, boolean fireChanged) {
//do nothing
}
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}