DO NOT MERGE - Clear cached CalendarObservers after Calendar wipe

* This fix may resolve the bugs referenced below; the issue fixed
  could cause pandemonium after the server commands a wipe of calendar
  data and most likely explains these issues (via Occam's Razor)
* Also backport a SQL fix to more reliably delete calendar data

Bug: 4077499
Bug: 4064237
Backport from: I628fb14ea2c04150d4f27341751f0eab61ee33d1

Change-Id: I7667a11663d8720a92b9eba0748f60256a25edba
This commit is contained in:
Andy Stadler 2011-03-25 16:18:06 -07:00
parent 8f0a79c2ef
commit 8faae52c0d
2 changed files with 26 additions and 15 deletions

View File

@ -69,21 +69,21 @@ import android.database.ContentObserver;
import android.database.Cursor;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.net.NetworkInfo.State;
import android.net.Uri;
import android.os.Bundle;
import android.os.Debug;
import android.os.Handler;
import android.os.IBinder;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.os.Process;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.PowerManager.WakeLock;
import android.provider.Calendar;
import android.provider.ContactsContract;
import android.provider.Calendar.Calendars;
import android.provider.Calendar.Events;
import android.provider.ContactsContract;
import android.util.Log;
import java.io.BufferedReader;
@ -95,6 +95,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
/**
* The SyncManager handles all aspects of starting, maintaining, and stopping the various sync
@ -210,8 +211,9 @@ public class SyncManager extends Service implements Runnable {
private Object mStatusChangeListener;
private EasAccountsUpdatedListener mAccountsUpdatedListener;
private HashMap<Long, CalendarObserver> mCalendarObservers =
new HashMap<Long, CalendarObserver>();
// Concurrent because CalendarSyncAdapter can modify the map during a wipe
private ConcurrentHashMap<Long, CalendarObserver> mCalendarObservers =
new ConcurrentHashMap<Long, CalendarObserver>();
private ContentResolver mResolver;
@ -659,11 +661,14 @@ public class SyncManager extends Service implements Runnable {
/**
* Unregister all CalendarObserver's
*/
private void unregisterCalendarObservers() {
for (CalendarObserver observer: mCalendarObservers.values()) {
mResolver.unregisterContentObserver(observer);
static public void unregisterCalendarObservers() {
SyncManager syncManager = INSTANCE;
if (syncManager == null) return;
ContentResolver resolver = syncManager.mResolver;
for (CalendarObserver observer: syncManager.mCalendarObservers.values()) {
resolver.unregisterContentObserver(observer);
}
mCalendarObservers.clear();
syncManager.mCalendarObservers.clear();
}
/**

View File

@ -25,6 +25,7 @@ import com.android.email.provider.EmailContent.Message;
import com.android.exchange.Eas;
import com.android.exchange.EasOutboxService;
import com.android.exchange.EasSyncService;
import com.android.exchange.SyncManager;
import com.android.exchange.utility.CalendarUtilities;
import com.android.exchange.utility.Duration;
@ -35,14 +36,14 @@ import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Entity;
import android.content.Entity.NamedContentValues;
import android.content.EntityIterator;
import android.content.OperationApplicationException;
import android.content.Entity.NamedContentValues;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.net.Uri;
import android.os.RemoteException;
import android.provider.Calendar;
import android.provider.SyncStateContract;
import android.provider.Calendar.Attendees;
import android.provider.Calendar.Calendars;
import android.provider.Calendar.Events;
@ -51,6 +52,7 @@ import android.provider.Calendar.ExtendedProperties;
import android.provider.Calendar.Reminders;
import android.provider.Calendar.SyncState;
import android.provider.ContactsContract.RawContacts;
import android.provider.SyncStateContract;
import android.text.TextUtils;
import android.util.Log;
@ -59,10 +61,10 @@ import java.io.InputStream;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.GregorianCalendar;
import java.util.Map.Entry;
import java.util.StringTokenizer;
import java.util.TimeZone;
import java.util.UUID;
import java.util.Map.Entry;
/**
* Sync adapter class for EAS calendars
@ -282,9 +284,13 @@ public class CalendarSyncAdapter extends AbstractSyncAdapter {
@Override
public void wipe() {
// Delete the calendar associated with this account
// TODO Make sure the Events, etc. are also deleted
mContentResolver.delete(Calendars.CONTENT_URI, CALENDAR_SELECTION,
new String[] {mEmailAddress, Email.EXCHANGE_ACCOUNT_MANAGER_TYPE});
// CalendarProvider2 does NOT handle selection arguments in deletions
mContentResolver.delete(Calendars.CONTENT_URI, Calendars._SYNC_ACCOUNT +
"=" + DatabaseUtils.sqlEscapeString(mEmailAddress) + " AND " +
Calendars._SYNC_ACCOUNT_TYPE + "=" +
DatabaseUtils.sqlEscapeString(Email.EXCHANGE_ACCOUNT_MANAGER_TYPE), null);
// Invalidate our calendar observers
SyncManager.unregisterCalendarObservers();
}
private void addOrganizerToAttendees(CalendarOperations ops, long eventId,