/* * 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.AutomaticZenRule; import android.content.Context; import android.content.pm.PackageManager.NameNotFoundException; import android.database.Cursor; import android.os.UserHandle; import android.os.UserManager; import android.provider.CalendarContract.Calendars; import android.provider.Settings; import android.service.notification.ZenModeConfig; import android.service.notification.ZenModeConfig.EventInfo; import android.support.v7.preference.DropDownPreference; import android.support.v7.preference.Preference; import android.support.v7.preference.Preference.OnPreferenceChangeListener; import android.support.v7.preference.PreferenceScreen; import com.android.internal.logging.MetricsProto.MetricsEvent; import com.android.settings.R; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; public class ZenModeEventRuleSettings extends ZenModeRuleSettingsBase { private static final String KEY_CALENDAR = "calendar"; private static final String KEY_REPLY = "reply"; public static final String ACTION = Settings.ACTION_ZEN_MODE_EVENT_RULE_SETTINGS; private DropDownPreference mCalendar; private DropDownPreference mReply; private EventInfo mEvent; private List<CalendarInfo> mCalendars; private boolean mCreate; @Override protected boolean setRule(AutomaticZenRule rule) { mEvent = rule != null ? ZenModeConfig.tryParseEventConditionId(rule.getConditionId()) : null; return mEvent != null; } @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()) { return; } if (!mCreate) { reloadCalendar(); } mCreate = false; } private void reloadCalendar() { mCalendars = getCalendars(mContext); ArrayList<CharSequence> entries = new ArrayList<>(); ArrayList<CharSequence> values = new ArrayList<>(); entries.add(getString(R.string.zen_mode_event_rule_calendar_any)); values.add(key(0, null)); final String eventCalendar = mEvent != null ? mEvent.calendar : null; boolean found = false; for (CalendarInfo calendar : mCalendars) { entries.add(calendar.name); values.add(key(calendar)); if (eventCalendar != null && eventCalendar.equals(calendar.name)) { found = true; } } if (eventCalendar != null && !found) { entries.add(eventCalendar); values.add(key(mEvent.userId, eventCalendar)); } mCalendar.setEntries(entries.toArray(new CharSequence[entries.size()])); mCalendar.setEntryValues(values.toArray(new CharSequence[values.size()])); } @Override protected void onCreateInternal() { mCreate = true; addPreferencesFromResource(R.xml.zen_mode_event_rule_settings); final PreferenceScreen root = getPreferenceScreen(); mCalendar = (DropDownPreference) root.findPreference(KEY_CALENDAR); mCalendar.setOnPreferenceChangeListener(new OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { final String calendarKey = (String) newValue; if (calendarKey.equals(key(mEvent))) return false; final int i = calendarKey.indexOf(':'); mEvent.userId = Integer.parseInt(calendarKey.substring(0, i)); mEvent.calendar = calendarKey.substring(i + 1); if (mEvent.calendar.isEmpty()) { mEvent.calendar = null; } updateRule(ZenModeConfig.toEventConditionId(mEvent)); return true; } }); mReply = (DropDownPreference) root.findPreference(KEY_REPLY); mReply.setEntries(new CharSequence[] { getString(R.string.zen_mode_event_rule_reply_any_except_no), getString(R.string.zen_mode_event_rule_reply_yes_or_maybe), getString(R.string.zen_mode_event_rule_reply_yes), }); mReply.setEntryValues(new CharSequence[] { Integer.toString(EventInfo.REPLY_ANY_EXCEPT_NO), Integer.toString(EventInfo.REPLY_YES_OR_MAYBE), Integer.toString(EventInfo.REPLY_YES), }); mReply.setOnPreferenceChangeListener(new OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { final int reply = Integer.parseInt((String) newValue); if (reply == mEvent.reply) return false; mEvent.reply = reply; updateRule(ZenModeConfig.toEventConditionId(mEvent)); return true; } }); reloadCalendar(); updateControlsInternal(); } @Override protected void updateControlsInternal() { mCalendar.setValue(key(mEvent)); mReply.setValue(Integer.toString(mEvent.reply)); } @Override protected int getMetricsCategory() { return MetricsEvent.NOTIFICATION_ZEN_MODE_EVENT_RULE; } public static CalendarInfo findCalendar(Context context, EventInfo event) { if (context == null || event == null) return null; final String eventKey = key(event); for (CalendarInfo calendar : getCalendars(context)) { if (eventKey.equals(key(calendar))) { return calendar; } } return null; } private static List<CalendarInfo> getCalendars(Context context) { final List<CalendarInfo> calendars = new ArrayList<>(); for (UserHandle user : UserManager.get(context).getUserProfiles()) { final Context userContext = getContextForUser(context, user); if (userContext != null) { addCalendars(userContext, calendars); } } Collections.sort(calendars, CALENDAR_NAME); return calendars; } private static Context getContextForUser(Context context, UserHandle user) { try { return context.createPackageContextAsUser(context.getPackageName(), 0, user); } catch (NameNotFoundException e) { return null; } } public static void addCalendars(Context context, List<CalendarInfo> outCalendars) { final String primary = "\"primary\""; final String[] projection = { Calendars._ID, Calendars.CALENDAR_DISPLAY_NAME, "(" + Calendars.ACCOUNT_NAME + "=" + Calendars.OWNER_ACCOUNT + ") AS " + primary }; final String selection = primary + " = 1"; Cursor cursor = null; try { cursor = context.getContentResolver().query(Calendars.CONTENT_URI, projection, selection, null, null); if (cursor == null) { return; } while (cursor.moveToNext()) { final CalendarInfo ci = new CalendarInfo(); ci.name = cursor.getString(1); ci.userId = context.getUserId(); outCalendars.add(ci); } } finally { if (cursor != null) { cursor.close(); } } } private static String key(CalendarInfo calendar) { return key(calendar.userId, calendar.name); } private static String key(EventInfo event) { return key(event.userId, event.calendar); } private static String key(int userId, String calendar) { return EventInfo.resolveUserId(userId) + ":" + (calendar == null ? "" : calendar); } private static final Comparator<CalendarInfo> CALENDAR_NAME = new Comparator<CalendarInfo>() { @Override public int compare(CalendarInfo lhs, CalendarInfo rhs) { return lhs.name.compareTo(rhs.name); } }; public static class CalendarInfo { public String name; public int userId; } }