Change EAS request implementation to use LinkedBlockingQueue

* Make sure that requests added during sync() aren't missed

Change-Id: I20a7788f3695ef6a99642240230f0d004f034f44
diff --git a/src/com/android/exchange/AbstractSyncService.java b/src/com/android/exchange/AbstractSyncService.java
index b750113..c676cce 100644
--- a/src/com/android/exchange/AbstractSyncService.java
+++ b/src/com/android/exchange/AbstractSyncService.java
@@ -29,7 +29,7 @@
 import android.os.Bundle;
 import android.util.Log;
 
-import java.util.ArrayList;
+import java.util.concurrent.LinkedBlockingQueue;
 
 /**
  * Base class for all protocol services SyncManager (extends Service, implements
@@ -70,7 +70,7 @@
     protected Object mSynchronizer = new Object();
 
     protected volatile long mRequestTime = 0;
-    protected ArrayList<Request> mRequests = new ArrayList<Request>();
+    protected LinkedBlockingQueue<Request> mRequestQueue = new LinkedBlockingQueue<Request>();
     protected PartRequest mPendingRequest = null;
 
     /**
@@ -294,15 +294,15 @@
      */
 
     public void addRequest(Request req) {
-        synchronized (mRequests) {
-            mRequests.add(req);
-            mRequestTime = System.currentTimeMillis();
-        }
+        mRequestQueue.offer(req);
     }
 
     public void removeRequest(Request req) {
-        synchronized (mRequests) {
-            mRequests.remove(req);
-        }
+        mRequestQueue.remove(req);
     }
+
+    public boolean hasPendingRequests() {
+        return !mRequestQueue.isEmpty();
+}
+
 }
diff --git a/src/com/android/exchange/EasSyncService.java b/src/com/android/exchange/EasSyncService.java
index 988fb75..740616a 100644
--- a/src/com/android/exchange/EasSyncService.java
+++ b/src/com/android/exchange/EasSyncService.java
@@ -2028,7 +2028,7 @@
 
         boolean moreAvailable = true;
         int loopingCount = 0;
-        while (!mStop && moreAvailable) {
+        while (!mStop && (moreAvailable || hasPendingRequests())) {
             // If we have no connectivity, just exit cleanly.  SyncManager will start us up again
             // when connectivity has returned
             if (!hasConnectivity()) {
@@ -2046,12 +2046,11 @@
             // Now, handle various requests
             while (true) {
                 Request req = null;
-                synchronized (mRequests) {
-                    if (mRequests.isEmpty()) {
-                        break;
-                    } else {
-                        req = mRequests.get(0);
-                    }
+
+                if (mRequestQueue.isEmpty()) {
+                    break;
+                } else {
+                    req = mRequestQueue.peek();
                 }
 
                 // Our two request types are PartRequest (loading attachment) and
@@ -2064,9 +2063,12 @@
 
                 // If there's an exception handling the request, we'll throw it
                 // Otherwise, we remove the request
-                synchronized(mRequests) {
-                    mRequests.remove(req);
-                }
+                mRequestQueue.remove();
+            }
+
+            // Don't sync if we've got nothing to do
+            if (!moreAvailable) {
+                continue;
             }
 
             Serializer s = new Serializer();
@@ -2134,7 +2136,6 @@
                 if (header != null && header.getValue().equals("0")) {
                     // If this happens, exit cleanly, and change the interval from push to ping
                     // if necessary
-                    mExitStatus = EXIT_DONE;
                     userLog("Empty sync response; finishing");
                     if (mMailbox.mSyncInterval == Mailbox.CHECK_INTERVAL_PUSH) {
                         userLog("Changing mailbox from push to ping");
@@ -2144,7 +2145,12 @@
                                 ContentUris.withAppendedId(Mailbox.CONTENT_URI, mMailbox.mId), cv,
                                 null, null);
                     }
-                    return;
+                    if (mRequestQueue.isEmpty()) {
+                        mExitStatus = EXIT_DONE;
+                        return;
+                    } else {
+                        continue;
+                    }
                 }
                 InputStream is = resp.getEntity().getContent();
                 if (is != null) {
diff --git a/src/com/android/exchange/SyncManager.java b/src/com/android/exchange/SyncManager.java
index a015a7f..8503f2e 100644
--- a/src/com/android/exchange/SyncManager.java
+++ b/src/com/android/exchange/SyncManager.java
@@ -2368,7 +2368,7 @@
             int exitStatus = svc.mExitStatus;
             switch (exitStatus) {
                 case AbstractSyncService.EXIT_DONE:
-                    if (!svc.mRequests.isEmpty()) {
+                    if (svc.hasPendingRequests()) {
                         // TODO Handle this case
                     }
                     errorMap.remove(mailboxId);