blob: 93b1b4890c340aa43098ed779d58ad5b5046035e [file] [log] [blame]
Michael Chan49701592010-06-30 11:04:03 -07001/*
2 * Copyright (C) 2010 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
17package com.android.calendar;
18
James Kung1d423f72013-01-14 13:40:38 -080019import static android.provider.CalendarContract.EXTRA_EVENT_ALL_DAY;
RoboErika27a8862011-06-23 15:26:23 -070020import static android.provider.CalendarContract.EXTRA_EVENT_BEGIN_TIME;
21import static android.provider.CalendarContract.EXTRA_EVENT_END_TIME;
Isaac Katzenelson6bcafcf2012-05-02 18:25:36 -070022import static android.provider.CalendarContract.Attendees.ATTENDEE_STATUS;
Michael Chan9e89dca2010-07-13 17:56:09 -070023
Erikba1b94a2010-07-20 17:50:50 -070024import android.accounts.Account;
Andy McFadden7dcd3012011-11-17 13:47:13 -080025import android.accounts.AccountManager;
Michael Chan83b0fe32010-07-08 16:46:26 -070026import android.app.Activity;
Daisuke Miyakawa6d2e6f72010-09-17 10:30:54 -070027import android.app.SearchManager;
28import android.app.SearchableInfo;
29import android.content.ComponentName;
Erikba1b94a2010-07-20 17:50:50 -070030import android.content.ContentResolver;
Michael Chan9e89dca2010-07-13 17:56:09 -070031import android.content.ContentUris;
Michael Chanab29d9e2010-07-21 06:08:47 -070032import android.content.Context;
Michael Chan9e89dca2010-07-13 17:56:09 -070033import android.content.Intent;
34import android.net.Uri;
Erikba1b94a2010-07-20 17:50:50 -070035import android.os.Bundle;
Isaac Katzenelson6bcafcf2012-05-02 18:25:36 -070036import android.provider.CalendarContract.Attendees;
RoboErika7c03902011-06-14 11:06:44 -070037import android.provider.CalendarContract.Calendars;
38import android.provider.CalendarContract.Events;
Michael Chan49701592010-06-30 11:04:03 -070039import android.text.format.Time;
Michael Chan83b0fe32010-07-08 16:46:26 -070040import android.util.Log;
RoboErik3864be02011-07-25 15:56:50 -070041import android.util.Pair;
Michael Chan49701592010-06-30 11:04:03 -070042
James Kung1d423f72013-01-14 13:40:38 -080043import com.android.calendar.event.EditEventActivity;
44import com.android.calendar.selectcalendars.SelectVisibleCalendarsActivity;
45
Paul Sliwowskia8ad4182013-07-01 18:05:28 -070046import java.lang.ref.WeakReference;
Erik3f348f32010-08-10 13:17:19 -070047import java.util.Iterator;
48import java.util.LinkedHashMap;
Michael Chanab29d9e2010-07-21 06:08:47 -070049import java.util.LinkedList;
Erik3f348f32010-08-10 13:17:19 -070050import java.util.Map.Entry;
Michael Chan83b0fe32010-07-08 16:46:26 -070051import java.util.WeakHashMap;
52
Erik25251192010-07-12 15:30:14 -070053public class CalendarController {
Michael Chan48bcc4c2012-12-12 11:38:16 -080054 private static final boolean DEBUG = false;
Michael Chan83b0fe32010-07-08 16:46:26 -070055 private static final String TAG = "CalendarController";
56
Erika7694ee2010-12-07 15:46:18 -080057 public static final String EVENT_EDIT_ON_LAUNCH = "editMode";
58
Erik981874e2010-10-05 16:52:52 -070059 public static final int MIN_CALENDAR_YEAR = 1970;
60 public static final int MAX_CALENDAR_YEAR = 2036;
61 public static final int MIN_CALENDAR_WEEK = 0;
62 public static final int MAX_CALENDAR_WEEK = 3497; // weeks between 1/1/1970 and 1/1/2037
63
Isaac Katzenelson6bcafcf2012-05-02 18:25:36 -070064 private final Context mContext;
Michael Chanab29d9e2010-07-21 06:08:47 -070065
Erik3f348f32010-08-10 13:17:19 -070066 // This uses a LinkedHashMap so that we can replace fragments based on the
67 // view id they are being expanded into since we can't guarantee a reference
68 // to the handler will be findable
Isaac Katzenelson6bcafcf2012-05-02 18:25:36 -070069 private final LinkedHashMap<Integer,EventHandler> eventHandlers =
Erik3f348f32010-08-10 13:17:19 -070070 new LinkedHashMap<Integer,EventHandler>(5);
Isaac Katzenelson6bcafcf2012-05-02 18:25:36 -070071 private final LinkedList<Integer> mToBeRemovedEventHandlers = new LinkedList<Integer>();
72 private final LinkedHashMap<Integer, EventHandler> mToBeAddedEventHandlers = new LinkedHashMap<
Erikcb811892010-09-28 13:44:19 -070073 Integer, EventHandler>();
RoboErik3864be02011-07-25 15:56:50 -070074 private Pair<Integer, EventHandler> mFirstEventHandler;
75 private Pair<Integer, EventHandler> mToBeAddedFirstEventHandler;
Isaac Katzenelsonccf565b2011-04-27 14:40:08 -070076 private volatile int mDispatchInProgressCounter = 0;
Michael Chanab29d9e2010-07-21 06:08:47 -070077
Paul Sliwowskia8ad4182013-07-01 18:05:28 -070078 private static WeakHashMap<Context, WeakReference<CalendarController>> instances =
79 new WeakHashMap<Context, WeakReference<CalendarController>>();
Michael Chan0558def2010-07-22 21:30:32 -070080
Isaac Katzenelson6bcafcf2012-05-02 18:25:36 -070081 private final WeakHashMap<Object, Long> filters = new WeakHashMap<Object, Long>(1);
Michael Chan83b0fe32010-07-08 16:46:26 -070082
Michael Chan3458a172010-07-13 17:58:21 -070083 private int mViewType = -1;
Michael Chan85e55092010-07-27 15:18:40 -070084 private int mDetailViewType = -1;
Michael Chanab29d9e2010-07-21 06:08:47 -070085 private int mPreviousViewType = -1;
Erik7b92da22010-09-23 14:55:22 -070086 private long mEventId = -1;
Isaac Katzenelson6bcafcf2012-05-02 18:25:36 -070087 private final Time mTime = new Time();
RoboErikc8e0f212011-10-13 17:57:39 -070088 private long mDateFlags = 0;
Michael Chan3458a172010-07-13 17:58:21 -070089
Isaac Katzenelson6bcafcf2012-05-02 18:25:36 -070090 private final Runnable mUpdateTimezone = new Runnable() {
RoboErik4679f602011-03-24 15:39:40 -070091 @Override
92 public void run() {
93 mTime.switchTimezone(Utils.getTimeZone(mContext, this));
94 }
95 };
96
Michael Chan49701592010-06-30 11:04:03 -070097 /**
Michael Chan83b0fe32010-07-08 16:46:26 -070098 * One of the event types that are sent to or from the controller
Michael Chan49701592010-06-30 11:04:03 -070099 */
Erik25251192010-07-12 15:30:14 -0700100 public interface EventType {
Michael Chan9e89dca2010-07-13 17:56:09 -0700101 final long CREATE_EVENT = 1L;
Michael Chandeced892010-12-10 15:59:35 -0800102
103 // Simple view of an event
Michael Chan83b0fe32010-07-08 16:46:26 -0700104 final long VIEW_EVENT = 1L << 1;
Michael Chandeced892010-12-10 15:59:35 -0800105
106 // Full detail view in read only mode
107 final long VIEW_EVENT_DETAILS = 1L << 2;
108
Erika7694ee2010-12-07 15:46:18 -0800109 // full detail view in edit mode
Michael Chandeced892010-12-10 15:59:35 -0800110 final long EDIT_EVENT = 1L << 3;
Michael Chan83b0fe32010-07-08 16:46:26 -0700111
Michael Chandeced892010-12-10 15:59:35 -0800112 final long DELETE_EVENT = 1L << 4;
Michael Chan83b0fe32010-07-08 16:46:26 -0700113
Michael Chandeced892010-12-10 15:59:35 -0800114 final long GO_TO = 1L << 5;
Erik954c8712010-08-06 10:12:34 -0700115
Michael Chandeced892010-12-10 15:59:35 -0800116 final long LAUNCH_SETTINGS = 1L << 6;
Mason Tang4003d1c2010-08-17 13:50:45 -0700117
Michael Chandeced892010-12-10 15:59:35 -0800118 final long EVENTS_CHANGED = 1L << 7;
119
120 final long SEARCH = 1L << 8;
Erik7b92da22010-09-23 14:55:22 -0700121
122 // User has pressed the home key
Michael Chandeced892010-12-10 15:59:35 -0800123 final long USER_HOME = 1L << 9;
Erikeaafa2b2010-12-23 14:30:37 -0800124
125 // date range has changed, update the title
126 final long UPDATE_TITLE = 1L << 10;
Michael Chan2aeb8d92011-07-10 13:32:09 -0700127
128 // select which calendars to display
129 final long LAUNCH_SELECT_VISIBLE_CALENDARS = 1L << 11;
Michael Chan83b0fe32010-07-08 16:46:26 -0700130 }
Michael Chan49701592010-06-30 11:04:03 -0700131
132 /**
Michael Chan83b0fe32010-07-08 16:46:26 -0700133 * One of the Agenda/Day/Week/Month view types
Michael Chan49701592010-06-30 11:04:03 -0700134 */
Erik25251192010-07-12 15:30:14 -0700135 public interface ViewType {
Michael Chand6734db2010-07-22 00:48:08 -0700136 final int DETAIL = -1;
Michael Chan3458a172010-07-13 17:58:21 -0700137 final int CURRENT = 0;
138 final int AGENDA = 1;
139 final int DAY = 2;
140 final int WEEK = 3;
141 final int MONTH = 4;
Erikdd95df52010-08-27 09:31:18 -0700142 final int EDIT = 5;
Isaac Katzenelson21270b82013-06-25 23:55:17 +0000143 final int MAX_VALUE = 5;
Michael Chan83b0fe32010-07-08 16:46:26 -0700144 }
145
Erik25251192010-07-12 15:30:14 -0700146 public static class EventInfo {
Isaac Katzenelson6bcafcf2012-05-02 18:25:36 -0700147
148 private static final long ATTENTEE_STATUS_MASK = 0xFF;
149 private static final long ALL_DAY_MASK = 0x100;
150 private static final int ATTENDEE_STATUS_NONE_MASK = 0x01;
151 private static final int ATTENDEE_STATUS_ACCEPTED_MASK = 0x02;
152 private static final int ATTENDEE_STATUS_DECLINED_MASK = 0x04;
153 private static final int ATTENDEE_STATUS_TENTATIVE_MASK = 0x08;
154
Mason Tang00b8c1a2010-08-23 12:02:00 -0700155 public long eventType; // one of the EventType
156 public int viewType; // one of the ViewType
157 public long id; // event id
158 public Time selectedTime; // the selected time in focus
James Kung1d423f72013-01-14 13:40:38 -0800159
160 // Event start and end times. All-day events are represented in:
161 // - local time for GO_TO commands
162 // - UTC time for VIEW_EVENT and other event-related commands
163 public Time startTime;
164 public Time endTime;
165
Mason Tang00b8c1a2010-08-23 12:02:00 -0700166 public int x; // x coordinate in the activity space
167 public int y; // y coordinate in the activity space
168 public String query; // query for a user search
Daisuke Miyakawa6d2e6f72010-09-17 10:30:54 -0700169 public ComponentName componentName; // used in combination with query
James Kung09fbd8e2012-11-12 11:19:46 -0800170 public String eventTitle;
171 public long calendarId;
Michael Chan46a8b112010-12-14 16:36:27 -0800172
173 /**
174 * For EventType.VIEW_EVENT:
Isaac Katzenelson6bcafcf2012-05-02 18:25:36 -0700175 * It is the default attendee response and an all day event indicator.
176 * Set to Attendees.ATTENDEE_STATUS_NONE, Attendees.ATTENDEE_STATUS_ACCEPTED,
177 * Attendees.ATTENDEE_STATUS_DECLINED, or Attendees.ATTENDEE_STATUS_TENTATIVE.
178 * To signal the event is an all-day event, "or" ALL_DAY_MASK with the response.
179 * Alternatively, use buildViewExtraLong(), getResponse(), and isAllDay().
Michael Chan46a8b112010-12-14 16:36:27 -0800180 * <p>
Michael Chanedecd9a2011-08-24 23:58:48 -0700181 * For EventType.CREATE_EVENT:
182 * Set to {@link #EXTRA_CREATE_ALL_DAY} for creating an all-day event.
183 * <p>
Michael Chan46a8b112010-12-14 16:36:27 -0800184 * For EventType.GO_TO:
185 * Set to {@link #EXTRA_GOTO_TIME} to go to the specified date/time.
186 * Set to {@link #EXTRA_GOTO_DATE} to consider the date but ignore the time.
Michael Chanfb0ec222011-08-12 17:39:30 -0700187 * Set to {@link #EXTRA_GOTO_BACK_TO_PREVIOUS} if back should bring back previous view.
RoboErik5b872522011-10-03 17:24:50 -0700188 * Set to {@link #EXTRA_GOTO_TODAY} if this is a user request to go to the current time.
Michael Chanfb0ec222011-08-12 17:39:30 -0700189 * <p>
190 * For EventType.UPDATE_TITLE:
191 * Set formatting flags for Utils.formatDateRange
Michael Chan46a8b112010-12-14 16:36:27 -0800192 */
193 public long extraLong;
Isaac Katzenelson6bcafcf2012-05-02 18:25:36 -0700194
195 public boolean isAllDay() {
196 if (eventType != EventType.VIEW_EVENT) {
197 Log.wtf(TAG, "illegal call to isAllDay , wrong event type " + eventType);
198 return false;
199 }
200 return ((extraLong & ALL_DAY_MASK) != 0) ? true : false;
201 }
202
203 public int getResponse() {
204 if (eventType != EventType.VIEW_EVENT) {
205 Log.wtf(TAG, "illegal call to getResponse , wrong event type " + eventType);
206 return Attendees.ATTENDEE_STATUS_NONE;
207 }
208
209 int response = (int)(extraLong & ATTENTEE_STATUS_MASK);
210 switch (response) {
211 case ATTENDEE_STATUS_NONE_MASK:
212 return Attendees.ATTENDEE_STATUS_NONE;
213 case ATTENDEE_STATUS_ACCEPTED_MASK:
214 return Attendees.ATTENDEE_STATUS_ACCEPTED;
215 case ATTENDEE_STATUS_DECLINED_MASK:
216 return Attendees.ATTENDEE_STATUS_DECLINED;
217 case ATTENDEE_STATUS_TENTATIVE_MASK:
218 return Attendees.ATTENDEE_STATUS_TENTATIVE;
219 default:
220 Log.wtf(TAG,"Unknown attendee response " + response);
221 }
222 return ATTENDEE_STATUS_NONE_MASK;
223 }
224
225 // Used to build the extra long for a VIEW event.
226 public static long buildViewExtraLong(int response, boolean allDay) {
227 long extra = allDay ? ALL_DAY_MASK : 0;
228
229 switch (response) {
230 case Attendees.ATTENDEE_STATUS_NONE:
231 extra |= ATTENDEE_STATUS_NONE_MASK;
232 break;
233 case Attendees.ATTENDEE_STATUS_ACCEPTED:
234 extra |= ATTENDEE_STATUS_ACCEPTED_MASK;
235 break;
236 case Attendees.ATTENDEE_STATUS_DECLINED:
237 extra |= ATTENDEE_STATUS_DECLINED_MASK;
238 break;
239 case Attendees.ATTENDEE_STATUS_TENTATIVE:
240 extra |= ATTENDEE_STATUS_TENTATIVE_MASK;
241 break;
242 default:
243 Log.wtf(TAG,"Unknown attendee response " + response);
244 extra |= ATTENDEE_STATUS_NONE_MASK;
245 break;
246 }
247 return extra;
248 }
Michael Chan83b0fe32010-07-08 16:46:26 -0700249 }
250
Michael Chan46a8b112010-12-14 16:36:27 -0800251 /**
Michael Chanedecd9a2011-08-24 23:58:48 -0700252 * Pass to the ExtraLong parameter for EventType.CREATE_EVENT to create
253 * an all-day event
254 */
255 public static final long EXTRA_CREATE_ALL_DAY = 0x10;
256
257 /**
Michael Chan46a8b112010-12-14 16:36:27 -0800258 * Pass to the ExtraLong parameter for EventType.GO_TO to signal the time
259 * can be ignored
260 */
261 public static final long EXTRA_GOTO_DATE = 1;
Michael Chanfb0ec222011-08-12 17:39:30 -0700262 public static final long EXTRA_GOTO_TIME = 2;
263 public static final long EXTRA_GOTO_BACK_TO_PREVIOUS = 4;
RoboErik5b872522011-10-03 17:24:50 -0700264 public static final long EXTRA_GOTO_TODAY = 8;
Michael Chan46a8b112010-12-14 16:36:27 -0800265
Erik25251192010-07-12 15:30:14 -0700266 public interface EventHandler {
Michael Chan83b0fe32010-07-08 16:46:26 -0700267 long getSupportedEventTypes();
268 void handleEvent(EventInfo event);
269
270 /**
Erik954c8712010-08-06 10:12:34 -0700271 * This notifies the handler that the database has changed and it should
272 * update its view.
Michael Chan83b0fe32010-07-08 16:46:26 -0700273 */
274 void eventsChanged();
Michael Chan83b0fe32010-07-08 16:46:26 -0700275 }
276
Michael Chan0558def2010-07-22 21:30:32 -0700277 /**
278 * Creates and/or returns an instance of CalendarController associated with
279 * the supplied context. It is best to pass in the current Activity.
280 *
281 * @param context The activity if at all possible.
282 */
283 public static CalendarController getInstance(Context context) {
284 synchronized (instances) {
Paul Sliwowskia8ad4182013-07-01 18:05:28 -0700285 CalendarController controller = null;
286 WeakReference<CalendarController> weakController = instances.get(context);
287 if (weakController != null) {
288 controller = weakController.get();
289 }
290
Michael Chan0558def2010-07-22 21:30:32 -0700291 if (controller == null) {
292 controller = new CalendarController(context);
Paul Sliwowskia8ad4182013-07-01 18:05:28 -0700293 instances.put(context, new WeakReference(controller));
Michael Chan0558def2010-07-22 21:30:32 -0700294 }
295 return controller;
296 }
297 }
298
Eriked61b482010-08-13 13:59:50 -0700299 /**
300 * Removes an instance when it is no longer needed. This should be called in
301 * an activity's onDestroy method.
302 *
303 * @param context The activity used to create the controller
304 */
305 public static void removeInstance(Context context) {
306 instances.remove(context);
307 }
308
Michael Chan0558def2010-07-22 21:30:32 -0700309 private CalendarController(Context context) {
Michael Chanab29d9e2010-07-21 06:08:47 -0700310 mContext = context;
RoboErik4679f602011-03-24 15:39:40 -0700311 mUpdateTimezone.run();
Michael Chan3458a172010-07-13 17:58:21 -0700312 mTime.setToNow();
Michael Chan85e55092010-07-27 15:18:40 -0700313 mDetailViewType = Utils.getSharedPreference(mContext,
Daisuke Miyakawa4b441bd2010-09-16 14:55:36 -0700314 GeneralPreferences.KEY_DETAILED_VIEW,
315 GeneralPreferences.DEFAULT_DETAILED_VIEW);
Michael Chan83b0fe32010-07-08 16:46:26 -0700316 }
Michael Chan49701592010-06-30 11:04:03 -0700317
Michael Chandeced892010-12-10 15:59:35 -0800318 public void sendEventRelatedEvent(Object sender, long eventType, long eventId, long startMillis,
RoboErik87f993f2011-02-03 17:47:20 -0800319 long endMillis, int x, int y, long selectedMillis) {
Isaac Katzenelson6bcafcf2012-05-02 18:25:36 -0700320 // TODO: pass the real allDay status or at least a status that says we don't know the
321 // status and have the receiver query the data.
322 // The current use of this method for VIEW_EVENT is by the day view to show an EventInfo
323 // so currently the missing allDay status has no effect.
Michael Chanedecd9a2011-08-24 23:58:48 -0700324 sendEventRelatedEventWithExtra(sender, eventType, eventId, startMillis, endMillis, x, y,
Isaac Katzenelson6bcafcf2012-05-02 18:25:36 -0700325 EventInfo.buildViewExtraLong(Attendees.ATTENDEE_STATUS_NONE, false),
326 selectedMillis);
Michael Chandeced892010-12-10 15:59:35 -0800327 }
328
Michael Chan49701592010-06-30 11:04:03 -0700329 /**
Michael Chan83b0fe32010-07-08 16:46:26 -0700330 * Helper for sending New/View/Edit/Delete events
331 *
332 * @param sender object of the caller
333 * @param eventType one of {@link EventType}
334 * @param eventId event id
Michael Chan3458a172010-07-13 17:58:21 -0700335 * @param startMillis start time
336 * @param endMillis end time
Michael Chan83b0fe32010-07-08 16:46:26 -0700337 * @param x x coordinate in the activity space
338 * @param y y coordinate in the activity space
Isaac Katzenelson6bcafcf2012-05-02 18:25:36 -0700339 * @param extraLong default response value for the "simple event view" and all day indication.
340 * Use Attendees.ATTENDEE_STATUS_NONE for no response.
RoboErik87f993f2011-02-03 17:47:20 -0800341 * @param selectedMillis The time to specify as selected
Michael Chan49701592010-06-30 11:04:03 -0700342 */
Michael Chanedecd9a2011-08-24 23:58:48 -0700343 public void sendEventRelatedEventWithExtra(Object sender, long eventType, long eventId,
RoboErik87f993f2011-02-03 17:47:20 -0800344 long startMillis, long endMillis, int x, int y, long extraLong, long selectedMillis) {
James Kung09fbd8e2012-11-12 11:19:46 -0800345 sendEventRelatedEventWithExtraWithTitleWithCalendarId(sender, eventType, eventId,
346 startMillis, endMillis, x, y, extraLong, selectedMillis, null, -1);
347 }
348
349 /**
350 * Helper for sending New/View/Edit/Delete events
351 *
352 * @param sender object of the caller
353 * @param eventType one of {@link EventType}
354 * @param eventId event id
355 * @param startMillis start time
356 * @param endMillis end time
357 * @param x x coordinate in the activity space
358 * @param y y coordinate in the activity space
359 * @param extraLong default response value for the "simple event view" and all day indication.
360 * Use Attendees.ATTENDEE_STATUS_NONE for no response.
361 * @param selectedMillis The time to specify as selected
362 * @param title The title of the event
363 * @param calendarId The id of the calendar which the event belongs to
364 */
365 public void sendEventRelatedEventWithExtraWithTitleWithCalendarId(Object sender, long eventType,
366 long eventId, long startMillis, long endMillis, int x, int y, long extraLong,
367 long selectedMillis, String title, long calendarId) {
Michael Chan83b0fe32010-07-08 16:46:26 -0700368 EventInfo info = new EventInfo();
369 info.eventType = eventType;
Erika7694ee2010-12-07 15:46:18 -0800370 if (eventType == EventType.EDIT_EVENT || eventType == EventType.VIEW_EVENT_DETAILS) {
Erik5f620792010-10-27 12:42:01 -0700371 info.viewType = ViewType.CURRENT;
Erikdd95df52010-08-27 09:31:18 -0700372 }
James Kung09fbd8e2012-11-12 11:19:46 -0800373
Michael Chan83b0fe32010-07-08 16:46:26 -0700374 info.id = eventId;
James Kungf068eab2013-01-14 11:36:17 -0800375 info.startTime = new Time(Utils.getTimeZone(mContext, mUpdateTimezone));
Michael Chan9e89dca2010-07-13 17:56:09 -0700376 info.startTime.set(startMillis);
RoboErik87f993f2011-02-03 17:47:20 -0800377 if (selectedMillis != -1) {
RoboErik4679f602011-03-24 15:39:40 -0700378 info.selectedTime = new Time(Utils.getTimeZone(mContext, mUpdateTimezone));
RoboErik87f993f2011-02-03 17:47:20 -0800379 info.selectedTime.set(selectedMillis);
380 } else {
381 info.selectedTime = info.startTime;
382 }
James Kungf068eab2013-01-14 11:36:17 -0800383 info.endTime = new Time(Utils.getTimeZone(mContext, mUpdateTimezone));
Michael Chan9e89dca2010-07-13 17:56:09 -0700384 info.endTime.set(endMillis);
Michael Chan83b0fe32010-07-08 16:46:26 -0700385 info.x = x;
386 info.y = y;
Michael Chandeced892010-12-10 15:59:35 -0800387 info.extraLong = extraLong;
James Kung09fbd8e2012-11-12 11:19:46 -0800388 info.eventTitle = title;
389 info.calendarId = calendarId;
Michael Chan83b0fe32010-07-08 16:46:26 -0700390 this.sendEvent(sender, info);
391 }
Michael Chan49701592010-06-30 11:04:03 -0700392 /**
Michael Chan83b0fe32010-07-08 16:46:26 -0700393 * Helper for sending non-calendar-event events
394 *
395 * @param sender object of the caller
396 * @param eventType one of {@link EventType}
Michael Chan83b0fe32010-07-08 16:46:26 -0700397 * @param start start time
398 * @param end end time
Michael Chand6734db2010-07-22 00:48:08 -0700399 * @param eventId event id
Michael Chan83b0fe32010-07-08 16:46:26 -0700400 * @param viewType {@link ViewType}
Michael Chan49701592010-06-30 11:04:03 -0700401 */
Erik25251192010-07-12 15:30:14 -0700402 public void sendEvent(Object sender, long eventType, Time start, Time end, long eventId,
Michael Chan3458a172010-07-13 17:58:21 -0700403 int viewType) {
Michael Chanf0868f62011-01-11 19:37:35 -0800404 sendEvent(sender, eventType, start, end, start, eventId, viewType, EXTRA_GOTO_TIME, null,
405 null);
Daisuke Miyakawa6d2e6f72010-09-17 10:30:54 -0700406 }
407
408 /**
Michael Chan46a8b112010-12-14 16:36:27 -0800409 * sendEvent() variant with extraLong, search query, and search component name.
Daisuke Miyakawa6d2e6f72010-09-17 10:30:54 -0700410 */
411 public void sendEvent(Object sender, long eventType, Time start, Time end, long eventId,
Michael Chan46a8b112010-12-14 16:36:27 -0800412 int viewType, long extraLong, String query, ComponentName componentName) {
Michael Chanf0868f62011-01-11 19:37:35 -0800413 sendEvent(sender, eventType, start, end, start, eventId, viewType, extraLong, query,
414 componentName);
415 }
416
417 public void sendEvent(Object sender, long eventType, Time start, Time end, Time selected,
418 long eventId, int viewType, long extraLong, String query, ComponentName componentName) {
Michael Chan83b0fe32010-07-08 16:46:26 -0700419 EventInfo info = new EventInfo();
420 info.eventType = eventType;
421 info.startTime = start;
Michael Chanf0868f62011-01-11 19:37:35 -0800422 info.selectedTime = selected;
Michael Chan83b0fe32010-07-08 16:46:26 -0700423 info.endTime = end;
424 info.id = eventId;
425 info.viewType = viewType;
Daisuke Miyakawa6d2e6f72010-09-17 10:30:54 -0700426 info.query = query;
427 info.componentName = componentName;
Michael Chan46a8b112010-12-14 16:36:27 -0800428 info.extraLong = extraLong;
Michael Chan83b0fe32010-07-08 16:46:26 -0700429 this.sendEvent(sender, info);
430 }
431
Erik25251192010-07-12 15:30:14 -0700432 public void sendEvent(Object sender, final EventInfo event) {
Michael Chan83b0fe32010-07-08 16:46:26 -0700433 // TODO Throw exception on invalid events
434
Erik3f348f32010-08-10 13:17:19 -0700435 if (DEBUG) {
James Kungf068eab2013-01-14 11:36:17 -0800436 Log.d(TAG, eventInfoToString(event));
Erik3f348f32010-08-10 13:17:19 -0700437 }
Michael Chan83b0fe32010-07-08 16:46:26 -0700438
439 Long filteredTypes = filters.get(sender);
440 if (filteredTypes != null && (filteredTypes.longValue() & event.eventType) != 0) {
441 // Suppress event per filter
Erik3f348f32010-08-10 13:17:19 -0700442 if (DEBUG) {
443 Log.d(TAG, "Event suppressed");
444 }
Michael Chan83b0fe32010-07-08 16:46:26 -0700445 return;
446 }
447
Michael Chanab29d9e2010-07-21 06:08:47 -0700448 mPreviousViewType = mViewType;
Michael Chan83b0fe32010-07-08 16:46:26 -0700449
Michael Chan3458a172010-07-13 17:58:21 -0700450 // Fix up view if not specified
Michael Chand6734db2010-07-22 00:48:08 -0700451 if (event.viewType == ViewType.DETAIL) {
Michael Chan85e55092010-07-27 15:18:40 -0700452 event.viewType = mDetailViewType;
453 mViewType = mDetailViewType;
Michael Chand6734db2010-07-22 00:48:08 -0700454 } else if (event.viewType == ViewType.CURRENT) {
Michael Chan3458a172010-07-13 17:58:21 -0700455 event.viewType = mViewType;
Michael Chanf0868f62011-01-11 19:37:35 -0800456 } else if (event.viewType != ViewType.EDIT) {
Michael Chanab29d9e2010-07-21 06:08:47 -0700457 mViewType = event.viewType;
Michael Chan85e55092010-07-27 15:18:40 -0700458
Erik63cd0532011-01-26 14:16:03 -0800459 if (event.viewType == ViewType.AGENDA || event.viewType == ViewType.DAY
460 || (Utils.getAllowWeekForDetailView() && event.viewType == ViewType.WEEK)) {
Michael Chan85e55092010-07-27 15:18:40 -0700461 mDetailViewType = mViewType;
462 }
Michael Chan3458a172010-07-13 17:58:21 -0700463 }
464
Michael Chanf0868f62011-01-11 19:37:35 -0800465 if (DEBUG) {
Michael Chan48bcc4c2012-12-12 11:38:16 -0800466 Log.d(TAG, "vvvvvvvvvvvvvvv");
467 Log.d(TAG, "Start " + (event.startTime == null ? "null" : event.startTime.toString()));
468 Log.d(TAG, "End " + (event.endTime == null ? "null" : event.endTime.toString()));
469 Log.d(TAG, "Select " + (event.selectedTime == null ? "null" : event.selectedTime.toString()));
470 Log.d(TAG, "mTime " + (mTime == null ? "null" : mTime.toString()));
Mason Tang4003d1c2010-08-17 13:50:45 -0700471 }
Michael Chanf0868f62011-01-11 19:37:35 -0800472
473 long startMillis = 0;
474 if (event.startTime != null) {
475 startMillis = event.startTime.toMillis(false);
476 }
477
478 // Set mTime if selectedTime is set
479 if (event.selectedTime != null && event.selectedTime.toMillis(false) != 0) {
480 mTime.set(event.selectedTime);
481 } else {
482 if (startMillis != 0) {
483 // selectedTime is not set so set mTime to startTime iff it is not
484 // within start and end times
485 long mtimeMillis = mTime.toMillis(false);
486 if (mtimeMillis < startMillis
487 || (event.endTime != null && mtimeMillis > event.endTime.toMillis(false))) {
488 mTime.set(event.startTime);
489 }
490 }
491 event.selectedTime = mTime;
492 }
RoboErikc8e0f212011-10-13 17:57:39 -0700493 // Store the formatting flags if this is an update to the title
494 if (event.eventType == EventType.UPDATE_TITLE) {
495 mDateFlags = event.extraLong;
496 }
Michael Chanf0868f62011-01-11 19:37:35 -0800497
498 // Fix up start time if not specified
499 if (startMillis == 0) {
500 event.startTime = mTime;
501 }
502 if (DEBUG) {
Michael Chan48bcc4c2012-12-12 11:38:16 -0800503 Log.d(TAG, "Start " + (event.startTime == null ? "null" : event.startTime.toString()));
504 Log.d(TAG, "End " + (event.endTime == null ? "null" : event.endTime.toString()));
505 Log.d(TAG, "Select " + (event.selectedTime == null ? "null" : event.selectedTime.toString()));
506 Log.d(TAG, "mTime " + (mTime == null ? "null" : mTime.toString()));
507 Log.d(TAG, "^^^^^^^^^^^^^^^");
Michael Chanf0868f62011-01-11 19:37:35 -0800508 }
Mason Tang4003d1c2010-08-17 13:50:45 -0700509
Erik7b92da22010-09-23 14:55:22 -0700510 // Store the eventId if we're entering edit event
Erika7694ee2010-12-07 15:46:18 -0800511 if ((event.eventType
512 & (EventType.CREATE_EVENT | EventType.EDIT_EVENT | EventType.VIEW_EVENT_DETAILS))
513 != 0) {
Erik7b92da22010-09-23 14:55:22 -0700514 if (event.id > 0) {
515 mEventId = event.id;
516 } else {
517 mEventId = -1;
518 }
519 }
520
Mason Tang4003d1c2010-08-17 13:50:45 -0700521 boolean handled = false;
Michael Chanab29d9e2010-07-21 06:08:47 -0700522 synchronized (this) {
Isaac Katzenelsonccf565b2011-04-27 14:40:08 -0700523 mDispatchInProgressCounter ++;
Michael Chan3458a172010-07-13 17:58:21 -0700524
Erik3f348f32010-08-10 13:17:19 -0700525 if (DEBUG) {
526 Log.d(TAG, "sendEvent: Dispatching to " + eventHandlers.size() + " handlers");
527 }
Michael Chanab29d9e2010-07-21 06:08:47 -0700528 // Dispatch to event handler(s)
RoboErik3864be02011-07-25 15:56:50 -0700529 if (mFirstEventHandler != null) {
530 // Handle the 'first' one before handling the others
531 EventHandler handler = mFirstEventHandler.second;
532 if (handler != null && (handler.getSupportedEventTypes() & event.eventType) != 0
533 && !mToBeRemovedEventHandlers.contains(mFirstEventHandler.first)) {
534 handler.handleEvent(event);
535 handled = true;
536 }
537 }
Erik3f348f32010-08-10 13:17:19 -0700538 for (Iterator<Entry<Integer, EventHandler>> handlers =
539 eventHandlers.entrySet().iterator(); handlers.hasNext();) {
540 Entry<Integer, EventHandler> entry = handlers.next();
541 int key = entry.getKey();
RoboErik3864be02011-07-25 15:56:50 -0700542 if (mFirstEventHandler != null && key == mFirstEventHandler.first) {
543 // If this was the 'first' handler it was already handled
544 continue;
545 }
Erik3f348f32010-08-10 13:17:19 -0700546 EventHandler eventHandler = entry.getValue();
Michael Chanab29d9e2010-07-21 06:08:47 -0700547 if (eventHandler != null
548 && (eventHandler.getSupportedEventTypes() & event.eventType) != 0) {
Erik3f348f32010-08-10 13:17:19 -0700549 if (mToBeRemovedEventHandlers.contains(key)) {
Michael Chanab29d9e2010-07-21 06:08:47 -0700550 continue;
551 }
552 eventHandler.handleEvent(event);
Mason Tang4003d1c2010-08-17 13:50:45 -0700553 handled = true;
Michael Chan83b0fe32010-07-08 16:46:26 -0700554 }
555 }
Michael Chanab29d9e2010-07-21 06:08:47 -0700556
Isaac Katzenelsonccf565b2011-04-27 14:40:08 -0700557 mDispatchInProgressCounter --;
Erikcb811892010-09-28 13:44:19 -0700558
Isaac Katzenelsonccf565b2011-04-27 14:40:08 -0700559 if (mDispatchInProgressCounter == 0) {
560
561 // Deregister removed handlers
562 if (mToBeRemovedEventHandlers.size() > 0) {
563 for (Integer zombie : mToBeRemovedEventHandlers) {
564 eventHandlers.remove(zombie);
RoboErik3864be02011-07-25 15:56:50 -0700565 if (mFirstEventHandler != null && zombie.equals(mFirstEventHandler.first)) {
566 mFirstEventHandler = null;
567 }
Isaac Katzenelsonccf565b2011-04-27 14:40:08 -0700568 }
569 mToBeRemovedEventHandlers.clear();
Michael Chanab29d9e2010-07-21 06:08:47 -0700570 }
Isaac Katzenelsonccf565b2011-04-27 14:40:08 -0700571 // Add new handlers
RoboErik3864be02011-07-25 15:56:50 -0700572 if (mToBeAddedFirstEventHandler != null) {
573 mFirstEventHandler = mToBeAddedFirstEventHandler;
574 mToBeAddedFirstEventHandler = null;
575 }
Isaac Katzenelsonccf565b2011-04-27 14:40:08 -0700576 if (mToBeAddedEventHandlers.size() > 0) {
577 for (Entry<Integer, EventHandler> food : mToBeAddedEventHandlers.entrySet()) {
578 eventHandlers.put(food.getKey(), food.getValue());
579 }
Erikcb811892010-09-28 13:44:19 -0700580 }
581 }
Michael Chan83b0fe32010-07-08 16:46:26 -0700582 }
Mason Tang4003d1c2010-08-17 13:50:45 -0700583
584 if (!handled) {
Erik6b858fc2010-09-15 18:59:04 -0700585 // Launch Settings
586 if (event.eventType == EventType.LAUNCH_SETTINGS) {
Mason Tang4003d1c2010-08-17 13:50:45 -0700587 launchSettings();
588 return;
589 }
590
Michael Chan2aeb8d92011-07-10 13:32:09 -0700591 // Launch Calendar Visible Selector
592 if (event.eventType == EventType.LAUNCH_SELECT_VISIBLE_CALENDARS) {
593 launchSelectVisibleCalendars();
594 return;
595 }
596
Mason Tang4003d1c2010-08-17 13:50:45 -0700597 // Create/View/Edit/Delete Event
598 long endTime = (event.endTime == null) ? -1 : event.endTime.toMillis(false);
599 if (event.eventType == EventType.CREATE_EVENT) {
Michael Chanedecd9a2011-08-24 23:58:48 -0700600 launchCreateEvent(event.startTime.toMillis(false), endTime,
James Kung09fbd8e2012-11-12 11:19:46 -0800601 event.extraLong == EXTRA_CREATE_ALL_DAY, event.eventTitle,
602 event.calendarId);
Mason Tang4003d1c2010-08-17 13:50:45 -0700603 return;
604 } else if (event.eventType == EventType.VIEW_EVENT) {
Isaac Katzenelson6bcafcf2012-05-02 18:25:36 -0700605 launchViewEvent(event.id, event.startTime.toMillis(false), endTime,
606 event.getResponse());
Mason Tang4003d1c2010-08-17 13:50:45 -0700607 return;
608 } else if (event.eventType == EventType.EDIT_EVENT) {
Erika7694ee2010-12-07 15:46:18 -0800609 launchEditEvent(event.id, event.startTime.toMillis(false), endTime, true);
610 return;
611 } else if (event.eventType == EventType.VIEW_EVENT_DETAILS) {
612 launchEditEvent(event.id, event.startTime.toMillis(false), endTime, false);
Mason Tang4003d1c2010-08-17 13:50:45 -0700613 return;
614 } else if (event.eventType == EventType.DELETE_EVENT) {
615 launchDeleteEvent(event.id, event.startTime.toMillis(false), endTime);
616 return;
Daisuke Miyakawa6d2e6f72010-09-17 10:30:54 -0700617 } else if (event.eventType == EventType.SEARCH) {
618 launchSearch(event.id, event.query, event.componentName);
619 return;
Mason Tang4003d1c2010-08-17 13:50:45 -0700620 }
621 }
Michael Chan83b0fe32010-07-08 16:46:26 -0700622 }
623
Erik3f348f32010-08-10 13:17:19 -0700624 /**
625 * Adds or updates an event handler. This uses a LinkedHashMap so that we can
626 * replace fragments based on the view id they are being expanded into.
627 *
628 * @param key The view id or placeholder for this handler
629 * @param eventHandler Typically a fragment or activity in the calendar app
630 */
631 public void registerEventHandler(int key, EventHandler eventHandler) {
Michael Chanab29d9e2010-07-21 06:08:47 -0700632 synchronized (this) {
Isaac Katzenelsonccf565b2011-04-27 14:40:08 -0700633 if (mDispatchInProgressCounter > 0) {
Erikcb811892010-09-28 13:44:19 -0700634 mToBeAddedEventHandlers.put(key, eventHandler);
635 } else {
636 eventHandlers.put(key, eventHandler);
637 }
Michael Chanab29d9e2010-07-21 06:08:47 -0700638 }
Michael Chan83b0fe32010-07-08 16:46:26 -0700639 }
640
RoboErik3864be02011-07-25 15:56:50 -0700641 public void registerFirstEventHandler(int key, EventHandler eventHandler) {
642 synchronized (this) {
643 registerEventHandler(key, eventHandler);
644 if (mDispatchInProgressCounter > 0) {
645 mToBeAddedFirstEventHandler = new Pair<Integer, EventHandler>(key, eventHandler);
646 } else {
647 mFirstEventHandler = new Pair<Integer, EventHandler>(key, eventHandler);
648 }
649 }
650 }
651
Erik3f348f32010-08-10 13:17:19 -0700652 public void deregisterEventHandler(Integer key) {
Michael Chanab29d9e2010-07-21 06:08:47 -0700653 synchronized (this) {
Isaac Katzenelsonccf565b2011-04-27 14:40:08 -0700654 if (mDispatchInProgressCounter > 0) {
Michael Chanab29d9e2010-07-21 06:08:47 -0700655 // To avoid ConcurrencyException, stash away the event handler for now.
Erik3f348f32010-08-10 13:17:19 -0700656 mToBeRemovedEventHandlers.add(key);
Michael Chanab29d9e2010-07-21 06:08:47 -0700657 } else {
Erik3f348f32010-08-10 13:17:19 -0700658 eventHandlers.remove(key);
RoboErik3864be02011-07-25 15:56:50 -0700659 if (mFirstEventHandler != null && mFirstEventHandler.first == key) {
660 mFirstEventHandler = null;
661 }
Michael Chanab29d9e2010-07-21 06:08:47 -0700662 }
663 }
Michael Chan83b0fe32010-07-08 16:46:26 -0700664 }
665
Paul Westbrook61310b72011-10-07 15:43:00 -0700666 public void deregisterAllEventHandlers() {
667 synchronized (this) {
668 if (mDispatchInProgressCounter > 0) {
669 // To avoid ConcurrencyException, stash away the event handler for now.
670 mToBeRemovedEventHandlers.addAll(eventHandlers.keySet());
671 } else {
672 eventHandlers.clear();
673 mFirstEventHandler = null;
674 }
675 }
676 }
677
Michael Chan3458a172010-07-13 17:58:21 -0700678 // FRAG_TODO doesn't work yet
Erik25251192010-07-12 15:30:14 -0700679 public void filterBroadcasts(Object sender, long eventTypes) {
Michael Chan83b0fe32010-07-08 16:46:26 -0700680 filters.put(sender, eventTypes);
681 }
682
Mason Tang8e3d4302010-07-12 17:39:30 -0700683 /**
684 * @return the time that this controller is currently pointed at
685 */
686 public long getTime() {
687 return mTime.toMillis(false);
688 }
689
Erik7b92da22010-09-23 14:55:22 -0700690 /**
RoboErikc8e0f212011-10-13 17:57:39 -0700691 * @return the last set of date flags sent with
692 * {@link EventType#UPDATE_TITLE}
693 */
694 public long getDateFlags() {
695 return mDateFlags;
696 }
697
698 /**
Erik144edfa2010-11-22 14:23:49 -0800699 * Set the time this controller is currently pointed at
700 *
701 * @param millisTime Time since epoch in millis
702 */
703 public void setTime(long millisTime) {
704 mTime.set(millisTime);
705 }
706
707 /**
Erik7b92da22010-09-23 14:55:22 -0700708 * @return the last event ID the edit view was launched with
709 */
710 public long getEventId() {
711 return mEventId;
712 }
713
Michael Chanab29d9e2010-07-21 06:08:47 -0700714 public int getViewType() {
715 return mViewType;
716 }
717
718 public int getPreviousViewType() {
719 return mPreviousViewType;
720 }
Mason Tang8e3d4302010-07-12 17:39:30 -0700721
Michael Chan2aeb8d92011-07-10 13:32:09 -0700722 private void launchSelectVisibleCalendars() {
723 Intent intent = new Intent(Intent.ACTION_VIEW);
Michael Chan07d9fee2011-07-25 09:41:21 -0700724 intent.setClass(mContext, SelectVisibleCalendarsActivity.class);
Michael Chan2aeb8d92011-07-10 13:32:09 -0700725 intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP);
726 mContext.startActivity(intent);
727 }
728
Michael Chan9e89dca2010-07-13 17:56:09 -0700729 private void launchSettings() {
730 Intent intent = new Intent(Intent.ACTION_VIEW);
Michael Chan07d9fee2011-07-25 09:41:21 -0700731 intent.setClass(mContext, CalendarSettingsActivity.class);
Michael Chan9e89dca2010-07-13 17:56:09 -0700732 intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP);
Michael Chanab29d9e2010-07-21 06:08:47 -0700733 mContext.startActivity(intent);
Michael Chan9e89dca2010-07-13 17:56:09 -0700734 }
735
James Kung09fbd8e2012-11-12 11:19:46 -0800736 private void launchCreateEvent(long startMillis, long endMillis, boolean allDayEvent,
737 String title, long calendarId) {
738 Intent intent = generateCreateEventIntent(startMillis, endMillis, allDayEvent, title,
739 calendarId);
740 mEventId = -1;
741 mContext.startActivity(intent);
742 }
743
744 public Intent generateCreateEventIntent(long startMillis, long endMillis,
745 boolean allDayEvent, String title, long calendarId) {
Michael Chan9e89dca2010-07-13 17:56:09 -0700746 Intent intent = new Intent(Intent.ACTION_VIEW);
Michael Chan07d9fee2011-07-25 09:41:21 -0700747 intent.setClass(mContext, EditEventActivity.class);
RoboErika27a8862011-06-23 15:26:23 -0700748 intent.putExtra(EXTRA_EVENT_BEGIN_TIME, startMillis);
749 intent.putExtra(EXTRA_EVENT_END_TIME, endMillis);
Michael Chanedecd9a2011-08-24 23:58:48 -0700750 intent.putExtra(EXTRA_EVENT_ALL_DAY, allDayEvent);
James Kung09fbd8e2012-11-12 11:19:46 -0800751 intent.putExtra(Events.CALENDAR_ID, calendarId);
752 intent.putExtra(Events.TITLE, title);
753 return intent;
Michael Chan9e89dca2010-07-13 17:56:09 -0700754 }
755
Isaac Katzenelson6bcafcf2012-05-02 18:25:36 -0700756 public void launchViewEvent(long eventId, long startMillis, long endMillis, int response) {
Michael Chan9e89dca2010-07-13 17:56:09 -0700757 Intent intent = new Intent(Intent.ACTION_VIEW);
758 Uri eventUri = ContentUris.withAppendedId(Events.CONTENT_URI, eventId);
759 intent.setData(eventUri);
Michael Chan07d9fee2011-07-25 09:41:21 -0700760 intent.setClass(mContext, AllInOneActivity.class);
RoboErika27a8862011-06-23 15:26:23 -0700761 intent.putExtra(EXTRA_EVENT_BEGIN_TIME, startMillis);
762 intent.putExtra(EXTRA_EVENT_END_TIME, endMillis);
Isaac Katzenelson6bcafcf2012-05-02 18:25:36 -0700763 intent.putExtra(ATTENDEE_STATUS, response);
Isaac Katzenelson4024dee2011-09-29 14:40:46 -0700764 intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
Michael Chanab29d9e2010-07-21 06:08:47 -0700765 mContext.startActivity(intent);
Michael Chan9e89dca2010-07-13 17:56:09 -0700766 }
767
Erika7694ee2010-12-07 15:46:18 -0800768 private void launchEditEvent(long eventId, long startMillis, long endMillis, boolean edit) {
Michael Chan9e89dca2010-07-13 17:56:09 -0700769 Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, eventId);
770 Intent intent = new Intent(Intent.ACTION_EDIT, uri);
RoboErika27a8862011-06-23 15:26:23 -0700771 intent.putExtra(EXTRA_EVENT_BEGIN_TIME, startMillis);
772 intent.putExtra(EXTRA_EVENT_END_TIME, endMillis);
Michael Chanab29d9e2010-07-21 06:08:47 -0700773 intent.setClass(mContext, EditEventActivity.class);
Erika7694ee2010-12-07 15:46:18 -0800774 intent.putExtra(EVENT_EDIT_ON_LAUNCH, edit);
Erik7b92da22010-09-23 14:55:22 -0700775 mEventId = eventId;
Michael Chanab29d9e2010-07-21 06:08:47 -0700776 mContext.startActivity(intent);
Michael Chan9e89dca2010-07-13 17:56:09 -0700777 }
778
Michael Chan1881a892011-02-08 18:16:58 -0800779// private void launchAlerts() {
780// Intent intent = new Intent();
781// intent.setClass(mContext, AlertActivity.class);
782// intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
783// mContext.startActivity(intent);
784// }
785
Michael Chan9e89dca2010-07-13 17:56:09 -0700786 private void launchDeleteEvent(long eventId, long startMillis, long endMillis) {
787 launchDeleteEventAndFinish(null, eventId, startMillis, endMillis, -1);
788 }
789
790 private void launchDeleteEventAndFinish(Activity parentActivity, long eventId, long startMillis,
791 long endMillis, int deleteWhich) {
Michael Chanab29d9e2010-07-21 06:08:47 -0700792 DeleteEventHelper deleteEventHelper = new DeleteEventHelper(mContext, parentActivity,
Michael Chan9e89dca2010-07-13 17:56:09 -0700793 parentActivity != null /* exit when done */);
794 deleteEventHelper.delete(startMillis, endMillis, eventId, deleteWhich);
795 }
Michael Chan3458a172010-07-13 17:58:21 -0700796
Daisuke Miyakawa6d2e6f72010-09-17 10:30:54 -0700797 private void launchSearch(long eventId, String query, ComponentName componentName) {
798 final SearchManager searchManager =
799 (SearchManager)mContext.getSystemService(Context.SEARCH_SERVICE);
800 final SearchableInfo searchableInfo = searchManager.getSearchableInfo(componentName);
801 final Intent intent = new Intent(Intent.ACTION_SEARCH);
802 intent.putExtra(SearchManager.QUERY, query);
803 intent.setComponent(searchableInfo.getSearchActivity());
RoboErik2bd5cc02011-07-28 14:19:54 -0700804 intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
Daisuke Miyakawa6d2e6f72010-09-17 10:30:54 -0700805 mContext.startActivity(intent);
806 }
807
Andy McFadden7dcd3012011-11-17 13:47:13 -0800808 /**
809 * Performs a manual refresh of calendars in all known accounts.
810 */
Erikba1b94a2010-07-20 17:50:50 -0700811 public void refreshCalendars() {
Andy McFadden7dcd3012011-11-17 13:47:13 -0800812 Account[] accounts = AccountManager.get(mContext).getAccounts();
813 Log.d(TAG, "Refreshing " + accounts.length + " accounts");
814
815 String authority = Calendars.CONTENT_URI.getAuthority();
816 for (int i = 0; i < accounts.length; i++) {
817 if (Log.isLoggable(TAG, Log.DEBUG)) {
818 Log.d(TAG, "Refreshing calendars for: " + accounts[i]);
819 }
820 Bundle extras = new Bundle();
821 extras.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
822 ContentResolver.requestSync(accounts[i], authority, extras);
823 }
Erikba1b94a2010-07-20 17:50:50 -0700824 }
825
Erikdd95df52010-08-27 09:31:18 -0700826 // Forces the viewType. Should only be used for initialization.
827 public void setViewType(int viewType) {
828 mViewType = viewType;
829 }
830
Erik7b92da22010-09-23 14:55:22 -0700831 // Sets the eventId. Should only be used for initialization.
832 public void setEventId(long eventId) {
833 mEventId = eventId;
834 }
835
James Kungf068eab2013-01-14 11:36:17 -0800836 private String eventInfoToString(EventInfo eventInfo) {
Michael Chan3458a172010-07-13 17:58:21 -0700837 String tmp = "Unknown";
James Kungf068eab2013-01-14 11:36:17 -0800838
839 StringBuilder builder = new StringBuilder();
Michael Chanab29d9e2010-07-21 06:08:47 -0700840 if ((eventInfo.eventType & EventType.GO_TO) != 0) {
Michael Chan3458a172010-07-13 17:58:21 -0700841 tmp = "Go to time/event";
842 } else if ((eventInfo.eventType & EventType.CREATE_EVENT) != 0) {
843 tmp = "New event";
844 } else if ((eventInfo.eventType & EventType.VIEW_EVENT) != 0) {
845 tmp = "View event";
Michael Chan6d4ce6e2011-01-11 11:15:16 -0800846 } else if ((eventInfo.eventType & EventType.VIEW_EVENT_DETAILS) != 0) {
847 tmp = "View details";
Michael Chan3458a172010-07-13 17:58:21 -0700848 } else if ((eventInfo.eventType & EventType.EDIT_EVENT) != 0) {
849 tmp = "Edit event";
850 } else if ((eventInfo.eventType & EventType.DELETE_EVENT) != 0) {
851 tmp = "Delete event";
Michael Chan2aeb8d92011-07-10 13:32:09 -0700852 } else if ((eventInfo.eventType & EventType.LAUNCH_SELECT_VISIBLE_CALENDARS) != 0) {
853 tmp = "Launch select visible calendars";
Michael Chan3458a172010-07-13 17:58:21 -0700854 } else if ((eventInfo.eventType & EventType.LAUNCH_SETTINGS) != 0) {
855 tmp = "Launch settings";
Erik3f348f32010-08-10 13:17:19 -0700856 } else if ((eventInfo.eventType & EventType.EVENTS_CHANGED) != 0) {
857 tmp = "Refresh events";
Mason Tang4003d1c2010-08-17 13:50:45 -0700858 } else if ((eventInfo.eventType & EventType.SEARCH) != 0) {
859 tmp = "Search";
Michael Chan6d4ce6e2011-01-11 11:15:16 -0800860 } else if ((eventInfo.eventType & EventType.USER_HOME) != 0) {
861 tmp = "Gone home";
862 } else if ((eventInfo.eventType & EventType.UPDATE_TITLE) != 0) {
863 tmp = "Update title";
Michael Chan3458a172010-07-13 17:58:21 -0700864 }
James Kungf068eab2013-01-14 11:36:17 -0800865 builder.append(tmp);
Michael Chan3458a172010-07-13 17:58:21 -0700866 builder.append(": id=");
867 builder.append(eventInfo.id);
Michael Chand6734db2010-07-22 00:48:08 -0700868 builder.append(", selected=");
869 builder.append(eventInfo.selectedTime);
870 builder.append(", start=");
Michael Chan3458a172010-07-13 17:58:21 -0700871 builder.append(eventInfo.startTime);
Michael Chand6734db2010-07-22 00:48:08 -0700872 builder.append(", end=");
Michael Chan3458a172010-07-13 17:58:21 -0700873 builder.append(eventInfo.endTime);
874 builder.append(", viewType=");
875 builder.append(eventInfo.viewType);
876 builder.append(", x=");
877 builder.append(eventInfo.x);
878 builder.append(", y=");
879 builder.append(eventInfo.y);
880 return builder.toString();
881 }
Michael Chan49701592010-06-30 11:04:03 -0700882}