Moved zenMode visual effects + automatic rule page
- Automatic zen rules have their own page like in N
- Minor string changes to page and add rule dialog
- Zen mode visual effects was moved into behavior settings
Bug: 63077372
Test: $ make SettingsUnitTests -j40
$ adb install -r ${OUT}/data/app/SettingsUnitTests/SettingsUnitTests.apk
$ adb shell am instrument -w com.android.settings.tests.unit/android.support.test.runner.AndroidJUnitRunner
Change-Id: I9635f8f7969b76d036bc06ec44705815e540777a
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index eac3801..6c21ff4 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -125,7 +125,6 @@
public static class ZenModeScheduleRuleSettingsActivity extends SettingsActivity { /* empty */ }
public static class ZenModeEventRuleSettingsActivity extends SettingsActivity { /* empty */ }
public static class ZenModeExternalRuleSettingsActivity extends SettingsActivity { /* empty */ }
- public static class ZenModeVisualInterruptionSettingsActivity extends SettingsActivity { /* empty */}
public static class SoundSettingsActivity extends SettingsActivity { /* empty */ }
public static class ConfigureNotificationSettingsActivity extends SettingsActivity { /* empty */ }
public static class NotificationAppListActivity extends SettingsActivity { /* empty */ }
diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java
index f2e49a4..057392b 100644
--- a/src/com/android/settings/core/gateway/SettingsGateway.java
+++ b/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -108,10 +108,10 @@
import com.android.settings.notification.SoundSettings;
import com.android.settings.notification.ZenAccessSettings;
import com.android.settings.notification.ZenModeBehaviorSettings;
+import com.android.settings.notification.ZenModeAutomationSettings;
import com.android.settings.notification.ZenModeEventRuleSettings;
import com.android.settings.notification.ZenModeScheduleRuleSettings;
import com.android.settings.notification.ZenModeSettings;
-import com.android.settings.notification.ZenModeVisualInterruptionSettings;
import com.android.settings.password.ChooseLockPassword;
import com.android.settings.password.ChooseLockPattern;
import com.android.settings.print.PrintJobSettingsFragment;
@@ -197,6 +197,7 @@
SpecialAccessSettings.class.getName(),
NotificationAccessSettings.class.getName(),
ZenAccessSettings.class.getName(),
+ ZenModeAutomationSettings.class.getName(),
PrintSettingsFragment.class.getName(),
PrintJobSettingsFragment.class.getName(),
TrustedCredentialsSettings.class.getName(),
@@ -219,7 +220,6 @@
ZenModeBehaviorSettings.class.getName(),
ZenModeScheduleRuleSettings.class.getName(),
ZenModeEventRuleSettings.class.getName(),
- ZenModeVisualInterruptionSettings.class.getName(),
ProcessStatsUi.class.getName(),
AdvancedPowerUsageDetail.class.getName(),
ProcessStatsSummary.class.getName(),
diff --git a/src/com/android/settings/notification/SoundSettings.java b/src/com/android/settings/notification/SoundSettings.java
index 982f4a4..06f15bb 100644
--- a/src/com/android/settings/notification/SoundSettings.java
+++ b/src/com/android/settings/notification/SoundSettings.java
@@ -244,7 +244,6 @@
List<String> keys = super.getNonIndexableKeys(context);
// Duplicate results
keys.add((new ZenModePreferenceController(context)).getPreferenceKey());
- keys.add(ZenModeSettings.KEY_VISUAL_SETTINGS);
keys.add(KEY_CELL_BROADCAST_SETTINGS);
return keys;
}
diff --git a/src/com/android/settings/notification/ZenModeAutomationSettings.java b/src/com/android/settings/notification/ZenModeAutomationSettings.java
new file mode 100644
index 0000000..07e9228
--- /dev/null
+++ b/src/com/android/settings/notification/ZenModeAutomationSettings.java
@@ -0,0 +1,348 @@
+/*
+ * 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.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.ZenServiceListing;
+import com.android.settingslib.TwoTargetPreference;
+
+import java.util.Arrays;
+import java.util.Comparator;
+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;
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ addPreferencesFromResource(R.xml.zen_mode_automation_settings);
+
+ mPm = mContext.getPackageManager();
+ mServiceListing = new ZenServiceListing(mContext, CONFIG);
+ mServiceListing.reloadApprovedServices();
+ }
+
+ @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);
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ 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();
+ c.tag = TAG;
+ c.intentAction = ConditionProviderService.SERVICE_INTERFACE;
+ c.permission = android.Manifest.permission.BIND_CONDITION_PROVIDER_SERVICE;
+ c.noun = "condition provider";
+ 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);
+ }
+ };
+}
diff --git a/src/com/android/settings/notification/ZenModeBehaviorSettings.java b/src/com/android/settings/notification/ZenModeBehaviorSettings.java
index d03b015..6fc97cf 100644
--- a/src/com/android/settings/notification/ZenModeBehaviorSettings.java
+++ b/src/com/android/settings/notification/ZenModeBehaviorSettings.java
@@ -46,6 +46,11 @@
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;
@@ -190,6 +195,43 @@
}
});
+ 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();
}
@@ -244,6 +286,10 @@
updateControlsPolicy();
setTogglesEnabled(true);
}
+
+ mScreenOff.setChecked(isEffectAllowed(Policy.SUPPRESSED_EFFECT_SCREEN_OFF));
+ mScreenOn.setChecked(isEffectAllowed(Policy.SUPPRESSED_EFFECT_SCREEN_ON));
+
mDisableListeners = false;
}
@@ -324,4 +370,17 @@
}
};
+ 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;
+ }
}
diff --git a/src/com/android/settings/notification/ZenModeRuleSettingsBase.java b/src/com/android/settings/notification/ZenModeRuleSettingsBase.java
index 86576cf..83c6753 100644
--- a/src/com/android/settings/notification/ZenModeRuleSettingsBase.java
+++ b/src/com/android/settings/notification/ZenModeRuleSettingsBase.java
@@ -221,7 +221,7 @@
}
private void showRuleNameDialog() {
- new ZenRuleNameDialog(mContext, mRule.getName()) {
+ new ZenRuleNameDialog(mContext, mRule.getName(), null) {
@Override
public void onOk(String ruleName) {
mRule.setName(ruleName);
diff --git a/src/com/android/settings/notification/ZenModeSettings.java b/src/com/android/settings/notification/ZenModeSettings.java
index 7f9a7c3..2699cfd 100644
--- a/src/com/android/settings/notification/ZenModeSettings.java
+++ b/src/com/android/settings/notification/ZenModeSettings.java
@@ -16,37 +16,22 @@
package com.android.settings.notification;
-import android.app.AlertDialog;
import android.app.AutomaticZenRule;
import android.app.NotificationManager;
import android.app.NotificationManager.Policy;
-import android.content.ComponentName;
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.annotation.VisibleForTesting;
import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceCategory;
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;
-import com.android.settings.utils.ZenServiceListing;
-import com.android.settingslib.TwoTargetPreference;
import java.util.ArrayList;
import java.util.Arrays;
@@ -57,19 +42,13 @@
public class ZenModeSettings extends ZenModeSettingsBase implements Indexable {
- public static final String KEY_VISUAL_SETTINGS = "zen_mode_visual_interruptions_settings";
private static final String KEY_BEHAVIOR_SETTINGS = "zen_mode_behavior_settings";
- private static final String KEY_AUTOMATIC_RULES = "zen_mode_automatic_rules";
+ private static final String KEY_AUTOMATION_SETTINGS = "zen_mode_automation_settings";
- static final ManagedServiceSettings.Config CONFIG = getConditionProviderConfig();
-
- private PreferenceCategory mAutomaticRules;
private Preference mBehaviorSettings;
- private Preference mVisualSettings;
+ private Preference mAutomationSettings;
private Policy mPolicy;
private SummaryBuilder mSummaryBuilder;
- private PackageManager mPm;
- private ZenServiceListing mServiceListing;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -78,14 +57,10 @@
addPreferencesFromResource(R.xml.zen_mode_settings);
final PreferenceScreen root = getPreferenceScreen();
- mAutomaticRules = (PreferenceCategory) root.findPreference(KEY_AUTOMATIC_RULES);
mBehaviorSettings = root.findPreference(KEY_BEHAVIOR_SETTINGS);
- mVisualSettings = root.findPreference(KEY_VISUAL_SETTINGS);
+ mAutomationSettings = root.findPreference(KEY_AUTOMATION_SETTINGS);
mPolicy = NotificationManager.from(mContext).getNotificationPolicy();
mSummaryBuilder = new SummaryBuilder(getContext());
- mPm = mContext.getPackageManager();
- mServiceListing = new ZenServiceListing(mContext, CONFIG);
- mServiceListing.reloadApprovedServices();
}
@Override
@@ -115,168 +90,15 @@
private void updateControls() {
updateBehaviorSettingsSummary();
- updateVisualSettingsSummary();
- updateAutomaticRules();
+ updateAutomationSettingsSummary();
}
private void updateBehaviorSettingsSummary() {
mBehaviorSettings.setSummary(mSummaryBuilder.getBehaviorSettingSummary(mPolicy, mZenMode));
}
- private void updateVisualSettingsSummary() {
- mVisualSettings.setSummary(mSummaryBuilder.getVisualSettingSummary(mPolicy));
- }
-
- private void updateAutomaticRules() {
- mAutomaticRules.removeAll();
- final Map.Entry<String,AutomaticZenRule>[] sortedRules = sortedRules();
- for (Map.Entry<String,AutomaticZenRule> sortedRule : sortedRules) {
- ZenRulePreference pref = new ZenRulePreference(getPrefContext(), sortedRule);
- if (pref.appExists) {
- mAutomaticRules.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 Preference.OnPreferenceClickListener() {
- @Override
- public boolean onPreferenceClick(Preference preference) {
- mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_ZEN_ADD_RULE);
- showAddRuleDialog();
- return true;
- }
- });
- mAutomaticRules.addPreference(p);
- }
-
- 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 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 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;
- c.noun = "condition provider";
- 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 void showNameRuleDialog(final ZenRuleInfo ri) {
- new ZenRuleNameDialog(mContext, null) {
- @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) {
- 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 updateAutomationSettingsSummary() {
+ mAutomationSettings.setSummary(mSummaryBuilder.getAutomaticRulesSummary());
}
@Override
@@ -284,67 +106,6 @@
return R.string.help_uri_interruptions;
}
- 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);
- }
- };
- }
-
public static class SummaryBuilder {
private Context mContext;
@@ -393,19 +154,6 @@
return mContext.getString(R.string.zen_mode_behavior_no_sound_except, s);
}
- String getVisualSettingSummary(Policy policy) {
- String s = mContext.getString(R.string.zen_mode_all_visual_interruptions);
- if (isEffectSuppressed(policy, Policy.SUPPRESSED_EFFECT_SCREEN_ON)
- && isEffectSuppressed(policy, Policy.SUPPRESSED_EFFECT_SCREEN_OFF)) {
- s = mContext.getString(R.string.zen_mode_no_visual_interruptions);
- } else if (isEffectSuppressed(policy, Policy.SUPPRESSED_EFFECT_SCREEN_ON)) {
- s = mContext.getString(R.string.zen_mode_screen_on_visual_interruptions);
- } else if (isEffectSuppressed(policy, Policy.SUPPRESSED_EFFECT_SCREEN_OFF)) {
- s = mContext.getString(R.string.zen_mode_screen_off_visual_interruptions);
- }
- return s;
- }
-
String getAutomaticRulesSummary() {
final int count = getEnabledAutomaticRulesCount();
return count == 0 ? mContext.getString(R.string.zen_mode_settings_summary_off)
@@ -479,7 +227,7 @@
}
}
- private static final Comparator<Map.Entry<String,AutomaticZenRule>> RULE_COMPARATOR =
+ private static final Comparator<Entry<String,AutomaticZenRule>> RULE_COMPARATOR =
new Comparator<Map.Entry<String,AutomaticZenRule>>() {
@Override
public int compare(Map.Entry<String,AutomaticZenRule> lhs,
@@ -502,6 +250,7 @@
return type + rule.getName().toString();
}
};
+
/**
* For Search.
*/
@@ -515,4 +264,5 @@
return Arrays.asList(sir);
}
};
+
}
diff --git a/src/com/android/settings/notification/ZenModeVisualInterruptionSettings.java b/src/com/android/settings/notification/ZenModeVisualInterruptionSettings.java
deleted file mode 100644
index 474992c..0000000
--- a/src/com/android/settings/notification/ZenModeVisualInterruptionSettings.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/**
- * Copyright (C) 2015 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.app.NotificationManager.Policy;
-import android.content.Context;
-import android.os.Bundle;
-import android.provider.SearchIndexableResource;
-import android.support.v14.preference.SwitchPreference;
-import android.support.v7.preference.Preference;
-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 java.util.Arrays;
-import java.util.List;
-
-public class ZenModeVisualInterruptionSettings extends ZenModeSettingsBase implements Indexable {
-
- private static final String KEY_SCREEN_OFF = "screenOff";
- private static final String KEY_SCREEN_ON = "screenOn";
-
- private SwitchPreference mScreenOff;
- private SwitchPreference mScreenOn;
-
- private boolean mDisableListeners;
- private NotificationManager.Policy mPolicy;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- addPreferencesFromResource(R.xml.zen_mode_visual_interruptions_settings);
- final PreferenceScreen root = getPreferenceScreen();
-
- mPolicy = NotificationManager.from(mContext).getNotificationPolicy();
-
- 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 val = (Boolean) newValue;
- mMetricsFeatureProvider.action(mContext,
- MetricsEvent.ACTION_ZEN_ALLOW_WHEN_SCREEN_OFF, val);
- if (DEBUG) Log.d(TAG, "onPrefChange suppressWhenScreenOff=" + val);
- savePolicy(getNewSuppressedEffects(val, 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 val = (Boolean) newValue;
- mMetricsFeatureProvider.action(mContext,
- MetricsEvent.ACTION_ZEN_ALLOW_WHEN_SCREEN_ON, val);
- if (DEBUG) Log.d(TAG, "onPrefChange suppressWhenScreenOn=" + val);
- savePolicy(getNewSuppressedEffects(val, Policy.SUPPRESSED_EFFECT_SCREEN_ON));
- return true;
- }
- });
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsEvent.NOTIFICATION_ZEN_MODE_VISUAL_INTERRUPTIONS;
- }
-
- @Override
- protected void onZenModeChanged() {
- // Don't care
- }
-
- @Override
- protected void onZenModeConfigChanged() {
- mPolicy = NotificationManager.from(mContext).getNotificationPolicy();
- updateControls();
- }
-
- private void updateControls() {
- mDisableListeners = true;
- mScreenOff.setChecked(isEffectSuppressed(Policy.SUPPRESSED_EFFECT_SCREEN_OFF));
- mScreenOn.setChecked(isEffectSuppressed(Policy.SUPPRESSED_EFFECT_SCREEN_ON));
- mDisableListeners = false;
- }
-
- private boolean isEffectSuppressed(int effect) {
- return (mPolicy.suppressedVisualEffects & effect) != 0;
- }
-
- private int getNewSuppressedEffects(boolean suppress, int effectType) {
- int effects = mPolicy.suppressedVisualEffects;
- if (suppress) {
- effects |= effectType;
- } else {
- effects &= ~effectType;
- }
- return effects;
- }
-
- private void savePolicy(int suppressedVisualEffects) {
- mPolicy = new Policy(mPolicy.priorityCategories,
- mPolicy.priorityCallSenders, mPolicy.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_visual_interruptions_settings;
- return Arrays.asList(sir);
- }
- };
-}
diff --git a/src/com/android/settings/notification/ZenRuleNameDialog.java b/src/com/android/settings/notification/ZenRuleNameDialog.java
index c6ce23b..eb85431 100644
--- a/src/com/android/settings/notification/ZenRuleNameDialog.java
+++ b/src/com/android/settings/notification/ZenRuleNameDialog.java
@@ -19,6 +19,8 @@
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
+import android.net.Uri;
+import android.service.notification.ZenModeConfig;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
@@ -35,20 +37,21 @@
private final CharSequence mOriginalRuleName;
private final boolean mIsNew;
- public ZenRuleNameDialog(Context context, CharSequence ruleName) {
+ public ZenRuleNameDialog(Context context, CharSequence ruleName, Uri conditionId) {
mIsNew = ruleName == null;
mOriginalRuleName = ruleName;
- final View v = LayoutInflater.from(context).inflate(R.layout.zen_rule_name, null, false);
- mEditText = (EditText) v.findViewById(R.id.rule_name);
+ final View v = LayoutInflater.from(context).inflate(R.layout.zen_rule_name, null,
+ false);
+ mEditText = (EditText) v.findViewById(R.id.zen_mode_rule_name);
if (!mIsNew) {
mEditText.setText(ruleName);
}
mEditText.setSelectAllOnFocus(true);
-
mDialog = new AlertDialog.Builder(context)
- .setTitle(mIsNew ? R.string.zen_mode_add_rule : R.string.zen_mode_rule_name)
+ .setTitle(getTitleResource(conditionId))
.setView(v)
- .setPositiveButton(R.string.okay, new DialogInterface.OnClickListener() {
+ .setPositiveButton(mIsNew ? R.string.zen_mode_add : R.string.okay,
+ new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
final String newName = trimmedText();
@@ -75,4 +78,18 @@
private String trimmedText() {
return mEditText.getText() == null ? null : mEditText.getText().toString().trim();
}
+
+ private int getTitleResource(Uri conditionId) {
+ final boolean isEvent = ZenModeConfig.isValidEventConditionId(conditionId);
+ final boolean isTime = ZenModeConfig.isValidScheduleConditionId(conditionId);
+ int titleResource = R.string.zen_mode_rule_name;
+ if (mIsNew) {
+ if (isEvent) {
+ titleResource = R.string.zen_mode_add_event_rule;
+ } else if (isTime) {
+ titleResource = R.string.zen_mode_add_time_rule;
+ }
+ }
+ return titleResource;
+ }
}
diff --git a/src/com/android/settings/notification/ZenRuleSelectionDialog.java b/src/com/android/settings/notification/ZenRuleSelectionDialog.java
index 4fa632a..3c49dcb 100644
--- a/src/com/android/settings/notification/ZenRuleSelectionDialog.java
+++ b/src/com/android/settings/notification/ZenRuleSelectionDialog.java
@@ -27,7 +27,6 @@
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.service.notification.ZenModeConfig;
-import android.util.ArraySet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -36,15 +35,11 @@
import android.widget.TextView;
import com.android.settings.R;
-import com.android.settings.utils.ServiceListing;
import com.android.settings.utils.ZenServiceListing;
import java.lang.ref.WeakReference;
import java.text.Collator;
-import java.util.ArrayList;
-import java.util.Collections;
import java.util.Comparator;
-import java.util.List;
import java.util.Set;
import java.util.TreeSet;
@@ -169,7 +164,7 @@
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 = ZenModeSettings.getRuleInfo(mPm, serviceInfo);
+ final ZenRuleInfo ri = ZenModeAutomationSettings.getRuleInfo(mPm, serviceInfo);
if (ri != null && ri.configurationActivity != null
&& mNm.isNotificationPolicyAccessGrantedForPackage(ri.packageName)
&& (ri.ruleInstanceLimit <= 0 || ri.ruleInstanceLimit
diff --git a/src/com/android/settings/search/SearchIndexableResources.java b/src/com/android/settings/search/SearchIndexableResources.java
index 7252e2d..af631fd 100644
--- a/src/com/android/settings/search/SearchIndexableResources.java
+++ b/src/com/android/settings/search/SearchIndexableResources.java
@@ -72,9 +72,9 @@
import com.android.settings.notification.ChannelImportanceSettings;
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.ZenModeSettings;
-import com.android.settings.notification.ZenModeVisualInterruptionSettings;
import com.android.settings.print.PrintSettingsFragment;
import com.android.settings.security.LockscreenDashboardFragment;
import com.android.settings.sim.SimSettings;
@@ -192,7 +192,7 @@
addIndex(BatterySaverSettings.class);
addIndex(LockscreenDashboardFragment.class);
addIndex(ZenModeBehaviorSettings.class);
- addIndex(ZenModeVisualInterruptionSettings.class);
+ addIndex(ZenModeAutomationSettings.class);
}
private SearchIndexableResources() {
@@ -209,4 +209,4 @@
public static Collection<SearchIndexableResource> values() {
return sResMap.values();
}
-}
+}
\ No newline at end of file