Ensure policy notifications are shown

cherry-pick of:
https://googleplex-android-review.googlesource.com/218352
https://googleplex-android-review.googlesource.com/218353

Bug: 8510828
Change-Id: Ic788c40456e32fec5e7589c4ed2f40e399dd062d
diff --git a/exchange2/src/com/android/exchange/EasAccountService.java b/exchange2/src/com/android/exchange/EasAccountService.java
index 533a5df..863e0d6 100644
--- a/exchange2/src/com/android/exchange/EasAccountService.java
+++ b/exchange2/src/com/android/exchange/EasAccountService.java
@@ -310,7 +310,15 @@
 
             while (!isStopped()) {
                 // If we're not allowed to sync (e.g. roaming policy), leave now
-                if (!ExchangeService.canAutoSync(mAccount)) return;
+                if (!ExchangeService.canAutoSync(mAccount)) {
+                    if (ExchangeService.onSecurityHold(mAccount)) {
+                        mExitStatus = EasSyncService.EXIT_SECURITY_FAILURE;
+                    } else {
+                        // Use backoff rules, etc.
+                        mExitStatus = EasSyncService.EXIT_IO_ERROR;
+                    }
+                    return;
+                }
                 userLog("Sending Account syncKey: ", mAccount.mSyncKey);
                 Serializer s = new Serializer();
                 s.start(Tags.FOLDER_FOLDER_SYNC).start(Tags.FOLDER_SYNC_KEY)
diff --git a/exchange2/src/com/android/exchange/ExchangeService.java b/exchange2/src/com/android/exchange/ExchangeService.java
index be2ad65..0310008 100644
--- a/exchange2/src/com/android/exchange/ExchangeService.java
+++ b/exchange2/src/com/android/exchange/ExchangeService.java
@@ -642,7 +642,7 @@
         }
     }
 
-    private boolean onSecurityHold(Account account) {
+    static boolean onSecurityHold(Account account) {
         return (account.mFlags & Account.FLAGS_SECURITY_HOLD) != 0;
     }
 
@@ -690,7 +690,7 @@
                                     PolicyServiceProxy.setAccountHoldFlag(ExchangeService.this,
                                             account, false);
                                     log("isActive true; release hold for " + account.mDisplayName);
-                                }
+				}
                             }
                         }
                     }
@@ -2162,7 +2162,11 @@
             if (policy == null) {
                 policy = Policy.restorePolicyWithId(INSTANCE, policyKey);
                 account.mPolicy = policy;
-                if (!PolicyServiceProxy.isActive(exchangeService, policy)) return false;
+                if (!PolicyServiceProxy.isActive(exchangeService, policy)) {
+                    PolicyServiceProxy.setAccountHoldFlag(exchangeService, account, true);
+                    log("canAutoSync; policies not active, set hold flag");
+                    return false;
+                }
             }
             if (policy != null && policy.mRequireManualSyncWhenRoaming && networkInfo.isRoaming()) {
                 return false;
@@ -2280,7 +2284,7 @@
         if (c == null) throw new ProviderUnavailableException();
         try {
             while (c.moveToNext()) {
-                long mailboxId = c.getLong(Mailbox.CONTENT_ID_COLUMN);
+                final long mailboxId = c.getLong(Mailbox.CONTENT_ID_COLUMN);
                 AbstractSyncService service = null;
                 synchronized (sSyncLock) {
                     service = mServiceMap.get(mailboxId);
@@ -2290,12 +2294,6 @@
                     Account account = getAccountById(c.getInt(Mailbox.CONTENT_ACCOUNT_KEY_COLUMN));
                     if (account == null) continue;
 
-                    // We handle a few types of mailboxes specially
-                    int mailboxType = c.getInt(Mailbox.CONTENT_TYPE_COLUMN);
-                    if (!isMailboxSyncable(account, mailboxType)) {
-                        continue;
-                    }
-
                     // Check whether we're in a hold (temporary or permanent)
                     SyncError syncError = mSyncErrorMap.get(mailboxId);
                     if (syncError != null) {
@@ -2315,6 +2313,18 @@
                         }
                     }
 
+                    // We handle a few types of mailboxes specially
+                    final int mailboxType = c.getInt(Mailbox.CONTENT_TYPE_COLUMN);
+                    if (!isMailboxSyncable(account, mailboxType)) {
+                        // If there isn't an entry in the sync error map, in case of a security
+                        // hold, add one to allow the next sync to be deferred
+                        if (syncError == null && onSecurityHold(account)) {
+                            mSyncErrorMap.put(mailboxId,
+                                    new SyncError(AbstractSyncService.EXIT_SECURITY_FAILURE, true));
+                        }
+                        continue;
+                    }
+
                     // Otherwise, we use the sync interval
                     long syncInterval = c.getInt(Mailbox.CONTENT_SYNC_INTERVAL_COLUMN);
                     if (syncInterval == Mailbox.CHECK_INTERVAL_PUSH) {