Java Examples for com.android.exchange.adapter.FolderSyncParser

The following java examples will help you to understand the usage of com.android.exchange.adapter.FolderSyncParser. These source code samples are taken from different open source projects.

Example 1
Project: android_packages_apps_Email-master  File: EasSyncService.java View source code
/**
     * Performs FolderSync
     *
     * @throws IOException
     * @throws EasParserException
     */
public void runAccountMailbox() throws IOException, EasParserException {
    // We'll reuse this ContentValues object
    ContentValues cv = new ContentValues();
    // Initialize exit status to success
    mExitStatus = EmailServiceStatus.SUCCESS;
    try {
        try {
            SyncManager.callback().syncMailboxListStatus(mAccount.mId, EmailServiceStatus.IN_PROGRESS, 0);
        } catch (RemoteException e1) {
        }
        if (mAccount.mSyncKey == null) {
            mAccount.mSyncKey = "0";
            userLog("Account syncKey INIT to 0");
            cv.clear();
            cv.put(AccountColumns.SYNC_KEY, mAccount.mSyncKey);
            mAccount.update(mContext, cv);
        }
        boolean firstSync = mAccount.mSyncKey.equals("0");
        if (firstSync) {
            userLog("Initial FolderSync");
        }
        // When we first start up, change all mailboxes to push.
        cv.clear();
        cv.put(Mailbox.SYNC_INTERVAL, Mailbox.CHECK_INTERVAL_PUSH);
        if (mContentResolver.update(Mailbox.CONTENT_URI, cv, WHERE_ACCOUNT_AND_SYNC_INTERVAL_PING, new String[] { Long.toString(mAccount.mId) }) > 0) {
            SyncManager.kick("change ping boxes to push");
        }
        // Determine our protocol version, if we haven't already and save it in the Account
        if (mAccount.mProtocolVersion == null) {
            userLog("Determine EAS protocol version");
            HttpResponse resp = sendHttpClientOptions();
            int code = resp.getStatusLine().getStatusCode();
            userLog("OPTIONS response: ", code);
            if (code == HttpStatus.SC_OK) {
                Header header = resp.getFirstHeader("MS-ASProtocolCommands");
                userLog(header.getValue());
                header = resp.getFirstHeader("ms-asprotocolversions");
                String versions = header.getValue();
                if (versions != null) {
                    if (versions.contains("12.0")) {
                        mProtocolVersion = "12.0";
                    }
                    mProtocolVersionDouble = Double.parseDouble(mProtocolVersion);
                    mAccount.mProtocolVersion = mProtocolVersion;
                    // Save the protocol version
                    cv.clear();
                    cv.put(Account.PROTOCOL_VERSION, mProtocolVersion);
                    mAccount.update(mContext, cv);
                    userLog(versions);
                    userLog("Using version ", mProtocolVersion);
                } else {
                    errorLog("No protocol versions in OPTIONS response");
                    throw new IOException();
                }
            } else {
                errorLog("OPTIONS command failed; throwing IOException");
                throw new IOException();
            }
        }
        // Change all pushable boxes to push when we start the account mailbox
        if (mAccount.mSyncInterval == Account.CHECK_INTERVAL_PUSH) {
            cv.clear();
            cv.put(Mailbox.SYNC_INTERVAL, Mailbox.CHECK_INTERVAL_PUSH);
            if (mContentResolver.update(Mailbox.CONTENT_URI, cv, SyncManager.WHERE_IN_ACCOUNT_AND_PUSHABLE, new String[] { Long.toString(mAccount.mId) }) > 0) {
                userLog("Push account; set pushable boxes to push...");
            }
        }
        while (!mStop) {
            userLog("Sending Account syncKey: ", mAccount.mSyncKey);
            Serializer s = new Serializer();
            s.start(Tags.FOLDER_FOLDER_SYNC).start(Tags.FOLDER_SYNC_KEY).text(mAccount.mSyncKey).end().end().done();
            HttpResponse resp = sendHttpClientPost("FolderSync", s.toByteArray());
            if (mStop)
                break;
            int code = resp.getStatusLine().getStatusCode();
            if (code == HttpStatus.SC_OK) {
                HttpEntity entity = resp.getEntity();
                int len = (int) entity.getContentLength();
                if (len != 0) {
                    InputStream is = entity.getContent();
                    // Returns true if we need to sync again
                    if (new FolderSyncParser(is, new AccountSyncAdapter(mMailbox, this)).parse()) {
                        continue;
                    }
                }
            } else if (isAuthError(code)) {
                mExitStatus = EXIT_LOGIN_FAILURE;
            } else {
                userLog("FolderSync response error: ", code);
            }
            // Change all push/hold boxes to push
            cv.clear();
            cv.put(Mailbox.SYNC_INTERVAL, Account.CHECK_INTERVAL_PUSH);
            if (mContentResolver.update(Mailbox.CONTENT_URI, cv, WHERE_PUSH_HOLD_NOT_ACCOUNT_MAILBOX, new String[] { Long.toString(mAccount.mId) }) > 0) {
                userLog("Set push/hold boxes to push...");
            }
            try {
                SyncManager.callback().syncMailboxListStatus(mAccount.mId, mExitStatus, 0);
            } catch (RemoteException e1) {
            }
            // Wait for push notifications.
            String threadName = Thread.currentThread().getName();
            try {
                runPingLoop();
            } catch (StaleFolderListException e) {
                userLog("Ping interrupted; folder list requires sync...");
            } finally {
                Thread.currentThread().setName(threadName);
            }
        }
    } catch (IOException e) {
        try {
            if (!mStop) {
                SyncManager.callback().syncMailboxListStatus(mAccount.mId, EmailServiceStatus.CONNECTION_ERROR, 0);
            }
        } catch (RemoteException e1) {
        }
        throw e;
    }
}
Example 2
Project: android_packages_apps-master  File: EasSyncService.java View source code
@Override
public Bundle validateAccount(HostAuth hostAuth, Context context) {
    Bundle bundle = new Bundle();
    int resultCode = MessagingException.NO_ERROR;
    try {
        userLog("Testing EAS: ", hostAuth.mAddress, ", ", hostAuth.mLogin, ", ssl = ", hostAuth.shouldUseSsl() ? "1" : "0");
        mContext = context;
        mHostAddress = hostAuth.mAddress;
        mUserName = hostAuth.mLogin;
        mPassword = hostAuth.mPassword;
        setConnectionParameters(hostAuth.shouldUseSsl(), hostAuth.shouldTrustAllServerCerts(), hostAuth.mClientCertAlias);
        mDeviceId = ExchangeService.getDeviceId(context);
        mAccount = new Account();
        mAccount.mEmailAddress = hostAuth.mLogin;
        EasResponse resp = sendHttpClientOptions();
        try {
            int code = resp.getStatus();
            userLog("Validation (OPTIONS) response: " + code);
            if (code == HttpStatus.SC_OK) {
                // No exception means successful validation
                Header commands = resp.getHeader("MS-ASProtocolCommands");
                Header versions = resp.getHeader("ms-asprotocolversions");
                // Make sure we've got the right protocol version set up
                try {
                    if (commands == null || versions == null) {
                        userLog("OPTIONS response without commands or versions");
                        // We'll treat this as a protocol exception
                        throw new MessagingException(0);
                    }
                    setupProtocolVersion(this, versions);
                } catch (MessagingException e) {
                    bundle.putInt(EmailServiceProxy.VALIDATE_BUNDLE_RESULT_CODE, MessagingException.PROTOCOL_VERSION_UNSUPPORTED);
                    return bundle;
                }
                // Run second test here for provisioning failures using FolderSync
                userLog("Try folder sync");
                // Send "0" as the sync key for new accounts; otherwise, use the current key
                String syncKey = "0";
                Account existingAccount = Utility.findExistingAccount(context, -1L, hostAuth.mAddress, hostAuth.mLogin);
                if (existingAccount != null && existingAccount.mSyncKey != null) {
                    syncKey = existingAccount.mSyncKey;
                }
                Serializer s = new Serializer();
                s.start(Tags.FOLDER_FOLDER_SYNC).start(Tags.FOLDER_SYNC_KEY).text(syncKey).end().end().done();
                resp = sendHttpClientPost("FolderSync", s.toByteArray());
                code = resp.getStatus();
                // Handle HTTP error responses accordingly
                if (code == HttpStatus.SC_FORBIDDEN) {
                    // For validation only, we take 403 as ACCESS_DENIED (the account isn't
                    // authorized, possibly due to device type)
                    resultCode = MessagingException.ACCESS_DENIED;
                } else if (EasResponse.isProvisionError(code)) {
                    // The device needs to have security policies enforced
                    throw new CommandStatusException(CommandStatus.NEEDS_PROVISIONING);
                } else if (code == HttpStatus.SC_NOT_FOUND) {
                    // We get a 404 from OWA addresses (which are NOT EAS addresses)
                    resultCode = MessagingException.PROTOCOL_VERSION_UNSUPPORTED;
                } else if (code == HttpStatus.SC_UNAUTHORIZED) {
                    resultCode = resp.isMissingCertificate() ? MessagingException.CLIENT_CERTIFICATE_REQUIRED : MessagingException.AUTHENTICATION_FAILED;
                } else if (code != HttpStatus.SC_OK) {
                    if ((code == EAS_REDIRECT_CODE) && (mRedirectCount++ < MAX_REDIRECTS) && getValidateRedirect(resp, hostAuth)) {
                        return validateAccount(hostAuth, context);
                    }
                    // Fail generically with anything other than success
                    userLog("Unexpected response for FolderSync: ", code);
                    resultCode = MessagingException.UNSPECIFIED_EXCEPTION;
                } else {
                    // (EAS 14.0 only)
                    if (!resp.isEmpty()) {
                        InputStream is = resp.getInputStream();
                        // Create the parser with statusOnly set to true; we only care about
                        // seeing if a CommandStatusException is thrown (indicating a
                        // provisioning failure)
                        new FolderSyncParser(is, new AccountSyncAdapter(this), true).parse();
                    }
                    userLog("Validation successful");
                }
            } else if (EasResponse.isAuthError(code)) {
                userLog("Authentication failed");
                resultCode = resp.isMissingCertificate() ? MessagingException.CLIENT_CERTIFICATE_REQUIRED : MessagingException.AUTHENTICATION_FAILED;
            } else if (code == INTERNAL_SERVER_ERROR_CODE) {
                // For Exchange 2003, this could mean an authentication failure OR server error
                userLog("Internal server error");
                resultCode = MessagingException.AUTHENTICATION_FAILED_OR_SERVER_ERROR;
            } else {
                if ((code == EAS_REDIRECT_CODE) && (mRedirectCount++ < MAX_REDIRECTS) && getValidateRedirect(resp, hostAuth)) {
                    return validateAccount(hostAuth, context);
                }
                // TODO Need to catch other kinds of errors (e.g. policy) For now, report code.
                userLog("Validation failed, reporting I/O error: ", code);
                resultCode = MessagingException.IOERROR;
            }
        } catch (CommandStatusException e) {
            int status = e.mStatus;
            if (CommandStatus.isNeedsProvisioning(status)) {
                ProvisionParser pp = canProvision();
                if (pp != null && pp.hasSupportablePolicySet()) {
                    resultCode = MessagingException.SECURITY_POLICIES_REQUIRED;
                    bundle.putParcelable(EmailServiceProxy.VALIDATE_BUNDLE_POLICY_SET, pp.getPolicy());
                    if (mProtocolVersionDouble == Eas.SUPPORTED_PROTOCOL_EX2010_DOUBLE) {
                        mAccount.mSecuritySyncKey = pp.getSecuritySyncKey();
                        if (!sendSettings()) {
                            userLog("Denied access: ", CommandStatus.toString(status));
                            resultCode = MessagingException.ACCESS_DENIED;
                        }
                    }
                } else
                    resultCode = MessagingException.SECURITY_POLICIES_UNSUPPORTED;
                bundle.putStringArray(EmailServiceProxy.VALIDATE_BUNDLE_UNSUPPORTED_POLICIES, ((pp == null) ? null : pp.getUnsupportedPolicies()));
            } else if (CommandStatus.isDeniedAccess(status)) {
                userLog("Denied access: ", CommandStatus.toString(status));
                resultCode = MessagingException.ACCESS_DENIED;
            } else if (CommandStatus.isTransientError(status)) {
                userLog("Transient error: ", CommandStatus.toString(status));
                resultCode = MessagingException.IOERROR;
            } else {
                userLog("Unexpected response: ", CommandStatus.toString(status));
                resultCode = MessagingException.UNSPECIFIED_EXCEPTION;
            }
        } finally {
            resp.close();
        }
    } catch (IOException e) {
        Throwable cause = e.getCause();
        if (cause != null && cause instanceof CertificateException) {
            userLog("CertificateException caught: ", e.getMessage());
            resultCode = MessagingException.GENERAL_SECURITY;
        }
        userLog("IOException caught: ", e.getMessage());
        resultCode = MessagingException.IOERROR;
    } catch (CertificateException e) {
        userLog("CertificateException caught: ", e.getMessage());
        resultCode = MessagingException.CLIENT_CERTIFICATE_ERROR;
    }
    bundle.putInt(EmailServiceProxy.VALIDATE_BUNDLE_RESULT_CODE, resultCode);
    return bundle;
}
Example 3
Project: Froyo_Email-master  File: EasSyncService.java View source code
/**
     * Performs FolderSync
     *
     * @throws IOException
     * @throws EasParserException
     */
public void runAccountMailbox() throws IOException, EasParserException {
    // Initialize exit status to success
    mExitStatus = EmailServiceStatus.SUCCESS;
    try {
        try {
            SyncManager.callback().syncMailboxListStatus(mAccount.mId, EmailServiceStatus.IN_PROGRESS, 0);
        } catch (RemoteException e1) {
        }
        if (mAccount.mSyncKey == null) {
            mAccount.mSyncKey = "0";
            userLog("Account syncKey INIT to 0");
            ContentValues cv = new ContentValues();
            cv.put(AccountColumns.SYNC_KEY, mAccount.mSyncKey);
            mAccount.update(mContext, cv);
        }
        boolean firstSync = mAccount.mSyncKey.equals("0");
        if (firstSync) {
            userLog("Initial FolderSync");
        }
        // When we first start up, change all mailboxes to push.
        ContentValues cv = new ContentValues();
        cv.put(Mailbox.SYNC_INTERVAL, Mailbox.CHECK_INTERVAL_PUSH);
        if (mContentResolver.update(Mailbox.CONTENT_URI, cv, WHERE_ACCOUNT_AND_SYNC_INTERVAL_PING, new String[] { Long.toString(mAccount.mId) }) > 0) {
            SyncManager.kick("change ping boxes to push");
        }
        // Also re-check protocol version at least once a day (in case of upgrade)
        if (mAccount.mProtocolVersion == null || ((System.currentTimeMillis() - mMailbox.mSyncTime) > DAYS)) {
            userLog("Determine EAS protocol version");
            HttpResponse resp = sendHttpClientOptions();
            int code = resp.getStatusLine().getStatusCode();
            userLog("OPTIONS response: ", code);
            if (code == HttpStatus.SC_OK) {
                Header header = resp.getFirstHeader("MS-ASProtocolCommands");
                userLog(header.getValue());
                header = resp.getFirstHeader("ms-asprotocolversions");
                try {
                    setupProtocolVersion(this, header);
                } catch (MessagingException e) {
                    throw new IOException();
                }
                // Save the protocol version
                cv.clear();
                // Save the protocol version in the account
                cv.put(Account.PROTOCOL_VERSION, mProtocolVersion);
                mAccount.update(mContext, cv);
                cv.clear();
                // Save the sync time of the account mailbox to current time
                cv.put(Mailbox.SYNC_TIME, System.currentTimeMillis());
                mMailbox.update(mContext, cv);
            } else {
                errorLog("OPTIONS command failed; throwing IOException");
                throw new IOException();
            }
        }
        // Change all pushable boxes to push when we start the account mailbox
        if (mAccount.mSyncInterval == Account.CHECK_INTERVAL_PUSH) {
            cv.clear();
            cv.put(Mailbox.SYNC_INTERVAL, Mailbox.CHECK_INTERVAL_PUSH);
            if (mContentResolver.update(Mailbox.CONTENT_URI, cv, SyncManager.WHERE_IN_ACCOUNT_AND_PUSHABLE, new String[] { Long.toString(mAccount.mId) }) > 0) {
                userLog("Push account; set pushable boxes to push...");
            }
        }
        while (!mStop) {
            userLog("Sending Account syncKey: ", mAccount.mSyncKey);
            Serializer s = new Serializer();
            s.start(Tags.FOLDER_FOLDER_SYNC).start(Tags.FOLDER_SYNC_KEY).text(mAccount.mSyncKey).end().end().done();
            HttpResponse resp = sendHttpClientPost("FolderSync", s.toByteArray());
            if (mStop)
                break;
            int code = resp.getStatusLine().getStatusCode();
            if (code == HttpStatus.SC_OK) {
                HttpEntity entity = resp.getEntity();
                int len = (int) entity.getContentLength();
                if (len != 0) {
                    InputStream is = entity.getContent();
                    // Returns true if we need to sync again
                    if (new FolderSyncParser(is, new AccountSyncAdapter(mMailbox, this)).parse()) {
                        continue;
                    }
                }
            } else if (isProvisionError(code)) {
                // of multiple policy keys.
                if (!tryProvision()) {
                    // Set the appropriate failure status
                    mExitStatus = EXIT_SECURITY_FAILURE;
                    return;
                } else {
                    // If we succeeded, try again...
                    continue;
                }
            } else if (isAuthError(code)) {
                mExitStatus = EXIT_LOGIN_FAILURE;
                return;
            } else {
                userLog("FolderSync response error: ", code);
            }
            // Change all push/hold boxes to push
            cv.clear();
            cv.put(Mailbox.SYNC_INTERVAL, Account.CHECK_INTERVAL_PUSH);
            if (mContentResolver.update(Mailbox.CONTENT_URI, cv, WHERE_PUSH_HOLD_NOT_ACCOUNT_MAILBOX, new String[] { Long.toString(mAccount.mId) }) > 0) {
                userLog("Set push/hold boxes to push...");
            }
            try {
                SyncManager.callback().syncMailboxListStatus(mAccount.mId, mExitStatus, 0);
            } catch (RemoteException e1) {
            }
            // Before each run of the pingLoop, if this Account has a PolicySet, make sure it's
            // active; otherwise, clear out the key/flag.  This should cause a provisioning
            // error on the next POST, and start the security sequence over again
            String key = mAccount.mSecuritySyncKey;
            if (!TextUtils.isEmpty(key)) {
                PolicySet ps = new PolicySet(mAccount);
                SecurityPolicy sp = SecurityPolicy.getInstance(mContext);
                if (!sp.isActive(ps)) {
                    cv.clear();
                    cv.put(AccountColumns.SECURITY_FLAGS, 0);
                    cv.putNull(AccountColumns.SECURITY_SYNC_KEY);
                    long accountId = mAccount.mId;
                    mContentResolver.update(ContentUris.withAppendedId(Account.CONTENT_URI, accountId), cv, null, null);
                    sp.policiesRequired(accountId);
                }
            }
            // Wait for push notifications.
            String threadName = Thread.currentThread().getName();
            try {
                runPingLoop();
            } catch (StaleFolderListException e) {
                userLog("Ping interrupted; folder list requires sync...");
            } catch (IllegalHeartbeatException e) {
                resetHeartbeats(e.mLegalHeartbeat);
            } finally {
                Thread.currentThread().setName(threadName);
            }
        }
    } catch (IOException e) {
        try {
            if (!mStop) {
                SyncManager.callback().syncMailboxListStatus(mAccount.mId, EmailServiceStatus.CONNECTION_ERROR, 0);
            }
        } catch (RemoteException e1) {
        }
        throw e;
    }
}
Example 4
Project: themes-platform-packages-apps-Email-master  File: EasSyncService.java View source code
/**
     * Performs FolderSync
     *
     * @throws IOException
     * @throws EasParserException
     */
public void runAccountMailbox() throws IOException, EasParserException {
    // Initialize exit status to success
    mExitStatus = EmailServiceStatus.SUCCESS;
    try {
        try {
            SyncManager.callback().syncMailboxListStatus(mAccount.mId, EmailServiceStatus.IN_PROGRESS, 0);
        } catch (RemoteException e1) {
        }
        if (mAccount.mSyncKey == null) {
            mAccount.mSyncKey = "0";
            userLog("Account syncKey INIT to 0");
            ContentValues cv = new ContentValues();
            cv.put(AccountColumns.SYNC_KEY, mAccount.mSyncKey);
            mAccount.update(mContext, cv);
        }
        boolean firstSync = mAccount.mSyncKey.equals("0");
        if (firstSync) {
            userLog("Initial FolderSync");
        }
        // When we first start up, change all mailboxes to push.
        ContentValues cv = new ContentValues();
        cv.put(Mailbox.SYNC_INTERVAL, Mailbox.CHECK_INTERVAL_PUSH);
        if (mContentResolver.update(Mailbox.CONTENT_URI, cv, WHERE_ACCOUNT_AND_SYNC_INTERVAL_PING, new String[] { Long.toString(mAccount.mId) }) > 0) {
            SyncManager.kick("change ping boxes to push");
        }
        // Also re-check protocol version at least once a day (in case of upgrade)
        if (mAccount.mProtocolVersion == null || ((System.currentTimeMillis() - mMailbox.mSyncTime) > DAYS)) {
            userLog("Determine EAS protocol version");
            HttpResponse resp = sendHttpClientOptions();
            int code = resp.getStatusLine().getStatusCode();
            userLog("OPTIONS response: ", code);
            if (code == HttpStatus.SC_OK) {
                Header header = resp.getFirstHeader("MS-ASProtocolCommands");
                userLog(header.getValue());
                header = resp.getFirstHeader("ms-asprotocolversions");
                try {
                    setupProtocolVersion(this, header);
                } catch (MessagingException e) {
                    throw new IOException();
                }
                // Save the protocol version
                cv.clear();
                // Save the protocol version in the account
                cv.put(Account.PROTOCOL_VERSION, mProtocolVersion);
                mAccount.update(mContext, cv);
                cv.clear();
                // Save the sync time of the account mailbox to current time
                cv.put(Mailbox.SYNC_TIME, System.currentTimeMillis());
                mMailbox.update(mContext, cv);
            } else {
                errorLog("OPTIONS command failed; throwing IOException");
                throw new IOException();
            }
        }
        // Change all pushable boxes to push when we start the account mailbox
        if (mAccount.mSyncInterval == Account.CHECK_INTERVAL_PUSH) {
            cv.clear();
            cv.put(Mailbox.SYNC_INTERVAL, Mailbox.CHECK_INTERVAL_PUSH);
            if (mContentResolver.update(Mailbox.CONTENT_URI, cv, SyncManager.WHERE_IN_ACCOUNT_AND_PUSHABLE, new String[] { Long.toString(mAccount.mId) }) > 0) {
                userLog("Push account; set pushable boxes to push...");
            }
        }
        while (!mStop) {
            userLog("Sending Account syncKey: ", mAccount.mSyncKey);
            Serializer s = new Serializer();
            s.start(Tags.FOLDER_FOLDER_SYNC).start(Tags.FOLDER_SYNC_KEY).text(mAccount.mSyncKey).end().end().done();
            HttpResponse resp = sendHttpClientPost("FolderSync", s.toByteArray());
            if (mStop)
                break;
            int code = resp.getStatusLine().getStatusCode();
            if (code == HttpStatus.SC_OK) {
                HttpEntity entity = resp.getEntity();
                int len = (int) entity.getContentLength();
                if (len != 0) {
                    InputStream is = entity.getContent();
                    // Returns true if we need to sync again
                    if (new FolderSyncParser(is, new AccountSyncAdapter(mMailbox, this)).parse()) {
                        continue;
                    }
                }
            } else if (isProvisionError(code)) {
                // of multiple policy keys.
                if (!tryProvision()) {
                    // Set the appropriate failure status
                    mExitStatus = EXIT_SECURITY_FAILURE;
                    return;
                } else {
                    // If we succeeded, try again...
                    continue;
                }
            } else if (isAuthError(code)) {
                mExitStatus = EXIT_LOGIN_FAILURE;
                return;
            } else {
                userLog("FolderSync response error: ", code);
            }
            // Change all push/hold boxes to push
            cv.clear();
            cv.put(Mailbox.SYNC_INTERVAL, Account.CHECK_INTERVAL_PUSH);
            if (mContentResolver.update(Mailbox.CONTENT_URI, cv, WHERE_PUSH_HOLD_NOT_ACCOUNT_MAILBOX, new String[] { Long.toString(mAccount.mId) }) > 0) {
                userLog("Set push/hold boxes to push...");
            }
            try {
                SyncManager.callback().syncMailboxListStatus(mAccount.mId, mExitStatus, 0);
            } catch (RemoteException e1) {
            }
            // Before each run of the pingLoop, if this Account has a PolicySet, make sure it's
            // active; otherwise, clear out the key/flag.  This should cause a provisioning
            // error on the next POST, and start the security sequence over again
            String key = mAccount.mSecuritySyncKey;
            if (!TextUtils.isEmpty(key)) {
                PolicySet ps = new PolicySet(mAccount);
                SecurityPolicy sp = SecurityPolicy.getInstance(mContext);
                if (!sp.isActive(ps)) {
                    cv.clear();
                    cv.put(AccountColumns.SECURITY_FLAGS, 0);
                    cv.putNull(AccountColumns.SECURITY_SYNC_KEY);
                    long accountId = mAccount.mId;
                    mContentResolver.update(ContentUris.withAppendedId(Account.CONTENT_URI, accountId), cv, null, null);
                    sp.policiesRequired(accountId);
                }
            }
            // Wait for push notifications.
            String threadName = Thread.currentThread().getName();
            try {
                runPingLoop();
            } catch (StaleFolderListException e) {
                userLog("Ping interrupted; folder list requires sync...");
            } finally {
                Thread.currentThread().setName(threadName);
            }
        }
    } catch (IOException e) {
        try {
            if (!mStop) {
                SyncManager.callback().syncMailboxListStatus(mAccount.mId, EmailServiceStatus.CONNECTION_ERROR, 0);
            }
        } catch (RemoteException e1) {
        }
        throw e;
    }
}