Event.java revision 98ab9de2fa5ad8dfd37faa6593dc66fa426d8960
1146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project/*
2146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project *
4146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * you may not use this file except in compliance with the License.
6146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * You may obtain a copy of the License at
7146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project *
8146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project *
10146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * See the License for the specific language governing permissions and
14146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * limitations under the License.
15146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project */
16146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
17146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectpackage com.android.calendar;
18146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
19146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.content.Context;
20146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.content.SharedPreferences;
21146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.content.res.Resources;
22146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.database.Cursor;
23146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.os.Debug;
24146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.preference.PreferenceManager;
25146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.provider.Calendar.Attendees;
26146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.provider.Calendar.Instances;
27146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.text.TextUtils;
28146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.text.format.DateUtils;
29146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.text.format.Time;
30146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.util.Log;
31146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
32146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport java.util.ArrayList;
33146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport java.util.Iterator;
34146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport java.util.concurrent.atomic.AtomicInteger;
35146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
36146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project// TODO: should Event be Parcelable so it can be passed via Intents?
37146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectpublic class Event implements Comparable, Cloneable {
38146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
39146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static final boolean PROFILE = false;
40146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
41146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static final String[] PROJECTION = new String[] {
42146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            Instances.TITLE,                 // 0
43146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            Instances.EVENT_LOCATION,        // 1
44146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            Instances.ALL_DAY,               // 2
45146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            Instances.COLOR,                 // 3
46146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            Instances.EVENT_TIMEZONE,        // 4
47146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            Instances.EVENT_ID,              // 5
48146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            Instances.BEGIN,                 // 6
49146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            Instances.END,                   // 7
50146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            Instances._ID,                   // 8
51146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            Instances.START_DAY,             // 9
52146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            Instances.END_DAY,               // 10
53146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            Instances.START_MINUTE,          // 11
54146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            Instances.END_MINUTE,            // 12
55146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            Instances.HAS_ALARM,             // 13
56146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            Instances.RRULE,                 // 14
57146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            Instances.RDATE,                 // 15
58146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            Instances.SELF_ATTENDEE_STATUS,  // 16
59146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    };
60146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
61146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    // The indices for the projection array above.
62146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static final int PROJECTION_TITLE_INDEX = 0;
63146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static final int PROJECTION_LOCATION_INDEX = 1;
64146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static final int PROJECTION_ALL_DAY_INDEX = 2;
65146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static final int PROJECTION_COLOR_INDEX = 3;
66146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static final int PROJECTION_TIMEZONE_INDEX = 4;
67146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static final int PROJECTION_EVENT_ID_INDEX = 5;
68146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static final int PROJECTION_BEGIN_INDEX = 6;
69146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static final int PROJECTION_END_INDEX = 7;
70146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static final int PROJECTION_START_DAY_INDEX = 9;
71146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static final int PROJECTION_END_DAY_INDEX = 10;
72146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static final int PROJECTION_START_MINUTE_INDEX = 11;
73146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static final int PROJECTION_END_MINUTE_INDEX = 12;
74146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static final int PROJECTION_HAS_ALARM_INDEX = 13;
75146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static final int PROJECTION_RRULE_INDEX = 14;
76146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static final int PROJECTION_RDATE_INDEX = 15;
77146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static final int PROJECTION_SELF_ATTENDEE_STATUS_INDEX = 16;
78146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
79146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public long id;
80146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public int color;
81146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public CharSequence title;
82146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public CharSequence location;
83146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public boolean allDay;
84146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
85146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public int startDay;       // start Julian day
86146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public int endDay;         // end Julian day
87146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public int startTime;      // Start and end time are in minutes since midnight
88146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public int endTime;
89146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
90146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public long startMillis;   // UTC milliseconds since the epoch
91146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public long endMillis;     // UTC milliseconds since the epoch
92146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private int mColumn;
93146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private int mMaxColumns;
94146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
95146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public boolean hasAlarm;
96146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public boolean isRepeating;
97146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
98146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public int selfAttendeeStatus;
99146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
100146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    // The coordinates of the event rectangle drawn on the screen.
101146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public float left;
102146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public float right;
103146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public float top;
104146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public float bottom;
105146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
106146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    // These 4 fields are used for navigating among events within the selected
107146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    // hour in the Day and Week view.
108146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public Event nextRight;
109146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public Event nextLeft;
110146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public Event nextUp;
111146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public Event nextDown;
112146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
113146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static final int MIDNIGHT_IN_MINUTES = 24 * 60;
114146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
115146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    @Override
11698ab9de2fa5ad8dfd37faa6593dc66fa426d8960Michael Chan    public final Object clone() throws CloneNotSupportedException {
11798ab9de2fa5ad8dfd37faa6593dc66fa426d8960Michael Chan        super.clone();
118146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        Event e = new Event();
119146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
120146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.title = title;
121146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.color = color;
122146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.location = location;
123146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.allDay = allDay;
124146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.startDay = startDay;
125146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.endDay = endDay;
126146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.startTime = startTime;
127146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.endTime = endTime;
128146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.startMillis = startMillis;
129146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.endMillis = endMillis;
130146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.hasAlarm = hasAlarm;
131146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.isRepeating = isRepeating;
132146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.selfAttendeeStatus = selfAttendeeStatus;
133146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
134146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        return e;
135146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
136146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
137146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public final void copyTo(Event dest) {
138146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        dest.id = id;
139146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        dest.title = title;
140146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        dest.color = color;
141146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        dest.location = location;
142146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        dest.allDay = allDay;
143146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        dest.startDay = startDay;
144146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        dest.endDay = endDay;
145146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        dest.startTime = startTime;
146146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        dest.endTime = endTime;
147146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        dest.startMillis = startMillis;
148146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        dest.endMillis = endMillis;
149146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        dest.hasAlarm = hasAlarm;
150146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        dest.isRepeating = isRepeating;
151146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        dest.selfAttendeeStatus = selfAttendeeStatus;
152146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
153146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
154146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public static final Event newInstance() {
155146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        Event e = new Event();
156146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
157146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.id = 0;
158146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.title = null;
159146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.color = 0;
160146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.location = null;
161146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.allDay = false;
162146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.startDay = 0;
163146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.endDay = 0;
164146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.startTime = 0;
165146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.endTime = 0;
166146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.startMillis = 0;
167146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.endMillis = 0;
168146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.hasAlarm = false;
169146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.isRepeating = false;
170146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        e.selfAttendeeStatus = Attendees.ATTENDEE_STATUS_NONE;
171146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
172146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        return e;
173146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
174146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
175146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    /**
176146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * Compares this event to the given event.  This is just used for checking
177146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * if two events differ.  It's not used for sorting anymore.
178146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     */
179146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public final int compareTo(Object obj) {
180146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        Event e = (Event) obj;
181146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
182146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        // The earlier start day and time comes first
183146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (startDay < e.startDay) return -1;
184146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (startDay > e.startDay) return 1;
185146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (startTime < e.startTime) return -1;
186146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (startTime > e.startTime) return 1;
187146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
188146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        // The later end time comes first (in order to put long strips on
189146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        // the left).
190146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (endDay < e.endDay) return 1;
191146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (endDay > e.endDay) return -1;
192146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (endTime < e.endTime) return 1;
193146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (endTime > e.endTime) return -1;
194146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
195146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        // Sort all-day events before normal events.
196146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (allDay && !e.allDay) return -1;
197146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (!allDay && e.allDay) return 1;
198146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
199146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        // If two events have the same time range, then sort them in
200146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        // alphabetical order based on their titles.
201146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        int cmp = compareStrings(title, e.title);
202146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (cmp != 0) {
203146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            return cmp;
204146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
205146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
206146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        // If the titles are the same then compare the other fields
207146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        // so that we can use this function to check for differences
208146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        // between events.
209146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        cmp = compareStrings(location, e.location);
210146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (cmp != 0) {
211146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            return cmp;
212146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
213146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        return 0;
214146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
215146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
216146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    /**
217146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * Compare string a with string b, but if either string is null,
218146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * then treat it (the null) as if it were the empty string ("").
219146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     *
220146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * @param a the first string
221146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * @param b the second string
222146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * @return the result of comparing a with b after replacing null
223146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     *  strings with "".
224146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     */
225146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private int compareStrings(CharSequence a, CharSequence b) {
226146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        String aStr, bStr;
227146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (a != null) {
228146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            aStr = a.toString();
229146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        } else {
230146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            aStr = "";
231146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
232146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (b != null) {
233146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            bStr = b.toString();
234146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        } else {
235146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            bStr = "";
236146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
237146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        return aStr.compareTo(bStr);
238146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
239146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
240146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    /**
241146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * Loads <i>days</i> days worth of instances starting at <i>start</i>.
242146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     */
243146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public static void loadEvents(Context context, ArrayList<Event> events,
244146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            long start, int days, int requestId, AtomicInteger sequenceNumber) {
245146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
246146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (PROFILE) {
247146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            Debug.startMethodTracing("loadEvents");
248146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
249146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
250146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        Cursor c = null;
251146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
252146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        events.clear();
253146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        try {
254146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            Time local = new Time();
255146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            int count;
256146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
257146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            local.set(start);
258146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            int startDay = Time.getJulianDay(start, local.gmtoff);
259146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            int endDay = startDay + days;
260146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
261146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            local.monthDay += days;
262146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            long end = local.normalize(true /* ignore isDst */);
263146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
264146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // Widen the time range that we query by one day on each end
265146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // so that we can catch all-day events.  All-day events are
266146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // stored starting at midnight in UTC but should be included
267146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // in the list of events starting at midnight local time.
268146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // This may fetch more events than we actually want, so we
269146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // filter them out below.
270146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            //
271146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // The sort order is: events with an earlier start time occur
272146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // first and if the start times are the same, then events with
273146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // a later end time occur first. The later end time is ordered
274146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // first so that long rectangles in the calendar views appear on
275146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // the left side.  If the start and end times of two events are
276146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // the same then we sort alphabetically on the title.  This isn't
277146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // required for correctness, it just adds a nice touch.
278146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
279146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            String orderBy = Instances.SORT_CALENDAR_VIEW;
280146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
281146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // Respect the preference to show/hide declined events
282146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
283146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            boolean hideDeclined = prefs.getBoolean(CalendarPreferenceActivity.KEY_HIDE_DECLINED,
284146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                    false);
285146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
286146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            String where = null;
287146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            if (hideDeclined) {
288146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                where = Instances.SELF_ATTENDEE_STATUS + "!=" + Attendees.ATTENDEE_STATUS_DECLINED;
289146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            }
290146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
291146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            c = Instances.query(context.getContentResolver(), PROJECTION,
292146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                    start - DateUtils.DAY_IN_MILLIS, end + DateUtils.DAY_IN_MILLIS, where, orderBy);
293146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
294146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            if (c == null) {
295146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                Log.e("Cal", "loadEvents() returned null cursor!");
296146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                return;
297146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            }
298146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
299146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // Check if we should return early because there are more recent
300146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // load requests waiting.
301146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            if (requestId != sequenceNumber.get()) {
302146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                return;
303146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            }
304146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
305146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            count = c.getCount();
306146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
307146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            if (count == 0) {
308146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                return;
309146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            }
310146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
311146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            Resources res = context.getResources();
312146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            while (c.moveToNext()) {
313146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                Event e = new Event();
314146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
315146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                e.id = c.getLong(PROJECTION_EVENT_ID_INDEX);
316146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                e.title = c.getString(PROJECTION_TITLE_INDEX);
317146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                e.location = c.getString(PROJECTION_LOCATION_INDEX);
318146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                e.allDay = c.getInt(PROJECTION_ALL_DAY_INDEX) != 0;
319146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                String timezone = c.getString(PROJECTION_TIMEZONE_INDEX);
320146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
321146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                if (e.title == null || e.title.length() == 0) {
322146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                    e.title = res.getString(R.string.no_title_label);
323146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                }
324146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
325146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                if (!c.isNull(PROJECTION_COLOR_INDEX)) {
326146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                    // Read the color from the database
327146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                    e.color = c.getInt(PROJECTION_COLOR_INDEX);
328146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                } else {
329146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                    e.color = res.getColor(R.color.event_center);
330146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                }
331146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
332146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                long eStart = c.getLong(PROJECTION_BEGIN_INDEX);
333146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                long eEnd = c.getLong(PROJECTION_END_INDEX);
334146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
335146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                e.startMillis = eStart;
336146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                e.startTime = c.getInt(PROJECTION_START_MINUTE_INDEX);
337146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                e.startDay = c.getInt(PROJECTION_START_DAY_INDEX);
338146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
339146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                e.endMillis = eEnd;
340146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                e.endTime = c.getInt(PROJECTION_END_MINUTE_INDEX);
341146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                e.endDay = c.getInt(PROJECTION_END_DAY_INDEX);
342146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
343146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                if (e.startDay > endDay || e.endDay < startDay) {
344146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                    continue;
345146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                }
346146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
347146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                e.hasAlarm = c.getInt(PROJECTION_HAS_ALARM_INDEX) != 0;
348146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
349146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                // Check if this is a repeating event
350146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                String rrule = c.getString(PROJECTION_RRULE_INDEX);
351146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                String rdate = c.getString(PROJECTION_RDATE_INDEX);
352146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                if (!TextUtils.isEmpty(rrule) || !TextUtils.isEmpty(rdate)) {
353146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                    e.isRepeating = true;
354146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                } else {
355146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                    e.isRepeating = false;
356146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                }
357146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
358146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                e.selfAttendeeStatus = c.getInt(PROJECTION_SELF_ATTENDEE_STATUS_INDEX);
359146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
360146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                events.add(e);
361146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            }
362146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
363146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            computePositions(events);
364146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        } finally {
365146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            if (c != null) {
366146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                c.close();
367146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            }
368146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            if (PROFILE) {
369146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                Debug.stopMethodTracing();
370146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            }
371146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
372146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
373146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
374146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    /**
375146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * Computes a position for each event.  Each event is displayed
376146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * as a non-overlapping rectangle.  For normal events, these rectangles
377146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * are displayed in separate columns in the week view and day view.  For
378146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * all-day events, these rectangles are displayed in separate rows along
379146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * the top.  In both cases, each event is assigned two numbers: N, and
380146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * Max, that specify that this event is the Nth event of Max number of
381146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * events that are displayed in a group. The width and position of each
382146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * rectangle depend on the maximum number of rectangles that occur at
383146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * the same time.
384146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     *
385146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * @param eventsList the list of events, sorted into increasing time order
386146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     */
387146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    static void computePositions(ArrayList<Event> eventsList) {
388146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (eventsList == null)
389146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            return;
390146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
391146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        // Compute the column positions separately for the all-day events
392146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        doComputePositions(eventsList, false);
393146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        doComputePositions(eventsList, true);
394146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
395146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
396146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static void doComputePositions(ArrayList<Event> eventsList,
397146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            boolean doAllDayEvents) {
398146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        ArrayList<Event> activeList = new ArrayList<Event>();
399146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        ArrayList<Event> groupList = new ArrayList<Event>();
400146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
401146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        long colMask = 0;
402146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        int maxCols = 0;
403146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        for (Event event : eventsList) {
404146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // Process all-day events separately
405146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            if (event.allDay != doAllDayEvents)
406146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                continue;
407146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
408146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            long start = event.getStartMillis();
409146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            if (false && event.allDay) {
410146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                Event e = event;
411146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                Log.i("Cal", "event start,end day: " + e.startDay + "," + e.endDay
412146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                        + " start,end time: " + e.startTime + "," + e.endTime
413146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                        + " start,end millis: " + e.getStartMillis() + "," + e.getEndMillis()
414146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                        + " "  + e.title);
415146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            }
416146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
417146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // Remove the inactive events. An event on the active list
418146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // becomes inactive when its end time is less than or equal to
419146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // the current event's start time.
420146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            Iterator<Event> iter = activeList.iterator();
421146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            while (iter.hasNext()) {
422146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                Event active = iter.next();
423146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                if (active.getEndMillis() <= start) {
424146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                    if (false && event.allDay) {
425146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                        Event e = active;
426146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                        Log.i("Cal", "  removing: start,end day: " + e.startDay + "," + e.endDay
427146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                                + " start,end time: " + e.startTime + "," + e.endTime
428146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                                + " start,end millis: " + e.getStartMillis() + "," + e.getEndMillis()
429146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                                + " "  + e.title);
430146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                    }
431146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                    colMask &= ~(1L << active.getColumn());
432146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                    iter.remove();
433146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                }
434146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            }
435146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
436146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // If the active list is empty, then reset the max columns, clear
437146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // the column bit mask, and empty the groupList.
438146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            if (activeList.isEmpty()) {
439146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                for (Event ev : groupList) {
440146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                    ev.setMaxColumns(maxCols);
441146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                }
442146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                maxCols = 0;
443146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                colMask = 0;
444146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                groupList.clear();
445146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            }
446146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
447146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // Find the first empty column.  Empty columns are represented by
448146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // zero bits in the column mask "colMask".
449146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            int col = findFirstZeroBit(colMask);
450146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            if (col == 64)
451146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                col = 63;
452146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            colMask |= (1L << col);
453146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            event.setColumn(col);
454146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            activeList.add(event);
455146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            groupList.add(event);
456146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            int len = activeList.size();
457146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            if (maxCols < len)
458146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                maxCols = len;
459146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
460146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        for (Event ev : groupList) {
461146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            ev.setMaxColumns(maxCols);
462146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
463146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
464146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
465146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public static int findFirstZeroBit(long val) {
466146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        for (int ii = 0; ii < 64; ++ii) {
467146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            if ((val & (1L << ii)) == 0)
468146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                return ii;
469146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
470146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        return 64;
471146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
472146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
473146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    /**
474146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * Returns a darker version of the given color.  It does this by dividing
475146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * each of the red, green, and blue components by 2.  The alpha value is
476146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * preserved.
477146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     */
478146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static final int getDarkerColor(int color) {
479146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        int darker = (color >> 1) & 0x007f7f7f;
480146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        int alpha = color & 0xff000000;
481146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        return alpha | darker;
482146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
483146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
484146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    // For testing. This method can be removed at any time.
485146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static ArrayList<Event> createTestEventList() {
486146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        ArrayList<Event> evList = new ArrayList<Event>();
487146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        createTestEvent(evList, 1, 5, 10);
488146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        createTestEvent(evList, 2, 5, 10);
489146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        createTestEvent(evList, 3, 15, 20);
490146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        createTestEvent(evList, 4, 20, 25);
491146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        createTestEvent(evList, 5, 30, 70);
492146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        createTestEvent(evList, 6, 32, 40);
493146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        createTestEvent(evList, 7, 32, 40);
494146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        createTestEvent(evList, 8, 34, 38);
495146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        createTestEvent(evList, 9, 34, 38);
496146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        createTestEvent(evList, 10, 42, 50);
497146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        createTestEvent(evList, 11, 45, 60);
498146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        createTestEvent(evList, 12, 55, 90);
499146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        createTestEvent(evList, 13, 65, 75);
500146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
501146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        createTestEvent(evList, 21, 105, 130);
502146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        createTestEvent(evList, 22, 110, 120);
503146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        createTestEvent(evList, 23, 115, 130);
504146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        createTestEvent(evList, 24, 125, 140);
505146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        createTestEvent(evList, 25, 127, 135);
506146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
507146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        createTestEvent(evList, 31, 150, 160);
508146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        createTestEvent(evList, 32, 152, 162);
509146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        createTestEvent(evList, 33, 153, 163);
510146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        createTestEvent(evList, 34, 155, 170);
511146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        createTestEvent(evList, 35, 158, 175);
512146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        createTestEvent(evList, 36, 165, 180);
513146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
514146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        return evList;
515146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
516146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
517146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    // For testing. This method can be removed at any time.
518146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static Event createTestEvent(ArrayList<Event> evList, int id,
519146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            int startMinute, int endMinute) {
520146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        Event ev = new Event();
521146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        ev.title = "ev" + id;
522146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        ev.startDay = 1;
523146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        ev.endDay = 1;
524146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        ev.setStartMillis(startMinute);
525146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        ev.setEndMillis(endMinute);
526146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        evList.add(ev);
527146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        return ev;
528146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
529146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
530146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public final void dump() {
531146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        Log.e("Cal", "+-----------------------------------------+");
532146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        Log.e("Cal", "+        id = " + id);
533146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        Log.e("Cal", "+     color = " + color);
534146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        Log.e("Cal", "+     title = " + title);
535146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        Log.e("Cal", "+  location = " + location);
536146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        Log.e("Cal", "+    allDay = " + allDay);
537146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        Log.e("Cal", "+  startDay = " + startDay);
538146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        Log.e("Cal", "+    endDay = " + endDay);
539146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        Log.e("Cal", "+ startTime = " + startTime);
540146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        Log.e("Cal", "+   endTime = " + endTime);
541146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
542146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
543146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public final boolean intersects(int julianDay, int startMinute,
544146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            int endMinute) {
545146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (endDay < julianDay) {
546146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            return false;
547146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
548146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
549146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (startDay > julianDay) {
550146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            return false;
551146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
552146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
553146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (endDay == julianDay) {
554146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            if (endTime < startMinute) {
555146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                return false;
556146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            }
557146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // An event that ends at the start minute should not be considered
558146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // as intersecting the given time span, but don't exclude
559146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // zero-length (or very short) events.
560146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            if (endTime == startMinute
561146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                    && (startTime != endTime || startDay != endDay)) {
562146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                return false;
563146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            }
564146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
565146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
566146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (startDay == julianDay && startTime > endMinute) {
567146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            return false;
568146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
569146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
570146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        return true;
571146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
572146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
573146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    /**
574146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * Returns the event title and location separated by a comma.  If the
575146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * location is already part of the title (at the end of the title), then
576146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * just the title is returned.
577146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     *
578146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * @return the event title and location as a String
579146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     */
580146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public String getTitleAndLocation() {
581146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        String text = title.toString();
582146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
583146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        // Append the location to the title, unless the title ends with the
584146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        // location (for example, "meeting in building 42" ends with the
585146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        // location).
586146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (location != null) {
587146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            String locationString = location.toString();
588146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            if (!text.endsWith(locationString)) {
589146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                text += ", " + locationString;
590146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            }
591146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
592146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        return text;
593146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
594146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
595146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public void setColumn(int column) {
596146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        mColumn = column;
597146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
598146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
599146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public int getColumn() {
600146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        return mColumn;
601146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
602146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
603146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public void setMaxColumns(int maxColumns) {
604146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        mMaxColumns = maxColumns;
605146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
606146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
607146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public int getMaxColumns() {
608146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        return mMaxColumns;
609146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
610146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
611146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public void setStartMillis(long startMillis) {
612146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        this.startMillis = startMillis;
613146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
614146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
615146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public long getStartMillis() {
616146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        return startMillis;
617146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
618146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
619146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public void setEndMillis(long endMillis) {
620146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        this.endMillis = endMillis;
621146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
622146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
623146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public long getEndMillis() {
624146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        return endMillis;
625146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
626146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project}
627