Fix #2422815 (Exception in EAS calendar upsync)

* Exception is due to the presence of values in ContentValues that
  are null (would normally expect those fields to be absent)
* Fix all relevant cases that might produce an NPE in this case

Bug: 2422815
Change-Id: I637a21307c2d518912edce093de90a06d94614e5
This commit is contained in:
Marc Blank 2010-02-05 11:59:22 -08:00
parent 4d2a701844
commit 204b7a3bf4
2 changed files with 44 additions and 59 deletions

View File

@ -990,36 +990,29 @@ public class CalendarSyncAdapter extends AbstractSyncAdapter {
s.data(Tags.CALENDAR_DTSTAMP, s.data(Tags.CALENDAR_DTSTAMP,
CalendarUtilities.millisToEasDateTime(System.currentTimeMillis())); CalendarUtilities.millisToEasDateTime(System.currentTimeMillis()));
if (entityValues.containsKey(Events.EVENT_LOCATION)) { s.writeStringValue(entityValues, Events.EVENT_LOCATION, Tags.CALENDAR_LOCATION);
s.data(Tags.CALENDAR_LOCATION, s.writeStringValue(entityValues, Events.TITLE, Tags.CALENDAR_SUBJECT);
entityValues.getAsString(Events.EVENT_LOCATION));
}
if (entityValues.containsKey(Events.TITLE)) {
s.data(Tags.CALENDAR_SUBJECT, entityValues.getAsString(Events.TITLE));
}
if (entityValues.containsKey(Events.VISIBILITY)) { Integer visibility = entityValues.getAsInteger(Events.VISIBILITY);
s.data(Tags.CALENDAR_SENSITIVITY, if (visibility != null) {
decodeVisibility(entityValues.getAsInteger(Events.VISIBILITY))); s.data(Tags.CALENDAR_SENSITIVITY, decodeVisibility(visibility));
} else { } else {
// Private if not set // Default to private if not set
s.data(Tags.CALENDAR_SENSITIVITY, "1"); s.data(Tags.CALENDAR_SENSITIVITY, "1");
} }
if (!isException) { if (!isException) {
// A time zone is required in all EAS events; we'll use the default if none // A time zone is required in all EAS events; we'll use the default if none is set
// is set. String timeZoneName = entityValues.getAsString(Events.EVENT_TIMEZONE);
String timeZoneName; if (timeZoneName == null) {
if (entityValues.containsKey(Events.EVENT_TIMEZONE)) {
timeZoneName = entityValues.getAsString(Events.EVENT_TIMEZONE);
} else {
timeZoneName = TimeZone.getDefault().getID(); timeZoneName = TimeZone.getDefault().getID();
} }
String x = CalendarUtilities.timeZoneToTziString(TimeZone.getTimeZone(timeZoneName)); String timeZone = CalendarUtilities.timeZoneToTziString(
s.data(Tags.CALENDAR_TIME_ZONE, x); TimeZone.getTimeZone(timeZoneName));
s.data(Tags.CALENDAR_TIME_ZONE, timeZone);
if (entityValues.containsKey(Events.DESCRIPTION)) {
String desc = entityValues.getAsString(Events.DESCRIPTION); String desc = entityValues.getAsString(Events.DESCRIPTION);
if (desc != null) {
if (mService.mProtocolVersionDouble >= 12.0) { if (mService.mProtocolVersionDouble >= 12.0) {
s.start(Tags.BASE_BODY); s.start(Tags.BASE_BODY);
s.data(Tags.BASE_TYPE, "1"); s.data(Tags.BASE_TYPE, "1");
@ -1030,14 +1023,11 @@ public class CalendarSyncAdapter extends AbstractSyncAdapter {
} }
} }
if (entityValues.containsKey(Events.ORGANIZER)) { s.writeStringValue(entityValues, Events.ORGANIZER, Tags.CALENDAR_ORGANIZER_EMAIL);
s.data(Tags.CALENDAR_ORGANIZER_EMAIL,
entityValues.getAsString(Events.ORGANIZER));
}
if (entityValues.containsKey(Events.RRULE)) { String rrule = entityValues.getAsString(Events.RRULE);
CalendarUtilities.recurrenceFromRrule( if (rrule != null) {
entityValues.getAsString(Events.RRULE), startTime, s); CalendarUtilities.recurrenceFromRrule(rrule, startTime, s);
} }
// Handle associated data EXCEPT for attendees, which have to be grouped // Handle associated data EXCEPT for attendees, which have to be grouped
@ -1046,17 +1036,16 @@ public class CalendarSyncAdapter extends AbstractSyncAdapter {
Uri ncvUri = ncv.uri; Uri ncvUri = ncv.uri;
ContentValues ncvValues = ncv.values; ContentValues ncvValues = ncv.values;
if (ncvUri.equals(ExtendedProperties.CONTENT_URI)) { if (ncvUri.equals(ExtendedProperties.CONTENT_URI)) {
if (ncvValues.containsKey("uid")) { String uid = ncvValues.getAsString("uid");
clientId = ncvValues.getAsString("uid"); if (uid != null) {
clientId = uid;
s.data(Tags.CALENDAR_UID, clientId); s.data(Tags.CALENDAR_UID, clientId);
} }
if (ncvValues.containsKey("dtstamp")) { s.writeStringValue(ncvValues, "dtstamp", Tags.CALENDAR_DTSTAMP);
s.data(Tags.CALENDAR_DTSTAMP, ncvValues.getAsString("dtstamp")); String categories = ncvValues.getAsString("categories");
} if (categories != null) {
if (ncvValues.containsKey("categories")) {
// Send all the categories back to the server // Send all the categories back to the server
// We've saved them as a String of delimited tokens // We've saved them as a String of delimited tokens
String categories = ncvValues.getAsString("categories");
StringTokenizer st = StringTokenizer st =
new StringTokenizer(categories, CATEGORY_TOKENIZER_DELIMITER); new StringTokenizer(categories, CATEGORY_TOKENIZER_DELIMITER);
if (st.countTokens() > 0) { if (st.countTokens() > 0) {
@ -1069,10 +1058,8 @@ public class CalendarSyncAdapter extends AbstractSyncAdapter {
} }
} }
} else if (ncvUri.equals(Reminders.CONTENT_URI)) { } else if (ncvUri.equals(Reminders.CONTENT_URI)) {
if (ncvValues.containsKey(Reminders.MINUTES)) { s.writeStringValue(ncvValues, Reminders.MINUTES,
s.data(Tags.CALENDAR_REMINDER_MINS_BEFORE, Tags.CALENDAR_REMINDER_MINS_BEFORE);
ncvValues.getAsString(Reminders.MINUTES));
}
} }
} }
@ -1087,17 +1074,11 @@ public class CalendarSyncAdapter extends AbstractSyncAdapter {
Uri ncvUri = ncv.uri; Uri ncvUri = ncv.uri;
ContentValues ncvValues = ncv.values; ContentValues ncvValues = ncv.values;
if (ncvUri.equals(Attendees.CONTENT_URI)) { if (ncvUri.equals(Attendees.CONTENT_URI)) {
if (ncvValues.containsKey(Attendees.ATTENDEE_RELATIONSHIP)) { Integer relationship = ncvValues.getAsInteger(Attendees.ATTENDEE_RELATIONSHIP);
int relationship = if (relationship != null) {
ncvValues.getAsInteger(Attendees.ATTENDEE_RELATIONSHIP);
// Organizer isn't among attendees in EAS // Organizer isn't among attendees in EAS
if (relationship == Attendees.RELATIONSHIP_ORGANIZER) { if (relationship == Attendees.RELATIONSHIP_ORGANIZER) {
if (ncvValues.containsKey(Attendees.ATTENDEE_NAME)) { organizerName = ncvValues.getAsString(Attendees.ATTENDEE_NAME);
// Remember this; we can't insert it into the stream in
// the middle of attendees
organizerName =
ncvValues.getAsString(Attendees.ATTENDEE_NAME);
}
continue; continue;
} }
if (!hasAttendees) { if (!hasAttendees) {
@ -1105,14 +1086,10 @@ public class CalendarSyncAdapter extends AbstractSyncAdapter {
hasAttendees = true; hasAttendees = true;
} }
s.start(Tags.CALENDAR_ATTENDEE); s.start(Tags.CALENDAR_ATTENDEE);
if (ncvValues.containsKey(Attendees.ATTENDEE_NAME)) { s.writeStringValue(ncvValues, Attendees.ATTENDEE_NAME,
s.data(Tags.CALENDAR_ATTENDEE_NAME, Tags.CALENDAR_ATTENDEE_NAME);
ncvValues.getAsString(Attendees.ATTENDEE_NAME)); s.writeStringValue(ncvValues, Attendees.ATTENDEE_EMAIL,
} Tags.CALENDAR_ATTENDEE_EMAIL);
if (ncvValues.containsKey(Attendees.ATTENDEE_EMAIL)) {
s.data(Tags.CALENDAR_ATTENDEE_EMAIL,
ncvValues.getAsString(Attendees.ATTENDEE_EMAIL));
}
s.data(Tags.CALENDAR_ATTENDEE_TYPE, "1"); // Required s.data(Tags.CALENDAR_ATTENDEE_TYPE, "1"); // Required
s.end(); // Attendee s.end(); // Attendee
} }
@ -1127,10 +1104,10 @@ public class CalendarSyncAdapter extends AbstractSyncAdapter {
} }
} else { } else {
// TODO Add reminders to exceptions (allow them to be specified!) // TODO Add reminders to exceptions (allow them to be specified!)
if (entityValues.containsKey(Events.ORIGINAL_INSTANCE_TIME)) { Long originalTime = entityValues.getAsLong(Events.ORIGINAL_INSTANCE_TIME);
if (originalTime != null) {
s.data(Tags.CALENDAR_EXCEPTION_START_TIME, s.data(Tags.CALENDAR_EXCEPTION_START_TIME,
CalendarUtilities.millisToEasDateTime(entityValues.getAsLong( CalendarUtilities.millisToEasDateTime(originalTime));
Events.ORIGINAL_INSTANCE_TIME)));
} else { } else {
// Illegal; what should we do? // Illegal; what should we do?
} }

View File

@ -26,6 +26,7 @@ package com.android.exchange.adapter;
import com.android.exchange.Eas; import com.android.exchange.Eas;
import com.android.exchange.utility.FileLogger; import com.android.exchange.utility.FileLogger;
import android.content.ContentValues;
import android.util.Log; import android.util.Log;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
@ -193,4 +194,11 @@ public class Serializer {
out.write(data); out.write(data);
out.write(0); out.write(0);
} }
void writeStringValue (ContentValues cv, String key, int tag) throws IOException {
String value = cv.getAsString(key);
if (value != null) {
data(tag, value);
}
}
} }