Fix upsync of exceptions in EAS 2.5 (Exchange 2003)

* Apparently, Exchange 2003 doesn't like to see Visibility set in
  Exceptions
* Apparently, Exchange 2003 likes to see Exception Deleted and
  ExceptionStartTime prior to other data
* The word "apparently" is used above to indicate that these
  findings are not part of any specification, but have been
  determined empirically

Bug: 2775885
Change-Id: I163f156675f65c494a59d5233b2b6e23b3f1d6a0
This commit is contained in:
Marc Blank 2010-10-08 10:55:23 -07:00
parent 30c99e0dc3
commit a0692b16e1

View File

@ -1441,6 +1441,45 @@ public class CalendarSyncAdapter extends AbstractSyncAdapter {
} }
} }
// NOTE: Exchange 2003 (EAS 2.5) seems to require the "exception deleted" and "exception
// start time" data before other data in exceptions. Failure to do so results in a
// status 6 error during sync
if (isException) {
// Send exception deleted flag if necessary
Integer deleted = entityValues.getAsInteger(Calendar.EventsColumns.DELETED);
boolean isDeleted = deleted != null && deleted == 1;
Integer eventStatus = entityValues.getAsInteger(Events.STATUS);
boolean isCanceled = eventStatus != null && eventStatus.equals(Events.STATUS_CANCELED);
if (isDeleted || isCanceled) {
s.data(Tags.CALENDAR_EXCEPTION_IS_DELETED, "1");
// If we're deleted, the UI will continue to show this exception until we mark
// it canceled, so we'll do that here...
if (isDeleted && !isCanceled) {
long eventId = entityValues.getAsLong(Events._ID);
ContentValues cv = new ContentValues();
cv.put(Events.STATUS, Events.STATUS_CANCELED);
mService.mContentResolver.update(
ContentUris.withAppendedId(EVENTS_URI, eventId), cv, null, null);
}
} else {
s.data(Tags.CALENDAR_EXCEPTION_IS_DELETED, "0");
}
// TODO Add reminders to exceptions (allow them to be specified!)
Long originalTime = entityValues.getAsLong(Events.ORIGINAL_INSTANCE_TIME);
if (originalTime != null) {
if (allDay) {
// For all day events, we need our local all-day time
originalTime =
CalendarUtilities.getLocalAllDayCalendarTime(originalTime, mLocalTimeZone);
}
s.data(Tags.CALENDAR_EXCEPTION_START_TIME,
CalendarUtilities.millisToEasDateTime(originalTime));
} else {
// Illegal; what should we do?
}
}
// Get the event's time zone // Get the event's time zone
String timeZoneName = String timeZoneName =
entityValues.getAsString(allDay ? EVENT_TIMEZONE2_COLUMN : Events.EVENT_TIMEZONE); entityValues.getAsString(allDay ? EVENT_TIMEZONE2_COLUMN : Events.EVENT_TIMEZONE);
@ -1499,14 +1538,6 @@ public class CalendarSyncAdapter extends AbstractSyncAdapter {
} }
s.writeStringValue(entityValues, Events.TITLE, Tags.CALENDAR_SUBJECT); s.writeStringValue(entityValues, Events.TITLE, Tags.CALENDAR_SUBJECT);
Integer visibility = entityValues.getAsInteger(Events.VISIBILITY);
if (visibility != null) {
s.data(Tags.CALENDAR_SENSITIVITY, decodeVisibility(visibility));
} else {
// Default to private if not set
s.data(Tags.CALENDAR_SENSITIVITY, "1");
}
String desc = entityValues.getAsString(Events.DESCRIPTION); String desc = entityValues.getAsString(Events.DESCRIPTION);
if (desc != null && desc.length() > 0) { if (desc != null && desc.length() > 0) {
if (version >= Eas.SUPPORTED_PROTOCOL_EX2007_DOUBLE) { if (version >= Eas.SUPPORTED_PROTOCOL_EX2007_DOUBLE) {
@ -1656,37 +1687,15 @@ public class CalendarSyncAdapter extends AbstractSyncAdapter {
organizerName != null) { organizerName != null) {
s.data(Tags.CALENDAR_ORGANIZER_NAME, organizerName); s.data(Tags.CALENDAR_ORGANIZER_NAME, organizerName);
} }
} else {
// TODO Add reminders to exceptions (allow them to be specified!)
Long originalTime = entityValues.getAsLong(Events.ORIGINAL_INSTANCE_TIME);
if (originalTime != null) {
if (allDay) {
// For all day events, we need our local all-day time
originalTime =
CalendarUtilities.getLocalAllDayCalendarTime(originalTime, mLocalTimeZone);
}
s.data(Tags.CALENDAR_EXCEPTION_START_TIME,
CalendarUtilities.millisToEasDateTime(originalTime));
} else {
// Illegal; what should we do?
}
// Send exception deleted flag if necessary // NOTE: Sensitivity must NOT be sent to the server for exceptions in Exchange 2003
Integer deleted = entityValues.getAsInteger(Calendar.EventsColumns.DELETED); // The result will be a status 6 failure during sync
boolean isDeleted = deleted != null && deleted == 1; Integer visibility = entityValues.getAsInteger(Events.VISIBILITY);
Integer eventStatus = entityValues.getAsInteger(Events.STATUS); if (visibility != null) {
boolean isCanceled = eventStatus != null && eventStatus.equals(Events.STATUS_CANCELED); s.data(Tags.CALENDAR_SENSITIVITY, decodeVisibility(visibility));
if (isDeleted || isCanceled) { } else {
s.data(Tags.CALENDAR_EXCEPTION_IS_DELETED, "1"); // Default to private if not set
// If we're deleted, the UI will continue to show this exception until we mark s.data(Tags.CALENDAR_SENSITIVITY, "1");
// it canceled, so we'll do that here...
if (isDeleted && !isCanceled) {
long eventId = entityValues.getAsLong(Events._ID);
ContentValues cv = new ContentValues();
cv.put(Events.STATUS, Events.STATUS_CANCELED);
mService.mContentResolver.update(
ContentUris.withAppendedId(EVENTS_URI, eventId), cv, null, null);
}
} }
} }
} }