Updates to automatic rule pages in Settings
- Re-added metrics for zen behavior preference controllers
- Dialogs in zen mode settings are rotate-friendly
- Automatic rules are refreshed on update state
- User-created (and default) automatic rules are always priority only and user cannot change this
- Automatic rules redesigned to have headers
Test: make ROBOTEST_FILTER=ZenModeAutomaticRulesPreferenceControllerTest RunSettingsRoboTests -j40
Bug: 63077372
Fixes: 68324465
Fixes: 69057696
Change-Id: I163acef2715dd4e60bfc08207f0e22352c4c0e28
diff --git a/res/values/strings.xml b/res/values/strings.xml
index c38c86b..7331d72 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -6741,6 +6741,9 @@
<!-- Do not disturb: Title for the zen mode automatic rules page in settings. [CHAR LIMIT=30] -->
<string name="zen_mode_automation_settings_page_title">Automatic rules</string>
+ <!-- Do not disturb: Title for a specific zen mode automatic rule in settings. [CHAR LIMIT=30] -->
+ <string name="zen_mode_automatic_rule_settings_page_title">Automatic rule</string>
+
<!-- Do not disturb: Title for the zen mode automation option Suggestion. [CHAR LIMIT=50] -->
<string name="zen_mode_automation_suggestion_title">Set Do Not Disturb rules</string>
diff --git a/res/xml/zen_mode_event_rule_settings.xml b/res/xml/zen_mode_event_rule_settings.xml
index 102d2a2..159dbe0 100644
--- a/res/xml/zen_mode_event_rule_settings.xml
+++ b/res/xml/zen_mode_event_rule_settings.xml
@@ -15,8 +15,18 @@
limitations under the License.
-->
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
- android:key="zen_mode_event_rule_settings" >
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:key="zen_mode_event_rule_settings"
+ android:title="@string/zen_mode_automatic_rule_settings_page_title">
+
+ <com.android.settings.applications.LayoutPreference
+ android:key="pref_app_header"
+ android:layout="@layout/settings_entity_header" />
+
+ <com.android.settings.applications.LayoutPreference
+ android:key="zen_automatic_rule_switch"
+ android:layout="@layout/styled_switch_bar" />
<!-- Rule name -->
<Preference
@@ -36,10 +46,4 @@
android:title="@string/zen_mode_event_rule_reply"
android:summary="%s" />
- <!-- Zen mode -->
- <DropDownPreference
- android:key="zen_mode"
- android:title="@string/zen_mode_settings_title"
- android:summary="%s" />
-
</PreferenceScreen>
diff --git a/res/xml/zen_mode_schedule_rule_settings.xml b/res/xml/zen_mode_schedule_rule_settings.xml
index 6224ce1..a0c52c0 100644
--- a/res/xml/zen_mode_schedule_rule_settings.xml
+++ b/res/xml/zen_mode_schedule_rule_settings.xml
@@ -15,8 +15,18 @@
limitations under the License.
-->
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
- android:key="zen_mode_schedule_rule_settings" >
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:key="zen_mode_schedule_rule_settings"
+ android:title="@string/zen_mode_automatic_rule_settings_page_title">
+
+ <com.android.settings.applications.LayoutPreference
+ android:key="pref_app_header"
+ android:layout="@layout/settings_entity_header" />
+
+ <com.android.settings.applications.LayoutPreference
+ android:key="zen_automatic_rule_switch"
+ android:layout="@layout/styled_switch_bar" />
<!-- Rule name -->
<Preference
@@ -39,11 +49,4 @@
android:summary="@string/zen_mode_schedule_alarm_summary"
android:order="99" />
- <!-- Zen mode -->
- <DropDownPreference
- android:key="zen_mode"
- android:title="@string/zen_mode_settings_title"
- android:order="100"
- android:summary="%s" />
-
</PreferenceScreen>
diff --git a/src/com/android/settings/notification/AbstractZenModeAutomaticRulePreferenceController.java b/src/com/android/settings/notification/AbstractZenModeAutomaticRulePreferenceController.java
index ec9cf2a..cc70a6f 100644
--- a/src/com/android/settings/notification/AbstractZenModeAutomaticRulePreferenceController.java
+++ b/src/com/android/settings/notification/AbstractZenModeAutomaticRulePreferenceController.java
@@ -29,8 +29,9 @@
import android.service.notification.ZenModeConfig;
import android.support.v7.preference.Preference;
+import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
import java.util.Arrays;
import java.util.Comparator;
@@ -38,19 +39,19 @@
import java.util.Set;
abstract public class AbstractZenModeAutomaticRulePreferenceController extends
- AbstractPreferenceController implements PreferenceControllerMixin {
+ AbstractZenModePreferenceController 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);
+ public AbstractZenModeAutomaticRulePreferenceController(Context context, String key, Fragment
+ parent, Lifecycle lifecycle) {
+ super(context, key, lifecycle);
mBackend = ZenModeBackend.getInstance(context);
- mParent = parent;
mPm = mContext.getPackageManager();
+ mParent = parent;
}
@Override
@@ -65,19 +66,9 @@
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 void showNameRuleDialog(final ZenRuleInfo ri, Fragment parent) {
+ ZenRuleNameDialog.show(parent, null, ri.defaultConditionId, new
+ RuleNameChangeListener(ri));
}
protected Map.Entry<String, AutomaticZenRule>[] sortedRules() {
@@ -157,4 +148,26 @@
}
return null;
}
+
+ public class RuleNameChangeListener implements ZenRuleNameDialog.PositiveClickListener {
+ ZenRuleInfo mRuleInfo;
+
+ public RuleNameChangeListener(ZenRuleInfo ruleInfo) {
+ mRuleInfo = ruleInfo;
+ }
+
+ @Override
+ public void onOk(String ruleName, Fragment parent) {
+ mMetricsFeatureProvider.action(mContext,
+ MetricsProto.MetricsEvent.ACTION_ZEN_MODE_RULE_NAME_CHANGE_OK);
+ AutomaticZenRule rule = new AutomaticZenRule(ruleName, mRuleInfo.serviceComponent,
+ mRuleInfo.defaultConditionId,
+ NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
+ String savedRuleId = mBackend.addZenRule(rule);
+ if (savedRuleId != null) {
+ parent.startActivity(getRuleIntent(mRuleInfo.settingsAction, null,
+ savedRuleId));
+ }
+ }
+ }
}
diff --git a/src/com/android/settings/notification/AbstractZenModePreferenceController.java b/src/com/android/settings/notification/AbstractZenModePreferenceController.java
index 2642f81..33c027c 100644
--- a/src/com/android/settings/notification/AbstractZenModePreferenceController.java
+++ b/src/com/android/settings/notification/AbstractZenModePreferenceController.java
@@ -35,6 +35,8 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.core.instrumentation.MetricsFeatureProvider;
+import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
@@ -51,6 +53,7 @@
private final String KEY;
final private NotificationManager mNotificationManager;
protected static ZenModeConfigWrapper mZenModeConfigWrapper;
+ protected MetricsFeatureProvider mMetricsFeatureProvider;
public AbstractZenModePreferenceController(Context context, String key,
Lifecycle lifecycle) {
@@ -62,6 +65,9 @@
KEY = key;
mNotificationManager = (NotificationManager) context.getSystemService(
Context.NOTIFICATION_SERVICE);
+
+ final FeatureFactory featureFactory = FeatureFactory.getFactory(mContext);
+ mMetricsFeatureProvider = featureFactory.getMetricsFeatureProvider();
}
@Override
diff --git a/src/com/android/settings/notification/ZenAutomaticRuleHeaderPreferenceController.java b/src/com/android/settings/notification/ZenAutomaticRuleHeaderPreferenceController.java
new file mode 100644
index 0000000..8494998
--- /dev/null
+++ b/src/com/android/settings/notification/ZenAutomaticRuleHeaderPreferenceController.java
@@ -0,0 +1,104 @@
+/*
+ * 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.android.settings.widget.EntityHeaderController.PREF_KEY_APP_HEADER;
+
+import android.app.AutomaticZenRule;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.graphics.drawable.Drawable;
+import android.support.v14.preference.PreferenceFragment;
+import android.support.v7.preference.Preference;
+import android.util.Slog;
+import android.view.View;
+
+import com.android.settings.R;
+import com.android.settings.applications.LayoutPreference;
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.widget.EntityHeaderController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public class ZenAutomaticRuleHeaderPreferenceController extends AbstractZenModePreferenceController
+ implements PreferenceControllerMixin {
+
+ private final String KEY = PREF_KEY_APP_HEADER;
+ private final PreferenceFragment mFragment;
+ private AutomaticZenRule mRule;
+ private EntityHeaderController mController;
+
+ public ZenAutomaticRuleHeaderPreferenceController(Context context, PreferenceFragment fragment,
+ Lifecycle lifecycle) {
+ super(context, PREF_KEY_APP_HEADER, lifecycle);
+ mFragment = fragment;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return mRule != null;
+ }
+
+ public void updateState(Preference preference) {
+ if (mRule == null) {
+ return;
+ }
+
+ if (mFragment != null) {
+ LayoutPreference pref = (LayoutPreference) preference;
+
+ if (mController == null) {
+ mController = EntityHeaderController
+ .newInstance(mFragment.getActivity(), mFragment,
+ pref.findViewById(R.id.entity_header));
+ }
+
+ pref = mController.setIcon(getIcon())
+ .setLabel(mRule.getName())
+ .setPackageName(mRule.getOwner().getPackageName())
+ .setUid(mContext.getUserId())
+ .setHasAppInfoLink(false)
+ .setButtonActions(EntityHeaderController.ActionType.ACTION_NONE,
+ EntityHeaderController.ActionType.ACTION_NONE)
+ .done(mFragment.getActivity(), mContext);
+
+ pref.findViewById(R.id.entity_header).setVisibility(View.VISIBLE);
+ }
+ }
+
+ private Drawable getIcon() {
+ try {
+ PackageManager packageManager = mContext.getPackageManager();
+ ApplicationInfo info = packageManager.getApplicationInfo(
+ mRule.getOwner().getPackageName(), 0);
+ return info.loadIcon(packageManager);
+ } catch (PackageManager.NameNotFoundException e) {
+ Slog.w(TAG, "Unable to load icon - PackageManager.NameNotFoundException");
+ }
+
+ return null;
+ }
+
+ protected void onResume(AutomaticZenRule rule) {
+ mRule = rule;
+ }
+}
diff --git a/src/com/android/settings/notification/ZenAutomaticRuleSwitchPreferenceController.java b/src/com/android/settings/notification/ZenAutomaticRuleSwitchPreferenceController.java
new file mode 100644
index 0000000..bc3fa25
--- /dev/null
+++ b/src/com/android/settings/notification/ZenAutomaticRuleSwitchPreferenceController.java
@@ -0,0 +1,97 @@
+/*
+ * 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.widget.Switch;
+import android.widget.Toast;
+
+import com.android.settings.R;
+import com.android.settings.applications.LayoutPreference;
+import com.android.settings.widget.SwitchBar;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public class ZenAutomaticRuleSwitchPreferenceController extends
+ AbstractZenModeAutomaticRulePreferenceController implements
+ SwitchBar.OnSwitchChangeListener {
+
+ private static final String KEY = "zen_automatic_rule_switch";
+ private AutomaticZenRule mRule;
+ private String mId;
+ private Toast mEnabledToast;
+ private int mToastTextResource;
+
+ public ZenAutomaticRuleSwitchPreferenceController(Context context, Fragment parent,
+ int toastTextResource, Lifecycle lifecycle) {
+ super(context, KEY, parent, lifecycle);
+ mToastTextResource = toastTextResource;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return mRule != null && mId != null;
+ }
+
+ public void onResume(AutomaticZenRule rule, String id) {
+ mRule = rule;
+ mId = id;
+ }
+
+ public void updateState(Preference preference) {
+ LayoutPreference pref = (LayoutPreference) preference;
+ SwitchBar bar = pref.findViewById(R.id.switch_bar);
+ if (mRule != null) {
+ bar.setChecked(mRule.isEnabled());
+ }
+ if (bar != null) {
+ bar.show();
+ try {
+ bar.addOnSwitchChangeListener(this);
+ } catch (IllegalStateException e) {
+ // an exception is thrown if you try to add the listener twice
+ }
+ }
+ bar.show();
+ }
+
+ @Override
+ public void onSwitchChanged(Switch switchView, boolean isChecked) {
+ final boolean enabled = isChecked;
+ if (enabled == mRule.isEnabled()) return;
+ mRule.setEnabled(enabled);
+ mBackend.setZenRule(mId, mRule);
+ if (enabled) {
+ final int toastText = mToastTextResource;
+ if (toastText != 0) {
+ mEnabledToast = Toast.makeText(mContext, toastText, Toast.LENGTH_SHORT);
+ mEnabledToast.show();
+ }
+ } else {
+ if (mEnabledToast != null) {
+ mEnabledToast.cancel();
+ }
+ }
+ }
+}
diff --git a/src/com/android/settings/notification/ZenDeleteRuleDialog.java b/src/com/android/settings/notification/ZenDeleteRuleDialog.java
new file mode 100644
index 0000000..d9061d3
--- /dev/null
+++ b/src/com/android/settings/notification/ZenDeleteRuleDialog.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.Fragment;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.view.View;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
+import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+
+public class ZenDeleteRuleDialog extends InstrumentedDialogFragment {
+ protected static final String TAG = "ZenDeleteRuleDialog";
+ private static final String EXTRA_ZEN_RULE_NAME = "zen_rule_name";
+ private static final String EXTRA_ZEN_RULE_ID = "zen_rule_id";
+ protected static PositiveClickListener mPositiveClickListener;
+
+ /**
+ * The interface we expect a listener to implement.
+ */
+ public interface PositiveClickListener {
+ void onOk(String id);
+ }
+
+ public static void show(Fragment parent, String ruleName, String id, PositiveClickListener
+ listener) {
+ final Bundle args = new Bundle();
+ args.putString(EXTRA_ZEN_RULE_NAME, ruleName);
+ args.putString(EXTRA_ZEN_RULE_ID, id);
+ mPositiveClickListener = listener;
+
+ ZenDeleteRuleDialog dialog = new ZenDeleteRuleDialog();
+ dialog.setArguments(args);
+ dialog.setTargetFragment(parent, 0);
+ dialog.show(parent.getFragmentManager(), TAG);
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsProto.MetricsEvent.NOTIFICATION_ZEN_MODE_DELETE_RULE_DIALOG;
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ Bundle arguments = getArguments();
+ String ruleName = arguments.getString(EXTRA_ZEN_RULE_NAME);
+ String id = arguments.getString(EXTRA_ZEN_RULE_ID);
+
+ final AlertDialog dialog = new AlertDialog.Builder(getContext())
+ .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) {
+ if (arguments != null) {
+ mPositiveClickListener.onOk(id);
+ }
+ }
+ }).create();
+ final View messageView = dialog.findViewById(android.R.id.message);
+ if (messageView != null) {
+ messageView.setTextDirection(View.TEXT_DIRECTION_LOCALE);
+ }
+ return dialog;
+ }
+
+}
diff --git a/src/com/android/settings/notification/ZenModeAddAutomaticRulePreferenceController.java b/src/com/android/settings/notification/ZenModeAddAutomaticRulePreferenceController.java
index a15536c..b2e69d8 100644
--- a/src/com/android/settings/notification/ZenModeAddAutomaticRulePreferenceController.java
+++ b/src/com/android/settings/notification/ZenModeAddAutomaticRulePreferenceController.java
@@ -21,6 +21,7 @@
import android.content.Intent;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
+import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settings.utils.ZenServiceListing;
@@ -28,19 +29,18 @@
AbstractZenModeAutomaticRulePreferenceController implements
Preference.OnPreferenceClickListener {
- private final String KEY_ADD_RULE;
+ protected static final String KEY = "zen_mode_add_automatic_rule";
private final ZenServiceListing mZenServiceListing;
- public ZenModeAddAutomaticRulePreferenceController(Context context, String key,
- Fragment parent, ZenServiceListing serviceListing) {
- super(context, parent);
- KEY_ADD_RULE = key;
+ public ZenModeAddAutomaticRulePreferenceController(Context context, Fragment parent,
+ ZenServiceListing serviceListing, Lifecycle lifecycle) {
+ super(context, KEY, parent, lifecycle);
mZenServiceListing = serviceListing;
}
@Override
public String getPreferenceKey() {
- return KEY_ADD_RULE;
+ return KEY;
}
@Override
@@ -51,25 +51,30 @@
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
- Preference pref = screen.findPreference(KEY_ADD_RULE);
+ Preference pref = screen.findPreference(KEY);
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();
+ ZenRuleSelectionDialog.show(mContext, mParent, new RuleSelectionListener(),
+ mZenServiceListing);
return true;
}
+
+ public class RuleSelectionListener implements ZenRuleSelectionDialog.PositiveClickListener {
+ public RuleSelectionListener() {}
+
+ @Override
+ public void onSystemRuleSelected(ZenRuleInfo ri, Fragment parent) {
+ showNameRuleDialog(ri, parent);
+ }
+
+ @Override
+ public void onExternalRuleSelected(ZenRuleInfo ri, Fragment parent) {
+ Intent intent = new Intent().setComponent(ri.configurationActivity);
+ parent.startActivity(intent);
+ }
+ }
}
diff --git a/src/com/android/settings/notification/ZenModeAlarmsPreferenceController.java b/src/com/android/settings/notification/ZenModeAlarmsPreferenceController.java
index ef8d026..a15f7fc 100644
--- a/src/com/android/settings/notification/ZenModeAlarmsPreferenceController.java
+++ b/src/com/android/settings/notification/ZenModeAlarmsPreferenceController.java
@@ -23,6 +23,7 @@
import android.support.v7.preference.Preference;
import android.util.Log;
+import com.android.internal.logging.nano.MetricsProto;
import com.android.settingslib.core.lifecycle.Lifecycle;
public class ZenModeAlarmsPreferenceController extends
@@ -73,6 +74,9 @@
if (ZenModeSettingsBase.DEBUG) {
Log.d(TAG, "onPrefChange allowAlarms=" + allowAlarms);
}
+
+ mMetricsFeatureProvider.action(mContext, MetricsProto.MetricsEvent.ACTION_ZEN_ALLOW_ALARMS,
+ allowAlarms);
mBackend.saveSoundPolicy(Policy.PRIORITY_CATEGORY_ALARMS, allowAlarms);
return true;
}
diff --git a/src/com/android/settings/notification/ZenModeAutomaticRulesPreferenceController.java b/src/com/android/settings/notification/ZenModeAutomaticRulesPreferenceController.java
index f91bdd6..55fe927 100644
--- a/src/com/android/settings/notification/ZenModeAutomaticRulesPreferenceController.java
+++ b/src/com/android/settings/notification/ZenModeAutomaticRulesPreferenceController.java
@@ -19,28 +19,31 @@
import android.app.AutomaticZenRule;
import android.app.Fragment;
import android.content.Context;
+import android.support.annotation.VisibleForTesting;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceCategory;
import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
import java.util.Map;
public class ZenModeAutomaticRulesPreferenceController extends
AbstractZenModeAutomaticRulePreferenceController {
- private final String KEY_AUTOMATIC_RULES;
- private PreferenceCategory mPreferenceCategory;
- Map.Entry<String, AutomaticZenRule>[] mSortedRules;
+ protected static final String KEY = "zen_mode_automatic_rules";
- public ZenModeAutomaticRulesPreferenceController(Context context, String key,
- Fragment parent) {
- super(context, parent);
- KEY_AUTOMATIC_RULES = key;
- mSortedRules = sortedRules();
+ @VisibleForTesting
+ protected PreferenceCategory mPreferenceCategory;
+
+ public ZenModeAutomaticRulesPreferenceController(Context context, Fragment parent, Lifecycle
+ lifecycle) {
+ super(context, KEY, parent, lifecycle);
}
@Override
public String getPreferenceKey() {
- return KEY_AUTOMATIC_RULES;
+ return KEY;
}
@Override
@@ -59,40 +62,14 @@
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();
+ mPreferenceCategory.removeAll();
+ Map.Entry<String, AutomaticZenRule>[] sortedRules = sortedRules();
+ for (Map.Entry<String, AutomaticZenRule> sortedRule : sortedRules) {
+ ZenRulePreference pref = new ZenRulePreference(mPreferenceCategory.getContext(),
+ sortedRule, mParent, mMetricsFeatureProvider);
+ mPreferenceCategory.addPreference(pref);
}
}
-
- private boolean wasRuleDeleted(int oldRuleLength) {
- int newRuleLength = mSortedRules.length;
- int prefCount = mPreferenceCategory.getPreferenceCount();
-
- return (prefCount == oldRuleLength -1) && (prefCount == newRuleLength);
- }
-
- private void updateAutomaticRules() {
- for (Map.Entry<String, AutomaticZenRule> sortedRule : mSortedRules) {
- ZenRulePreference currPref = (ZenRulePreference)
- mPreferenceCategory.findPreference(sortedRule.getKey());
- if (currPref != null && currPref.appExists) {
- // rule already exists in preferences, update it
- currPref.setAttributes(sortedRule.getValue());
- } else {
- // rule doesn't exist in preferences, add it
- ZenRulePreference pref = new ZenRulePreference(mPreferenceCategory.getContext(),
- sortedRule, mPreferenceCategory);
- if (pref.appExists) {
- mPreferenceCategory.addPreference(pref);
- }
- }
- }
-
- }
}
diff --git a/src/com/android/settings/notification/ZenModeAutomationSettings.java b/src/com/android/settings/notification/ZenModeAutomationSettings.java
index 582fb03..55d0fca 100644
--- a/src/com/android/settings/notification/ZenModeAutomationSettings.java
+++ b/src/com/android/settings/notification/ZenModeAutomationSettings.java
@@ -28,29 +28,27 @@
import com.android.settings.utils.ManagedServiceSettings;
import com.android.settings.utils.ZenServiceListing;
import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
import java.util.ArrayList;
import java.util.List;
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 static final ManagedServiceSettings.Config CONFIG = getConditionProviderConfig();
+ protected final ManagedServiceSettings.Config CONFIG = getConditionProviderConfig();
@Override
protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
ZenServiceListing serviceListing = new ZenServiceListing(getContext(), CONFIG);
serviceListing.reloadApprovedServices();
- return buildPreferenceControllers(context, this, serviceListing);
+ return buildPreferenceControllers(context, this, serviceListing, getLifecycle());
}
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
- Fragment parent, ZenServiceListing serviceListing) {
+ Fragment parent, ZenServiceListing serviceListing, Lifecycle lifecycle) {
List<AbstractPreferenceController> controllers = new ArrayList<>();
- controllers.add(new ZenModeAddAutomaticRulePreferenceController(context, KEY_ADD_RULE,
- parent, serviceListing));
- controllers.add(new ZenModeAutomaticRulesPreferenceController(context,
- KEY_AUTOMATIC_RULES, parent));
+ controllers.add(new ZenModeAddAutomaticRulePreferenceController(context, parent,
+ serviceListing, lifecycle));
+ controllers.add(new ZenModeAutomaticRulesPreferenceController(context, parent, lifecycle));
return controllers;
}
@@ -94,15 +92,15 @@
@Override
public List<String> getNonIndexableKeys(Context context) {
final List<String> keys = super.getNonIndexableKeys(context);
- keys.add(KEY_ADD_RULE);
- keys.add(KEY_AUTOMATIC_RULES);
+ keys.add(ZenModeAddAutomaticRulePreferenceController.KEY);
+ keys.add(ZenModeAutomaticRulesPreferenceController.KEY);
return keys;
}
@Override
public List<AbstractPreferenceController> getPreferenceControllers(
Context context) {
- return buildPreferenceControllers(context, null, null);
+ return buildPreferenceControllers(context, null, null, null);
}
};
}
diff --git a/src/com/android/settings/notification/ZenModeButtonPreferenceController.java b/src/com/android/settings/notification/ZenModeButtonPreferenceController.java
index 79115f2..1886dab 100644
--- a/src/com/android/settings/notification/ZenModeButtonPreferenceController.java
+++ b/src/com/android/settings/notification/ZenModeButtonPreferenceController.java
@@ -22,6 +22,7 @@
import android.view.View;
import android.widget.Button;
+import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.applications.LayoutPreference;
import com.android.settings.core.PreferenceControllerMixin;
@@ -57,15 +58,21 @@
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));
+ mZenButtonOn.setOnClickListener(v -> {
+ mMetricsFeatureProvider.action(mContext,
+ MetricsProto.MetricsEvent.ACTION_ZEN_TOGGLE_DND_BUTTON, true);
+ 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));
+ mZenButtonOff.setOnClickListener(v -> {
+ mMetricsFeatureProvider.action(mContext,
+ MetricsProto.MetricsEvent.ACTION_ZEN_TOGGLE_DND_BUTTON, false);
+ mBackend.setZenMode(Settings.Global.ZEN_MODE_OFF);
+ });
}
updateButtons();
diff --git a/src/com/android/settings/notification/ZenModeEventRuleSettings.java b/src/com/android/settings/notification/ZenModeEventRuleSettings.java
index aa2cc3f..bb66768 100644
--- a/src/com/android/settings/notification/ZenModeEventRuleSettings.java
+++ b/src/com/android/settings/notification/ZenModeEventRuleSettings.java
@@ -61,16 +61,6 @@
}
@Override
- protected String getZenModeDependency() {
- return null;
- }
-
- @Override
- protected int getEnabledToastText() {
- return R.string.zen_event_rule_enabled_toast;
- }
-
- @Override
public void onResume() {
super.onResume();
if (isUiRestricted()) {
@@ -89,7 +79,14 @@
@Override
protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
- return null;
+ List<AbstractPreferenceController> controllers = new ArrayList<>();
+ mHeader = new ZenAutomaticRuleHeaderPreferenceController(context, this,
+ getLifecycle());
+ mSwitch = new ZenAutomaticRuleSwitchPreferenceController(context, this,
+ R.string.zen_event_rule_enabled_toast, getLifecycle());
+ controllers.add(mHeader);
+ controllers.add(mSwitch);
+ return controllers;
}
private void reloadCalendar() {
diff --git a/src/com/android/settings/notification/ZenModeEventsPreferenceController.java b/src/com/android/settings/notification/ZenModeEventsPreferenceController.java
index 3763fed..be5e6d6 100644
--- a/src/com/android/settings/notification/ZenModeEventsPreferenceController.java
+++ b/src/com/android/settings/notification/ZenModeEventsPreferenceController.java
@@ -24,6 +24,7 @@
import android.util.Log;
+import com.android.internal.logging.nano.MetricsProto;
import com.android.settingslib.core.lifecycle.Lifecycle;
public class ZenModeEventsPreferenceController extends AbstractZenModePreferenceController
@@ -71,6 +72,8 @@
if (ZenModeSettingsBase.DEBUG) {
Log.d(TAG, "onPrefChange allowEvents=" + allowEvents);
}
+ mMetricsFeatureProvider.action(mContext, MetricsProto.MetricsEvent.ACTION_ZEN_ALLOW_EVENTS,
+ allowEvents);
mBackend.saveSoundPolicy(Policy.PRIORITY_CATEGORY_EVENTS, allowEvents);
return true;
}
diff --git a/src/com/android/settings/notification/ZenModeRemindersPreferenceController.java b/src/com/android/settings/notification/ZenModeRemindersPreferenceController.java
index edc7cf9..99a4f0d7 100644
--- a/src/com/android/settings/notification/ZenModeRemindersPreferenceController.java
+++ b/src/com/android/settings/notification/ZenModeRemindersPreferenceController.java
@@ -23,6 +23,7 @@
import android.support.v7.preference.Preference;
import android.util.Log;
+import com.android.internal.logging.nano.MetricsProto;
import com.android.settingslib.core.lifecycle.Lifecycle;
public class ZenModeRemindersPreferenceController extends AbstractZenModePreferenceController
@@ -67,7 +68,11 @@
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
final boolean allowReminders = (Boolean) newValue;
- if (ZenModeSettingsBase.DEBUG) Log.d(TAG, "onPrefChange allowReminders=" + allowReminders);
+ if (ZenModeSettingsBase.DEBUG) {
+ Log.d(TAG, "onPrefChange allowReminders=" + allowReminders);
+ }
+ mMetricsFeatureProvider.action(mContext,
+ MetricsProto.MetricsEvent.ACTION_ZEN_ALLOW_REMINDERS, allowReminders);
mBackend.saveSoundPolicy(NotificationManager.Policy.PRIORITY_CATEGORY_REMINDERS,
allowReminders);
return true;
diff --git a/src/com/android/settings/notification/ZenModeRepeatCallersPreferenceController.java b/src/com/android/settings/notification/ZenModeRepeatCallersPreferenceController.java
index 1d18409..82fe865 100644
--- a/src/com/android/settings/notification/ZenModeRepeatCallersPreferenceController.java
+++ b/src/com/android/settings/notification/ZenModeRepeatCallersPreferenceController.java
@@ -23,6 +23,7 @@
import android.support.v7.preference.Preference;
import android.util.Log;
+import com.android.internal.logging.nano.MetricsProto;
import com.android.settingslib.core.lifecycle.Lifecycle;
public class ZenModeRepeatCallersPreferenceController extends AbstractZenModePreferenceController
@@ -77,8 +78,11 @@
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
final boolean allowRepeatCallers = (Boolean) newValue;
- if (ZenModeSettingsBase.DEBUG) Log.d(TAG, "onPrefChange allowRepeatCallers="
- + allowRepeatCallers);
+ if (ZenModeSettingsBase.DEBUG) {
+ Log.d(TAG, "onPrefChange allowRepeatCallers=" + allowRepeatCallers);
+ }
+ mMetricsFeatureProvider.action(mContext,
+ MetricsProto.MetricsEvent.ACTION_ZEN_ALLOW_REPEAT_CALLS, allowRepeatCallers);
mBackend.saveSoundPolicy(Policy.PRIORITY_CATEGORY_REPEAT_CALLERS, allowRepeatCallers);
return true;
}
diff --git a/src/com/android/settings/notification/ZenModeRuleSettingsBase.java b/src/com/android/settings/notification/ZenModeRuleSettingsBase.java
index 069d38b..0234c8e 100644
--- a/src/com/android/settings/notification/ZenModeRuleSettingsBase.java
+++ b/src/com/android/settings/notification/ZenModeRuleSettingsBase.java
@@ -16,62 +16,43 @@
package com.android.settings.notification;
-import android.app.Activity;
-import android.app.AlertDialog;
import android.app.AutomaticZenRule;
+import android.app.Fragment;
import android.app.NotificationManager;
import android.content.Context;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.service.notification.ConditionProviderService;
-import android.support.v7.preference.DropDownPreference;
import android.support.v7.preference.Preference;
-import android.support.v7.preference.Preference.OnPreferenceChangeListener;
import android.support.v7.preference.Preference.OnPreferenceClickListener;
import android.support.v7.preference.PreferenceScreen;
import android.util.Log;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.Switch;
import android.widget.Toast;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
-import com.android.settings.SettingsActivity;
-import com.android.settings.widget.SwitchBar;
import com.android.settingslib.core.AbstractPreferenceController;
-import java.util.List;
+public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase {
-public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase
- implements SwitchBar.OnSwitchChangeListener {
protected static final String TAG = ZenModeSettingsBase.TAG;
protected static final boolean DEBUG = ZenModeSettingsBase.DEBUG;
private static final String KEY_RULE_NAME = "rule_name";
- private static final String KEY_ZEN_MODE = "zen_mode";
protected Context mContext;
protected boolean mDisableListeners;
protected AutomaticZenRule mRule;
protected String mId;
- private boolean mDeleting;
private Preference mRuleName;
- private SwitchBar mSwitchBar;
- private DropDownPreference mZenMode;
- private Toast mEnabledToast;
+ protected ZenAutomaticRuleHeaderPreferenceController mHeader;
+ protected ZenAutomaticRuleSwitchPreferenceController mSwitch;
abstract protected void onCreateInternal();
abstract protected boolean setRule(AutomaticZenRule rule);
- abstract protected String getZenModeDependency();
abstract protected void updateControlsInternal();
- abstract protected int getEnabledToastText();
@Override
public void onCreate(Bundle icicle) {
@@ -99,8 +80,6 @@
super.onCreate(icicle);
- setHasOptionsMenu(true);
-
onCreateInternal();
final PreferenceScreen root = getPreferenceScreen();
@@ -112,37 +91,6 @@
return true;
}
});
-
- mZenMode = (DropDownPreference) root.findPreference(KEY_ZEN_MODE);
- mZenMode.setEntries(new CharSequence[] {
- getString(R.string.zen_mode_option_important_interruptions),
- getString(R.string.zen_mode_option_alarms),
- getString(R.string.zen_mode_option_no_interruptions),
- });
- mZenMode.setEntryValues(new CharSequence[] {
- Integer.toString(NotificationManager.INTERRUPTION_FILTER_PRIORITY),
- Integer.toString(NotificationManager.INTERRUPTION_FILTER_ALARMS),
- Integer.toString(NotificationManager.INTERRUPTION_FILTER_NONE),
- });
- mZenMode.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- if (mDisableListeners) return false;
- final int zenMode = Integer.parseInt((String) newValue);
- if (zenMode == mRule.getInterruptionFilter()) return false;
- if (DEBUG) Log.d(TAG, "onPrefChange zenMode=" + zenMode);
- mRule.setInterruptionFilter(zenMode);
- mBackend.setZenRule(mId, mRule);
- return true;
- }
- });
- mZenMode.setOrder(10); // sort at the bottom of the category
- mZenMode.setDependency(getZenModeDependency());
- }
-
- @Override
- protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
- return null;
}
@Override
@@ -155,43 +103,39 @@
}
@Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
-
- final SettingsActivity activity = (SettingsActivity) getActivity();
- mSwitchBar = activity.getSwitchBar();
- mSwitchBar.addOnSwitchChangeListener(this);
- mSwitchBar.show();
+ public int getHelpResource() {
+ return R.string.help_uri_interruptions;
}
- @Override
- public void onDestroyView() {
- super.onDestroyView();
- mSwitchBar.removeOnSwitchChangeListener(this);
- mSwitchBar.hide();
+ /**
+ * Update state of header preference managed by PreferenceController.
+ */
+ protected void updateHeader() {
+ final PreferenceScreen screen = getPreferenceScreen();
+
+ mSwitch.onResume(mRule,mId);
+ mSwitch.displayPreference(screen);
+ updatePreference(mSwitch);
+
+ mHeader.onResume(mRule);
+ mHeader.displayPreference(screen);
+ updatePreference(mHeader);
}
- @Override
- public void onSwitchChanged(Switch switchView, boolean isChecked) {
- if (DEBUG) Log.d(TAG, "onSwitchChanged " + isChecked);
- if (mDisableListeners) return;
- final boolean enabled = isChecked;
- if (enabled == mRule.isEnabled()) return;
- mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_ZEN_ENABLE_RULE, enabled);
- if (DEBUG) Log.d(TAG, "onSwitchChanged enabled=" + enabled);
- mRule.setEnabled(enabled);
- mBackend.setZenRule(mId, mRule);
- if (enabled) {
- final int toastText = getEnabledToastText();
- if (toastText != 0) {
- mEnabledToast = Toast.makeText(mContext, toastText, Toast.LENGTH_SHORT);
- mEnabledToast.show();
- }
- } else {
- if (mEnabledToast != null) {
- mEnabledToast.cancel();
- }
+ private void updatePreference(AbstractPreferenceController controller) {
+ final PreferenceScreen screen = getPreferenceScreen();
+ if (!controller.isAvailable()) {
+ return;
}
+ final String key = controller.getPreferenceKey();
+
+ final Preference preference = screen.findPreference(key);
+ if (preference == null) {
+ Log.d(TAG, String.format("Cannot find preference with key %s in Controller %s",
+ key, controller.getClass().getSimpleName()));
+ return;
+ }
+ controller.updateState(preference);
}
protected void updateRule(Uri newConditionId) {
@@ -207,33 +151,6 @@
}
}
- @Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
- if (DEBUG) Log.d(TAG, "onCreateOptionsMenu");
- inflater.inflate(R.menu.zen_mode_rule, menu);
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- if (DEBUG) Log.d(TAG, "onOptionsItemSelected " + item.getItemId());
- if (item.getItemId() == R.id.delete) {
- mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_ZEN_DELETE_RULE);
- showDeleteRuleDialog();
- return true;
- }
- return super.onOptionsItemSelected(item);
- }
-
- private void showRuleNameDialog() {
- new ZenRuleNameDialog(mContext, mRule.getName(), null) {
- @Override
- public void onOk(String ruleName) {
- mRule.setName(ruleName);
- mBackend.setZenRule(mId, mRule);
- }
- }.show();
- }
-
private boolean refreshRuleOrFinish() {
mRule = getZenRule();
if (DEBUG) Log.d(TAG, "mRule=" + mRule);
@@ -244,42 +161,22 @@
return false;
}
- private void showDeleteRuleDialog() {
- final AlertDialog dialog = new AlertDialog.Builder(mContext)
- .setMessage(getString(R.string.zen_mode_delete_rule_confirmation, mRule.getName()))
- .setNegativeButton(R.string.cancel, null)
- .setPositiveButton(R.string.zen_mode_delete_rule_button, new OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- mMetricsFeatureProvider.action(mContext,
- MetricsEvent.ACTION_ZEN_DELETE_RULE_OK);
- mDeleting = true;
- mBackend.removeZenRule(mId);
- }
- })
- .show();
- final View messageView = dialog.findViewById(android.R.id.message);
- if (messageView != null) {
- messageView.setTextDirection(View.TEXT_DIRECTION_LOCALE);
- }
+ private void showRuleNameDialog() {
+ ZenRuleNameDialog.show(this, mRule.getName(), null, new RuleNameChangeListener());
}
private void toastAndFinish() {
- if (!mDeleting) {
- Toast.makeText(mContext, R.string.zen_mode_rule_not_found_text, Toast.LENGTH_SHORT)
+ Toast.makeText(mContext, R.string.zen_mode_rule_not_found_text, Toast.LENGTH_SHORT)
.show();
- }
getActivity().finish();
}
private void updateRuleName() {
- Activity activity = getActivity();
- if (activity != null) {
- activity.setTitle(mRule.getName());
+ if (mRule != null) {
mRuleName.setSummary(mRule.getName());
} else {
- if (DEBUG) Log.d(TAG, "updateRuleName - activity title and mRuleName "
- + "not updated; getActivity() returned null");
+ if (DEBUG) Log.d(TAG, "updateRuleName - mRuleName "
+ + "not updated; mRuleName returned null");
}
}
@@ -291,10 +188,19 @@
mDisableListeners = true;
updateRuleName();
updateControlsInternal();
- mZenMode.setValue(Integer.toString(mRule.getInterruptionFilter()));
- if (mSwitchBar != null) {
- mSwitchBar.setChecked(mRule.isEnabled());
- }
+ updateHeader();
mDisableListeners = false;
}
+
+ public class RuleNameChangeListener implements ZenRuleNameDialog.PositiveClickListener {
+ public RuleNameChangeListener() {}
+
+ @Override
+ public void onOk(String ruleName, Fragment parent) {
+ mMetricsFeatureProvider.action(mContext,
+ MetricsProto.MetricsEvent.ACTION_ZEN_MODE_RULE_NAME_CHANGE_OK);
+ mRule.setName(ruleName);
+ mBackend.setZenRule(mId, mRule);
+ }
+ }
}
diff --git a/src/com/android/settings/notification/ZenModeScheduleRuleSettings.java b/src/com/android/settings/notification/ZenModeScheduleRuleSettings.java
index ab0349e..ecfe91b 100644
--- a/src/com/android/settings/notification/ZenModeScheduleRuleSettings.java
+++ b/src/com/android/settings/notification/ZenModeScheduleRuleSettings.java
@@ -42,6 +42,7 @@
import com.android.settingslib.core.AbstractPreferenceController;
import java.text.SimpleDateFormat;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
@@ -77,21 +78,6 @@
}
@Override
- protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
- return null;
- }
-
- @Override
- protected String getZenModeDependency() {
- return mDays.getKey();
- }
-
- @Override
- protected int getEnabledToastText() {
- return R.string.zen_schedule_rule_enabled_toast;
- }
-
- @Override
protected void onCreateInternal() {
final PreferenceScreen root = getPreferenceScreen();
@@ -208,6 +194,20 @@
updateEndSummary();
}
+
+ @Override
+ protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
+ List<AbstractPreferenceController> controllers = new ArrayList<>();
+ mHeader = new ZenAutomaticRuleHeaderPreferenceController(context, this,
+ getLifecycle());
+ mSwitch = new ZenAutomaticRuleSwitchPreferenceController(context, this,
+ R.string.zen_schedule_rule_enabled_toast, getLifecycle());
+
+ controllers.add(mHeader);
+ controllers.add(mSwitch);
+ return controllers;
+ }
+
@Override
public int getMetricsCategory() {
return MetricsEvent.NOTIFICATION_ZEN_MODE_SCHEDULE_RULE;
diff --git a/src/com/android/settings/notification/ZenModeScreenOffPreferenceController.java b/src/com/android/settings/notification/ZenModeScreenOffPreferenceController.java
index 2b70706..0ba24c0 100644
--- a/src/com/android/settings/notification/ZenModeScreenOffPreferenceController.java
+++ b/src/com/android/settings/notification/ZenModeScreenOffPreferenceController.java
@@ -22,6 +22,7 @@
import android.support.v7.preference.Preference;
import android.util.Log;
+import com.android.internal.logging.nano.MetricsProto;
import com.android.settingslib.core.lifecycle.Lifecycle;
public class ZenModeScreenOffPreferenceController extends
@@ -56,8 +57,11 @@
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
final boolean bypass = (Boolean) newValue;
- if (ZenModeSettingsBase.DEBUG) Log.d(TAG, "onPrefChange allowWhenScreenOff="
- + !bypass);
+ if (ZenModeSettingsBase.DEBUG) {
+ Log.d(TAG, "onPrefChange allowWhenScreenOff=" + bypass);
+ }
+ mMetricsFeatureProvider.action(mContext,
+ MetricsProto.MetricsEvent.ACTION_ZEN_ALLOW_WHEN_SCREEN_OFF, bypass);
mBackend.saveVisualEffectsPolicy(Policy.SUPPRESSED_EFFECT_SCREEN_OFF, bypass);
return true;
}
diff --git a/src/com/android/settings/notification/ZenModeScreenOnPreferenceController.java b/src/com/android/settings/notification/ZenModeScreenOnPreferenceController.java
index 8e0b348..bcb1af8 100644
--- a/src/com/android/settings/notification/ZenModeScreenOnPreferenceController.java
+++ b/src/com/android/settings/notification/ZenModeScreenOnPreferenceController.java
@@ -22,6 +22,7 @@
import android.support.v7.preference.Preference;
import android.util.Log;
+import com.android.internal.logging.nano.MetricsProto;
import com.android.settingslib.core.lifecycle.Lifecycle;
public class ZenModeScreenOnPreferenceController extends
@@ -57,8 +58,9 @@
public boolean onPreferenceChange(Preference preference, Object newValue) {
final boolean bypass = (Boolean) newValue;
if (ZenModeSettingsBase.DEBUG) Log.d(TAG, "onPrefChange allowWhenScreenOn="
- + !bypass);
-
+ + bypass);
+ mMetricsFeatureProvider.action(mContext,
+ MetricsProto.MetricsEvent.ACTION_ZEN_ALLOW_WHEN_SCREEN_ON, bypass);
mBackend.saveVisualEffectsPolicy(Policy.SUPPRESSED_EFFECT_SCREEN_ON, bypass);
return true;
}
diff --git a/src/com/android/settings/notification/ZenRuleNameDialog.java b/src/com/android/settings/notification/ZenRuleNameDialog.java
index eb85431..819ba5b 100644
--- a/src/com/android/settings/notification/ZenRuleNameDialog.java
+++ b/src/com/android/settings/notification/ZenRuleNameDialog.java
@@ -17,73 +17,103 @@
package com.android.settings.notification;
import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.Fragment;
import android.content.Context;
import android.content.DialogInterface;
import android.net.Uri;
+import android.os.Bundle;
import android.service.notification.ZenModeConfig;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
+import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
+import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
-public abstract class ZenRuleNameDialog {
- private static final String TAG = "ZenRuleNameDialog";
- private static final boolean DEBUG = ZenModeSettings.DEBUG;
+public class ZenRuleNameDialog extends InstrumentedDialogFragment {
+ protected static final String TAG = "ZenRuleNameDialog";
+ private static final String EXTRA_ZEN_RULE_NAME = "zen_rule_name";
+ private static final String EXTRA_CONDITION_ID = "extra_zen_condition_id";
+ protected static PositiveClickListener mPositiveClickListener;
- private final AlertDialog mDialog;
- private final EditText mEditText;
- private final CharSequence mOriginalRuleName;
- private final boolean mIsNew;
+ @Override
+ public int getMetricsCategory() {
+ return MetricsProto.MetricsEvent.NOTIFICATION_ZEN_MODE_RULE_NAME_DIALOG;
+ }
- public ZenRuleNameDialog(Context context, CharSequence ruleName, Uri conditionId) {
- mIsNew = ruleName == null;
- mOriginalRuleName = ruleName;
+ /**
+ * The interface we expect a listener to implement.
+ */
+ public interface PositiveClickListener {
+ void onOk(String newName, Fragment parent);
+ }
+
+ public static void show(Fragment parent, String ruleName, Uri conditionId, PositiveClickListener
+ listener) {
+ final Bundle args = new Bundle();
+ args.putString(EXTRA_ZEN_RULE_NAME, ruleName);
+ args.putParcelable(EXTRA_CONDITION_ID, conditionId);
+ mPositiveClickListener = listener;
+
+ ZenRuleNameDialog dialog = new ZenRuleNameDialog();
+ dialog.setArguments(args);
+ dialog.setTargetFragment(parent, 0);
+ dialog.show(parent.getFragmentManager(), TAG);
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ Bundle arguments = getArguments();
+ Uri conditionId = arguments.getParcelable(EXTRA_CONDITION_ID);
+ String ruleName = arguments.getString(EXTRA_ZEN_RULE_NAME);
+
+ boolean isNew = ruleName == null;
+ CharSequence originalRuleName = ruleName;
+ Context context = getContext();
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);
+ EditText editText = (EditText) v.findViewById(R.id.zen_mode_rule_name);
+ if (!isNew) {
+ // set text to current rule name
+ editText.setText(ruleName);
+ // move cursor to end of text
+ editText.setSelection(editText.getText().length());
}
- mEditText.setSelectAllOnFocus(true);
- mDialog = new AlertDialog.Builder(context)
- .setTitle(getTitleResource(conditionId))
+ editText.setSelectAllOnFocus(true);
+ return new AlertDialog.Builder(context)
+ .setTitle(getTitleResource(conditionId, isNew))
.setView(v)
- .setPositiveButton(mIsNew ? R.string.zen_mode_add : R.string.okay,
+ .setPositiveButton(isNew ? R.string.zen_mode_add : R.string.okay,
new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- final String newName = trimmedText();
- if (TextUtils.isEmpty(newName)) {
- return;
- }
- if (!mIsNew && mOriginalRuleName != null
- && mOriginalRuleName.equals(newName)) {
- return; // no change to an existing rule, just dismiss
- }
- onOk(newName);
- }
- })
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ final String newName = trimmedText(editText);
+ if (TextUtils.isEmpty(newName)) {
+ return;
+ }
+ if (!isNew && originalRuleName != null
+ && originalRuleName.equals(newName)) {
+ return; // no change to an existing rule, just dismiss
+ }
+ mPositiveClickListener.onOk(newName, getTargetFragment());
+ }
+ })
.setNegativeButton(R.string.cancel, null)
.create();
}
- abstract public void onOk(String ruleName);
-
- public void show() {
- mDialog.show();
+ private String trimmedText(EditText editText) {
+ return editText.getText() == null ? null : editText.getText().toString().trim();
}
- private String trimmedText() {
- return mEditText.getText() == null ? null : mEditText.getText().toString().trim();
- }
-
- private int getTitleResource(Uri conditionId) {
+ private int getTitleResource(Uri conditionId, boolean isNew) {
final boolean isEvent = ZenModeConfig.isValidEventConditionId(conditionId);
final boolean isTime = ZenModeConfig.isValidScheduleConditionId(conditionId);
int titleResource = R.string.zen_mode_rule_name;
- if (mIsNew) {
+ if (isNew) {
if (isEvent) {
titleResource = R.string.zen_mode_add_event_rule;
} else if (isTime) {
diff --git a/src/com/android/settings/notification/ZenRulePreference.java b/src/com/android/settings/notification/ZenRulePreference.java
index 4d7181a..90f6a94 100644
--- a/src/com/android/settings/notification/ZenRulePreference.java
+++ b/src/com/android/settings/notification/ZenRulePreference.java
@@ -16,23 +16,21 @@
package com.android.settings.notification;
-import android.app.AlertDialog;
import android.app.AutomaticZenRule;
-import android.app.NotificationManager;
+import android.app.Fragment;
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.internal.logging.nano.MetricsProto;
import com.android.settings.R;
+import com.android.settings.core.instrumentation.MetricsFeatureProvider;
import com.android.settings.utils.ManagedServiceSettings;
import com.android.settings.utils.ZenServiceListing;
import com.android.settingslib.TwoTargetPreference;
@@ -45,16 +43,17 @@
final CharSequence mName;
final String mId;
boolean appExists;
- final PreferenceCategory mParent;
+ final Fragment mParent;
final Preference mPref;
final Context mContext;
final ZenModeBackend mBackend;
final ZenServiceListing mServiceListing;
final PackageManager mPm;
+ final MetricsFeatureProvider mMetricsFeatureProvider;
public ZenRulePreference(Context context,
final Map.Entry<String, AutomaticZenRule> ruleEntry,
- PreferenceCategory prefCategory) {
+ Fragment parent, MetricsFeatureProvider metricsProvider) {
super(context);
mBackend = ZenModeBackend.getInstance(context);
@@ -62,11 +61,12 @@
final AutomaticZenRule rule = ruleEntry.getValue();
mName = rule.getName();
mId = ruleEntry.getKey();
- mParent = prefCategory;
+ mParent = parent;
mPm = mContext.getPackageManager();
mServiceListing = new ZenServiceListing(mContext, CONFIG);
mServiceListing.reloadApprovedServices();
mPref = this;
+ mMetricsFeatureProvider = metricsProvider;
setAttributes(rule);
}
@@ -89,25 +89,21 @@
private final View.OnClickListener mDeleteListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
- showDeleteRuleDialog(mId, mName, mParent, mPref);
+ showDeleteRuleDialog(mParent, mId, mName.toString());
}
};
- 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();
+ private void showDeleteRuleDialog(final Fragment parent, final String ruleId,
+ final String ruleName) {
+ ZenDeleteRuleDialog.show(parent, ruleName, ruleId,
+ new ZenDeleteRuleDialog.PositiveClickListener() {
+ @Override
+ public void onOk(String id) {
+ mMetricsFeatureProvider.action(mContext,
+ MetricsProto.MetricsEvent.ACTION_ZEN_DELETE_RULE_OK);
+ mBackend.removeZenRule(id);
+ }
+ });
}
protected void setAttributes(AutomaticZenRule rule) {
@@ -141,26 +137,8 @@
private String computeRuleSummary(AutomaticZenRule rule, boolean isSystemRule,
CharSequence providerLabel) {
- final String mode = computeZenModeCaption(mContext.getResources(),
- rule.getInterruptionFilter());
- final String ruleState = (rule == null || !rule.isEnabled())
+ return (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;
- }
+ : mContext.getResources().getString(R.string.switch_on_text);
}
}
\ No newline at end of file
diff --git a/src/com/android/settings/notification/ZenRuleSelectionDialog.java b/src/com/android/settings/notification/ZenRuleSelectionDialog.java
index 0c725ed..0784d5a 100644
--- a/src/com/android/settings/notification/ZenRuleSelectionDialog.java
+++ b/src/com/android/settings/notification/ZenRuleSelectionDialog.java
@@ -16,16 +16,20 @@
package com.android.settings.notification;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+
import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.Fragment;
import android.app.NotificationManager;
import android.content.Context;
import android.content.DialogInterface;
-import android.content.DialogInterface.OnDismissListener;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
+import android.os.Bundle;
import android.service.notification.ZenModeConfig;
import android.util.Log;
import android.view.LayoutInflater;
@@ -35,6 +39,7 @@
import android.widget.TextView;
import com.android.settings.R;
+import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settings.utils.ZenServiceListing;
import java.lang.ref.WeakReference;
@@ -43,24 +48,48 @@
import java.util.Set;
import java.util.TreeSet;
-public abstract class ZenRuleSelectionDialog {
+public class ZenRuleSelectionDialog extends InstrumentedDialogFragment {
private static final String TAG = "ZenRuleSelectionDialog";
private static final boolean DEBUG = ZenModeSettings.DEBUG;
- private final Context mContext;
- private final PackageManager mPm;
- private NotificationManager mNm;
- private final AlertDialog mDialog;
- private final LinearLayout mRuleContainer;
- private final ZenServiceListing mServiceListing;
+ private static ZenServiceListing mServiceListing;
+ protected static PositiveClickListener mPositiveClickListener;
- public ZenRuleSelectionDialog(Context context, ZenServiceListing serviceListing) {
+ private static Context mContext;
+ private static PackageManager mPm;
+ private static NotificationManager mNm;
+ private LinearLayout mRuleContainer;
+
+ /**
+ * The interface we expect a listener to implement.
+ */
+ public interface PositiveClickListener {
+ void onSystemRuleSelected(ZenRuleInfo ruleInfo, Fragment parent);
+ void onExternalRuleSelected(ZenRuleInfo ruleInfo, Fragment parent);
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsEvent.NOTIFICATION_ZEN_MODE_RULE_SELECTION_DIALOG;
+ }
+
+ public static void show(Context context, Fragment parent, PositiveClickListener
+ listener, ZenServiceListing serviceListing) {
+ mPositiveClickListener = listener;
mContext = context;
- mPm = context.getPackageManager();
- mNm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
+ mPm = mContext.getPackageManager();
+ mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
mServiceListing = serviceListing;
- final View v =
- LayoutInflater.from(context).inflate(R.layout.zen_rule_type_selection, null, false);
+
+ ZenRuleSelectionDialog dialog = new ZenRuleSelectionDialog();
+ dialog.setTargetFragment(parent, 0);
+ dialog.show(parent.getFragmentManager(), TAG);
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ final View v = LayoutInflater.from(getContext()).inflate(R.layout.zen_rule_type_selection,
+ null, false);
mRuleContainer = (LinearLayout) v.findViewById(R.id.rule_container);
if (mServiceListing != null) {
@@ -69,28 +98,21 @@
mServiceListing.addZenCallback(mServiceListingCallback);
mServiceListing.reloadApprovedServices();
}
- mDialog = new AlertDialog.Builder(context)
+ return new AlertDialog.Builder(getContext())
.setTitle(R.string.zen_mode_choose_rule_type)
.setView(v)
- .setOnDismissListener(new OnDismissListener() {
- @Override
- public void onDismiss(DialogInterface dialog) {
- if (mServiceListing != null) {
- mServiceListing.removeZenCallback(mServiceListingCallback);
- }
- }
- })
.setNegativeButton(R.string.cancel, null)
.create();
}
- public void show() {
- mDialog.show();
+ @Override
+ public void onDismiss(DialogInterface dialog) {
+ super.onDismiss(dialog);
+ if (mServiceListing != null) {
+ mServiceListing.removeZenCallback(mServiceListingCallback);
+ }
}
- abstract public void onSystemRuleSelected(ZenRuleInfo ruleInfo);
- abstract public void onExternalRuleSelected(ZenRuleInfo ruleInfo);
-
private void bindType(final ZenRuleInfo ri) {
try {
ApplicationInfo info = mPm.getApplicationInfo(ri.packageName, 0);
@@ -108,11 +130,11 @@
v.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- mDialog.dismiss();
+ dismiss();
if (ri.isSystem) {
- onSystemRuleSelected(ri);
+ mPositiveClickListener.onSystemRuleSelected(ri, getTargetFragment());
} else {
- onExternalRuleSelected(ri);
+ mPositiveClickListener.onExternalRuleSelected(ri, getTargetFragment());
}
}
});
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeAutomaticRulesPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeAutomaticRulesPreferenceControllerTest.java
new file mode 100644
index 0000000..0dae923
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/ZenModeAutomaticRulesPreferenceControllerTest.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertTrue;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.app.AutomaticZenRule;
+import android.app.Fragment;
+import android.app.NotificationManager;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v7.preference.PreferenceCategory;
+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.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.util.ReflectionHelpers;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class ZenModeAutomaticRulesPreferenceControllerTest {
+ private ZenModeAutomaticRulesPreferenceController mController;
+ private final String GENERIC_RULE_NAME = "test";
+
+ @Mock
+ private ZenModeBackend mBackend;
+ @Mock
+ private NotificationManager mNotificationManager;
+ @Mock
+ private PreferenceCategory mockPref;
+ @Mock
+ private NotificationManager.Policy mPolicy;
+ @Mock
+ private PreferenceScreen mPreferenceScreen;
+
+ private Context mContext;
+ private ContentResolver mContentResolver;
+
+ @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 ZenModeAutomaticRulesPreferenceController(mContext, mock(Fragment.class),
+ mock(Lifecycle.class));
+ ReflectionHelpers.setField(mController, "mBackend", mBackend);
+
+ when(mPreferenceScreen.findPreference(mController.getPreferenceKey())).thenReturn(
+ mockPref);
+ mController.displayPreference(mPreferenceScreen);
+ }
+
+ @Test
+ public void updateState_checkRuleOrderingDescending() {
+ final int NUM_RULES = 4;
+ when(mNotificationManager.getAutomaticZenRules()).thenReturn(
+ mockAutoZenRulesDecreasingCreationTime(NUM_RULES));
+
+ Map.Entry<String, AutomaticZenRule>[] rules = mController.sortedRules();
+ assertEquals(NUM_RULES, rules.length);
+
+ // check ordering, most recent should be at the bottom/end (ie higher creation time)
+ for (int i = 0; i < NUM_RULES; i++) {
+ assertEquals(rules[i].getKey(), GENERIC_RULE_NAME + (NUM_RULES - 1 - i));
+ }
+ }
+
+ @Test
+ public void updateState_checkRuleOrderingAscending() {
+ final int NUM_RULES = 4;
+ when(mNotificationManager.getAutomaticZenRules()).thenReturn(
+ mockAutoZenRulesAscendingCreationTime(NUM_RULES));
+
+ Map.Entry<String, AutomaticZenRule>[] rules = mController.sortedRules();
+ assertEquals(NUM_RULES, rules.length);
+
+ // check ordering, most recent should be at the bottom/end (ie higher creation time)
+ for (int i = 0; i < NUM_RULES; i++) {
+ assertEquals(rules[i].getKey(), GENERIC_RULE_NAME + i);
+ }
+ }
+
+ @Test
+ public void updateState_checkRuleOrderingMix() {
+ final int NUM_RULES = 4;
+ // map with creation times: 0, 2, 4, 6
+ Map<String,AutomaticZenRule> rMap = mockAutoZenRulesAscendingCreationTime(NUM_RULES);
+
+ final String insertedRule1 = "insertedRule1";
+ rMap.put(insertedRule1, new AutomaticZenRule(insertedRule1, null, null,
+ Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, 5));
+
+ final String insertedRule2 = "insertedRule2";
+ rMap.put(insertedRule2, new AutomaticZenRule(insertedRule2, null, null,
+ Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, 3));
+
+ // rule map with rule creation times, 0, 2, 4, 6, 5, 3
+ // sort should create ordering based on creation times: 0, 2, 3, 4, 5, 6
+ when(mNotificationManager.getAutomaticZenRules()).thenReturn(rMap);
+
+ Map.Entry<String, AutomaticZenRule>[] rules = mController.sortedRules();
+ assertEquals(NUM_RULES + 2, rules.length); // inserted 2 rules
+
+ // check ordering of inserted rules
+ assertEquals(rules[4].getKey(), insertedRule1);
+ assertEquals(rules[2].getKey(), insertedRule2);
+ }
+
+ private Map<String, AutomaticZenRule> mockAutoZenRulesAscendingCreationTime(int numRules) {
+ Map<String, AutomaticZenRule> ruleMap = new HashMap<>();
+
+ for (int i = 0; i < numRules; i++) {
+ ruleMap.put(GENERIC_RULE_NAME + i, new AutomaticZenRule(GENERIC_RULE_NAME + i, null,
+ null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, i * 2));
+ }
+
+ return ruleMap;
+ }
+
+ private Map<String, AutomaticZenRule> mockAutoZenRulesDecreasingCreationTime(int numRules) {
+ Map<String, AutomaticZenRule> ruleMap = new HashMap<>();
+
+ for (int i = 0; i < numRules; i++) {
+ ruleMap.put(GENERIC_RULE_NAME + i, new AutomaticZenRule(GENERIC_RULE_NAME + i, null,
+ null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, numRules - i));
+ }
+
+ return ruleMap;
+ }
+}
\ No newline at end of file