summaryrefslogtreecommitdiffstats
path: root/src/com/android
diff options
context:
space:
mode:
authorJohn Spurlock <jspurlock@google.com>2015-04-09 12:50:04 -0400
committerJohn Spurlock <jspurlock@google.com>2015-04-09 20:56:16 -0400
commit45fa140b8c6846b4546fdeabebf989ae9102cebb (patch)
treeddebdae6ced30e4be858c4381c7c029e132dfa4a /src/com/android
parent342d08537fe316f0d046a3a3097c294e4b30e912 (diff)
downloadpackages_apps_Settings-45fa140b8c6846b4546fdeabebf989ae9102cebb.zip
packages_apps_Settings-45fa140b8c6846b4546fdeabebf989ae9102cebb.tar.gz
packages_apps_Settings-45fa140b8c6846b4546fdeabebf989ae9102cebb.tar.bz2
Settings: An update on Downtime.
- Migrate settings to the new zen mode state model. - Remove downtime settings. - Add automatic rule management page (add/remove) - Bind new automatic schedule rules to detail editor. - Clean up a few found miscapitalized string captions. - Migrate zen switch to report the shared summary string. Bug: 20064962 Change-Id: Ia561e7f77c90c962729240b4d51ba1915297f64a
Diffstat (limited to 'src/com/android')
-rw-r--r--src/com/android/settings/Settings.java1
-rw-r--r--src/com/android/settings/SettingsActivity.java4
-rw-r--r--src/com/android/settings/notification/ZenModeAutomaticConditionSelection.java157
-rw-r--r--src/com/android/settings/notification/ZenModeAutomationSettings.java456
-rw-r--r--src/com/android/settings/notification/ZenModeConditionSelection.java7
-rw-r--r--src/com/android/settings/notification/ZenModeScheduleDaysSelection.java (renamed from src/com/android/settings/notification/ZenModeDowntimeDaysSelection.java)46
-rw-r--r--src/com/android/settings/notification/ZenModeScheduleRuleSettings.java477
-rw-r--r--src/com/android/settings/notification/ZenModeSettings.java47
-rw-r--r--src/com/android/settings/notification/ZenModeSettingsBase.java39
-rw-r--r--src/com/android/settings/notification/ZenRuleNameDialog.java93
-rw-r--r--src/com/android/settings/search/SearchIndexableResources.java12
11 files changed, 706 insertions, 633 deletions
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 70455a4..b58159e 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -96,6 +96,7 @@ public class Settings extends SettingsActivity {
public static class ZenModeSettingsActivity extends SettingsActivity { /* empty */ }
public static class ZenModePrioritySettingsActivity extends SettingsActivity { /* empty */ }
public static class ZenModeAutomationSettingsActivity extends SettingsActivity { /* empty */ }
+ public static class ZenModeScheduleRuleSettingsActivity extends SettingsActivity { /* empty */ }
public static class NotificationSettingsActivity extends SettingsActivity { /* empty */ }
public static class NotificationAppListActivity extends SettingsActivity { /* empty */ }
public static class AppNotificationSettingsActivity extends SettingsActivity { /* empty */ }
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index 0973b14..24209b0 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -100,6 +100,7 @@ import com.android.settings.notification.NotificationSettings;
import com.android.settings.notification.NotificationStation;
import com.android.settings.notification.OtherSoundSettings;
import com.android.settings.notification.ZenModeSettings;
+import com.android.settings.notification.ZenModeScheduleRuleSettings;
import com.android.settings.print.PrintJobSettingsFragment;
import com.android.settings.print.PrintSettingsFragment;
import com.android.settings.search.DynamicIndexableContentMonitor;
@@ -332,7 +333,8 @@ public class SettingsActivity extends Activity
AppNotificationSettings.class.getName(),
OtherSoundSettings.class.getName(),
ApnSettings.class.getName(),
- WifiCallingSettings.class.getName()
+ WifiCallingSettings.class.getName(),
+ ZenModeScheduleRuleSettings.class.getName(),
};
diff --git a/src/com/android/settings/notification/ZenModeAutomaticConditionSelection.java b/src/com/android/settings/notification/ZenModeAutomaticConditionSelection.java
deleted file mode 100644
index 0e77632..0000000
--- a/src/com/android/settings/notification/ZenModeAutomaticConditionSelection.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) 2014 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.animation.LayoutTransition;
-import android.app.INotificationManager;
-import android.content.Context;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.Message;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.service.notification.Condition;
-import android.service.notification.IConditionListener;
-import android.util.ArraySet;
-import android.util.Log;
-import android.widget.CheckBox;
-import android.widget.CompoundButton;
-import android.widget.LinearLayout;
-
-import com.android.settings.R;
-
-public class ZenModeAutomaticConditionSelection extends LinearLayout {
- private static final String TAG = "ZenModeAutomaticConditionSelection";
- private static final boolean DEBUG = true;
-
- private final INotificationManager mNoMan;
- private final H mHandler = new H();
- private final Context mContext;
- private final ArraySet<Uri> mSelectedConditions = new ArraySet<Uri>();
-
- public ZenModeAutomaticConditionSelection(Context context) {
- super(context);
- mContext = context;
- setOrientation(VERTICAL);
- setLayoutTransition(new LayoutTransition());
- final int p = mContext.getResources().getDimensionPixelSize(R.dimen.content_margin_left);
- setPadding(p, p, p, 0);
- mNoMan = INotificationManager.Stub.asInterface(
- ServiceManager.getService(Context.NOTIFICATION_SERVICE));
- refreshSelectedConditions();
- }
-
- private void refreshSelectedConditions() {
- try {
- final Condition[] automatic = mNoMan.getAutomaticZenModeConditions();
- mSelectedConditions.clear();
- if (automatic != null) {
- for (Condition c : automatic) {
- mSelectedConditions.add(c.id);
- }
- }
- } catch (RemoteException e) {
- Log.w(TAG, "Error calling getAutomaticZenModeConditions", e);
- }
- }
-
- private CheckBox newCheckBox(Object tag) {
- final CheckBox button = new CheckBox(mContext);
- button.setTag(tag);
- button.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- setSelectedCondition((Uri)button.getTag(), isChecked);
- }
- });
- addView(button);
- return button;
- }
-
- private void setSelectedCondition(Uri conditionId, boolean selected) {
- if (DEBUG) Log.d(TAG, "setSelectedCondition conditionId=" + conditionId
- + " selected=" + selected);
- if (selected) {
- mSelectedConditions.add(conditionId);
- } else {
- mSelectedConditions.remove(conditionId);
- }
- final Uri[] automatic = new Uri[mSelectedConditions.size()];
- for (int i = 0; i < automatic.length; i++) {
- automatic[i] = mSelectedConditions.valueAt(i);
- }
- try {
- mNoMan.setAutomaticZenModeConditions(automatic);
- } catch (RemoteException e) {
- Log.w(TAG, "Error calling setAutomaticZenModeConditions", e);
- }
- }
-
- @Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- requestZenModeConditions(Condition.FLAG_RELEVANT_ALWAYS);
- }
-
- @Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- requestZenModeConditions(0 /*none*/);
- }
-
- protected void requestZenModeConditions(int relevance) {
- if (DEBUG) Log.d(TAG, "requestZenModeConditions " + Condition.relevanceToString(relevance));
- try {
- mNoMan.requestZenModeConditions(mListener, relevance);
- } catch (RemoteException e) {
- Log.w(TAG, "Error calling requestZenModeConditions", e);
- }
- }
-
- protected void handleConditions(Condition[] conditions) {
- for (final Condition c : conditions) {
- CheckBox v = (CheckBox) findViewWithTag(c.id);
- if (c.state != Condition.STATE_ERROR) {
- if (v == null) {
- v = newCheckBox(c.id);
- }
- }
- if (v != null) {
- v.setText(c.summary);
- v.setEnabled(c.state != Condition.STATE_ERROR);
- v.setChecked(mSelectedConditions.contains(c.id));
- }
- }
- }
-
- private final IConditionListener mListener = new IConditionListener.Stub() {
- @Override
- public void onConditionsReceived(Condition[] conditions) {
- if (conditions == null || conditions.length == 0) return;
- mHandler.obtainMessage(H.CONDITIONS, conditions).sendToTarget();
- }
- };
-
- private final class H extends Handler {
- private static final int CONDITIONS = 1;
-
- @Override
- public void handleMessage(Message msg) {
- if (msg.what == CONDITIONS) handleConditions((Condition[])msg.obj);
- }
- }
-}
diff --git a/src/com/android/settings/notification/ZenModeAutomationSettings.java b/src/com/android/settings/notification/ZenModeAutomationSettings.java
index 378643e..09de7d1 100644
--- a/src/com/android/settings/notification/ZenModeAutomationSettings.java
+++ b/src/com/android/settings/notification/ZenModeAutomationSettings.java
@@ -16,248 +16,76 @@
package com.android.settings.notification;
-import static com.android.settings.notification.ZenModeDowntimeDaysSelection.DAYS;
-
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.DialogFragment;
-import android.app.FragmentManager;
-import android.app.INotificationManager;
-import android.app.TimePickerDialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnDismissListener;
-import android.content.pm.PackageManager;
-import android.content.res.Resources;
+import android.content.Intent;
import android.os.Bundle;
-import android.os.ServiceManager;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
-import android.preference.PreferenceCategory;
import android.preference.PreferenceScreen;
-import android.service.notification.Condition;
+import android.provider.Settings.Global;
import android.service.notification.ZenModeConfig;
-import android.text.format.DateFormat;
+import android.service.notification.ZenModeConfig.ScheduleInfo;
+import android.service.notification.ZenModeConfig.ZenRule;
import android.util.Log;
-import android.util.SparseArray;
-import android.widget.TimePicker;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
import com.android.internal.logging.MetricsLogger;
-import com.android.settings.DropDownPreference;
import com.android.settings.R;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
-import com.android.settings.search.SearchIndexableRaw;
-
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.List;
-import java.util.Objects;
-
-public class ZenModeAutomationSettings extends ZenModeSettingsBase implements Indexable {
- private static final String KEY_DOWNTIME = "downtime";
- private static final String KEY_DAYS = "days";
- private static final String KEY_START_TIME = "start_time";
- private static final String KEY_END_TIME = "end_time";
- private static final String KEY_DOWNTIME_MODE = "downtime_mode";
-
- private static final String KEY_AUTOMATION = "automation";
- private static final String KEY_ENTRY = "entry";
- private static final String KEY_CONDITION_PROVIDERS = "manage_condition_providers";
-
- private static final SimpleDateFormat DAY_FORMAT = new SimpleDateFormat("EEE");
-
- private PackageManager mPM;
- private boolean mDisableListeners;
- private boolean mDowntimeSupported;
- private Preference mDays;
- private TimePickerPreference mStart;
- private TimePickerPreference mEnd;
- private DropDownPreference mDowntimeMode;
- private PreferenceCategory mAutomationCategory;
- private Preference mEntry;
- private Preference mConditionProviders;
+public class ZenModeAutomationSettings extends ZenModeSettingsBase {
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
- mPM = mContext.getPackageManager();
+
+ setHasOptionsMenu(true);
addPreferencesFromResource(R.xml.zen_mode_automation_settings);
- final PreferenceScreen root = getPreferenceScreen();
+ }
- onCreateDowntimeSettings(root);
+ private void showRule(String ruleId, String ruleName) {
+ if (DEBUG) Log.d(TAG, "showRule " + ruleId + " name=" + ruleName);
+ mContext.startActivity(new Intent(ZenModeScheduleRuleSettings.ACTION)
+ .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
+ .putExtra(ZenModeScheduleRuleSettings.EXTRA_RULE_ID, ruleId));
+ }
- mAutomationCategory = (PreferenceCategory) findPreference(KEY_AUTOMATION);
- mEntry = findPreference(KEY_ENTRY);
- mEntry.setOnPreferenceClickListener(new OnPreferenceClickListener() {
- @Override
- public boolean onPreferenceClick(Preference preference) {
- new AlertDialog.Builder(mContext)
- .setTitle(R.string.zen_mode_entry_conditions_title)
- .setView(new ZenModeAutomaticConditionSelection(mContext))
- .setOnDismissListener(new OnDismissListener() {
- @Override
- public void onDismiss(DialogInterface dialog) {
- refreshAutomationSection();
- }
- })
- .setPositiveButton(R.string.dlg_ok, null)
- .show();
- return true;
- }
- });
- mConditionProviders = findPreference(KEY_CONDITION_PROVIDERS);
+ @Override
+ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ inflater.inflate(R.menu.zen_mode_automation, menu);
}
- private void onCreateDowntimeSettings(PreferenceScreen root) {
- mDowntimeSupported = isDowntimeSupported(mContext);
- if (!mDowntimeSupported) {
- removePreference(KEY_DOWNTIME);
- return;
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if (item.getItemId() == R.id.add) {
+ showAddRuleDialog();
+ return true;
}
- final PreferenceCategory downtime = (PreferenceCategory) findPreference(KEY_DOWNTIME);
- mDays = downtime.findPreference(KEY_DAYS);
- mDays.setOnPreferenceClickListener(new OnPreferenceClickListener() {
- @Override
- public boolean onPreferenceClick(Preference preference) {
- new AlertDialog.Builder(mContext)
- .setTitle(R.string.zen_mode_downtime_days)
- .setView(new ZenModeDowntimeDaysSelection(mContext, mConfig.sleepMode) {
- @Override
- protected void onChanged(String mode) {
- if (mDisableListeners) return;
- if (Objects.equals(mode, mConfig.sleepMode)) return;
- if (DEBUG) Log.d(TAG, "days.onChanged sleepMode=" + mode);
- final ZenModeConfig newConfig = mConfig.copy();
- newConfig.sleepMode = mode;
- setZenModeConfig(newConfig);
- }
- })
- .setOnDismissListener(new OnDismissListener() {
- @Override
- public void onDismiss(DialogInterface dialog) {
- updateDays();
- }
- })
- .setPositiveButton(R.string.done_button, null)
- .show();
- return true;
- }
- });
-
- final FragmentManager mgr = getFragmentManager();
-
- mStart = new TimePickerPreference(mContext, mgr);
- mStart.setKey(KEY_START_TIME);
- mStart.setTitle(R.string.zen_mode_start_time);
- mStart.setCallback(new TimePickerPreference.Callback() {
- @Override
- public boolean onSetTime(int hour, int minute) {
- if (mDisableListeners) return true;
- if (!ZenModeConfig.isValidHour(hour)) return false;
- if (!ZenModeConfig.isValidMinute(minute)) return false;
- if (hour == mConfig.sleepStartHour && minute == mConfig.sleepStartMinute) {
- return true;
- }
- if (DEBUG) Log.d(TAG, "onPrefChange sleepStart h=" + hour + " m=" + minute);
- final ZenModeConfig newConfig = mConfig.copy();
- newConfig.sleepStartHour = hour;
- newConfig.sleepStartMinute = minute;
- return setZenModeConfig(newConfig);
- }
- });
- downtime.addPreference(mStart);
- mStart.setDependency(mDays.getKey());
-
- mEnd = new TimePickerPreference(mContext, mgr);
- mEnd.setKey(KEY_END_TIME);
- mEnd.setTitle(R.string.zen_mode_end_time);
- mEnd.setCallback(new TimePickerPreference.Callback() {
- @Override
- public boolean onSetTime(int hour, int minute) {
- if (mDisableListeners) return true;
- if (!ZenModeConfig.isValidHour(hour)) return false;
- if (!ZenModeConfig.isValidMinute(minute)) return false;
- if (hour == mConfig.sleepEndHour && minute == mConfig.sleepEndMinute) {
- return true;
- }
- if (DEBUG) Log.d(TAG, "onPrefChange sleepEnd h=" + hour + " m=" + minute);
- final ZenModeConfig newConfig = mConfig.copy();
- newConfig.sleepEndHour = hour;
- newConfig.sleepEndMinute = minute;
- return setZenModeConfig(newConfig);
- }
- });
- downtime.addPreference(mEnd);
- mEnd.setDependency(mDays.getKey());
+ return super.onOptionsItemSelected(item);
+ }
- mDowntimeMode = (DropDownPreference) downtime.findPreference(KEY_DOWNTIME_MODE);
- mDowntimeMode.addItem(R.string.zen_mode_downtime_mode_priority, false);
- mDowntimeMode.addItem(R.string.zen_mode_downtime_mode_none, true);
- mDowntimeMode.setCallback(new DropDownPreference.Callback() {
+ private void showAddRuleDialog() {
+ new ZenRuleNameDialog(mContext, "", mConfig.getAutomaticRuleNames()) {
@Override
- public boolean onItemSelected(int pos, Object value) {
- if (mDisableListeners) return true;
- final boolean sleepNone = value instanceof Boolean ? ((Boolean) value) : false;
- if (mConfig == null || mConfig.sleepNone == sleepNone) return false;
+ public void onOk(String ruleName) {
+ final ScheduleInfo schedule = new ScheduleInfo();
+ schedule.days = ZenModeConfig.ALL_DAYS;
+ schedule.startHour = 22;
+ schedule.endHour = 7;
+ final ZenRule rule = new ZenRule();
+ rule.name = ruleName;
+ rule.enabled = true;
+ rule.zenMode = Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ rule.conditionId = ZenModeConfig.toScheduleConditionId(schedule);
final ZenModeConfig newConfig = mConfig.copy();
- newConfig.sleepNone = sleepNone;
- if (DEBUG) Log.d(TAG, "onPrefChange sleepNone=" + sleepNone);
- return setZenModeConfig(newConfig);
- }
- });
- mDowntimeMode.setOrder(10); // sort at the bottom of the category
- mDowntimeMode.setDependency(mDays.getKey());
- }
-
- private void updateDays() {
- // Compute an ordered, delimited list of day names based on the persisted user config.
- if (mConfig != null) {
- final int[] days = ZenModeConfig.tryParseDays(mConfig.sleepMode);
- if (days != null && days.length != 0) {
- final StringBuilder sb = new StringBuilder();
- final Calendar c = Calendar.getInstance();
- for (int i = 0; i < DAYS.length; i++) {
- final int day = DAYS[i];
- for (int j = 0; j < days.length; j++) {
- if (day == days[j]) {
- c.set(Calendar.DAY_OF_WEEK, day);
- if (sb.length() > 0) {
- sb.append(mContext.getString(R.string.summary_divider_text));
- }
- sb.append(DAY_FORMAT.format(c.getTime()));
- break;
- }
- }
- }
- if (sb.length() > 0) {
- mDays.setSummary(sb);
- mDays.notifyDependencyChange(false);
- return;
+ final String ruleId = newConfig.newRuleId();
+ newConfig.automaticRules.put(ruleId, rule);
+ if (setZenModeConfig(newConfig)) {
+ showRule(ruleId, rule.name);
}
}
- }
- mDays.setSummary(R.string.zen_mode_downtime_days_none);
- mDays.notifyDependencyChange(true);
- }
-
- private void updateEndSummary() {
- if (!mDowntimeSupported) return;
- final int startMin = 60 * mConfig.sleepStartHour + mConfig.sleepStartMinute;
- final int endMin = 60 * mConfig.sleepEndHour + mConfig.sleepEndMinute;
- final boolean nextDay = startMin >= endMin;
- final int summaryFormat;
- if (mConfig.sleepNone) {
- summaryFormat = nextDay ? R.string.zen_mode_end_time_none_next_day_summary_format
- : R.string.zen_mode_end_time_none_same_day_summary_format;
- } else {
- summaryFormat = nextDay ? R.string.zen_mode_end_time_priority_next_day_summary_format
- : 0;
- }
- mEnd.setSummaryFormat(summaryFormat);
+ }.show();
}
@Override
@@ -277,188 +105,32 @@ public class ZenModeAutomationSettings extends ZenModeSettingsBase implements In
}
private void updateControls() {
- mDisableListeners = true;
- if (mDowntimeSupported) {
- updateDays();
- mStart.setTime(mConfig.sleepStartHour, mConfig.sleepStartMinute);
- mEnd.setTime(mConfig.sleepEndHour, mConfig.sleepEndMinute);
- mDowntimeMode.setSelectedValue(mConfig.sleepNone);
- }
- mDisableListeners = false;
- refreshAutomationSection();
- updateEndSummary();
- }
-
- @Override
- protected int getMetricsCategory() {
- return MetricsLogger.NOTIFICATION_ZEN_MODE_AUTOMATION;
- }
-
- private void refreshAutomationSection() {
- if (mConditionProviders != null) {
- final int total = ConditionProviderSettings.getProviderCount(mPM);
- if (total == 0) {
- getPreferenceScreen().removePreference(mAutomationCategory);
- } else {
- final int n = ConditionProviderSettings.getEnabledProviderCount(mContext);
- if (n == 0) {
- mConditionProviders.setSummary(getResources().getString(
- R.string.manage_condition_providers_summary_zero));
- } else {
- mConditionProviders.setSummary(String.format(getResources().getQuantityString(
- R.plurals.manage_condition_providers_summary_nonzero,
- n, n)));
- }
- final String entrySummary = getEntryConditionSummary();
- if (n == 0 || entrySummary == null) {
- mEntry.setSummary(R.string.zen_mode_entry_conditions_summary_none);
- } else {
- mEntry.setSummary(entrySummary);
- }
- }
- }
- }
-
- private String getEntryConditionSummary() {
- final INotificationManager nm = INotificationManager.Stub.asInterface(
- ServiceManager.getService(Context.NOTIFICATION_SERVICE));
- try {
- final Condition[] automatic = nm.getAutomaticZenModeConditions();
- if (automatic == null || automatic.length == 0) {
- return null;
- }
- final String divider = getString(R.string.summary_divider_text);
- final StringBuilder sb = new StringBuilder();
- for (int i = 0; i < automatic.length; i++) {
- if (i > 0) sb.append(divider);
- sb.append(automatic[i].summary);
- }
- return sb.toString();
- } catch (Exception e) {
- Log.w(TAG, "Error calling getAutomaticZenModeConditions", e);
- return null;
- }
- }
-
- private static SparseArray<String> allKeyTitles(Context context) {
- final SparseArray<String> rt = new SparseArray<String>();
- rt.put(R.string.zen_mode_downtime_category, KEY_DOWNTIME);
- rt.put(R.string.zen_mode_downtime_days, KEY_DAYS);
- rt.put(R.string.zen_mode_start_time, KEY_START_TIME);
- rt.put(R.string.zen_mode_end_time, KEY_END_TIME);
- rt.put(R.string.zen_mode_downtime_mode_title, KEY_DOWNTIME_MODE);
- rt.put(R.string.zen_mode_automation_category, KEY_AUTOMATION);
- rt.put(R.string.manage_condition_providers, KEY_CONDITION_PROVIDERS);
- return rt;
- }
-
- // Enable indexing of searchable data
- public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider() {
-
- @Override
- public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) {
- final SparseArray<String> keyTitles = allKeyTitles(context);
- final int N = keyTitles.size();
- final List<SearchIndexableRaw> result = new ArrayList<SearchIndexableRaw>(N);
- final Resources res = context.getResources();
- for (int i = 0; i < N; i++) {
- final SearchIndexableRaw data = new SearchIndexableRaw(context);
- data.key = keyTitles.valueAt(i);
- data.title = res.getString(keyTitles.keyAt(i));
- data.screenTitle = res.getString(R.string.zen_mode_automation_settings_title);
- result.add(data);
- }
- return result;
- }
-
- @Override
- public List<String> getNonIndexableKeys(Context context) {
- final ArrayList<String> rt = new ArrayList<String>();
- if (!isDowntimeSupported(context)) {
- rt.add(KEY_DOWNTIME);
- rt.add(KEY_DAYS);
- rt.add(KEY_START_TIME);
- rt.add(KEY_END_TIME);
- rt.add(KEY_DOWNTIME_MODE);
- }
- return rt;
- }
- };
-
- private static class TimePickerPreference extends Preference {
- private final Context mContext;
-
- private int mSummaryFormat;
- private int mHourOfDay;
- private int mMinute;
- private Callback mCallback;
-
- public TimePickerPreference(Context context, final FragmentManager mgr) {
- super(context);
- mContext = context;
- setPersistent(false);
- setOnPreferenceClickListener(new OnPreferenceClickListener(){
+ final PreferenceScreen root = getPreferenceScreen();
+ root.removeAll();
+
+ if (mConfig == null) return;
+ for (int i = 0; i < mConfig.automaticRules.size(); i++) {
+ final String id = mConfig.automaticRules.keyAt(i);
+ final ZenRule rule = mConfig.automaticRules.valueAt(i);
+ if (!ZenModeConfig.isValidScheduleConditionId(rule.conditionId)) continue;
+ final Preference p = new Preference(mContext);
+ p.setTitle(rule.name);
+ p.setSummary(rule.enabled ? R.string.switch_on_text : R.string.switch_off_text);
+ p.setPersistent(false);
+ p.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
- final TimePickerFragment frag = new TimePickerFragment();
- frag.pref = TimePickerPreference.this;
- frag.show(mgr, TimePickerPreference.class.getName());
+ showRule(id, rule.name);
return true;
}
});
+ root.addPreference(p);
}
+ }
- public void setCallback(Callback callback) {
- mCallback = callback;
- }
-
- public void setSummaryFormat(int resId) {
- mSummaryFormat = resId;
- updateSummary();
- }
-
- public void setTime(int hourOfDay, int minute) {
- if (mCallback != null && !mCallback.onSetTime(hourOfDay, minute)) return;
- mHourOfDay = hourOfDay;
- mMinute = minute;
- updateSummary();
- }
-
- private void updateSummary() {
- final Calendar c = Calendar.getInstance();
- c.set(Calendar.HOUR_OF_DAY, mHourOfDay);
- c.set(Calendar.MINUTE, mMinute);
- String time = DateFormat.getTimeFormat(mContext).format(c.getTime());
- if (mSummaryFormat != 0) {
- time = mContext.getResources().getString(mSummaryFormat, time);
- }
- setSummary(time);
- }
-
- public static class TimePickerFragment extends DialogFragment implements
- TimePickerDialog.OnTimeSetListener {
- public TimePickerPreference pref;
-
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- final boolean usePref = pref != null && pref.mHourOfDay >= 0 && pref.mMinute >= 0;
- final Calendar c = Calendar.getInstance();
- final int hour = usePref ? pref.mHourOfDay : c.get(Calendar.HOUR_OF_DAY);
- final int minute = usePref ? pref.mMinute : c.get(Calendar.MINUTE);
- return new TimePickerDialog(getActivity(), this, hour, minute,
- DateFormat.is24HourFormat(getActivity()));
- }
-
- public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
- if (pref != null) {
- pref.setTime(hourOfDay, minute);
- }
- }
- }
-
- public interface Callback {
- boolean onSetTime(int hour, int minute);
- }
+ @Override
+ protected int getMetricsCategory() {
+ return MetricsLogger.NOTIFICATION_ZEN_MODE_AUTOMATION;
}
+
}
diff --git a/src/com/android/settings/notification/ZenModeConditionSelection.java b/src/com/android/settings/notification/ZenModeConditionSelection.java
index 9beea0a..481bd88 100644
--- a/src/com/android/settings/notification/ZenModeConditionSelection.java
+++ b/src/com/android/settings/notification/ZenModeConditionSelection.java
@@ -45,11 +45,14 @@ public class ZenModeConditionSelection extends RadioGroup {
private final H mHandler = new H();
private final Context mContext;
private final List<Condition> mConditions;
+ private final int mZenMode;
+
private Condition mCondition;
- public ZenModeConditionSelection(Context context) {
+ public ZenModeConditionSelection(Context context, int zenMode) {
super(context);
mContext = context;
+ mZenMode = zenMode;
mConditions = new ArrayList<Condition>();
setLayoutTransition(new LayoutTransition());
final int p = mContext.getResources().getDimensionPixelSize(R.dimen.content_margin_left);
@@ -130,7 +133,7 @@ public class ZenModeConditionSelection extends RadioGroup {
public void confirmCondition() {
if (DEBUG) Log.d(TAG, "confirmCondition " + mCondition);
try {
- mNoMan.setZenModeCondition(mCondition);
+ mNoMan.setZenMode(mZenMode, mCondition != null ? mCondition.id : null, TAG);
} catch (RemoteException e) {
// noop
}
diff --git a/src/com/android/settings/notification/ZenModeDowntimeDaysSelection.java b/src/com/android/settings/notification/ZenModeScheduleDaysSelection.java
index 3361ad0..6d11ffb 100644
--- a/src/com/android/settings/notification/ZenModeDowntimeDaysSelection.java
+++ b/src/com/android/settings/notification/ZenModeScheduleDaysSelection.java
@@ -17,37 +17,42 @@
package com.android.settings.notification;
import android.content.Context;
-import android.service.notification.ZenModeConfig;
import android.util.SparseBooleanArray;
import android.view.LayoutInflater;
import android.widget.CheckBox;
import android.widget.CompoundButton;
-import android.widget.ScrollView;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.LinearLayout;
+import android.widget.ScrollView;
import com.android.settings.R;
import java.text.SimpleDateFormat;
+import java.util.Arrays;
import java.util.Calendar;
-public class ZenModeDowntimeDaysSelection extends ScrollView {
+public class ZenModeScheduleDaysSelection extends ScrollView {
public static final int[] DAYS = {
- Calendar.MONDAY, Calendar.TUESDAY, Calendar.WEDNESDAY, Calendar.THURSDAY, Calendar.FRIDAY,
- Calendar.SATURDAY, Calendar.SUNDAY
+ Calendar.SUNDAY,
+ Calendar.MONDAY,
+ Calendar.TUESDAY,
+ Calendar.WEDNESDAY,
+ Calendar.THURSDAY,
+ Calendar.FRIDAY,
+ Calendar.SATURDAY,
};
private static final SimpleDateFormat DAY_FORMAT = new SimpleDateFormat("EEEE");
private final SparseBooleanArray mDays = new SparseBooleanArray();
private final LinearLayout mLayout;
- public ZenModeDowntimeDaysSelection(Context context, String mode) {
+ public ZenModeScheduleDaysSelection(Context context, int[] days) {
super(context);
mLayout = new LinearLayout(mContext);
- final int hPad = context.getResources().getDimensionPixelSize(R.dimen.zen_downtime_margin);
+ final int hPad = context.getResources()
+ .getDimensionPixelSize(R.dimen.zen_schedule_day_margin);
mLayout.setPadding(hPad, 0, hPad, 0);
addView(mLayout);
- final int[] days = ZenModeConfig.tryParseDays(mode);
if (days != null) {
for (int i = 0; i < days.length; i++) {
mDays.put(days[i], true);
@@ -58,7 +63,7 @@ public class ZenModeDowntimeDaysSelection extends ScrollView {
final LayoutInflater inflater = LayoutInflater.from(context);
for (int i = 0; i < DAYS.length; i++) {
final int day = DAYS[i];
- final CheckBox checkBox = (CheckBox) inflater.inflate(R.layout.zen_downtime_day,
+ final CheckBox checkBox = (CheckBox) inflater.inflate(R.layout.zen_schedule_rule_day,
this, false);
c.set(Calendar.DAY_OF_WEEK, day);
checkBox.setText(DAY_FORMAT.format(c.getTime()));
@@ -67,30 +72,29 @@ public class ZenModeDowntimeDaysSelection extends ScrollView {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mDays.put(day, isChecked);
- onChanged(getMode());
+ onChanged(getDays());
}
});
mLayout.addView(checkBox);
}
}
- private String getMode() {
- final StringBuilder sb = new StringBuilder(ZenModeConfig.SLEEP_MODE_DAYS_PREFIX);
- boolean empty = true;
+ private int[] getDays() {
+ final SparseBooleanArray rt = new SparseBooleanArray(mDays.size());
for (int i = 0; i < mDays.size(); i++) {
final int day = mDays.keyAt(i);
if (!mDays.valueAt(i)) continue;
- if (empty) {
- empty = false;
- } else {
- sb.append(',');
- }
- sb.append(day);
+ rt.put(day, true);
+ }
+ final int[] rta = new int[rt.size()];
+ for (int i = 0; i < rta.length; i++) {
+ rta[i] = rt.keyAt(i);
}
- return empty ? null : sb.toString();
+ Arrays.sort(rta);
+ return rta;
}
- protected void onChanged(String mode) {
+ protected void onChanged(int[] days) {
// event hook for subclasses
}
}
diff --git a/src/com/android/settings/notification/ZenModeScheduleRuleSettings.java b/src/com/android/settings/notification/ZenModeScheduleRuleSettings.java
new file mode 100644
index 0000000..7bec3c4
--- /dev/null
+++ b/src/com/android/settings/notification/ZenModeScheduleRuleSettings.java
@@ -0,0 +1,477 @@
+/*
+ * 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 static com.android.settings.notification.ZenModeScheduleDaysSelection.DAYS;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.FragmentManager;
+import android.app.TimePickerDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.content.DialogInterface.OnDismissListener;
+import android.content.Intent;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.Preference.OnPreferenceClickListener;
+import android.preference.PreferenceScreen;
+import android.provider.Settings;
+import android.provider.Settings.Global;
+import android.service.notification.ZenModeConfig;
+import android.service.notification.ZenModeConfig.ScheduleInfo;
+import android.service.notification.ZenModeConfig.ZenRule;
+import android.text.format.DateFormat;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.widget.Switch;
+import android.widget.TimePicker;
+import android.widget.Toast;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.settings.DropDownPreference;
+import com.android.settings.R;
+import com.android.settings.SettingsActivity;
+import com.android.settings.widget.SwitchBar;
+
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Calendar;
+
+public class ZenModeScheduleRuleSettings extends ZenModeSettingsBase
+ implements SwitchBar.OnSwitchChangeListener {
+ private static final String TAG = ZenModeSettingsBase.TAG;
+ private static final boolean DEBUG = ZenModeSettingsBase.DEBUG;
+
+ private static final String KEY_RULE_NAME = "rule_name";
+ private static final String KEY_DAYS = "days";
+ private static final String KEY_START_TIME = "start_time";
+ private static final String KEY_END_TIME = "end_time";
+ private static final String KEY_ZEN_MODE = "zen_mode";
+
+ private static final SimpleDateFormat DAY_FORMAT = new SimpleDateFormat("EEE");
+
+ public static final String ACTION = Settings.ACTION_ZEN_MODE_SCHEDULE_RULE_SETTINGS;
+ public static final String EXTRA_RULE_ID = "rule_id";
+
+ private Context mContext;
+ private boolean mDisableListeners;
+ private SwitchBar mSwitchBar;
+ private Preference mRuleName;
+ private Preference mDays;
+ private TimePickerPreference mStart;
+ private TimePickerPreference mEnd;
+ private DropDownPreference mZenMode;
+
+ private String mRuleId;
+ private ZenRule mRule;
+ private ScheduleInfo mSchedule;
+ private boolean mDeleting;
+
+ @Override
+ protected void onZenModeChanged() {
+ // noop
+ }
+
+ @Override
+ protected void onZenModeConfigChanged() {
+ if (!refreshRuleOrFinish()) {
+ updateControls();
+ }
+ }
+
+ private boolean refreshRuleOrFinish() {
+ mRule = mConfig.automaticRules.get(mRuleId);
+ if (DEBUG) Log.d(TAG, "mRule=" + mRule);
+ mSchedule = mRule != null ? ZenModeConfig.tryParseScheduleConditionId(mRule.conditionId)
+ : null;
+ if (mSchedule == null) {
+ toastAndFinish();
+ return true;
+ }
+ return false;
+ }
+
+ @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) {
+ showDeleteRuleDialog();
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ mContext = getActivity();
+
+ final Intent intent = getActivity().getIntent();
+ if (DEBUG) Log.d(TAG, "onCreate getIntent()=" + intent);
+ if (intent == null) {
+ Log.w(TAG, "No intent");
+ toastAndFinish();
+ return;
+ }
+
+ mRuleId = intent.getStringExtra(EXTRA_RULE_ID);
+ if (DEBUG) Log.d(TAG, "mRuleId=" + mRuleId);
+ if (refreshRuleOrFinish()) {
+ return;
+ }
+
+ addPreferencesFromResource(R.xml.zen_mode_schedule_rule_settings);
+ final PreferenceScreen root = getPreferenceScreen();
+
+ setHasOptionsMenu(true);
+
+ mRuleName = root.findPreference(KEY_RULE_NAME);
+ mRuleName.setOnPreferenceClickListener(new OnPreferenceClickListener() {
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ showRuleNameDialog();
+ return true;
+ }
+ });
+
+ mDays = root.findPreference(KEY_DAYS);
+ mDays.setOnPreferenceClickListener(new OnPreferenceClickListener() {
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ showDaysDialog();
+ return true;
+ }
+ });
+
+ final FragmentManager mgr = getFragmentManager();
+
+ mStart = new TimePickerPreference(mContext, mgr);
+ mStart.setKey(KEY_START_TIME);
+ mStart.setTitle(R.string.zen_mode_start_time);
+ mStart.setCallback(new TimePickerPreference.Callback() {
+ @Override
+ public boolean onSetTime(final int hour, final int minute) {
+ if (mDisableListeners) return true;
+ if (!ZenModeConfig.isValidHour(hour)) return false;
+ if (!ZenModeConfig.isValidMinute(minute)) return false;
+ if (hour == mSchedule.startHour && minute == mSchedule.startMinute) {
+ return true;
+ }
+ if (DEBUG) Log.d(TAG, "onPrefChange start h=" + hour + " m=" + minute);
+ mSchedule.startHour = hour;
+ mSchedule.startMinute = minute;
+ mRule.conditionId = ZenModeConfig.toScheduleConditionId(mSchedule);
+ mRule.condition = null;
+ mRule.snoozing = false;
+ setZenModeConfig(mConfig);
+ return true;
+ }
+ });
+ root.addPreference(mStart);
+ mStart.setDependency(mDays.getKey());
+
+ mEnd = new TimePickerPreference(mContext, mgr);
+ mEnd.setKey(KEY_END_TIME);
+ mEnd.setTitle(R.string.zen_mode_end_time);
+ mEnd.setCallback(new TimePickerPreference.Callback() {
+ @Override
+ public boolean onSetTime(final int hour, final int minute) {
+ if (mDisableListeners) return true;
+ if (!ZenModeConfig.isValidHour(hour)) return false;
+ if (!ZenModeConfig.isValidMinute(minute)) return false;
+ if (hour == mSchedule.endHour && minute == mSchedule.endMinute) {
+ return true;
+ }
+ if (DEBUG) Log.d(TAG, "onPrefChange end h=" + hour + " m=" + minute);
+ mSchedule.startHour = hour;
+ mSchedule.startMinute = minute;
+ mRule.conditionId = ZenModeConfig.toScheduleConditionId(mSchedule);
+ mRule.condition = null;
+ mRule.snoozing = false;
+ setZenModeConfig(mConfig);
+ return true;
+ }
+ });
+ root.addPreference(mEnd);
+ mEnd.setDependency(mDays.getKey());
+
+ mZenMode = (DropDownPreference) root.findPreference(KEY_ZEN_MODE);
+ mZenMode.addItem(R.string.zen_mode_option_important_interruptions, Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS);
+ mZenMode.addItem(R.string.zen_mode_option_alarms, Global.ZEN_MODE_ALARMS);
+ mZenMode.addItem(R.string.zen_mode_option_no_interruptions, Global.ZEN_MODE_NO_INTERRUPTIONS);
+ mZenMode.setCallback(new DropDownPreference.Callback() {
+ @Override
+ public boolean onItemSelected(int pos, Object value) {
+ if (mDisableListeners) return true;
+ final int zenMode = (Integer) value;
+ if (zenMode == mRule.zenMode) return true;
+ if (DEBUG) Log.d(TAG, "onPrefChange zenMode=" + zenMode);
+ mRule.zenMode = zenMode;
+ setZenModeConfig(mConfig);
+ return true;
+ }
+ });
+ mZenMode.setOrder(10); // sort at the bottom of the category
+ mZenMode.setDependency(mDays.getKey());
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ final SettingsActivity activity = (SettingsActivity) getActivity();
+ mSwitchBar = activity.getSwitchBar();
+ mSwitchBar.addOnSwitchChangeListener(this);
+ mSwitchBar.show();
+ }
+
+ @Override
+ public void onDestroyView() {
+ super.onDestroyView();
+ mSwitchBar.removeOnSwitchChangeListener(this);
+ mSwitchBar.hide();
+ }
+
+ @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.enabled) return;
+ if (DEBUG) Log.d(TAG, "onSwitchChanged enabled=" + enabled);
+ mRule.enabled = enabled;
+ mRule.snoozing = false;
+ setZenModeConfig(mConfig);
+ }
+
+ private void updateDays() {
+ // Compute an ordered, delimited list of day names based on the persisted user config.
+ final int[] days = mSchedule.days;
+ if (days != null && days.length > 0) {
+ final StringBuilder sb = new StringBuilder();
+ final Calendar c = Calendar.getInstance();
+ for (int i = 0; i < DAYS.length; i++) {
+ final int day = DAYS[i];
+ for (int j = 0; j < days.length; j++) {
+ if (day == days[j]) {
+ c.set(Calendar.DAY_OF_WEEK, day);
+ if (sb.length() > 0) {
+ sb.append(mContext.getString(R.string.summary_divider_text));
+ }
+ sb.append(DAY_FORMAT.format(c.getTime()));
+ break;
+ }
+ }
+ }
+ if (sb.length() > 0) {
+ mDays.setSummary(sb);
+ mDays.notifyDependencyChange(false);
+ return;
+ }
+ }
+ mDays.setSummary(R.string.zen_mode_schedule_rule_days_none);
+ mDays.notifyDependencyChange(true);
+ }
+
+ private void updateEndSummary() {
+ final int startMin = 60 * mSchedule.startHour + mSchedule.startMinute;
+ final int endMin = 60 * mSchedule.endHour + mSchedule.endMinute;
+ final boolean nextDay = startMin >= endMin;
+ final int summaryFormat = nextDay ? R.string.zen_mode_end_time_next_day_summary_format : 0;
+ mEnd.setSummaryFormat(summaryFormat);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ updateControls();
+ }
+
+ private void updateRuleName() {
+ getActivity().setTitle(mRule.name);
+ mRuleName.setSummary(mRule.name);
+ }
+
+ private void updateControls() {
+ mDisableListeners = true;
+ updateRuleName();
+ updateDays();
+ mStart.setTime(mSchedule.startHour, mSchedule.startMinute);
+ mEnd.setTime(mSchedule.endHour, mSchedule.endMinute);
+ mZenMode.setSelectedValue(mRule.zenMode);
+ mDisableListeners = false;
+ updateEndSummary();
+ if (mSwitchBar != null) {
+ mSwitchBar.setChecked(mRule.enabled);
+ }
+ }
+
+ @Override
+ protected int getMetricsCategory() {
+ return MetricsLogger.NOTIFICATION_ZEN_MODE_SCHEDULE_RULE;
+ }
+
+ private void showDeleteRuleDialog() {
+ new AlertDialog.Builder(mContext)
+ .setMessage(getString(R.string.zen_mode_delete_rule_confirmation, mRule.name))
+ .setNegativeButton(R.string.cancel, null)
+ .setPositiveButton(R.string.zen_mode_delete_rule_button, new OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ mDeleting = true;
+ mConfig.automaticRules.remove(mRuleId);
+ setZenModeConfig(mConfig);
+ }
+ })
+ .show();
+ }
+
+ private void showRuleNameDialog() {
+ new ZenRuleNameDialog(mContext, mRule.name, mConfig.getAutomaticRuleNames()) {
+ @Override
+ public void onOk(String ruleName) {
+ final ZenModeConfig newConfig = mConfig.copy();
+ final ZenRule rule = newConfig.automaticRules.get(mRuleId);
+ if (rule == null) return;
+ rule.name = ruleName;
+ setZenModeConfig(newConfig);
+ }
+ }.show();
+ }
+
+ private void showDaysDialog() {
+ new AlertDialog.Builder(mContext)
+ .setTitle(R.string.zen_mode_schedule_rule_days)
+ .setView(new ZenModeScheduleDaysSelection(mContext, mSchedule.days) {
+ @Override
+ protected void onChanged(final int[] days) {
+ if (mDisableListeners) return;
+ if (Arrays.equals(days, mSchedule.days)) return;
+ if (DEBUG) Log.d(TAG, "days.onChanged days=" + Arrays.asList(days));
+ mSchedule.days = days;
+ mRule.conditionId = ZenModeConfig.toScheduleConditionId(mSchedule);
+ mRule.condition = null;
+ mRule.snoozing = false;
+ setZenModeConfig(mConfig);
+ }
+ })
+ .setOnDismissListener(new OnDismissListener() {
+ @Override
+ public void onDismiss(DialogInterface dialog) {
+ updateDays();
+ }
+ })
+ .setPositiveButton(R.string.done_button, null)
+ .show();
+ }
+
+ private void toastAndFinish() {
+ if (!mDeleting) {
+ Toast.makeText(mContext, R.string.zen_mode_rule_not_found_text, Toast.LENGTH_SHORT)
+ .show();
+ }
+ getActivity().finish();
+ }
+
+ private static class TimePickerPreference extends Preference {
+ private final Context mContext;
+
+ private int mSummaryFormat;
+ private int mHourOfDay;
+ private int mMinute;
+ private Callback mCallback;
+
+ public TimePickerPreference(Context context, final FragmentManager mgr) {
+ super(context);
+ mContext = context;
+ setPersistent(false);
+ setOnPreferenceClickListener(new OnPreferenceClickListener(){
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ final TimePickerFragment frag = new TimePickerFragment();
+ frag.pref = TimePickerPreference.this;
+ frag.show(mgr, TimePickerPreference.class.getName());
+ return true;
+ }
+ });
+ }
+
+ public void setCallback(Callback callback) {
+ mCallback = callback;
+ }
+
+ public void setSummaryFormat(int resId) {
+ mSummaryFormat = resId;
+ updateSummary();
+ }
+
+ public void setTime(int hourOfDay, int minute) {
+ if (mCallback != null && !mCallback.onSetTime(hourOfDay, minute)) return;
+ mHourOfDay = hourOfDay;
+ mMinute = minute;
+ updateSummary();
+ }
+
+ private void updateSummary() {
+ final Calendar c = Calendar.getInstance();
+ c.set(Calendar.HOUR_OF_DAY, mHourOfDay);
+ c.set(Calendar.MINUTE, mMinute);
+ String time = DateFormat.getTimeFormat(mContext).format(c.getTime());
+ if (mSummaryFormat != 0) {
+ time = mContext.getResources().getString(mSummaryFormat, time);
+ }
+ setSummary(time);
+ }
+
+ public static class TimePickerFragment extends DialogFragment implements
+ TimePickerDialog.OnTimeSetListener {
+ public TimePickerPreference pref;
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ final boolean usePref = pref != null && pref.mHourOfDay >= 0 && pref.mMinute >= 0;
+ final Calendar c = Calendar.getInstance();
+ final int hour = usePref ? pref.mHourOfDay : c.get(Calendar.HOUR_OF_DAY);
+ final int minute = usePref ? pref.mMinute : c.get(Calendar.MINUTE);
+ return new TimePickerDialog(getActivity(), this, hour, minute,
+ DateFormat.is24HourFormat(getActivity()));
+ }
+
+ public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
+ if (pref != null) {
+ pref.setTime(hourOfDay, minute);
+ }
+ }
+ }
+
+ public interface Callback {
+ boolean onSetTime(int hour, int minute);
+ }
+ }
+}
diff --git a/src/com/android/settings/notification/ZenModeSettings.java b/src/com/android/settings/notification/ZenModeSettings.java
index f519796..4ff5e0f 100644
--- a/src/com/android/settings/notification/ZenModeSettings.java
+++ b/src/com/android/settings/notification/ZenModeSettings.java
@@ -21,10 +21,12 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.os.Bundle;
+import android.os.UserHandle;
import android.preference.Preference;
import android.preference.PreferenceScreen;
import android.provider.Settings.Global;
import android.service.notification.Condition;
+import android.service.notification.ZenModeConfig;
import android.text.TextUtils;
import android.util.Log;
import android.util.SparseArray;
@@ -51,6 +53,7 @@ public class ZenModeSettings extends ZenModeSettingsBase
private AlertDialog mDialog;
private SwitchBar mSwitchBar;
private boolean mShowing;
+ private boolean mUpdatingControls;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -60,7 +63,7 @@ public class ZenModeSettings extends ZenModeSettingsBase
final PreferenceScreen root = getPreferenceScreen();
mPrioritySettings = root.findPreference(KEY_PRIORITY_SETTINGS);
- if (!isDowntimeSupported(mContext)) {
+ if (!isScheduleSupported(mContext)) {
removePreference(KEY_AUTOMATION_SETTINGS);
}
}
@@ -97,13 +100,14 @@ public class ZenModeSettings extends ZenModeSettingsBase
@Override
public void onSwitchChanged(Switch switchView, boolean isChecked) {
- if (DEBUG) Log.d(TAG, "onSwitchChanged " + isChecked + " mShowing=" + mShowing);
- if (!mShowing) return; // not from the user
+ if (DEBUG) Log.d(TAG, "onSwitchChanged " + isChecked + " mShowing=" + mShowing
+ + " mUpdatingControls=" + mUpdatingControls);
+ if (!mShowing || mUpdatingControls) return; // not from the user
if (isChecked) {
- setZenMode(Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS);
+ setZenMode(Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, null);
showConditionSelection(Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS);
} else {
- setZenMode(Global.ZEN_MODE_OFF);
+ setZenMode(Global.ZEN_MODE_OFF, null);
}
}
@@ -135,29 +139,20 @@ public class ZenModeSettings extends ZenModeSettingsBase
}
}
- private String computeExitConditionText() {
- return mConfig == null || mConfig.exitCondition == null
- ? getString(com.android.internal.R.string.zen_mode_forever)
- : computeConditionText(mConfig.exitCondition);
- }
-
- public static String computeConditionText(Condition c) {
- return !TextUtils.isEmpty(c.line1) ? c.line1
- : !TextUtils.isEmpty(c.summary) ? c.summary
- : "";
- }
-
private String computeZenModeSummaryLine() {
final String caption = computeZenModeCaption(mZenMode);
- if (caption == null) return null;
- final String conditionText = computeExitConditionText().toLowerCase();
+ if (caption == null) return null; // zen mode off
+ final String conditionText = ZenModeConfig.getConditionLine1(mContext, mConfig,
+ UserHandle.myUserId());
return getString(R.string.zen_mode_summary_combination, caption, conditionText);
}
private void updateControls() {
if (mSwitchBar != null) {
final String summaryLine = computeZenModeSummaryLine();
+ mUpdatingControls = true;
mSwitchBar.setChecked(summaryLine != null);
+ mUpdatingControls = false;
mSwitchBar.setSummary(summaryLine);
}
updatePrioritySettingsSummary();
@@ -184,7 +179,7 @@ public class ZenModeSettings extends ZenModeSettingsBase
if (mDialog != null) return;
final ZenModeConditionSelection zenModeConditionSelection =
- new ZenModeConditionSelection(mContext);
+ new ZenModeConditionSelection(mContext, zenMode);
DialogInterface.OnClickListener positiveListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
@@ -198,7 +193,7 @@ public class ZenModeSettings extends ZenModeSettingsBase
.setTitle(computeZenModeCaption(zenMode))
.setView(scrollView)
.setPositiveButton(R.string.okay, positiveListener)
- .setNegativeButton(R.string.cancel_all_caps, new DialogInterface.OnClickListener() {
+ .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
cancelDialog();
@@ -216,10 +211,16 @@ public class ZenModeSettings extends ZenModeSettingsBase
private void cancelDialog() {
if (DEBUG) Log.d(TAG, "cancelDialog");
// If not making a decision, reset zen to off.
- setZenMode(Global.ZEN_MODE_OFF);
+ setZenMode(Global.ZEN_MODE_OFF, null);
mDialog = null;
}
+ public static String computeConditionText(Condition c) {
+ return !TextUtils.isEmpty(c.line1) ? c.line1
+ : !TextUtils.isEmpty(c.summary) ? c.summary
+ : "";
+ }
+
private static SparseArray<String> allKeyTitles(Context context) {
final SparseArray<String> rt = new SparseArray<String>();
rt.put(R.string.zen_mode_priority_settings_title, KEY_PRIORITY_SETTINGS);
@@ -250,7 +251,7 @@ public class ZenModeSettings extends ZenModeSettingsBase
@Override
public List<String> getNonIndexableKeys(Context context) {
final ArrayList<String> rt = new ArrayList<String>();
- if (!isDowntimeSupported(context)) {
+ if (!isScheduleSupported(context)) {
rt.add(KEY_AUTOMATION_SETTINGS);
}
return rt;
diff --git a/src/com/android/settings/notification/ZenModeSettingsBase.java b/src/com/android/settings/notification/ZenModeSettingsBase.java
index 5ef0da4..9824dc7 100644
--- a/src/com/android/settings/notification/ZenModeSettingsBase.java
+++ b/src/com/android/settings/notification/ZenModeSettingsBase.java
@@ -16,14 +16,12 @@
package com.android.settings.notification;
-import android.app.INotificationManager;
import android.app.NotificationManager;
import android.content.Context;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
-import android.os.ServiceManager;
import android.provider.Settings;
import android.provider.Settings.Global;
import android.service.notification.ZenModeConfig;
@@ -91,40 +89,27 @@ abstract public class ZenModeSettingsBase extends SettingsPreferenceFragment {
}
protected boolean setZenModeConfig(ZenModeConfig config) {
- final INotificationManager nm = INotificationManager.Stub.asInterface(
- ServiceManager.getService(Context.NOTIFICATION_SERVICE));
- try {
- final boolean success = nm.setZenModeConfig(config);
- if (success) {
- mConfig = config;
- if (DEBUG) Log.d(TAG, "Saved mConfig=" + mConfig);
- onZenModeConfigChanged();
- }
- return success;
- } catch (Exception e) {
- Log.w(TAG, "Error calling NoMan", e);
- return false;
+ final String reason = getClass().getSimpleName();
+ final boolean success = NotificationManager.from(mContext).setZenModeConfig(config, reason);
+ if (success) {
+ mConfig = config;
+ if (DEBUG) Log.d(TAG, "Saved mConfig=" + mConfig);
+ onZenModeConfigChanged();
}
+ return success;
}
- protected void setZenMode(int zenMode) {
- Global.putInt(getContentResolver(), Global.ZEN_MODE, zenMode);
+ protected void setZenMode(int zenMode, Uri conditionId) {
+ NotificationManager.from(mContext).setZenMode(zenMode, conditionId, TAG);
}
- protected static boolean isDowntimeSupported(Context context) {
+ protected static boolean isScheduleSupported(Context context) {
return NotificationManager.from(context)
- .isSystemConditionProviderEnabled(ZenModeConfig.DOWNTIME_PATH);
+ .isSystemConditionProviderEnabled(ZenModeConfig.SCHEDULE_PATH);
}
private ZenModeConfig getZenModeConfig() {
- final INotificationManager nm = INotificationManager.Stub.asInterface(
- ServiceManager.getService(Context.NOTIFICATION_SERVICE));
- try {
- return nm.getZenModeConfig();
- } catch (Exception e) {
- Log.w(TAG, "Error calling NoMan", e);
- return new ZenModeConfig();
- }
+ return NotificationManager.from(mContext).getZenModeConfig();
}
private final class SettingsObserver extends ContentObserver {
diff --git a/src/com/android/settings/notification/ZenRuleNameDialog.java b/src/com/android/settings/notification/ZenRuleNameDialog.java
new file mode 100644
index 0000000..b0eaaec
--- /dev/null
+++ b/src/com/android/settings/notification/ZenRuleNameDialog.java
@@ -0,0 +1,93 @@
+/*
+ * 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.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.text.Editable;
+import android.text.TextUtils;
+import android.text.TextWatcher;
+import android.util.ArraySet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.EditText;
+
+import com.android.settings.R;
+
+public abstract class ZenRuleNameDialog {
+ private final AlertDialog mDialog;
+ private final EditText mEditText;
+ private final ArraySet<String> mExistingNames;
+
+ public ZenRuleNameDialog(Context context, String ruleName, ArraySet<String> existingNames) {
+ final View v = LayoutInflater.from(context).inflate(R.layout.zen_rule_name, null, false);
+ mEditText = (EditText) v.findViewById(R.id.rule_name);
+ mEditText.setText(ruleName);
+ mEditText.setSelectAllOnFocus(true);
+ mDialog = new AlertDialog.Builder(context)
+ .setTitle(R.string.zen_mode_rule_name)
+ .setView(v)
+ .setPositiveButton(R.string.okay, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ onOk(trimmedText());
+ }
+ })
+ .setNegativeButton(R.string.cancel, null)
+ .create();
+ mEditText.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ // noop
+ }
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ // noop
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ updatePositiveButton();
+ }
+ });
+ mExistingNames = new ArraySet<String>(existingNames.size());
+ for (String existingName : existingNames) {
+ mExistingNames.add(existingName.toLowerCase());
+ }
+ }
+
+ abstract public void onOk(String ruleName);
+
+ private String trimmedText() {
+ return mEditText.getText() == null ? null : mEditText.getText().toString().trim();
+ }
+
+ public void show() {
+ mDialog.show();
+ updatePositiveButton();
+ }
+
+ private void updatePositiveButton() {
+ final String name = trimmedText();
+ final boolean validName = !TextUtils.isEmpty(name)
+ && !mExistingNames.contains(name.toLowerCase());
+ mDialog.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(validName);
+ }
+
+} \ No newline at end of file
diff --git a/src/com/android/settings/search/SearchIndexableResources.java b/src/com/android/settings/search/SearchIndexableResources.java
index 0ad9503..dae8860 100644
--- a/src/com/android/settings/search/SearchIndexableResources.java
+++ b/src/com/android/settings/search/SearchIndexableResources.java
@@ -24,11 +24,12 @@ import com.android.settings.DevelopmentSettings;
import com.android.settings.DeviceInfoSettings;
import com.android.settings.DisplaySettings;
import com.android.settings.HomeSettings;
-import com.android.settings.ScreenPinningSettings;
import com.android.settings.PrivacySettings;
import com.android.settings.R;
+import com.android.settings.ScreenPinningSettings;
import com.android.settings.SecuritySettings;
import com.android.settings.WallpaperTypeSettings;
+import com.android.settings.WifiCallingSettings;
import com.android.settings.WirelessSettings;
import com.android.settings.accessibility.AccessibilitySettings;
import com.android.settings.applications.AdvancedAppSettings;
@@ -43,7 +44,6 @@ import com.android.settings.location.ScanningSettings;
import com.android.settings.net.DataUsageMeteredSettings;
import com.android.settings.notification.NotificationSettings;
import com.android.settings.notification.OtherSoundSettings;
-import com.android.settings.notification.ZenModeAutomationSettings;
import com.android.settings.notification.ZenModePrioritySettings;
import com.android.settings.notification.ZenModeSettings;
import com.android.settings.print.PrintSettingsFragment;
@@ -53,7 +53,6 @@ import com.android.settings.voice.VoiceInputSettings;
import com.android.settings.wifi.AdvancedWifiSettings;
import com.android.settings.wifi.SavedAccessPointsWifiSettings;
import com.android.settings.wifi.WifiSettings;
-import com.android.settings.WifiCallingSettings;
import java.util.Collection;
import java.util.HashMap;
@@ -171,13 +170,6 @@ public final class SearchIndexableResources {
ZenModePrioritySettings.class.getName(),
R.drawable.ic_settings_notifications));
- sResMap.put(ZenModeAutomationSettings.class.getName(),
- new SearchIndexableResource(
- Ranking.getRankForClassName(ZenModeAutomationSettings.class.getName()),
- NO_DATA_RES_ID,
- ZenModeAutomationSettings.class.getName(),
- R.drawable.ic_settings_notifications));
-
sResMap.put(Memory.class.getName(),
new SearchIndexableResource(
Ranking.getRankForClassName(Memory.class.getName()),