/** * Persists this folder. We will always perform the proper database operation (e.g. 'save' or * 'update'). As an optimization, if a folder has not been modified, no database operations are * performed. */ void save(Context context) { final Mailbox mailbox = mMailbox; if (!mailbox.isSaved()) { mailbox.save(context); mHash = mailbox.getHashes(); } else { Object[] hash = mailbox.getHashes(); if (!Arrays.equals(mHash, hash)) { mailbox.update(context, mailbox.toContentValues()); mHash = hash; // Save updated hash } } }
/// M: The folder sync must be synchronized, otherwise the folders may be duplicate @Override public synchronized void updateFolderList(long accountId) throws RemoteException { /// M: We Can't updateFolderList in low storage state @{ if (StorageLowState.checkIfStorageLow(mContext)) { LogUtils.e(Logging.LOG_TAG, "Can't updateFolderList due to low storage"); return; } /// @} final Account account = Account.restoreAccountWithId(mContext, accountId); if (account == null) { return; } long inboxId = -1; TrafficStats.setThreadStatsTag(TrafficFlags.getSyncFlags(mContext, account)); Cursor localFolderCursor = null; try { // Step 0: Make sure the default system mailboxes exist. for (final int type : Mailbox.REQUIRED_FOLDER_TYPES) { if (Mailbox.findMailboxOfType(mContext, accountId, type) == Mailbox.NO_MAILBOX) { final Mailbox mailbox = Mailbox.newSystemMailbox(mContext, accountId, type); mailbox.save(mContext); if (type == Mailbox.TYPE_INBOX) { inboxId = mailbox.mId; } } } // Step 1: Get remote mailboxes final Store store = Store.getInstance(account, mContext); final Folder[] remoteFolders = store.updateFolders(); final HashSet<String> remoteFolderNames = new HashSet<String>(); for (final Folder remoteFolder : remoteFolders) { remoteFolderNames.add(remoteFolder.getName()); } // Step 2: Get local mailboxes localFolderCursor = mContext .getContentResolver() .query( Mailbox.CONTENT_URI, MAILBOX_PROJECTION, EmailContent.MailboxColumns.ACCOUNT_KEY + "=?", new String[] {String.valueOf(account.mId)}, null); // Step 3: Remove any local mailbox not on the remote list while (localFolderCursor.moveToNext()) { final String mailboxPath = localFolderCursor.getString(MAILBOX_COLUMN_SERVER_ID); // Short circuit if we have a remote mailbox with the same name if (remoteFolderNames.contains(mailboxPath)) { continue; } final int mailboxType = localFolderCursor.getInt(MAILBOX_COLUMN_TYPE); final long mailboxId = localFolderCursor.getLong(MAILBOX_COLUMN_ID); switch (mailboxType) { case Mailbox.TYPE_INBOX: case Mailbox.TYPE_DRAFTS: case Mailbox.TYPE_OUTBOX: case Mailbox.TYPE_SENT: case Mailbox.TYPE_TRASH: case Mailbox.TYPE_SEARCH: // Never, ever delete special mailboxes break; default: // Drop all attachment files related to this mailbox AttachmentUtilities.deleteAllMailboxAttachmentFiles(mContext, accountId, mailboxId); // Delete the mailbox; database triggers take care of related // Message, Body and Attachment records Uri uri = ContentUris.withAppendedId(Mailbox.CONTENT_URI, mailboxId); mContext.getContentResolver().delete(uri, null, null); break; } } } catch (MessagingException me) { LogUtils.i(Logging.LOG_TAG, me, "Error in updateFolderList"); // We'll hope this is temporary } finally { if (localFolderCursor != null) { localFolderCursor.close(); } // If we just created the inbox, sync it if (inboxId != -1) { startSync(inboxId, true, 0); } } }