summaryrefslogtreecommitdiffstats
path: root/src/com/android/settings/notification/ZenModeScheduleRuleSettings.java
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/settings/notification/ZenModeScheduleRuleSettings.java
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/settings/notification/ZenModeScheduleRuleSettings.java')
-rw-r--r--src/com/android/settings/notification/ZenModeScheduleRuleSettings.java477
1 files changed, 477 insertions, 0 deletions
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);
+ }
+ }
+}