136219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens/*
236219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens * Copyright (C) 2009 The Android Open Source Project
336219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens *
436219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens * Licensed under the Apache License, Version 2.0 (the "License");
536219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens * you may not use this file except in compliance with the License.
636219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens * You may obtain a copy of the License at
736219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens *
836219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens *      http://www.apache.org/licenses/LICENSE-2.0
936219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens *
1036219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens * Unless required by applicable law or agreed to in writing, software
1136219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens * distributed under the License is distributed on an "AS IS" BASIS,
1236219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1336219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens * See the License for the specific language governing permissions and
1436219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens * limitations under the License.
1536219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens */
1636219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens
1736219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephenspackage com.android.providers.calendar;
1836219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens
195b13ed3cd9373fc384fdce2d1c358dad61128954Omari Stephensimport android.accounts.Account;
205b13ed3cd9373fc384fdce2d1c358dad61128954Omari Stephensimport android.accounts.AccountManager;
2136219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephensimport android.content.ContentResolver;
2236219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephensimport android.content.ContentUris;
2336219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephensimport android.content.ContentValues;
2436219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephensimport android.content.Context;
2536219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephensimport android.database.Cursor;
2636219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephensimport android.net.Uri;
2736219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephensimport android.os.SystemClock;
28b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErikimport android.provider.CalendarContract;
2936219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephensimport android.test.SyncBaseInstrumentation;
305b13ed3cd9373fc384fdce2d1c358dad61128954Omari Stephensimport android.text.format.DateUtils;
315b13ed3cd9373fc384fdce2d1c358dad61128954Omari Stephensimport android.text.format.Time;
3236219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephensimport android.util.Log;
335b13ed3cd9373fc384fdce2d1c358dad61128954Omari Stephens
3436219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephensimport com.google.android.collect.Maps;
3536219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens
3636219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephensimport java.util.HashSet;
3736219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephensimport java.util.Map;
3836219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephensimport java.util.Set;
3936219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens
4036219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephenspublic class CalendarSyncTestingBase extends SyncBaseInstrumentation {
415b13ed3cd9373fc384fdce2d1c358dad61128954Omari Stephens    protected AccountManager mAccountManager;
4236219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    protected Context mTargetContext;
4336219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    protected String mAccount;
4436219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    protected ContentResolver mResolver;
45b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik    protected Uri mEventsUri = CalendarContract.Events.CONTENT_URI;
4636219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens
4736219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    static final String TAG = "calendar";
4836219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    static final String DEFAULT_TIMEZONE = "America/Los_Angeles";
4936219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    static final Set<String> EVENT_COLUMNS_TO_SKIP = new HashSet<String>();
5036219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    static final Set<String> ATTENDEES_COLUMNS_TO_SKIP = new HashSet<String>();
5136219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    static final Set<String> CALENDARS_COLUMNS_TO_SKIP = new HashSet<String>();
5236219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    static final Set<String> INSTANCES_COLUMNS_TO_SKIP = new HashSet<String>();
5336219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens
5436219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    static {
55b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik        EVENT_COLUMNS_TO_SKIP.add(CalendarContract.Events._ID);
56b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik        EVENT_COLUMNS_TO_SKIP.add(CalendarContract.Events.SYNC_DATA5);
57b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik        EVENT_COLUMNS_TO_SKIP.add(CalendarContract.Events.SYNC_DATA4);
58b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik        EVENT_COLUMNS_TO_SKIP.add(CalendarContract.Events.SYNC_DATA2);
59b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik        EVENT_COLUMNS_TO_SKIP.add(CalendarContract.Events.DIRTY);
60b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik        EVENT_COLUMNS_TO_SKIP.add(CalendarContract.Events.SYNC_DATA8);
61b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik        ATTENDEES_COLUMNS_TO_SKIP.add(CalendarContract.Attendees._ID);
62b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik        CALENDARS_COLUMNS_TO_SKIP.add(CalendarContract.Calendars._ID);
63b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik        CALENDARS_COLUMNS_TO_SKIP.add(CalendarContract.Calendars.CAL_SYNC8);
64b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik        CALENDARS_COLUMNS_TO_SKIP.add(CalendarContract.Calendars.CAL_SYNC7);
65b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik        CALENDARS_COLUMNS_TO_SKIP.add(CalendarContract.Calendars.DIRTY);
66b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik        CALENDARS_COLUMNS_TO_SKIP.add(CalendarContract.Calendars.CAL_SYNC6);
67b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik        INSTANCES_COLUMNS_TO_SKIP.add(CalendarContract.Instances._ID);
6836219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    }
6936219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens
7036219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    @Override
7136219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    protected void setUp() throws Exception {
7236219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        super.setUp();
7336219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        mTargetContext = getInstrumentation().getTargetContext();
745b13ed3cd9373fc384fdce2d1c358dad61128954Omari Stephens
755b13ed3cd9373fc384fdce2d1c358dad61128954Omari Stephens        mAccountManager = AccountManager.get(mTargetContext);
7636219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        mAccount = getAccount();
7736219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        mResolver = mTargetContext.getContentResolver();
7836219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    }
7936219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens
8036219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    /**
8136219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     * A simple method that syncs the calendar provider.
8236219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     * @throws Exception
8336219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     */
8436219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    protected void syncCalendar() throws Exception {
8536219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        cancelSyncsandDisableAutoSync();
86b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik        syncProvider(CalendarContract.CONTENT_URI, mAccount, CalendarContract.AUTHORITY);
8736219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    }
8836219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens
8936219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    /**
9036219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     * Creates a new event in the default calendar.
9136219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     * @param event Event to be created.
9236219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     * @return Uri of the created event.
9336219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     * @throws Exception
9436219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     */
9536219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    protected Uri insertEvent(EventInfo event) throws Exception {
9636219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        return insertEvent(getDefaultCalendarId(), event);
9736219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    }
9836219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens
9936219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    /**
10036219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     * Creates a new event in the given calendarId.
10136219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     * @param calendarId Calendar to be used.
10236219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     * @param event Event to be created.
10336219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     * @return Uri of the event created.
10436219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     * @throws Exception
10536219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     */
10636219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    protected Uri insertEvent(int calendarId, EventInfo event) throws Exception{
10736219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        ContentValues m = new ContentValues();
108b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik        m.put(CalendarContract.Events.CALENDAR_ID, calendarId);
109b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik        m.put(CalendarContract.Events.TITLE, event.mTitle);
110b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik        m.put(CalendarContract.Events.DTSTART, event.mDtstart);
111b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik        m.put(CalendarContract.Events.ALL_DAY, event.mAllDay ? 1 : 0);
11236219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens
11336219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        if (event.mRrule == null) {
11436219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            // This is a normal event
115b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik            m.put(CalendarContract.Events.DTEND, event.mDtend);
11636219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        } else {
11736219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            // This is a repeating event
118b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik            m.put(CalendarContract.Events.RRULE, event.mRrule);
119b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik            m.put(CalendarContract.Events.DURATION, event.mDuration);
12036219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        }
12136219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens
12236219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        if (event.mDescription != null) {
123b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik            m.put(CalendarContract.Events.DESCRIPTION, event.mDescription);
12436219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        }
12536219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        if (event.mTimezone != null) {
126b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik            m.put(CalendarContract.Events.EVENT_TIMEZONE, event.mTimezone);
12736219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        }
12836219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens
12936219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        Uri url = mResolver.insert(mEventsUri, m);
13036219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        syncCalendar();
13136219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        return url;
13236219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    }
13336219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens
13436219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    /**
13536219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     * Edits the given event.
13636219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     * @param eventId EventID of the event to be edited.
13736219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     * @param event Edited event details.
13836219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     * @throws Exception
13936219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     */
14036219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    protected void editEvent(long eventId, EventInfo event) throws Exception {
14136219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        ContentValues values = new ContentValues();
142b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik        values.put(CalendarContract.Events.TITLE, event.mTitle);
143b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik        values.put(CalendarContract.Events.DTSTART, event.mDtstart);
144b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik        values.put(CalendarContract.Events.DTEND, event.mDtend);
145b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik        values.put(CalendarContract.Events.ALL_DAY, event.mAllDay ? 1 : 0);
14636219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens
14736219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        if (event.mDescription != null) {
148b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik            values.put(CalendarContract.Events.DESCRIPTION, event.mDescription);
14936219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        }
1505b13ed3cd9373fc384fdce2d1c358dad61128954Omari Stephens
151b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik        Uri uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventId);
15236219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        mResolver.update(uri, values, null, null);
15336219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        syncCalendar();
15436219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    }
15536219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens
15636219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    /**
15736219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     * Deletes a given event.
15836219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     * @param uri
15936219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     * @throws Exception
16036219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     */
16136219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    protected void deleteEvent(Uri uri) throws Exception {
16236219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        mResolver.delete(uri, null, null);
16336219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        syncCalendar();
16436219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    }
16536219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens
16636219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    /**
16736219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     * Inserts a new calendar.
16836219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     * @param name
16936219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     * @param timezone
17036219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     * @param calendarUrl
17136219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     * @throws Exception
17236219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     */
17336219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    protected void insertCalendar(String name, String timezone, String calendarUrl)
17436219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            throws Exception {
17536219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        ContentValues values = new ContentValues();
17636219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens
177b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik        values.put(CalendarContract.Calendars.ACCOUNT_NAME, getAccount());
178b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik        values.put(CalendarContract.Calendars.CAL_SYNC1, calendarUrl);
179b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik        values.put(CalendarContract.Calendars.NAME, name);
180b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik        values.put(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, name);
18136219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens
182b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik        values.put(CalendarContract.Calendars.SYNC_EVENTS, 1);
183b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik        values.put(CalendarContract.Calendars.VISIBLE, 1);
184b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik        values.put(CalendarContract.Calendars.CALENDAR_COLOR, -14069085 /* blue */);
185b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik        values.put(CalendarContract.Calendars.CALENDAR_ACCESS_LEVEL,
186b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik                CalendarContract.Calendars.CAL_ACCESS_OWNER);
18736219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens
188b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik        values.put(CalendarContract.Calendars.CALENDAR_COLOR, "0xff123456");
189b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik        values.put(CalendarContract.Calendars.CALENDAR_TIME_ZONE, timezone);
190b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik        mResolver.insert(CalendarContract.Calendars.CONTENT_URI, values);
19136219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        syncCalendar();
19236219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    }
19336219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens
19436219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    /**
19536219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     * Returns a fresh count of events.
19636219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     * @return
19736219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     */
19836219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    protected int getEventsCount() {
19936219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        Cursor cursor;
20036219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        cursor = mResolver.query(mEventsUri, null, null, null, null);
2015b13ed3cd9373fc384fdce2d1c358dad61128954Omari Stephens        return cursor.getCount();
20236219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    }
20336219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens
20436219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    /**
20536219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     * Returns the ID of the default calendar.
20636219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     * @return
20736219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     */
20836219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    protected int getDefaultCalendarId() {
20936219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        Cursor calendarsCursor;
210b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik        calendarsCursor = mResolver.query(CalendarContract.Calendars.CONTENT_URI, null, null, null,
211b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik                null);
21236219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        calendarsCursor.moveToNext();
2135b13ed3cd9373fc384fdce2d1c358dad61128954Omari Stephens        return calendarsCursor.getInt(calendarsCursor.getColumnIndex("_id"));
21436219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    }
21536219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens
21636219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    /**
21736219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     * This class stores all the useful information about an event.
21836219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     */
21936219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    protected class EventInfo {
22036219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        String mTitle;
22136219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        String mDescription;
22236219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        String mTimezone;
22336219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        boolean mAllDay;
22436219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        long mDtstart;
22536219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        long mDtend;
22636219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        String mRrule;
22736219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        String mDuration;
22836219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        String mOriginalTitle;
22936219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        long mOriginalInstance;
23036219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        int mSyncId;
23136219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens
23236219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        // Constructor for normal events, using the default timezone
23336219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        public EventInfo(String title, String startDate, String endDate,
23436219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens                boolean allDay) {
23536219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            init(title, startDate, endDate, allDay, DEFAULT_TIMEZONE);
23636219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        }
23736219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens
23836219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        public EventInfo(String title, long startDate, long endDate,
23936219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens                boolean allDay) {
24036219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            mTitle = title;
24136219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            mTimezone = DEFAULT_TIMEZONE;
24236219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            mDtstart = startDate;
24336219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            mDtend = endDate;
24436219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            mDuration = null;
24536219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            mRrule = null;
24636219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            mAllDay = allDay;
24736219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        }
24836219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens
24936219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        public EventInfo(String title, long startDate, long endDate,
25036219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens                boolean allDay, String description) {
25136219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            mTitle = title;
25236219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            mTimezone = DEFAULT_TIMEZONE;
25336219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            mDtstart = startDate;
25436219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            mDtend = endDate;
25536219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            mDuration = null;
25636219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            mRrule = null;
25736219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            mAllDay = allDay;
25836219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            mDescription = description;
25936219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        }
26036219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens
26136219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        // Constructor for normal events, specifying the timezone
26236219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        public EventInfo(String title, String startDate, String endDate,
26336219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens                boolean allDay, String timezone) {
26436219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            init(title, startDate, endDate, allDay, timezone);
26536219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        }
26636219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens
26736219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        public void init(String title, String startDate, String endDate,
26836219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens                boolean allDay, String timezone) {
26936219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            mTitle = title;
27036219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            Time time = new Time();
27136219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            if (allDay) {
27236219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens                time.timezone = Time.TIMEZONE_UTC;
27336219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            } else if (timezone != null) {
27436219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens                time.timezone = timezone;
27536219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            }
27636219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            mTimezone = time.timezone;
27736219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            time.parse3339(startDate);
27836219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            mDtstart = time.toMillis(false /* use isDst */);
27936219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            time.parse3339(endDate);
28036219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            mDtend = time.toMillis(false /* use isDst */);
28136219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            mDuration = null;
28236219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            mRrule = null;
28336219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            mAllDay = allDay;
28436219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        }
28536219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens
28636219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        // Constructor for repeating events, using the default timezone
28736219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        public EventInfo(String title, String description, String startDate, String endDate,
28836219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens                String rrule, boolean allDay) {
28936219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            init(title, description, startDate, endDate, rrule, allDay, DEFAULT_TIMEZONE);
29036219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        }
29136219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens
29236219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        // Constructor for repeating events, specifying the timezone
29336219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        public EventInfo(String title, String description, String startDate, String endDate,
29436219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens                String rrule, boolean allDay, String timezone) {
29536219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            init(title, description, startDate, endDate, rrule, allDay, timezone);
29636219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        }
29736219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens
29836219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        public void init(String title, String description, String startDate, String endDate,
29936219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens                String rrule, boolean allDay, String timezone) {
30036219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            mTitle = title;
30136219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            mDescription = description;
30236219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            Time time = new Time();
30336219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            if (allDay) {
30436219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens                time.timezone = Time.TIMEZONE_UTC;
30536219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            } else if (timezone != null) {
30636219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens                time.timezone = timezone;
30736219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            }
30836219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            mTimezone = time.timezone;
30936219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            time.parse3339(startDate);
31036219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            mDtstart = time.toMillis(false /* use isDst */);
31136219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            if (endDate != null) {
31236219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens                time.parse3339(endDate);
31336219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens                mDtend = time.toMillis(false /* use isDst */);
31436219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            }
31536219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            if (allDay) {
31636219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens                long days = 1;
31736219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens                if (endDate != null) {
31836219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens                    days = (mDtend - mDtstart) / DateUtils.DAY_IN_MILLIS;
31936219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens                }
32036219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens                mDuration = "P" + days + "D";
32136219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            } else {
32236219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens                long seconds = (mDtend - mDtstart) / DateUtils.SECOND_IN_MILLIS;
32336219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens                mDuration = "P" + seconds + "S";
32436219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            }
32536219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            mRrule = rrule;
32636219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            mAllDay = allDay;
32736219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        }
32836219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens
32936219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        // Constructor for recurrence exceptions, using the default timezone
33036219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        public EventInfo(String originalTitle, String originalInstance, String title,
33136219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens                String description, String startDate, String endDate, boolean allDay) {
33236219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            init(originalTitle, originalInstance,
33336219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens                    title, description, startDate, endDate, allDay, DEFAULT_TIMEZONE);
33436219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        }
33536219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens
33636219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        public void init(String originalTitle, String originalInstance,
33736219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens                String title, String description, String startDate, String endDate,
33836219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens                boolean allDay, String timezone) {
33936219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            mOriginalTitle = originalTitle;
34036219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            Time time = new Time(timezone);
34136219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            time.parse3339(originalInstance);
34236219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            mOriginalInstance = time.toMillis(false /* use isDst */);
34336219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            init(title, description, startDate, endDate, null /* rrule */, allDay, timezone);
34436219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        }
34536219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    }
34636219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens
34736219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    /**
34836219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     * Returns the default account on the device.
34936219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     * @return
35036219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     */
35136219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    protected String getAccount() {
352a5ef613c55f3bc68eeeafde67732e53ee229f40dChia-chi Yeh        Account[] accounts = mAccountManager.getAccountsByType("com.google");
3535b13ed3cd9373fc384fdce2d1c358dad61128954Omari Stephens
3545b13ed3cd9373fc384fdce2d1c358dad61128954Omari Stephens        assertTrue("Didn't find any Google accounts", accounts.length > 0);
3555b13ed3cd9373fc384fdce2d1c358dad61128954Omari Stephens
3565b13ed3cd9373fc384fdce2d1c358dad61128954Omari Stephens        Account account = accounts[accounts.length - 1];
3575b13ed3cd9373fc384fdce2d1c358dad61128954Omari Stephens        Log.v(TAG, "Found " + accounts.length + " accounts; using the last one, " + account.name);
3585b13ed3cd9373fc384fdce2d1c358dad61128954Omari Stephens        return account.name;
35936219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    }
36036219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens
36136219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    /**
36236219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     * Compares two cursors
36336219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens     */
36436219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    protected void compareCursors(Cursor cursor1, Cursor cursor2,
36536219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens                                  Set<String> columnsToSkip, String tableName) {
36636219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        String[] cols = cursor1.getColumnNames();
36736219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        int length = cols.length;
36836219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens
36936219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        assertEquals(tableName + " count failed to match", cursor1.getCount(),
37036219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens                cursor2.getCount());
37136219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        Map<String, String> row = Maps.newHashMap();
37236219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        while (cursor1.moveToNext() && cursor2.moveToNext()) {
37336219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            for (int i = 0; i < length; i++) {
37436219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens                String col = cols[i];
37536219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens                if (columnsToSkip != null && columnsToSkip.contains(col)) {
37636219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens                    continue;
37736219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens                }
37836219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens                row.put(col, cursor1.getString(i));
37936219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens
38036219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens                assertEquals("Row: " + row + " Table: " + tableName + ": " + cols[i] +
38136219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens                        " failed to match", cursor1.getString(i),
38236219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens                        cursor2.getString(i));
38336219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens            }
38436219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens        }
38536219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens    }
38636219115c4ba93dc934dfd9c92d56ef81be0340bOmari Stephens}
387