1ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank/* 2ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * Copyright (C) 2008-2009 Marc Blank 3ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * Licensed to The Android Open Source Project. 4ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * 5ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * Licensed under the Apache License, Version 2.0 (the "License"); 6ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * you may not use this file except in compliance with the License. 7ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * You may obtain a copy of the License at 8ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * 9ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * http://www.apache.org/licenses/LICENSE-2.0 10ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * 11ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * Unless required by applicable law or agreed to in writing, software 12ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * distributed under the License is distributed on an "AS IS" BASIS, 13ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * See the License for the specific language governing permissions and 15ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * limitations under the License. 16ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank */ 17ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 18ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blankpackage com.android.exchange.adapter; 19ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 20680e59f477fe2221ffa6d5bb6b3c8fe64c1f5a74Marc Blankimport android.content.ContentResolver; 21680e59f477fe2221ffa6d5bb6b3c8fe64c1f5a74Marc Blankimport android.content.ContentValues; 22680e59f477fe2221ffa6d5bb6b3c8fe64c1f5a74Marc Blankimport android.content.Context; 2336e181376b06c8905af2d22bf494a2423f50aa65Alon Albertimport android.content.OperationApplicationException; 24f7773165a611f7cdf97aa9c289e41cfcaa28f7aeYu Ping Huimport android.os.Bundle; 2536e181376b06c8905af2d22bf494a2423f50aa65Alon Albertimport android.os.RemoteException; 26680e59f477fe2221ffa6d5bb6b3c8fe64c1f5a74Marc Blank 277372782488977df778a33d990401ce9e397f646bMarc Blankimport com.android.emailcommon.provider.Account; 28f7773165a611f7cdf97aa9c289e41cfcaa28f7aeYu Ping Huimport com.android.emailcommon.provider.EmailContent; 29c8e4352ea6cfa67f15140512e84af8ccede222d2Marc Blankimport com.android.emailcommon.provider.EmailContent.MailboxColumns; 304d8774462ace9a45154b2df418b9f2fe7a9c685dBen Komaloimport com.android.emailcommon.provider.Mailbox; 3177186bb1a174432ef272584374942d8b9228e39cMarc Blankimport com.android.exchange.CommandStatusException; 3277186bb1a174432ef272584374942d8b9228e39cMarc Blankimport com.android.exchange.CommandStatusException.CommandStatus; 33110837ebff288a75f9bda067c38e2c46797d99b5Alon Albertimport com.android.exchange.Eas; 3436e181376b06c8905af2d22bf494a2423f50aa65Alon Albertimport com.android.mail.utils.LogUtils; 35ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 3667698e240187c902bed123bf18d342ff25ec75c7Marc Blankimport java.io.IOException; 3767698e240187c902bed123bf18d342ff25ec75c7Marc Blankimport java.io.InputStream; 38ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 39ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank/** 40ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * Base class for the Email and PIM sync parsers 41ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * Handles the basic flow of syncKeys, looping to get more data, handling errors, etc. 42ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * Each subclass must implement a handful of methods that relate specifically to the data type 43ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * 44ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank */ 45368adeb5779fed5d64770d2131125dd93e43ab78Marc Blankpublic abstract class AbstractSyncParser extends Parser { 46110837ebff288a75f9bda067c38e2c46797d99b5Alon Albert private static final String TAG = Eas.LOG_TAG; 4736e181376b06c8905af2d22bf494a2423f50aa65Alon Albert 481b06024587a4499bcf3f9005337e8f7cae5ffa26Marc Blank protected Mailbox mMailbox; 491b06024587a4499bcf3f9005337e8f7cae5ffa26Marc Blank protected Account mAccount; 501b06024587a4499bcf3f9005337e8f7cae5ffa26Marc Blank protected Context mContext; 511b06024587a4499bcf3f9005337e8f7cae5ffa26Marc Blank protected ContentResolver mContentResolver; 52ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 538efd25be4e1db3c0c79aae2ca1b4664b21bb410bMarc Blank private boolean mLooping; 548efd25be4e1db3c0c79aae2ca1b4664b21bb410bMarc Blank 55c9e47f85203da0ea3b6e9a49aa2007d1fc6f0814Yu Ping Hu public AbstractSyncParser(final Context context, final ContentResolver resolver, 56c9e47f85203da0ea3b6e9a49aa2007d1fc6f0814Yu Ping Hu final InputStream in, final Mailbox mailbox, final Account account) throws IOException { 57c9e47f85203da0ea3b6e9a49aa2007d1fc6f0814Yu Ping Hu super(in); 58c9e47f85203da0ea3b6e9a49aa2007d1fc6f0814Yu Ping Hu init(context, resolver, mailbox, account); 59c9e47f85203da0ea3b6e9a49aa2007d1fc6f0814Yu Ping Hu } 60c9e47f85203da0ea3b6e9a49aa2007d1fc6f0814Yu Ping Hu 6148af7392c82262d17700e3fbdccf3a582809d449Marc Blank public AbstractSyncParser(InputStream in, AbstractSyncAdapter adapter) throws IOException { 62ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank super(in); 6326d9677a1eb48553241897b63a77bbd33daa9f92Marc Blank init(adapter); 6426d9677a1eb48553241897b63a77bbd33daa9f92Marc Blank } 6526d9677a1eb48553241897b63a77bbd33daa9f92Marc Blank 6626d9677a1eb48553241897b63a77bbd33daa9f92Marc Blank public AbstractSyncParser(Parser p, AbstractSyncAdapter adapter) throws IOException { 6726d9677a1eb48553241897b63a77bbd33daa9f92Marc Blank super(p); 6826d9677a1eb48553241897b63a77bbd33daa9f92Marc Blank init(adapter); 6926d9677a1eb48553241897b63a77bbd33daa9f92Marc Blank } 7026d9677a1eb48553241897b63a77bbd33daa9f92Marc Blank 710756a9ff8e69b8cc52374fa68efb2e81971ee5c4Martin Hibdon public AbstractSyncParser(final Parser p, final Context context, final ContentResolver resolver, 720756a9ff8e69b8cc52374fa68efb2e81971ee5c4Martin Hibdon final Mailbox mailbox, final Account account) throws IOException { 730756a9ff8e69b8cc52374fa68efb2e81971ee5c4Martin Hibdon super(p); 740756a9ff8e69b8cc52374fa68efb2e81971ee5c4Martin Hibdon init(context, resolver, mailbox, account); 750756a9ff8e69b8cc52374fa68efb2e81971ee5c4Martin Hibdon } 760756a9ff8e69b8cc52374fa68efb2e81971ee5c4Martin Hibdon 77c9e47f85203da0ea3b6e9a49aa2007d1fc6f0814Yu Ping Hu private void init(final AbstractSyncAdapter adapter) { 78c9e47f85203da0ea3b6e9a49aa2007d1fc6f0814Yu Ping Hu init(adapter.mContext, adapter.mContext.getContentResolver(), adapter.mMailbox, 79c9e47f85203da0ea3b6e9a49aa2007d1fc6f0814Yu Ping Hu adapter.mAccount); 80c9e47f85203da0ea3b6e9a49aa2007d1fc6f0814Yu Ping Hu } 81c9e47f85203da0ea3b6e9a49aa2007d1fc6f0814Yu Ping Hu 82c9e47f85203da0ea3b6e9a49aa2007d1fc6f0814Yu Ping Hu private void init(final Context context, final ContentResolver resolver, final Mailbox mailbox, 83c9e47f85203da0ea3b6e9a49aa2007d1fc6f0814Yu Ping Hu final Account account) { 84c9e47f85203da0ea3b6e9a49aa2007d1fc6f0814Yu Ping Hu mContext = context; 85c9e47f85203da0ea3b6e9a49aa2007d1fc6f0814Yu Ping Hu mContentResolver = resolver; 86c9e47f85203da0ea3b6e9a49aa2007d1fc6f0814Yu Ping Hu mMailbox = mailbox; 87c9e47f85203da0ea3b6e9a49aa2007d1fc6f0814Yu Ping Hu mAccount = account; 88ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 89ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 90ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank /** 91ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * Read, parse, and act on incoming commands from the Exchange server 92ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * @throws IOException if the connection is broken 9377186bb1a174432ef272584374942d8b9228e39cMarc Blank * @throws CommandStatusException 94ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank */ 9577186bb1a174432ef272584374942d8b9228e39cMarc Blank public abstract void commandsParser() throws IOException, CommandStatusException; 96ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 97ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank /** 98ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * Read, parse, and act on server responses 99ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * @throws IOException 100ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank */ 10148af7392c82262d17700e3fbdccf3a582809d449Marc Blank public abstract void responsesParser() throws IOException; 10248af7392c82262d17700e3fbdccf3a582809d449Marc Blank 10348af7392c82262d17700e3fbdccf3a582809d449Marc Blank /** 10448af7392c82262d17700e3fbdccf3a582809d449Marc Blank * Commit any changes found during parsing 10548af7392c82262d17700e3fbdccf3a582809d449Marc Blank * @throws IOException 10648af7392c82262d17700e3fbdccf3a582809d449Marc Blank */ 10736e181376b06c8905af2d22bf494a2423f50aa65Alon Albert public abstract void commit() throws IOException, RemoteException, 10836e181376b06c8905af2d22bf494a2423f50aa65Alon Albert OperationApplicationException; 109ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 1108efd25be4e1db3c0c79aae2ca1b4664b21bb410bMarc Blank public boolean isLooping() { 1118efd25be4e1db3c0c79aae2ca1b4664b21bb410bMarc Blank return mLooping; 1128efd25be4e1db3c0c79aae2ca1b4664b21bb410bMarc Blank } 1138efd25be4e1db3c0c79aae2ca1b4664b21bb410bMarc Blank 114ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank /** 11577186bb1a174432ef272584374942d8b9228e39cMarc Blank * Skip through tags until we reach the specified end tag 11677186bb1a174432ef272584374942d8b9228e39cMarc Blank * @param endTag the tag we end with 11777186bb1a174432ef272584374942d8b9228e39cMarc Blank * @throws IOException 11877186bb1a174432ef272584374942d8b9228e39cMarc Blank */ 11977186bb1a174432ef272584374942d8b9228e39cMarc Blank public void skipParser(int endTag) throws IOException { 12077186bb1a174432ef272584374942d8b9228e39cMarc Blank while (nextTag(endTag) != END) { 12177186bb1a174432ef272584374942d8b9228e39cMarc Blank skipTag(); 12277186bb1a174432ef272584374942d8b9228e39cMarc Blank } 12377186bb1a174432ef272584374942d8b9228e39cMarc Blank } 12477186bb1a174432ef272584374942d8b9228e39cMarc Blank 12577186bb1a174432ef272584374942d8b9228e39cMarc Blank /** 126ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * Loop through the top-level structure coming from the Exchange server 127ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * Sync keys and the more available flag are handled here, whereas specific data parsing 128ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * is handled by abstract methods implemented for each data class (e.g. Email, Contacts, etc.) 12977186bb1a174432ef272584374942d8b9228e39cMarc Blank * @throws CommandStatusException 130ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank */ 1317c582a7fb883b3be728f270fbe5277676fe37cf9Marc Blank @Override 13277186bb1a174432ef272584374942d8b9228e39cMarc Blank public boolean parse() throws IOException, CommandStatusException { 133ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank int status; 134ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank boolean moreAvailable = false; 135da7f22d3a76dca40eaa95243288cea576852864cMarc Blank boolean newSyncKey = false; 1368efd25be4e1db3c0c79aae2ca1b4664b21bb410bMarc Blank mLooping = false; 137ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank // If we're not at the top of the xml tree, throw an exception 1387c582a7fb883b3be728f270fbe5277676fe37cf9Marc Blank if (nextTag(START_DOCUMENT) != Tags.SYNC_SYNC) { 1391431215b5fc40d0d6498b0fe602ad4d1b8a66ff3Marc Blank throw new EasParserException(); 140ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 141a05c26d8d2cce3faa152096cb8116fce375c6d81Marc Blank 142a05c26d8d2cce3faa152096cb8116fce375c6d81Marc Blank boolean mailboxUpdated = false; 143a05c26d8d2cce3faa152096cb8116fce375c6d81Marc Blank ContentValues cv = new ContentValues(); 144a05c26d8d2cce3faa152096cb8116fce375c6d81Marc Blank 145ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank // Loop here through the remaining xml 146ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank while (nextTag(START_DOCUMENT) != END_DOCUMENT) { 1477c582a7fb883b3be728f270fbe5277676fe37cf9Marc Blank if (tag == Tags.SYNC_COLLECTION || tag == Tags.SYNC_COLLECTIONS) { 148ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank // Ignore these tags, since we've only got one collection syncing in this loop 1497c582a7fb883b3be728f270fbe5277676fe37cf9Marc Blank } else if (tag == Tags.SYNC_STATUS) { 150ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank // Status = 1 is success; everything else is a failure 151ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank status = getValueInt(); 152ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank if (status != 1) { 15377186bb1a174432ef272584374942d8b9228e39cMarc Blank if (status == 3 || CommandStatus.isBadSyncKey(status)) { 154ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank // Must delete all of the data and start over with syncKey of "0" 155c9e47f85203da0ea3b6e9a49aa2007d1fc6f0814Yu Ping Hu mMailbox.mSyncKey = "0"; 1565cc7ea3e24f1c05f71a3223ac6fa8b69d211735cYu Ping Hu newSyncKey = true; 157722006c7b116240d9383c84d5e76ee69796dd571Alon Albert wipe(); 158ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank // Indicate there's more so that we'll start syncing again 159ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank moreAvailable = true; 160f7b0fd783fa0eec52473e0d0b832bc5adee1d69bMarc Blank } else if (status == 16 || status == 5) { 161f7b0fd783fa0eec52473e0d0b832bc5adee1d69bMarc Blank // Status 16 indicates a transient server error (indeterminate state) 162f7b0fd783fa0eec52473e0d0b832bc5adee1d69bMarc Blank // Status 5 indicates "server error"; this tends to loop for a while so 163f7b0fd783fa0eec52473e0d0b832bc5adee1d69bMarc Blank // throwing IOException will at least provide backoff behavior 1645ec3d0587c18603167f7a751c9b8974ba7a19758Marc Blank throw new IOException(); 165680e59f477fe2221ffa6d5bb6b3c8fe64c1f5a74Marc Blank } else if (status == 8 || status == 12) { 166680e59f477fe2221ffa6d5bb6b3c8fe64c1f5a74Marc Blank // Status 8 is Bad; it means the server doesn't recognize the serverId it 167680e59f477fe2221ffa6d5bb6b3c8fe64c1f5a74Marc Blank // sent us. 12 means that we're being asked to refresh the folder list. 168680e59f477fe2221ffa6d5bb6b3c8fe64c1f5a74Marc Blank // We'll do that with 8 also... 169f7773165a611f7cdf97aa9c289e41cfcaa28f7aeYu Ping Hu // TODO: Improve this -- probably best to do this synchronously and then 170f7773165a611f7cdf97aa9c289e41cfcaa28f7aeYu Ping Hu // immediately retry the current sync. 171f7773165a611f7cdf97aa9c289e41cfcaa28f7aeYu Ping Hu final Bundle extras = new Bundle(1); 172f7773165a611f7cdf97aa9c289e41cfcaa28f7aeYu Ping Hu extras.putBoolean(Mailbox.SYNC_EXTRA_ACCOUNT_ONLY, true); 173f7773165a611f7cdf97aa9c289e41cfcaa28f7aeYu Ping Hu ContentResolver.requestSync(new android.accounts.Account( 174f7773165a611f7cdf97aa9c289e41cfcaa28f7aeYu Ping Hu mAccount.mEmailAddress, Eas.EXCHANGE_ACCOUNT_MANAGER_TYPE), 175f7773165a611f7cdf97aa9c289e41cfcaa28f7aeYu Ping Hu EmailContent.AUTHORITY, extras); 176680e59f477fe2221ffa6d5bb6b3c8fe64c1f5a74Marc Blank // We don't have any provision for telling the user "wait a minute while 177680e59f477fe2221ffa6d5bb6b3c8fe64c1f5a74Marc Blank // we sync folders"... 178680e59f477fe2221ffa6d5bb6b3c8fe64c1f5a74Marc Blank throw new IOException(); 179376260021db980af284f824f0c918b203e965407Marc Blank } else if (status == 7) { 1807d35f61afc910b8f21d3225762c251df10dc76eaYu Ping Hu // TODO: Fix this. The handling here used to be pretty bogus, and it's not 1817d35f61afc910b8f21d3225762c251df10dc76eaYu Ping Hu // obvious that simply forcing another resync makes sense here. 18261c48abf43082f3094f21fd4c645ad9cf4dfbd74Marc Blank moreAvailable = true; 18377186bb1a174432ef272584374942d8b9228e39cMarc Blank } else { 1849cdb8c8219349c654101ee5fc71e2986a6cebc3bAlon Albert LogUtils.e(LogUtils.TAG, "Sync: Unknown status: " + status); 18577186bb1a174432ef272584374942d8b9228e39cMarc Blank // Access, provisioning, transient, etc. 18677186bb1a174432ef272584374942d8b9228e39cMarc Blank throw new CommandStatusException(status); 187ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 188ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 1897c582a7fb883b3be728f270fbe5277676fe37cf9Marc Blank } else if (tag == Tags.SYNC_COMMANDS) { 190ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank commandsParser(); 1917c582a7fb883b3be728f270fbe5277676fe37cf9Marc Blank } else if (tag == Tags.SYNC_RESPONSES) { 192ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank responsesParser(); 1937c582a7fb883b3be728f270fbe5277676fe37cf9Marc Blank } else if (tag == Tags.SYNC_MORE_AVAILABLE) { 194ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank moreAvailable = true; 1957c582a7fb883b3be728f270fbe5277676fe37cf9Marc Blank } else if (tag == Tags.SYNC_SYNC_KEY) { 196c9e47f85203da0ea3b6e9a49aa2007d1fc6f0814Yu Ping Hu if (mMailbox.mSyncKey.equals("0")) { 197ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank moreAvailable = true; 1989d4ac93efbba01afe668f9406feec69b3a2374ebMarc Blank } 199ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank String newKey = getValue(); 2000a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank userLog("Parsed key for ", mMailbox.mDisplayName, ": ", newKey); 201a05c26d8d2cce3faa152096cb8116fce375c6d81Marc Blank if (!newKey.equals(mMailbox.mSyncKey)) { 202c9e47f85203da0ea3b6e9a49aa2007d1fc6f0814Yu Ping Hu mMailbox.mSyncKey = newKey; 203a05c26d8d2cce3faa152096cb8116fce375c6d81Marc Blank cv.put(MailboxColumns.SYNC_KEY, newKey); 204a05c26d8d2cce3faa152096cb8116fce375c6d81Marc Blank mailboxUpdated = true; 205da7f22d3a76dca40eaa95243288cea576852864cMarc Blank newSyncKey = true; 206da7f22d3a76dca40eaa95243288cea576852864cMarc Blank } 207ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } else { 208ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank skipTag(); 209ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 210ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 211ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 212da7f22d3a76dca40eaa95243288cea576852864cMarc Blank // If we don't have a new sync key, ignore moreAvailable (or we'll loop) 213da7f22d3a76dca40eaa95243288cea576852864cMarc Blank if (moreAvailable && !newSyncKey) { 21438ebc3d89a3c82589cf7bb413dc26c1a70b1a802Alon Albert LogUtils.e(TAG, "Looping detected"); 2158efd25be4e1db3c0c79aae2ca1b4664b21bb410bMarc Blank mLooping = true; 216da7f22d3a76dca40eaa95243288cea576852864cMarc Blank } 217da7f22d3a76dca40eaa95243288cea576852864cMarc Blank 21848af7392c82262d17700e3fbdccf3a582809d449Marc Blank // Commit any changes 21936e181376b06c8905af2d22bf494a2423f50aa65Alon Albert try { 22036e181376b06c8905af2d22bf494a2423f50aa65Alon Albert commit(); 22136e181376b06c8905af2d22bf494a2423f50aa65Alon Albert if (mailboxUpdated) { 22236e181376b06c8905af2d22bf494a2423f50aa65Alon Albert mMailbox.update(mContext, cv); 22336e181376b06c8905af2d22bf494a2423f50aa65Alon Albert } 22436e181376b06c8905af2d22bf494a2423f50aa65Alon Albert } catch (RemoteException e) { 22536e181376b06c8905af2d22bf494a2423f50aa65Alon Albert LogUtils.e(TAG, "Failed to commit changes", e); 22636e181376b06c8905af2d22bf494a2423f50aa65Alon Albert } catch (OperationApplicationException e) { 22736e181376b06c8905af2d22bf494a2423f50aa65Alon Albert LogUtils.e(TAG, "Failed to commit changes", e); 22827cf341571fac3d8dbe866f503c34fc31e02bf85Marc Blank } 229ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank // Let the caller know that there's more to do 2300638c5ede5fc97b32e4b48d40c431c007860d0f6Marc Blank if (moreAvailable) { 2310638c5ede5fc97b32e4b48d40c431c007860d0f6Marc Blank userLog("MoreAvailable"); 2320638c5ede5fc97b32e4b48d40c431c007860d0f6Marc Blank } 233ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank return moreAvailable; 234ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 235ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 23628f3556f92b20b2efb800c1d95c29b04a3bbbb4fMartin Hibdon abstract protected void wipe(); 237722006c7b116240d9383c84d5e76ee69796dd571Alon Albert 2380a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank void userLog(String ...strings) { 239c9e47f85203da0ea3b6e9a49aa2007d1fc6f0814Yu Ping Hu // TODO: Convert to other logging types? 240c9e47f85203da0ea3b6e9a49aa2007d1fc6f0814Yu Ping Hu //mService.userLog(strings); 2410a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank } 242ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 2430a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank void userLog(String string, int num, String string2) { 244c9e47f85203da0ea3b6e9a49aa2007d1fc6f0814Yu Ping Hu // TODO: Convert to other logging types? 245c9e47f85203da0ea3b6e9a49aa2007d1fc6f0814Yu Ping Hu //mService.userLog(string, num, string2); 2460a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank } 247ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank} 248