Implement password expiration for EAS
* Hoist wipe() method from AbstractSyncParser to AbstractSyncAdapter
* Add deleteAccountPIMData(accountId) to the EmailService API
* Implement deleteAccountPIMData for EAS
Change-Id: I1037cde25fc2b24419f399446cfa0906dc0174d1
diff --git a/src/com/android/exchange/EasSyncService.java b/src/com/android/exchange/EasSyncService.java
index 3f40d44..70c531f 100644
--- a/src/com/android/exchange/EasSyncService.java
+++ b/src/com/android/exchange/EasSyncService.java
@@ -18,8 +18,8 @@
package com.android.exchange;
import com.android.email.SecurityPolicy;
-import com.android.email.Utility;
import com.android.email.SecurityPolicy.PolicySet;
+import com.android.email.Utility;
import com.android.email.mail.Address;
import com.android.email.mail.MeetingInfo;
import com.android.email.mail.MessagingException;
@@ -46,11 +46,11 @@
import com.android.exchange.adapter.GalParser;
import com.android.exchange.adapter.MeetingResponseParser;
import com.android.exchange.adapter.MoveItemsParser;
+import com.android.exchange.adapter.Parser.EasParserException;
import com.android.exchange.adapter.PingParser;
import com.android.exchange.adapter.ProvisionParser;
import com.android.exchange.adapter.Serializer;
import com.android.exchange.adapter.Tags;
-import com.android.exchange.adapter.Parser.EasParserException;
import com.android.exchange.provider.GalResult;
import com.android.exchange.utility.CalendarUtilities;
@@ -1644,8 +1644,7 @@
if (len != 0) {
InputStream is = entity.getContent();
// Returns true if we need to sync again
- if (new FolderSyncParser(is, new AccountSyncAdapter(mMailbox, this))
- .parse()) {
+ if (new FolderSyncParser(is, new AccountSyncAdapter(this)).parse()) {
continue;
}
}
@@ -2303,11 +2302,11 @@
} else {
AbstractSyncAdapter target;
if (mMailbox.mType == Mailbox.TYPE_CONTACTS) {
- target = new ContactsSyncAdapter(mMailbox, this);
+ target = new ContactsSyncAdapter( this);
} else if (mMailbox.mType == Mailbox.TYPE_CALENDAR) {
- target = new CalendarSyncAdapter(mMailbox, this);
+ target = new CalendarSyncAdapter(this);
} else {
- target = new EmailSyncAdapter(mMailbox, this);
+ target = new EmailSyncAdapter(this);
}
// We loop here because someone might have put a request in while we were syncing
// and we've missed that opportunity...
diff --git a/src/com/android/exchange/ExchangeService.java b/src/com/android/exchange/ExchangeService.java
index aece41e..90f65f7 100644
--- a/src/com/android/exchange/ExchangeService.java
+++ b/src/com/android/exchange/ExchangeService.java
@@ -36,6 +36,7 @@
import com.android.email.service.IEmailServiceCallback;
import com.android.email.service.MailService;
import com.android.exchange.adapter.CalendarSyncAdapter;
+import com.android.exchange.adapter.ContactsSyncAdapter;
import com.android.exchange.utility.FileLogger;
import org.apache.http.conn.ClientConnectionManager;
@@ -66,21 +67,21 @@
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;
@@ -448,6 +449,31 @@
public void moveMessage(long messageId, long mailboxId) throws RemoteException {
sendMessageRequest(new MessageMoveRequest(messageId, mailboxId));
}
+
+ /**
+ * Delete PIM (calendar, contacts) data for the specified account
+ *
+ * @param accountId the account whose data should be deleted
+ * @throws RemoteException
+ */
+ public void deleteAccountPIMData(long accountId) throws RemoteException {
+ ExchangeService exchangeService = INSTANCE;
+ if (exchangeService == null) return;
+ Mailbox mailbox =
+ Mailbox.restoreMailboxOfType(exchangeService, accountId, Mailbox.TYPE_CONTACTS);
+ if (mailbox != null) {
+ EasSyncService service = new EasSyncService(exchangeService, mailbox);
+ ContactsSyncAdapter adapter = new ContactsSyncAdapter(service);
+ adapter.wipe();
+ }
+ mailbox =
+ Mailbox.restoreMailboxOfType(exchangeService, accountId, Mailbox.TYPE_CALENDAR);
+ if (mailbox != null) {
+ EasSyncService service = new EasSyncService(exchangeService, mailbox);
+ CalendarSyncAdapter adapter = new CalendarSyncAdapter(service);
+ adapter.wipe();
+ }
+ }
};
static class AccountList extends ArrayList<Account> {
@@ -796,7 +822,7 @@
EasSyncService service =
new EasSyncService(INSTANCE, mailbox);
CalendarSyncAdapter adapter =
- new CalendarSyncAdapter(mailbox, service);
+ new CalendarSyncAdapter(service);
try {
adapter.setSyncKey("0", false);
} catch (IOException e) {
diff --git a/src/com/android/exchange/adapter/AbstractSyncAdapter.java b/src/com/android/exchange/adapter/AbstractSyncAdapter.java
index 41b2281..14cca36 100644
--- a/src/com/android/exchange/adapter/AbstractSyncAdapter.java
+++ b/src/com/android/exchange/adapter/AbstractSyncAdapter.java
@@ -23,6 +23,7 @@
import com.android.exchange.Eas;
import com.android.exchange.EasSyncService;
+import android.content.ContentResolver;
import android.content.Context;
import java.io.IOException;
@@ -46,6 +47,7 @@
public EasSyncService mService;
public Context mContext;
public Account mAccount;
+ public final ContentResolver mContentResolver;
public final android.accounts.Account mAccountManagerAccount;
// Create the data for local changes that need to be sent up to the server
@@ -62,18 +64,23 @@
// Add sync options (filter, body type - html vs plain, and truncation)
public abstract void sendSyncOptions(Double protocolVersion, Serializer s)
throws IOException;
+ /**
+ * Delete all records of this class in this account
+ */
+ public abstract void wipe();
public boolean isLooping() {
return false;
}
- public AbstractSyncAdapter(Mailbox mailbox, EasSyncService service) {
- mMailbox = mailbox;
+ public AbstractSyncAdapter(EasSyncService service) {
mService = service;
+ mMailbox = service.mMailbox;
mContext = service.mContext;
mAccount = service.mAccount;
mAccountManagerAccount = new android.accounts.Account(mAccount.mEmailAddress,
Email.EXCHANGE_ACCOUNT_MANAGER_TYPE);
+ mContentResolver = mContext.getContentResolver();
}
public void userLog(String ...strings) {
diff --git a/src/com/android/exchange/adapter/AbstractSyncParser.java b/src/com/android/exchange/adapter/AbstractSyncParser.java
index b2b17f0..250767b 100644
--- a/src/com/android/exchange/adapter/AbstractSyncParser.java
+++ b/src/com/android/exchange/adapter/AbstractSyncParser.java
@@ -75,11 +75,6 @@
*/
public abstract void commit() throws IOException;
- /**
- * Delete all records of this class in this account
- */
- public abstract void wipe();
-
public boolean isLooping() {
return mLooping;
}
@@ -121,7 +116,7 @@
// TODO Make frequency conditional on user settings!
mMailbox.mSyncInterval = Mailbox.CHECK_INTERVAL_PUSH;
mService.errorLog("Bad sync key; RESET and delete data");
- wipe();
+ mAdapter.wipe();
// Indicate there's more so that we'll start syncing again
moreAvailable = true;
} else if (status == 8) {
diff --git a/src/com/android/exchange/adapter/AccountSyncAdapter.java b/src/com/android/exchange/adapter/AccountSyncAdapter.java
index 25b8ad6..cf54ed5 100644
--- a/src/com/android/exchange/adapter/AccountSyncAdapter.java
+++ b/src/com/android/exchange/adapter/AccountSyncAdapter.java
@@ -1,6 +1,5 @@
package com.android.exchange.adapter;
-import com.android.email.provider.EmailContent.Mailbox;
import com.android.exchange.EasSyncService;
import java.io.IOException;
@@ -8,8 +7,8 @@
public class AccountSyncAdapter extends AbstractSyncAdapter {
- public AccountSyncAdapter(Mailbox mailbox, EasSyncService service) {
- super(mailbox, service);
+ public AccountSyncAdapter(EasSyncService service) {
+ super(service);
}
@Override
@@ -17,6 +16,10 @@
}
@Override
+ public void wipe() {
+ }
+
+ @Override
public String getCollectionName() {
return null;
}
diff --git a/src/com/android/exchange/adapter/CalendarSyncAdapter.java b/src/com/android/exchange/adapter/CalendarSyncAdapter.java
index 503585a..197cdcf 100644
--- a/src/com/android/exchange/adapter/CalendarSyncAdapter.java
+++ b/src/com/android/exchange/adapter/CalendarSyncAdapter.java
@@ -20,7 +20,6 @@
import com.android.email.Email;
import com.android.email.Utility;
import com.android.email.provider.EmailContent;
-import com.android.email.provider.EmailContent.Mailbox;
import com.android.email.provider.EmailContent.Message;
import com.android.exchange.Eas;
import com.android.exchange.EasOutboxService;
@@ -35,14 +34,13 @@
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.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 +49,7 @@
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 +58,10 @@
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
@@ -161,8 +160,8 @@
private ArrayList<Long> mSendCancelIdList = new ArrayList<Long>();
private ArrayList<Message> mOutgoingMailList = new ArrayList<Message>();
- public CalendarSyncAdapter(Mailbox mailbox, EasSyncService service) {
- super(mailbox, service);
+ public CalendarSyncAdapter(EasSyncService service) {
+ super(service);
mEmailAddress = mAccount.mEmailAddress;
Cursor c = mService.mContentResolver.query(Calendars.CONTENT_URI,
new String[] {Calendars._ID}, CALENDAR_SELECTION,
@@ -191,6 +190,13 @@
}
@Override
+ public void wipe() {
+ // Delete the calendar associated with this account
+ mContentResolver.delete(Calendars.CONTENT_URI, CALENDAR_SELECTION,
+ new String[] {mEmailAddress, Email.EXCHANGE_ACCOUNT_MANAGER_TYPE});
+ }
+
+ @Override
public void sendSyncOptions(Double protocolVersion, Serializer s) throws IOException {
setPimSyncOptions(protocolVersion, Eas.FILTER_2_WEEKS, s);
}
@@ -284,14 +290,6 @@
mAccountUri = Events.CONTENT_URI;
}
- @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});
- }
-
private void addOrganizerToAttendees(CalendarOperations ops, long eventId,
String organizerName, String organizerEmail) {
// Handle the organizer (who IS an attendee on device, but NOT in EAS)
diff --git a/src/com/android/exchange/adapter/ContactsSyncAdapter.java b/src/com/android/exchange/adapter/ContactsSyncAdapter.java
index 4aea090..8a3617e 100644
--- a/src/com/android/exchange/adapter/ContactsSyncAdapter.java
+++ b/src/com/android/exchange/adapter/ContactsSyncAdapter.java
@@ -17,32 +17,24 @@
package com.android.exchange.adapter;
-import com.android.email.provider.EmailContent.Mailbox;
import com.android.exchange.Eas;
import com.android.exchange.EasSyncService;
import android.content.ContentProviderClient;
import android.content.ContentProviderOperation;
+import android.content.ContentProviderOperation.Builder;
import android.content.ContentProviderResult;
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.ContentProviderOperation.Builder;
-import android.content.Entity.NamedContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.RemoteException;
import android.provider.ContactsContract;
-import android.provider.SyncStateContract;
-import android.provider.ContactsContract.Data;
-import android.provider.ContactsContract.Groups;
-import android.provider.ContactsContract.RawContacts;
-import android.provider.ContactsContract.RawContactsEntity;
-import android.provider.ContactsContract.Settings;
-import android.provider.ContactsContract.SyncState;
import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.Event;
import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
@@ -56,6 +48,13 @@
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
import android.provider.ContactsContract.CommonDataKinds.Website;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.Groups;
+import android.provider.ContactsContract.RawContacts;
+import android.provider.ContactsContract.RawContactsEntity;
+import android.provider.ContactsContract.Settings;
+import android.provider.ContactsContract.SyncState;
+import android.provider.SyncStateContract;
import android.text.TextUtils;
import android.text.util.Rfc822Token;
import android.text.util.Rfc822Tokenizer;
@@ -124,10 +123,14 @@
ArrayList<Long> mDeletedIdList = new ArrayList<Long>();
ArrayList<Long> mUpdatedIdList = new ArrayList<Long>();
+ private final Uri mAccountUri;
+ private final ContentResolver mContentResolver;
private boolean mGroupsUsed = false;
- public ContactsSyncAdapter(Mailbox mailbox, EasSyncService service) {
- super(mailbox, service);
+ public ContactsSyncAdapter(EasSyncService service) {
+ super(service);
+ mAccountUri = uriWithAccountAndIsSyncAdapter(RawContacts.CONTENT_URI);
+ mContentResolver = mContext.getContentResolver();
}
static Uri addCallerIsSyncAdapterParameter(Uri uri) {
@@ -153,6 +156,12 @@
return p.parse();
}
+
+ @Override
+ public void wipe() {
+ mContentResolver.delete(mAccountUri, null, null);
+ }
+
interface UntypedRow {
public void addValues(RowBuilder builder);
public boolean isSameAs(int type, String value);
@@ -331,18 +340,11 @@
String[] mBindArgument = new String[1];
String mMailboxIdAsString;
- Uri mAccountUri;
ContactOperations ops = new ContactOperations();
public EasContactsSyncParser(InputStream in, ContactsSyncAdapter adapter)
throws IOException {
super(in, adapter);
- mAccountUri = uriWithAccountAndIsSyncAdapter(RawContacts.CONTENT_URI);
- }
-
- @Override
- public void wipe() {
- mContentResolver.delete(mAccountUri, null, null);
}
public void addData(String serverId, ContactOperations ops, Entity entity)
diff --git a/src/com/android/exchange/adapter/EmailSyncAdapter.java b/src/com/android/exchange/adapter/EmailSyncAdapter.java
index de312a3..5635af2 100644
--- a/src/com/android/exchange/adapter/EmailSyncAdapter.java
+++ b/src/com/android/exchange/adapter/EmailSyncAdapter.java
@@ -28,7 +28,6 @@
import com.android.email.mail.internet.MimeUtility;
import com.android.email.provider.AttachmentProvider;
import com.android.email.provider.EmailContent;
-import com.android.email.provider.EmailProvider;
import com.android.email.provider.EmailContent.Account;
import com.android.email.provider.EmailContent.AccountColumns;
import com.android.email.provider.EmailContent.Attachment;
@@ -37,6 +36,7 @@
import com.android.email.provider.EmailContent.Message;
import com.android.email.provider.EmailContent.MessageColumns;
import com.android.email.provider.EmailContent.SyncColumns;
+import com.android.email.provider.EmailProvider;
import com.android.email.service.MailService;
import com.android.exchange.Eas;
import com.android.exchange.EasSyncService;
@@ -102,8 +102,18 @@
// Holds the parser's value for isLooping()
boolean mIsLooping = false;
- public EmailSyncAdapter(Mailbox mailbox, EasSyncService service) {
- super(mailbox, service);
+ public EmailSyncAdapter(EasSyncService service) {
+ super(service);
+ }
+
+ @Override
+ public void wipe() {
+ mContentResolver.delete(Message.CONTENT_URI,
+ Message.MAILBOX_KEY + "=" + mMailbox.mId, null);
+ mContentResolver.delete(Message.DELETED_CONTENT_URI,
+ Message.MAILBOX_KEY + "=" + mMailbox.mId, null);
+ mContentResolver.delete(Message.UPDATED_CONTENT_URI,
+ Message.MAILBOX_KEY + "=" + mMailbox.mId, null);
}
private String getEmailFilter() {
@@ -238,16 +248,6 @@
mMailboxIdAsString = Long.toString(mMailbox.mId);
}
- @Override
- public void wipe() {
- mContentResolver.delete(Message.CONTENT_URI,
- Message.MAILBOX_KEY + "=" + mMailbox.mId, null);
- mContentResolver.delete(Message.DELETED_CONTENT_URI,
- Message.MAILBOX_KEY + "=" + mMailbox.mId, null);
- mContentResolver.delete(Message.UPDATED_CONTENT_URI,
- Message.MAILBOX_KEY + "=" + mMailbox.mId, null);
- }
-
public void addData (Message msg) throws IOException {
ArrayList<Attachment> atts = new ArrayList<Attachment>();
boolean truncated = false;
diff --git a/src/com/android/exchange/adapter/FolderSyncParser.java b/src/com/android/exchange/adapter/FolderSyncParser.java
index 7e4863c..7a675d5 100644
--- a/src/com/android/exchange/adapter/FolderSyncParser.java
+++ b/src/com/android/exchange/adapter/FolderSyncParser.java
@@ -20,10 +20,10 @@
import com.android.email.Utility;
import com.android.email.provider.AttachmentProvider;
import com.android.email.provider.EmailContent;
-import com.android.email.provider.EmailProvider;
import com.android.email.provider.EmailContent.AccountColumns;
import com.android.email.provider.EmailContent.Mailbox;
import com.android.email.provider.EmailContent.MailboxColumns;
+import com.android.email.provider.EmailProvider;
import com.android.exchange.Eas;
import com.android.exchange.ExchangeService;
import com.android.exchange.MockParserStream;
@@ -465,10 +465,6 @@
}
@Override
- public void wipe() {
- }
-
- @Override
public void responsesParser() throws IOException {
}
diff --git a/src/com/android/exchange/adapter/ProvisionParser.java b/src/com/android/exchange/adapter/ProvisionParser.java
index 5ba43e4..dfd255d 100644
--- a/src/com/android/exchange/adapter/ProvisionParser.java
+++ b/src/com/android/exchange/adapter/ProvisionParser.java
@@ -96,10 +96,6 @@
break;
case Tags.PROVISION_DEVICE_PASSWORD_EXPIRATION:
passwordExpiration = getValueInt();
- // We don't yet support this
- if (passwordExpiration > 0) {
- tagIsSupported = false;
- }
break;
case Tags.PROVISION_DEVICE_PASSWORD_HISTORY:
passwordHistory = getValueInt();
diff --git a/tests/src/com/android/exchange/adapter/EmailSyncAdapterTests.java b/tests/src/com/android/exchange/adapter/EmailSyncAdapterTests.java
index 7a4ea1b..e64b951 100644
--- a/tests/src/com/android/exchange/adapter/EmailSyncAdapterTests.java
+++ b/tests/src/com/android/exchange/adapter/EmailSyncAdapterTests.java
@@ -17,12 +17,12 @@
package com.android.exchange.adapter;
import com.android.email.provider.EmailContent;
-import com.android.email.provider.ProviderTestUtils;
import com.android.email.provider.EmailContent.Account;
import com.android.email.provider.EmailContent.Body;
import com.android.email.provider.EmailContent.Mailbox;
import com.android.email.provider.EmailContent.Message;
import com.android.email.provider.EmailContent.SyncColumns;
+import com.android.email.provider.ProviderTestUtils;
import com.android.exchange.EasSyncService;
import com.android.exchange.adapter.EmailSyncAdapter.EasEmailSyncParser;
import com.android.exchange.adapter.EmailSyncAdapter.EasEmailSyncParser.ServerChange;
@@ -48,7 +48,7 @@
*/
public void testGetMimeTypeFromFileName() throws IOException {
EasSyncService service = getTestService();
- EmailSyncAdapter adapter = new EmailSyncAdapter(service.mMailbox, service);
+ EmailSyncAdapter adapter = new EmailSyncAdapter(service);
EasEmailSyncParser p = adapter.new EasEmailSyncParser(getTestInputStream(), adapter);
// Test a few known types
String mimeType = p.getMimeTypeFromFileName("foo.jpg");
@@ -87,7 +87,7 @@
public void testSendDeletedItems() throws IOException {
EasSyncService service = getTestService();
- EmailSyncAdapter adapter = new EmailSyncAdapter(service.mMailbox, service);
+ EmailSyncAdapter adapter = new EmailSyncAdapter(service);
Serializer s = new Serializer();
ArrayList<Long> ids = new ArrayList<Long>();
ArrayList<Long> deletedIds = new ArrayList<Long>();
@@ -150,7 +150,7 @@
void setupSyncParserAndAdapter(Account account, Mailbox mailbox) throws IOException {
EasSyncService service = getTestService(account, mailbox);
- mSyncAdapter = new EmailSyncAdapter(mailbox, service);
+ mSyncAdapter = new EmailSyncAdapter(service);
mSyncParser = mSyncAdapter.new EasEmailSyncParser(getTestInputStream(), mSyncAdapter);
}
diff --git a/tests/src/com/android/exchange/adapter/FolderSyncParserTests.java b/tests/src/com/android/exchange/adapter/FolderSyncParserTests.java
index 9de9b8f..3122913 100644
--- a/tests/src/com/android/exchange/adapter/FolderSyncParserTests.java
+++ b/tests/src/com/android/exchange/adapter/FolderSyncParserTests.java
@@ -16,9 +16,9 @@
package com.android.exchange.adapter;
-import com.android.email.provider.ProviderTestUtils;
import com.android.email.provider.EmailContent.Account;
import com.android.email.provider.EmailContent.Mailbox;
+import com.android.email.provider.ProviderTestUtils;
import com.android.exchange.EasSyncService;
import java.io.IOException;
@@ -37,7 +37,7 @@
public void testIsValidMailFolder() throws IOException {
EasSyncService service = getTestService();
- EmailSyncAdapter adapter = new EmailSyncAdapter(service.mMailbox, service);
+ EmailSyncAdapter adapter = new EmailSyncAdapter(service);
FolderSyncParser parser = new FolderSyncParser(getTestInputStream(), adapter);
HashMap<String, Mailbox> mailboxMap = new HashMap<String, Mailbox>();
Account acct = ProviderTestUtils.setupAccount("account", true, mMockContext);