DO NOT MERGE: Add safety net to prevent sync stoppage

* Backport of Ie70df4d991f772069726b809d3bd51fbe06de728 from
  master; makes sure that security holds are updated when
  ExchangeService starts
* Partial backport of I55086899be9a2715cfbd3975e886781d8fc7080e
  from master; prevents erroneous security errors from non-
  account mailboxes

Bug: 4464610
Change-Id: Ic22c0942c5999f2e00dffbcdea8071592ec0d537
diff --git a/src/com/android/exchange/EasSyncService.java b/src/com/android/exchange/EasSyncService.java
index c45df9d..87bcd17 100644
--- a/src/com/android/exchange/EasSyncService.java
+++ b/src/com/android/exchange/EasSyncService.java
@@ -1643,12 +1643,6 @@
                 // Don't care if this fails
             }
 
-            // Don't run if we're being held
-            if ((mAccount.mFlags & Account.FLAGS_SECURITY_HOLD) != 0) {
-                mExitStatus = EXIT_SECURITY_FAILURE;
-                return;
-            }
-
             if (mAccount.mSyncKey == null) {
                 mAccount.mSyncKey = "0";
                 userLog("Account syncKey INIT to 0");
@@ -2360,7 +2354,8 @@
                 } else {
                     userLog("Sync response error: ", code);
                     if (isProvisionError(code)) {
-                        mExitStatus = EXIT_SECURITY_FAILURE;
+                        // Simply report "ok" here; account mailbox handles security errors
+                        mExitStatus = EXIT_DONE;
                     } else if (isAuthError(code)) {
                         mExitStatus = EXIT_LOGIN_FAILURE;
                     } else {
diff --git a/src/com/android/exchange/ExchangeService.java b/src/com/android/exchange/ExchangeService.java
index ffdbb82..c085b57 100644
--- a/src/com/android/exchange/ExchangeService.java
+++ b/src/com/android/exchange/ExchangeService.java
@@ -33,6 +33,7 @@
 import com.android.emailcommon.service.EmailServiceStatus;
 import com.android.emailcommon.service.IEmailService;
 import com.android.emailcommon.service.IEmailServiceCallback;
+import com.android.emailcommon.service.PolicyServiceProxy;
 import com.android.emailcommon.utility.AccountReconciler;
 import com.android.emailcommon.utility.SSLUtils;
 import com.android.emailcommon.utility.Utility;
@@ -552,9 +553,11 @@
         String mSyncableEasMailboxSelector = null;
         String mEasAccountSelector = null;
 
+        // Runs when ExchangeService first starts
         public AccountObserver(Handler handler) {
             super(handler);
             // At startup, we want to see what EAS accounts exist and cache them
+            // TODO: Move database work out of UI thread
             Context context = getContext();
             synchronized (mAccountList) {
                 collectEasAccounts(context, mAccountList);
@@ -563,10 +566,33 @@
                     int cnt = Mailbox.count(context, Mailbox.CONTENT_URI, "accountKey="
                             + account.mId, null);
                     if (cnt == 0) {
+                        // This case handles a newly created account
                         addAccountMailbox(account.mId);
                     }
                 }
             }
+            // Run through accounts and update account hold information
+            Utility.runAsync(new Runnable() {
+                @Override
+                public void run() {
+                    synchronized (mAccountList) {
+                        for (Account account : mAccountList) {
+                            if ((account.mFlags & Account.FLAGS_SECURITY_HOLD) != 0) {
+                                // If we're in a security hold, and our policies are active, release
+                                // the hold; otherwise, ping PolicyService that this account's
+                                // policies are required
+                                if (PolicyServiceProxy.isActive(ExchangeService.this, null)) {
+                                    PolicyServiceProxy.setAccountHoldFlag(ExchangeService.this,
+                                            account, false);
+                                    log("isActive true; release hold for " + account.mDisplayName);
+                                } else {
+                                    PolicyServiceProxy.policiesRequired(ExchangeService.this,
+                                            account.mId);
+                                }
+                            }
+                        }
+                    }
+                }});
         }
 
         /**