Implement folder sync correctly.

Change-Id: I9f9fde6bf2f991873a04360be43ee669a97cc1dd
diff --git a/src/com/android/exchange/adapter/FolderSyncParser.java b/src/com/android/exchange/adapter/FolderSyncParser.java
index a51fa04..422c50a 100644
--- a/src/com/android/exchange/adapter/FolderSyncParser.java
+++ b/src/com/android/exchange/adapter/FolderSyncParser.java
@@ -126,9 +126,9 @@
     }
 
     public FolderSyncParser(final Context context, final ContentResolver resolver,
-            final InputStream in, final Account account, final Mailbox mailbox,
-            final boolean statusOnly) throws IOException {
-        super(context, resolver, in, mailbox, account);
+            final InputStream in, final Account account, final boolean statusOnly)
+                    throws IOException {
+        super(context, resolver, in, null, account);
         mAccountId = mAccount.mId;
         mAccountIdAsString = Long.toString(mAccountId);
         mStatusOnly = statusOnly;
@@ -245,17 +245,18 @@
         while (nextTag(Tags.FOLDER_DELETE) != END) {
             switch (tag) {
                 case Tags.FOLDER_SERVER_ID:
-                    String serverId = getValue();
+                    final String serverId = getValue();
                     // Find the mailbox in this account with the given serverId
-                    Cursor c = getServerIdCursor(serverId);
+                    final Cursor c = getServerIdCursor(serverId);
                     try {
                         if (c.moveToFirst()) {
                             userLog("Deleting ", serverId);
+                            final long mailboxId = c.getLong(MAILBOX_ID_COLUMNS_ID);
                             ops.add(ContentProviderOperation.newDelete(
                                     ContentUris.withAppendedId(Mailbox.CONTENT_URI,
-                                            c.getLong(MAILBOX_ID_COLUMNS_ID))).build());
+                                            mailboxId)).build());
                             AttachmentUtilities.deleteAllMailboxAttachmentFiles(mContext,
-                                    mAccountId, mMailbox.mId);
+                                    mAccountId, mailboxId);
                             if (!mInitialSync) {
                                 String parentId = c.getString(MAILBOX_ID_COLUMNS_PARENT_SERVER_ID);
                                 if (!TextUtils.isEmpty(parentId)) {
@@ -511,7 +512,7 @@
 
         while (nextTag(Tags.FOLDER_CHANGES) != END) {
             if (tag == Tags.FOLDER_ADD) {
-                Mailbox mailbox = addParser();
+                final Mailbox mailbox = addParser();
                 if (mailbox != null) {
                     addMailboxes.add(mailbox);
                 }
@@ -526,8 +527,8 @@
         }
 
         // Map folder serverId to mailbox (used to validate user mailboxes)
-        HashMap<String, Mailbox> mailboxMap = new HashMap<String, Mailbox>();
-        for (Mailbox mailbox : addMailboxes) {
+        final HashMap<String, Mailbox> mailboxMap = new HashMap<String, Mailbox>();
+        for (final Mailbox mailbox : addMailboxes) {
             mailboxMap.put(mailbox.mServerId, mailbox);
         }
         userLog("Total of " + addMailboxes.size() + " mailboxes parsed");
diff --git a/src/com/android/exchange/service/EasAccountSyncHandler.java b/src/com/android/exchange/service/EasAccountSyncHandler.java
index 8f5e64e..67d98dd 100644
--- a/src/com/android/exchange/service/EasAccountSyncHandler.java
+++ b/src/com/android/exchange/service/EasAccountSyncHandler.java
@@ -8,7 +8,6 @@
 
 import com.android.emailcommon.provider.Account;
 import com.android.emailcommon.provider.EmailContent.HostAuthColumns;
-import com.android.emailcommon.provider.Mailbox;
 import com.android.exchange.CommandStatusException;
 import com.android.exchange.CommandStatusException.CommandStatus;
 import com.android.exchange.EasResponse;
@@ -28,9 +27,9 @@
 
 
     public EasAccountSyncHandler(final Context context, final ContentResolver contentResolver,
-            final Account account, final Mailbox mailbox, final Bundle syncExtras,
+            final Account account, final Bundle syncExtras,
             final SyncResult syncResult) {
-        super(context, contentResolver, account, mailbox, syncExtras, syncResult);
+        super(context, contentResolver, account, null, syncExtras, syncResult);
     }
 
     @Override
@@ -40,9 +39,10 @@
             needsResync = false;
             final EasResponse resp;
             try {
+                final String syncKey = (mAccount.mSyncKey != null) ? mAccount.mSyncKey : "0";
                 final Serializer s = new Serializer();
                 s.start(Tags.FOLDER_FOLDER_SYNC).start(Tags.FOLDER_SYNC_KEY)
-                    .text(mAccount.mSyncKey).end().end().done();
+                    .text(syncKey).end().end().done();
                 resp = sendHttpClientPost("FolderSync", s.toByteArray());
             } catch (final IOException e) {
                 return SyncStatus.FAILURE_IO;
@@ -54,10 +54,8 @@
                         final InputStream is = resp.getInputStream();
                         try {
                             // Returns true if we need to sync again
-                            // TODO: FolderSyncParser needs to be cleaned up to remove dependency
-                            // on AbstractSyncAdapter.
                             if (new FolderSyncParser(mContext, mContentResolver, is, mAccount,
-                                    mMailbox, false).parse()) {
+                                    false).parse()) {
                                 needsResync = true;
                             }
                         } catch (final IOException e) {
diff --git a/src/com/android/exchange/service/EasAccountValidator.java b/src/com/android/exchange/service/EasAccountValidator.java
index 4ebb9fb..720f8f6 100644
--- a/src/com/android/exchange/service/EasAccountValidator.java
+++ b/src/com/android/exchange/service/EasAccountValidator.java
@@ -192,7 +192,7 @@
                     // seeing if a CommandStatusException is thrown (indicating a
                     // provisioning failure)
                     new FolderSyncParser(mContext, mContext.getContentResolver(),
-                            resp.getInputStream(), account, null, true).parse();
+                            resp.getInputStream(), account, true).parse();
                 }
                 resultCode = MessagingException.NO_ERROR;
             } else if (code == HttpStatus.SC_FORBIDDEN) {
diff --git a/src/com/android/exchange/service/EasSyncHandler.java b/src/com/android/exchange/service/EasSyncHandler.java
index ce1c513..1404258 100644
--- a/src/com/android/exchange/service/EasSyncHandler.java
+++ b/src/com/android/exchange/service/EasSyncHandler.java
@@ -84,7 +84,7 @@
                     return new EasOutboxSyncHandler(context, contentResolver, account, mailbox,
                             syncExtras, syncResult);
                 case Mailbox.TYPE_EAS_ACCOUNT_MAILBOX:
-                    return new EasAccountSyncHandler(context, contentResolver, account, mailbox,
+                    return new EasAccountSyncHandler(context, contentResolver, account,
                             syncExtras, syncResult);
             }
         }
diff --git a/src/com/android/exchange/service/EmailSyncAdapterService.java b/src/com/android/exchange/service/EmailSyncAdapterService.java
index ac21c0a..5f24af0 100644
--- a/src/com/android/exchange/service/EmailSyncAdapterService.java
+++ b/src/com/android/exchange/service/EmailSyncAdapterService.java
@@ -17,7 +17,9 @@
 package com.android.exchange.service;
 
 import com.android.emailcommon.Api;
+import com.android.emailcommon.TempDirectory;
 import com.android.emailcommon.provider.Account;
+import com.android.emailcommon.provider.EmailContent;
 import com.android.emailcommon.provider.EmailContent.AccountColumns;
 import com.android.emailcommon.provider.HostAuth;
 import com.android.emailcommon.provider.Mailbox;
@@ -25,6 +27,7 @@
 import com.android.emailcommon.service.IEmailService;
 import com.android.emailcommon.service.IEmailServiceCallback;
 import com.android.emailcommon.service.SearchParams;
+import com.android.emailcommon.utility.Utility;
 import com.android.exchange.Eas;
 import com.android.mail.providers.UIProvider.AccountCapabilities;
 
@@ -231,7 +234,14 @@
         @Override
         public void updateFolderList(final long accountId) {
             Log.d(TAG, "IEmailService.updateFolderList");
-            //reloadFolderList(ExchangeService.this, accountId, false);
+            final String emailAddress = Utility.getFirstRowString(EmailSyncAdapterService.this,
+                    Account.CONTENT_URI, new String[] {AccountColumns.EMAIL_ADDRESS},
+                    Account.ID_SELECTION, new String[] {Long.toString(accountId)}, null, 0);
+            if (emailAddress != null) {
+                ContentResolver.requestSync(new android.accounts.Account(
+                        emailAddress, Eas.EXCHANGE_ACCOUNT_MANAGER_TYPE),
+                        EmailContent.AUTHORITY, new Bundle());
+            }
         }
 
         @Override
@@ -415,6 +425,8 @@
         public void onPerformSync(android.accounts.Account acct, Bundle extras,
                 String authority, ContentProviderClient provider, SyncResult syncResult) {
 
+            TempDirectory.setTempDirectory(EmailSyncAdapterService.this);
+
             // TODO: Perform any connectivity checks, bail early if we don't have proper network
             // for this sync operation.
 
@@ -454,8 +466,13 @@
                 // If no mailbox is specified, this is an account sync. This means we should both
                 // sync the account (to get folders, etc.) as well as the inbox.
                 // TODO: Why does the "account mailbox" even exist?
-                final Mailbox accountMailbox = Mailbox.restoreMailboxOfType(context, account.mId,
+                Mailbox accountMailbox = Mailbox.restoreMailboxOfType(context, account.mId,
                         Mailbox.TYPE_EAS_ACCOUNT_MAILBOX);
+                if (accountMailbox == null) {
+                    // TODO: This is a hack to work around the lack of an account observer.
+                    accountMailbox = new Mailbox();
+                    accountMailbox.mType = Mailbox.TYPE_EAS_ACCOUNT_MAILBOX;
+                }
                 final EasSyncHandler accountSyncHandler = EasSyncHandler.getEasSyncHandler(
                         context, cr, account, accountMailbox, extras, syncResult);
 
@@ -466,7 +483,7 @@
                     final Mailbox inbox = Mailbox.restoreMailboxOfType(context, account.mId,
                             Mailbox.TYPE_INBOX);
                     final EasSyncHandler inboxSyncHandler = EasSyncHandler.getEasSyncHandler(
-                            context, cr, account, accountMailbox, extras, syncResult);
+                            context, cr, account, inbox, extras, syncResult);
                     if (inboxSyncHandler == null) {
                         // TODO: Inbox does not exist for this account, add proper error handling.
                     } else {