• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.settings.notification;
18 
19 import android.app.AutomaticZenRule;
20 import android.content.Context;
21 import android.content.pm.PackageManager.NameNotFoundException;
22 import android.database.Cursor;
23 import android.os.UserHandle;
24 import android.os.UserManager;
25 import android.provider.CalendarContract.Calendars;
26 import android.provider.Settings;
27 import android.service.notification.ZenModeConfig;
28 import android.service.notification.ZenModeConfig.EventInfo;
29 import android.support.v7.preference.DropDownPreference;
30 import android.support.v7.preference.Preference;
31 import android.support.v7.preference.Preference.OnPreferenceChangeListener;
32 import android.support.v7.preference.PreferenceScreen;
33 
34 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
35 import com.android.settings.R;
36 import com.android.settingslib.core.AbstractPreferenceController;
37 
38 import java.util.ArrayList;
39 import java.util.Collections;
40 import java.util.Comparator;
41 import java.util.List;
42 
43 public class ZenModeEventRuleSettings extends ZenModeRuleSettingsBase {
44     private static final String KEY_CALENDAR = "calendar";
45     private static final String KEY_REPLY = "reply";
46 
47     public static final String ACTION = Settings.ACTION_ZEN_MODE_EVENT_RULE_SETTINGS;
48 
49     private DropDownPreference mCalendar;
50     private DropDownPreference mReply;
51 
52     private EventInfo mEvent;
53     private List<CalendarInfo> mCalendars;
54     private boolean mCreate;
55 
56     @Override
setRule(AutomaticZenRule rule)57     protected boolean setRule(AutomaticZenRule rule) {
58         mEvent = rule != null ? ZenModeConfig.tryParseEventConditionId(rule.getConditionId())
59                 : null;
60         return mEvent != null;
61     }
62 
63     @Override
onResume()64     public void onResume() {
65         super.onResume();
66         if (isUiRestricted()) {
67             return;
68         }
69         if (!mCreate) {
70             reloadCalendar();
71         }
72         mCreate = false;
73     }
74 
75     @Override
getPreferenceScreenResId()76     protected int getPreferenceScreenResId() {
77         return R.xml.zen_mode_event_rule_settings;
78     }
79 
80     @Override
createPreferenceControllers(Context context)81     protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
82         List<AbstractPreferenceController> controllers = new ArrayList<>();
83         mHeader = new ZenAutomaticRuleHeaderPreferenceController(context, this,
84                 getLifecycle());
85         mSwitch = new ZenAutomaticRuleSwitchPreferenceController(context, this, getLifecycle());
86         controllers.add(mHeader);
87         controllers.add(mSwitch);
88         return controllers;
89     }
90 
reloadCalendar()91     private void reloadCalendar() {
92         mCalendars = getCalendars(mContext);
93         ArrayList<CharSequence> entries = new ArrayList<>();
94         ArrayList<CharSequence> values = new ArrayList<>();
95         entries.add(getString(R.string.zen_mode_event_rule_calendar_any));
96         values.add(key(0, null));
97         final String eventCalendar = mEvent != null ? mEvent.calendar : null;
98         boolean found = false;
99         for (CalendarInfo calendar : mCalendars) {
100             entries.add(calendar.name);
101             values.add(key(calendar));
102             if (eventCalendar != null && eventCalendar.equals(calendar.name)) {
103                 found = true;
104             }
105         }
106         if (eventCalendar != null && !found) {
107             entries.add(eventCalendar);
108             values.add(key(mEvent.userId, eventCalendar));
109         }
110         mCalendar.setEntries(entries.toArray(new CharSequence[entries.size()]));
111         mCalendar.setEntryValues(values.toArray(new CharSequence[values.size()]));
112     }
113 
114     @Override
onCreateInternal()115     protected void onCreateInternal() {
116         mCreate = true;
117         final PreferenceScreen root = getPreferenceScreen();
118 
119         mCalendar = (DropDownPreference) root.findPreference(KEY_CALENDAR);
120         mCalendar.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
121             @Override
122             public boolean onPreferenceChange(Preference preference, Object newValue) {
123                 final String calendarKey = (String) newValue;
124                 if (calendarKey.equals(key(mEvent))) return false;
125                 final int i = calendarKey.indexOf(':');
126                 mEvent.userId = Integer.parseInt(calendarKey.substring(0, i));
127                 mEvent.calendar = calendarKey.substring(i + 1);
128                 if (mEvent.calendar.isEmpty()) {
129                     mEvent.calendar = null;
130                 }
131                 updateRule(ZenModeConfig.toEventConditionId(mEvent));
132                 return true;
133             }
134         });
135 
136         mReply = (DropDownPreference) root.findPreference(KEY_REPLY);
137         mReply.setEntries(new CharSequence[] {
138                 getString(R.string.zen_mode_event_rule_reply_any_except_no),
139                 getString(R.string.zen_mode_event_rule_reply_yes_or_maybe),
140                 getString(R.string.zen_mode_event_rule_reply_yes),
141         });
142         mReply.setEntryValues(new CharSequence[] {
143                 Integer.toString(EventInfo.REPLY_ANY_EXCEPT_NO),
144                 Integer.toString(EventInfo.REPLY_YES_OR_MAYBE),
145                 Integer.toString(EventInfo.REPLY_YES),
146         });
147         mReply.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
148             @Override
149             public boolean onPreferenceChange(Preference preference, Object newValue) {
150                 final int reply = Integer.parseInt((String) newValue);
151                 if (reply == mEvent.reply) return false;
152                 mEvent.reply = reply;
153                 updateRule(ZenModeConfig.toEventConditionId(mEvent));
154                 return true;
155             }
156         });
157 
158         reloadCalendar();
159         updateControlsInternal();
160     }
161 
162     @Override
updateControlsInternal()163     protected void updateControlsInternal() {
164         mCalendar.setValue(key(mEvent));
165         mReply.setValue(Integer.toString(mEvent.reply));
166     }
167 
168     @Override
getMetricsCategory()169     public int getMetricsCategory() {
170         return MetricsEvent.NOTIFICATION_ZEN_MODE_EVENT_RULE;
171     }
172 
findCalendar(Context context, EventInfo event)173     public static CalendarInfo findCalendar(Context context, EventInfo event) {
174         if (context == null || event == null) return null;
175         final String eventKey = key(event);
176         for (CalendarInfo calendar : getCalendars(context)) {
177             if (eventKey.equals(key(calendar))) {
178                 return calendar;
179             }
180         }
181         return null;
182     }
183 
getCalendars(Context context)184     private static List<CalendarInfo> getCalendars(Context context) {
185         final List<CalendarInfo> calendars = new ArrayList<>();
186         for (UserHandle user : UserManager.get(context).getUserProfiles()) {
187             final Context userContext = getContextForUser(context, user);
188             if (userContext != null) {
189                 addCalendars(userContext, calendars);
190             }
191         }
192         Collections.sort(calendars, CALENDAR_NAME);
193         return calendars;
194     }
195 
getContextForUser(Context context, UserHandle user)196     private static Context getContextForUser(Context context, UserHandle user) {
197         try {
198             return context.createPackageContextAsUser(context.getPackageName(), 0, user);
199         } catch (NameNotFoundException e) {
200             return null;
201         }
202     }
203 
addCalendars(Context context, List<CalendarInfo> outCalendars)204     public static void addCalendars(Context context, List<CalendarInfo> outCalendars) {
205         final String primary = "\"primary\"";
206         final String[] projection = { Calendars._ID, Calendars.CALENDAR_DISPLAY_NAME,
207                 "(" + Calendars.ACCOUNT_NAME + "=" + Calendars.OWNER_ACCOUNT + ") AS " + primary };
208         final String selection = primary + " = 1";
209         Cursor cursor = null;
210         try {
211             cursor = context.getContentResolver().query(Calendars.CONTENT_URI, projection,
212                     selection, null, null);
213             if (cursor == null) {
214                 return;
215             }
216             while (cursor.moveToNext()) {
217                 final CalendarInfo ci = new CalendarInfo();
218                 ci.name = cursor.getString(1);
219                 ci.userId = context.getUserId();
220                 outCalendars.add(ci);
221             }
222         } finally {
223             if (cursor != null) {
224                 cursor.close();
225             }
226         }
227     }
228 
key(CalendarInfo calendar)229     private static String key(CalendarInfo calendar) {
230         return key(calendar.userId, calendar.name);
231     }
232 
key(EventInfo event)233     private static String key(EventInfo event) {
234         return key(event.userId, event.calendar);
235     }
236 
key(int userId, String calendar)237     private static String key(int userId, String calendar) {
238         return EventInfo.resolveUserId(userId) + ":" + (calendar == null ? "" : calendar);
239     }
240 
241     private static final Comparator<CalendarInfo> CALENDAR_NAME = new Comparator<CalendarInfo>() {
242         @Override
243         public int compare(CalendarInfo lhs, CalendarInfo rhs) {
244             return lhs.name.compareTo(rhs.name);
245         }
246     };
247 
248     public static class CalendarInfo {
249         public String name;
250         public int userId;
251     }
252 }
253