Fix a few sync-related bugs:
* Don't leak the receiver registered by AccountManager for updates
* Only restart dead threads if they aren't logged in the syncErrorMap
(to prevent looping behavior as seen in bug #2072456
Change-Id: Id1b4c53ef8b721bf8bfa8426627fd76831864c70
diff --git a/src/com/android/exchange/AbstractSyncService.java b/src/com/android/exchange/AbstractSyncService.java
index 59dc58b..15cede8 100644
--- a/src/com/android/exchange/AbstractSyncService.java
+++ b/src/com/android/exchange/AbstractSyncService.java
@@ -203,7 +203,12 @@
}
}
- public void userLog(Exception e) {
+ public void userLog(String str, Exception e) {
+ if (Eas.USER_LOG) {
+ Log.e(TAG, str, e);
+ } else {
+ Log.e(TAG, str + e);
+ }
if (Eas.FILE_LOG) {
FileLogger.log(e);
}
diff --git a/src/com/android/exchange/EasSyncService.java b/src/com/android/exchange/EasSyncService.java
index 9d0e21b..62e770b 100644
--- a/src/com/android/exchange/EasSyncService.java
+++ b/src/com/android/exchange/EasSyncService.java
@@ -57,7 +57,6 @@
import android.content.Context;
import android.database.Cursor;
import android.os.RemoteException;
-import android.util.Log;
import java.io.File;
import java.io.FileOutputStream;
@@ -1024,11 +1023,10 @@
}
} catch (IOException e) {
String message = e.getMessage();
- userLog("Caught IOException: ", ((message == null) ? "" : message));
+ userLog("Caught IOException: ", ((message == null) ? "No message" : message));
mExitStatus = EXIT_IO_ERROR;
} catch (Exception e) {
- Log.e(TAG, "Uncaught exception in EasSyncService" + e);
- userLog(e);
+ userLog("Uncaught exception in EasSyncService", e);
} finally {
if (!mStop) {
userLog(mMailbox.mDisplayName, ": sync finished");
diff --git a/src/com/android/exchange/SyncManager.java b/src/com/android/exchange/SyncManager.java
index ab3e23f..ae31c8e 100644
--- a/src/com/android/exchange/SyncManager.java
+++ b/src/com/android/exchange/SyncManager.java
@@ -63,7 +63,6 @@
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
-import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
@@ -621,7 +620,7 @@
*/
static public synchronized String getDeviceId() throws IOException {
if (INSTANCE == null) {
- throw new IOException();
+ throw new IOException("No SyncManager instance");
}
// If we've already got the id, return it
if (INSTANCE.mDeviceId != null) {
@@ -645,14 +644,9 @@
w.close();
return id;
}
- } catch (FileNotFoundException e) {
- // We'll just use the default below
- Log.e(TAG, "Can't get device name!");
} catch (IOException e) {
- // We'll just use the default below
- Log.e(TAG, "Can't get device name!");
}
- throw new IOException();
+ throw new IOException("Can't get device name");
}
@Override
@@ -705,6 +699,9 @@
resolver.unregisterContentObserver(mSyncedMessageObserver);
resolver.unregisterContentObserver(mMessageObserver);
+ // Don't leak the Intent associated with this listener
+ AccountManager.get(this).removeOnAccountsUpdatedListener(mAccountsUpdatedListener);
+
// Clear pending alarms
clearAlarms();
@@ -1286,7 +1283,8 @@
}
} else {
Thread thread = service.mThread;
- if (thread != null && !thread.isAlive()) {
+ // Look for threads that have died but aren't in an error state
+ if (thread != null && !thread.isAlive() && !mSyncErrorMap.containsKey(mid)) {
releaseMailbox(mid);
// Restart this if necessary
if (nextWait > 3*SECONDS) {
diff --git a/src/com/android/exchange/adapter/AbstractSyncParser.java b/src/com/android/exchange/adapter/AbstractSyncParser.java
index 2a323cf..d598c22 100644
--- a/src/com/android/exchange/adapter/AbstractSyncParser.java
+++ b/src/com/android/exchange/adapter/AbstractSyncParser.java
@@ -87,7 +87,7 @@
// If we're not at the top of the xml tree, throw an exception
if (nextTag(START_DOCUMENT) != Tags.SYNC_SYNC) {
- throw new IOException();
+ throw new EasParserException();
}
// Loop here through the remaining xml
while (nextTag(START_DOCUMENT) != END_DOCUMENT) {
diff --git a/src/com/android/exchange/adapter/FolderSyncParser.java b/src/com/android/exchange/adapter/FolderSyncParser.java
index b4fd00b..379a80f 100644
--- a/src/com/android/exchange/adapter/FolderSyncParser.java
+++ b/src/com/android/exchange/adapter/FolderSyncParser.java
@@ -103,7 +103,7 @@
boolean res = false;
boolean resetFolders = false;
if (nextTag(START_DOCUMENT) != Tags.FOLDER_FOLDER_SYNC)
- throw new IOException();
+ throw new EasParserException();
while (nextTag(START_DOCUMENT) != END_DOCUMENT) {
if (tag == Tags.FOLDER_STATUS) {
status = getValueInt();
@@ -122,7 +122,7 @@
// Other errors are at the server, so let's throw an error that will
// cause this sync to be retried at a later time
mService.errorLog("Throwing IOException; will retry later");
- throw new IOException();
+ throw new EasParserException("Folder status error");
}
}
} else if (tag == Tags.FOLDER_SYNC_KEY) {
diff --git a/src/com/android/exchange/adapter/Parser.java b/src/com/android/exchange/adapter/Parser.java
index f9a005f..ffe8039 100644
--- a/src/com/android/exchange/adapter/Parser.java
+++ b/src/com/android/exchange/adapter/Parser.java
@@ -116,6 +116,14 @@
public class EasParserException extends IOException {
private static final long serialVersionUID = 1L;
+
+ EasParserException() {
+ super("WBXML format error");
+ }
+
+ EasParserException(String reason) {
+ super(reason);
+ }
}
public boolean parse() throws IOException, EasException {
diff --git a/src/com/android/exchange/adapter/Serializer.java b/src/com/android/exchange/adapter/Serializer.java
index 0d9e669..faaade4 100644
--- a/src/com/android/exchange/adapter/Serializer.java
+++ b/src/com/android/exchange/adapter/Serializer.java
@@ -57,7 +57,7 @@
public void done() throws IOException {
if (depth != 0) {
- throw new IOException();
+ throw new IOException("Done received with unclosed tags");
}
writeInteger(out, 0);
out.write(buf.toByteArray());