Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 271702fc authored by Suprabh Shukla's avatar Suprabh Shukla
Browse files

Clearing up invalid entries when SyncStorageEngine starts

Fixing the original change which was reverted. Using the
available api Context.getSystemService(String) instead of
the unavailable Context.getSystemService(Class)

Test: cts-tradefed run cts -p android.content.syncmanager

Bug: 35028827

This reverts commit 4a9d3584.

Change-Id: I725430401eaec861f45bb91ee1352bb1307a6915
parent e1adf224
Loading
Loading
Loading
Loading
+60 −5
Original line number Original line Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.server.content;


import android.accounts.Account;
import android.accounts.Account;
import android.accounts.AccountAndUser;
import android.accounts.AccountAndUser;
import android.accounts.AccountManager;
import android.content.ComponentName;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Context;
@@ -26,6 +27,7 @@ import android.content.PeriodicSync;
import android.content.SyncInfo;
import android.content.SyncInfo;
import android.content.SyncRequest;
import android.content.SyncRequest;
import android.content.SyncStatusInfo;
import android.content.SyncStatusInfo;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteException;
@@ -404,6 +406,49 @@ public class SyncStorageEngine extends Handler {
        public void onSyncRequest(EndPoint info, int reason, Bundle extras);
        public void onSyncRequest(EndPoint info, int reason, Bundle extras);
    }
    }


    /**
     * Validator that maintains a lazy cache of accounts and providers to tell if an authority or
     * account is valid.
     */
    private static class AccountAuthorityValidator {
        final private AccountManager mAccountManager;
        final private PackageManager mPackageManager;
        final private SparseArray<Account[]> mAccountsCache;
        final private SparseArray<ArrayMap<String, Boolean>> mProvidersPerUserCache;

        AccountAuthorityValidator(Context context) {
            mAccountManager = (AccountManager) context.getSystemService(Context.ACCOUNT_SERVICE);
            mPackageManager = context.getPackageManager();
            mAccountsCache = new SparseArray<>();
            mProvidersPerUserCache = new SparseArray<>();
        }

        // An account is valid if an installed authenticator has previously created that account
        // on the device
        boolean isAccountValid(Account account, int userId) {
            Account[] accountsForUser = mAccountsCache.get(userId);
            if (accountsForUser == null) {
                accountsForUser = mAccountManager.getAccountsAsUser(userId);
                mAccountsCache.put(userId, accountsForUser);
            }
            return ArrayUtils.contains(accountsForUser, account);
        }

        // An authority is only valid if it has a content provider installed on the system
        boolean isAuthorityValid(String authority, int userId) {
            ArrayMap<String, Boolean> authorityMap = mProvidersPerUserCache.get(userId);
            if (authorityMap == null) {
                authorityMap = new ArrayMap<>();
                mProvidersPerUserCache.put(userId, authorityMap);
            }
            if (!authorityMap.containsKey(authority)) {
                authorityMap.put(authority,
                        mPackageManager.resolveContentProviderAsUser(authority, 0, userId) != null);
            }
            return authorityMap.get(authority);
        }
    }

    // Primary list of all syncable authorities.  Also our global lock.
    // Primary list of all syncable authorities.  Also our global lock.
    private final SparseArray<AuthorityInfo> mAuthorities =
    private final SparseArray<AuthorityInfo> mAuthorities =
            new SparseArray<AuthorityInfo>();
            new SparseArray<AuthorityInfo>();
@@ -1862,12 +1907,13 @@ public class SyncStorageEngine extends Handler {
                eventType = parser.next();
                eventType = parser.next();
                AuthorityInfo authority = null;
                AuthorityInfo authority = null;
                PeriodicSync periodicSync = null;
                PeriodicSync periodicSync = null;
                AccountAuthorityValidator validator = new AccountAuthorityValidator(mContext);
                do {
                do {
                    if (eventType == XmlPullParser.START_TAG) {
                    if (eventType == XmlPullParser.START_TAG) {
                        tagName = parser.getName();
                        tagName = parser.getName();
                        if (parser.getDepth() == 2) {
                        if (parser.getDepth() == 2) {
                            if ("authority".equals(tagName)) {
                            if ("authority".equals(tagName)) {
                                authority = parseAuthority(parser, version);
                                authority = parseAuthority(parser, version, validator);
                                periodicSync = null;
                                periodicSync = null;
                                if (authority != null) {
                                if (authority != null) {
                                    if (authority.ident > highestAuthorityId) {
                                    if (authority.ident > highestAuthorityId) {
@@ -2000,7 +2046,8 @@ public class SyncStorageEngine extends Handler {
        mMasterSyncAutomatically.put(userId, listen);
        mMasterSyncAutomatically.put(userId, listen);
    }
    }


    private AuthorityInfo parseAuthority(XmlPullParser parser, int version) {
    private AuthorityInfo parseAuthority(XmlPullParser parser, int version,
            AccountAuthorityValidator validator) {
        AuthorityInfo authority = null;
        AuthorityInfo authority = null;
        int id = -1;
        int id = -1;
        try {
        try {
@@ -2045,12 +2092,22 @@ public class SyncStorageEngine extends Handler {
                    info = new EndPoint(
                    info = new EndPoint(
                            new Account(accountName, accountType),
                            new Account(accountName, accountType),
                            authorityName, userId);
                            authorityName, userId);
                    if (validator.isAccountValid(info.account, userId)
                            && validator.isAuthorityValid(authorityName, userId)) {
                        authority = getOrCreateAuthorityLocked(info, id, false);
                    } else {
                        EventLog.writeEvent(0x534e4554, "35028827", -1,
                                "account:" + info.account + " provider:" + authorityName + " user:"
                                        + userId);
                    }
                } else {
                } else {
                    info = new EndPoint(
                    info = new EndPoint(
                            new ComponentName(packageName, className),
                            new ComponentName(packageName, className),
                            userId);
                            userId);
                }
                    authority = getOrCreateAuthorityLocked(info, id, false);
                    authority = getOrCreateAuthorityLocked(info, id, false);
                }
            }
            if (authority != null) {
                // If the version is 0 then we are upgrading from a file format that did not
                // If the version is 0 then we are upgrading from a file format that did not
                // know about periodic syncs. In that case don't clear the list since we
                // know about periodic syncs. In that case don't clear the list since we
                // want the default, which is a daily periodic sync.
                // want the default, which is a daily periodic sync.
@@ -2059,8 +2116,6 @@ public class SyncStorageEngine extends Handler {
                if (version > 0) {
                if (version > 0) {
                    authority.periodicSyncs.clear();
                    authority.periodicSyncs.clear();
                }
                }
            }
            if (authority != null) {
                authority.enabled = enabled == null || Boolean.parseBoolean(enabled);
                authority.enabled = enabled == null || Boolean.parseBoolean(enabled);
                if ("unknown".equals(syncable)) {
                if ("unknown".equals(syncable)) {
                    authority.syncable = -1;
                    authority.syncable = -1;