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

Commit 97bc3e79 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Make SyncManager calls in ContentService consistent."

parents 2e85d4a0 949c9cae
Loading
Loading
Loading
Loading
+57 −106
Original line number Original line Diff line number Diff line
@@ -50,7 +50,6 @@ import android.content.SyncStatusInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
import android.content.pm.ProviderInfo;
import android.database.IContentObserver;
import android.database.IContentObserver;
import android.database.sqlite.SQLiteException;
import android.net.Uri;
import android.net.Uri;
import android.os.Binder;
import android.os.Binder;
import android.os.Build;
import android.os.Build;
@@ -206,11 +205,8 @@ public final class ContentService extends IContentService.Stub {


    private SyncManager getSyncManager() {
    private SyncManager getSyncManager() {
        synchronized(mSyncManagerLock) {
        synchronized(mSyncManagerLock) {
            try {
            if (mSyncManager == null) {
                // Try to create the SyncManager, return null if it fails (which it shouldn't).
                mSyncManager = new SyncManager(mContext, mFactoryTest);
                if (mSyncManager == null) mSyncManager = new SyncManager(mContext, mFactoryTest);
            } catch (SQLiteException e) {
                Log.e(TAG, "Can't create SyncManager", e);
            }
            }
            return mSyncManager;
            return mSyncManager;
        }
        }
@@ -477,6 +473,7 @@ public final class ContentService extends IContentService.Stub {
            // Actually dispatch all the notifications we collected
            // Actually dispatch all the notifications we collected
            collector.dispatch();
            collector.dispatch();


            final SyncManager syncManager = getSyncManager();
            for (int i = 0; i < validatedProviders.size(); i++) {
            for (int i = 0; i < validatedProviders.size(); i++) {
                final String authority = validatedProviders.keyAt(i).first;
                final String authority = validatedProviders.keyAt(i).first;
                final int resolvedUserId = validatedProviders.keyAt(i).second;
                final int resolvedUserId = validatedProviders.keyAt(i).second;
@@ -484,14 +481,11 @@ public final class ContentService extends IContentService.Stub {


                // Kick off sync adapters for any authorities we touched
                // Kick off sync adapters for any authorities we touched
                if ((flags & ContentResolver.NOTIFY_SYNC_TO_NETWORK) != 0) {
                if ((flags & ContentResolver.NOTIFY_SYNC_TO_NETWORK) != 0) {
                    SyncManager syncManager = getSyncManager();
                    if (syncManager != null) {
                    syncManager.scheduleLocalSync(null /* all accounts */, callingUserId,
                    syncManager.scheduleLocalSync(null /* all accounts */, callingUserId,
                            callingUid,
                            callingUid,
                            authority, getSyncExemptionForCaller(callingUid),
                            authority, getSyncExemptionForCaller(callingUid),
                            callingUid, callingPid, callingPackage);
                            callingUid, callingPid, callingPackage);
                }
                }
                }


                // Invalidate caches for any authorities we touched
                // Invalidate caches for any authorities we touched
                synchronized (mCache) {
                synchronized (mCache) {
@@ -619,12 +613,9 @@ public final class ContentService extends IContentService.Stub {
        // process rather than the caller's process. We will restore this before returning.
        // process rather than the caller's process. We will restore this before returning.
        final long identityToken = clearCallingIdentity();
        final long identityToken = clearCallingIdentity();
        try {
        try {
            SyncManager syncManager = getSyncManager();
            getSyncManager().scheduleSync(account, userId, callingUid, authority, extras,
            if (syncManager != null) {
                syncManager.scheduleSync(account, userId, callingUid, authority, extras,
                    SyncStorageEngine.AuthorityInfo.UNDEFINED,
                    SyncStorageEngine.AuthorityInfo.UNDEFINED,
                    syncExemption, callingUid, callingPid, callingPackage);
                    syncExemption, callingUid, callingPid, callingPackage);
            }
        } finally {
        } finally {
            restoreCallingIdentity(identityToken);
            restoreCallingIdentity(identityToken);
        }
        }
@@ -676,10 +667,6 @@ public final class ContentService extends IContentService.Stub {
        // process rather than the caller's process. We will restore this before returning.
        // process rather than the caller's process. We will restore this before returning.
        final long identityToken = clearCallingIdentity();
        final long identityToken = clearCallingIdentity();
        try {
        try {
            SyncManager syncManager = getSyncManager();
            if (syncManager == null) {
                return;
            }
            long flextime = request.getSyncFlexTime();
            long flextime = request.getSyncFlexTime();
            long runAtTime = request.getSyncRunTime();
            long runAtTime = request.getSyncRunTime();
            if (request.isPeriodic()) {
            if (request.isPeriodic()) {
@@ -695,7 +682,7 @@ public final class ContentService extends IContentService.Stub {
                getSyncManager().updateOrAddPeriodicSync(info, runAtTime,
                getSyncManager().updateOrAddPeriodicSync(info, runAtTime,
                        flextime, extras);
                        flextime, extras);
            } else {
            } else {
                syncManager.scheduleSync(
                getSyncManager().scheduleSync(
                        request.getAccount(), userId, callingUid, request.getProvider(), extras,
                        request.getAccount(), userId, callingUid, request.getProvider(), extras,
                        SyncStorageEngine.AuthorityInfo.UNDEFINED,
                        SyncStorageEngine.AuthorityInfo.UNDEFINED,
                        syncExemption, callingUid, callingPid, callingPackage);
                        syncExemption, callingUid, callingPid, callingPackage);
@@ -740,21 +727,20 @@ public final class ContentService extends IContentService.Stub {
        }
        }
        enforceCrossUserPermission(userId,
        enforceCrossUserPermission(userId,
                "no permission to modify the sync settings for user " + userId);
                "no permission to modify the sync settings for user " + userId);
        // This makes it so that future permission checks will be in the context of this

        // process rather than the caller's process. We will restore this before returning.
        final long identityToken = clearCallingIdentity();
        if (cname != null) {
        if (cname != null) {
            Slog.e(TAG, "cname not null.");
            Slog.e(TAG, "cname not null.");
            return;
            return;
        }
        }

        // This makes it so that future permission checks will be in the context of this
        // process rather than the caller's process. We will restore this before returning.
        final long identityToken = clearCallingIdentity();
        try {
        try {
            SyncManager syncManager = getSyncManager();
            if (syncManager != null) {
            SyncStorageEngine.EndPoint info;
            SyncStorageEngine.EndPoint info;
            info = new SyncStorageEngine.EndPoint(account, authority, userId);
            info = new SyncStorageEngine.EndPoint(account, authority, userId);
                syncManager.clearScheduledSyncOperations(info);
            getSyncManager().clearScheduledSyncOperations(info);
                syncManager.cancelActiveSync(info, null /* all syncs for this adapter */, "API");
            getSyncManager().cancelActiveSync(info, null /* all syncs for this adapter */, "API");
            }
        } finally {
        } finally {
            restoreCallingIdentity(identityToken);
            restoreCallingIdentity(identityToken);
        }
        }
@@ -762,19 +748,16 @@ public final class ContentService extends IContentService.Stub {


    @Override
    @Override
    public void cancelRequest(SyncRequest request) {
    public void cancelRequest(SyncRequest request) {
        SyncManager syncManager = getSyncManager();
        if (syncManager == null) return;
        int userId = UserHandle.getCallingUserId();
        final int callingUid = Binder.getCallingUid();

        if (request.isPeriodic()) {
        if (request.isPeriodic()) {
            mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS,
            mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS,
                    "no permission to write the sync settings");
                    "no permission to write the sync settings");
        }
        }


        final int callingUid = Binder.getCallingUid();
        Bundle extras = new Bundle(request.getBundle());
        Bundle extras = new Bundle(request.getBundle());
        validateExtras(callingUid, extras);
        validateExtras(callingUid, extras);


        int userId = UserHandle.getCallingUserId();
        final long identityToken = clearCallingIdentity();
        final long identityToken = clearCallingIdentity();
        try {
        try {
            SyncStorageEngine.EndPoint info;
            SyncStorageEngine.EndPoint info;
@@ -788,8 +771,8 @@ public final class ContentService extends IContentService.Stub {
                        "cancelRequest() by uid=" + callingUid);
                        "cancelRequest() by uid=" + callingUid);
            }
            }
            // Cancel active syncs and clear pending syncs from the queue.
            // Cancel active syncs and clear pending syncs from the queue.
            syncManager.cancelScheduledSyncOperation(info, extras);
            getSyncManager().cancelScheduledSyncOperation(info, extras);
            syncManager.cancelActiveSync(info, extras, "API");
            getSyncManager().cancelActiveSync(info, extras, "API");
        } finally {
        } finally {
            restoreCallingIdentity(identityToken);
            restoreCallingIdentity(identityToken);
        }
        }
@@ -816,13 +799,13 @@ public final class ContentService extends IContentService.Stub {
    public SyncAdapterType[] getSyncAdapterTypesAsUser(int userId) {
    public SyncAdapterType[] getSyncAdapterTypesAsUser(int userId) {
        enforceCrossUserPermission(userId,
        enforceCrossUserPermission(userId,
                "no permission to read sync settings for user " + userId);
                "no permission to read sync settings for user " + userId);
        final int callingUid = Binder.getCallingUid();

        // This makes it so that future permission checks will be in the context of this
        // This makes it so that future permission checks will be in the context of this
        // process rather than the caller's process. We will restore this before returning.
        // process rather than the caller's process. We will restore this before returning.
        final int callingUid = Binder.getCallingUid();
        final long identityToken = clearCallingIdentity();
        final long identityToken = clearCallingIdentity();
        try {
        try {
            SyncManager syncManager = getSyncManager();
            return getSyncManager().getSyncAdapterTypes(callingUid, userId);
            return syncManager.getSyncAdapterTypes(callingUid, userId);
        } finally {
        } finally {
            restoreCallingIdentity(identityToken);
            restoreCallingIdentity(identityToken);
        }
        }
@@ -832,13 +815,13 @@ public final class ContentService extends IContentService.Stub {
    public String[] getSyncAdapterPackagesForAuthorityAsUser(String authority, int userId) {
    public String[] getSyncAdapterPackagesForAuthorityAsUser(String authority, int userId) {
        enforceCrossUserPermission(userId,
        enforceCrossUserPermission(userId,
                "no permission to read sync settings for user " + userId);
                "no permission to read sync settings for user " + userId);
        final int callingUid = Binder.getCallingUid();

        // This makes it so that future permission checks will be in the context of this
        // This makes it so that future permission checks will be in the context of this
        // process rather than the caller's process. We will restore this before returning.
        // process rather than the caller's process. We will restore this before returning.
        final int callingUid = Binder.getCallingUid();
        final long identityToken = clearCallingIdentity();
        final long identityToken = clearCallingIdentity();
        try {
        try {
            SyncManager syncManager = getSyncManager();
            return getSyncManager().getSyncAdapterPackagesForAuthorityAsUser(authority, callingUid,
            return syncManager.getSyncAdapterPackagesForAuthorityAsUser(authority, callingUid,
                    userId);
                    userId);
        } finally {
        } finally {
            restoreCallingIdentity(identityToken);
            restoreCallingIdentity(identityToken);
@@ -846,10 +829,12 @@ public final class ContentService extends IContentService.Stub {
    }
    }


    @Override
    @Override
    @Nullable
    public String getSyncAdapterPackageAsUser(@NonNull String accountType,
    public String getSyncAdapterPackageAsUser(@NonNull String accountType,
            @NonNull String authority, @UserIdInt int userId) {
            @NonNull String authority, @UserIdInt int userId) {
        enforceCrossUserPermission(userId,
        enforceCrossUserPermission(userId,
                "no permission to read sync settings for user " + userId);
                "no permission to read sync settings for user " + userId);

        final int callingUid = Binder.getCallingUid();
        final int callingUid = Binder.getCallingUid();
        final long identityToken = clearCallingIdentity();
        final long identityToken = clearCallingIdentity();
        try {
        try {
@@ -881,15 +866,11 @@ public final class ContentService extends IContentService.Stub {


        final long identityToken = clearCallingIdentity();
        final long identityToken = clearCallingIdentity();
        try {
        try {
            SyncManager syncManager = getSyncManager();
            return getSyncManager().getSyncStorageEngine()
            if (syncManager != null) {
                return syncManager.getSyncStorageEngine()
                    .getSyncAutomatically(account, userId, providerName);
                    .getSyncAutomatically(account, userId, providerName);
            }
        } finally {
        } finally {
            restoreCallingIdentity(identityToken);
            restoreCallingIdentity(identityToken);
        }
        }
        return false;
    }
    }


    @Override
    @Override
@@ -918,11 +899,8 @@ public final class ContentService extends IContentService.Stub {


        final long identityToken = clearCallingIdentity();
        final long identityToken = clearCallingIdentity();
        try {
        try {
            SyncManager syncManager = getSyncManager();
            getSyncManager().getSyncStorageEngine().setSyncAutomatically(account, userId,
            if (syncManager != null) {
                syncManager.getSyncStorageEngine().setSyncAutomatically(account, userId,
                    providerName, sync, syncExemptionFlag, callingUid, callingPid);
                    providerName, sync, syncExemptionFlag, callingUid, callingPid);
            }
        } finally {
        } finally {
            restoreCallingIdentity(identityToken);
            restoreCallingIdentity(identityToken);
        }
        }
@@ -946,13 +924,13 @@ public final class ContentService extends IContentService.Stub {
        if (!hasAccountAccess(true, account, callingUid)) {
        if (!hasAccountAccess(true, account, callingUid)) {
            return;
            return;
        }
        }
        validateExtras(callingUid, extras);


        int userId = UserHandle.getCallingUserId();
        validateExtras(callingUid, extras);


        pollFrequency = clampPeriod(pollFrequency);
        pollFrequency = clampPeriod(pollFrequency);
        long defaultFlex = SyncStorageEngine.calculateDefaultFlexTime(pollFrequency);
        long defaultFlex = SyncStorageEngine.calculateDefaultFlexTime(pollFrequency);


        int userId = UserHandle.getCallingUserId();
        final long identityToken = clearCallingIdentity();
        final long identityToken = clearCallingIdentity();
        try {
        try {
            SyncStorageEngine.EndPoint info =
            SyncStorageEngine.EndPoint info =
@@ -980,13 +958,13 @@ public final class ContentService extends IContentService.Stub {
        if (!hasAccountAccess(true, account, callingUid)) {
        if (!hasAccountAccess(true, account, callingUid)) {
            return;
            return;
        }
        }

        validateExtras(callingUid, extras);
        validateExtras(callingUid, extras);


        int userId = UserHandle.getCallingUserId();
        int userId = UserHandle.getCallingUserId();
        final long identityToken = clearCallingIdentity();
        final long identityToken = clearCallingIdentity();
        try {
        try {
            getSyncManager()
            getSyncManager().removePeriodicSync(
                    .removePeriodicSync(
                    new SyncStorageEngine.EndPoint(account, authority, userId),
                    new SyncStorageEngine.EndPoint(account, authority, userId),
                    extras, "removePeriodicSync() by uid=" + callingUid);
                    extras, "removePeriodicSync() by uid=" + callingUid);
        } finally {
        } finally {
@@ -1040,15 +1018,10 @@ public final class ContentService extends IContentService.Stub {


        final long identityToken = clearCallingIdentity();
        final long identityToken = clearCallingIdentity();
        try {
        try {
            SyncManager syncManager = getSyncManager();
            return getSyncManager().computeSyncable(account, userId, providerName, false);
            if (syncManager != null) {
                return syncManager.computeSyncable(
                        account, userId, providerName, false);
            }
        } finally {
        } finally {
            restoreCallingIdentity(identityToken);
            restoreCallingIdentity(identityToken);
        }
        }
        return -1;
    }
    }


    @Override
    @Override
@@ -1079,11 +1052,8 @@ public final class ContentService extends IContentService.Stub {


        final long identityToken = clearCallingIdentity();
        final long identityToken = clearCallingIdentity();
        try {
        try {
            SyncManager syncManager = getSyncManager();
            getSyncManager().getSyncStorageEngine().setIsSyncable(
            if (syncManager != null) {
                syncManager.getSyncStorageEngine().setIsSyncable(
                    account, userId, providerName, syncable, callingUid, callingPid);
                    account, userId, providerName, syncable, callingUid, callingPid);
            }
        } finally {
        } finally {
            restoreCallingIdentity(identityToken);
            restoreCallingIdentity(identityToken);
        }
        }
@@ -1107,14 +1077,10 @@ public final class ContentService extends IContentService.Stub {


        final long identityToken = clearCallingIdentity();
        final long identityToken = clearCallingIdentity();
        try {
        try {
            SyncManager syncManager = getSyncManager();
            return getSyncManager().getSyncStorageEngine().getMasterSyncAutomatically(userId);
            if (syncManager != null) {
                return syncManager.getSyncStorageEngine().getMasterSyncAutomatically(userId);
            }
        } finally {
        } finally {
            restoreCallingIdentity(identityToken);
            restoreCallingIdentity(identityToken);
        }
        }
        return false;
    }
    }


    @Override
    @Override
@@ -1134,11 +1100,8 @@ public final class ContentService extends IContentService.Stub {


        final long identityToken = clearCallingIdentity();
        final long identityToken = clearCallingIdentity();
        try {
        try {
            SyncManager syncManager = getSyncManager();
            getSyncManager().getSyncStorageEngine().setMasterSyncAutomatically(flag, userId,
            if (syncManager != null) {
                syncManager.getSyncStorageEngine().setMasterSyncAutomatically(flag, userId,
                    getSyncExemptionForCaller(callingUid), callingUid, callingPid);
                    getSyncExemptionForCaller(callingUid), callingUid, callingPid);
            }
        } finally {
        } finally {
            restoreCallingIdentity(identityToken);
            restoreCallingIdentity(identityToken);
        }
        }
@@ -1155,11 +1118,7 @@ public final class ContentService extends IContentService.Stub {
        int userId = UserHandle.getCallingUserId();
        int userId = UserHandle.getCallingUserId();
        final long identityToken = clearCallingIdentity();
        final long identityToken = clearCallingIdentity();
        try {
        try {
            SyncManager syncManager = getSyncManager();
            return getSyncManager().getSyncStorageEngine().isSyncActive(
            if (syncManager == null) {
                return false;
            }
            return syncManager.getSyncStorageEngine().isSyncActive(
                    new SyncStorageEngine.EndPoint(account, authority, userId));
                    new SyncStorageEngine.EndPoint(account, authority, userId));
        } finally {
        } finally {
            restoreCallingIdentity(identityToken);
            restoreCallingIdentity(identityToken);
@@ -1204,6 +1163,7 @@ public final class ContentService extends IContentService.Stub {
     * INTERACT_ACROSS_USERS_FULL permission.
     * INTERACT_ACROSS_USERS_FULL permission.
     */
     */
    @Override
    @Override
    @Nullable
    public SyncStatusInfo getSyncStatusAsUser(Account account, String authority,
    public SyncStatusInfo getSyncStatusAsUser(Account account, String authority,
                                              ComponentName cname, int userId) {
                                              ComponentName cname, int userId) {
        if (TextUtils.isEmpty(authority)) {
        if (TextUtils.isEmpty(authority)) {
@@ -1220,17 +1180,13 @@ public final class ContentService extends IContentService.Stub {


        final long identityToken = clearCallingIdentity();
        final long identityToken = clearCallingIdentity();
        try {
        try {
            SyncManager syncManager = getSyncManager();
            if (syncManager == null) {
                return null;
            }
            SyncStorageEngine.EndPoint info;
            SyncStorageEngine.EndPoint info;
            if (!(account == null || authority == null)) {
            if (!(account == null || authority == null)) {
                info = new SyncStorageEngine.EndPoint(account, authority, userId);
                info = new SyncStorageEngine.EndPoint(account, authority, userId);
            } else {
            } else {
                throw new IllegalArgumentException("Must call sync status with valid authority");
                throw new IllegalArgumentException("Must call sync status with valid authority");
            }
            }
            return syncManager.getSyncStorageEngine().getStatusByAuthority(info);
            return getSyncManager().getSyncStorageEngine().getStatusByAuthority(info);
        } finally {
        } finally {
            restoreCallingIdentity(identityToken);
            restoreCallingIdentity(identityToken);
        }
        }
@@ -1253,9 +1209,6 @@ public final class ContentService extends IContentService.Stub {
        }
        }


        final long identityToken = clearCallingIdentity();
        final long identityToken = clearCallingIdentity();
        SyncManager syncManager = getSyncManager();
        if (syncManager == null) return false;

        try {
        try {
            SyncStorageEngine.EndPoint info;
            SyncStorageEngine.EndPoint info;
            if (!(account == null || authority == null)) {
            if (!(account == null || authority == null)) {
@@ -1263,7 +1216,7 @@ public final class ContentService extends IContentService.Stub {
            } else {
            } else {
                throw new IllegalArgumentException("Invalid authority specified");
                throw new IllegalArgumentException("Invalid authority specified");
            }
            }
            return syncManager.getSyncStorageEngine().isSyncPending(info);
            return getSyncManager().getSyncStorageEngine().isSyncPending(info);
        } finally {
        } finally {
            restoreCallingIdentity(identityToken);
            restoreCallingIdentity(identityToken);
        }
        }
@@ -1274,9 +1227,8 @@ public final class ContentService extends IContentService.Stub {
        final int callingUid = Binder.getCallingUid();
        final int callingUid = Binder.getCallingUid();
        final long identityToken = clearCallingIdentity();
        final long identityToken = clearCallingIdentity();
        try {
        try {
            SyncManager syncManager = getSyncManager();
            if (callback != null) {
            if (syncManager != null && callback != null) {
                getSyncManager().getSyncStorageEngine().addStatusChangeListener(
                syncManager.getSyncStorageEngine().addStatusChangeListener(
                        mask, callingUid, callback);
                        mask, callingUid, callback);
            }
            }
        } finally {
        } finally {
@@ -1288,9 +1240,8 @@ public final class ContentService extends IContentService.Stub {
    public void removeStatusChangeListener(ISyncStatusObserver callback) {
    public void removeStatusChangeListener(ISyncStatusObserver callback) {
        final long identityToken = clearCallingIdentity();
        final long identityToken = clearCallingIdentity();
        try {
        try {
            SyncManager syncManager = getSyncManager();
            if (callback != null) {
            if (syncManager != null && callback != null) {
                getSyncManager().getSyncStorageEngine().removeStatusChangeListener(callback);
                syncManager.getSyncStorageEngine().removeStatusChangeListener(callback);
            }
            }
        } finally {
        } finally {
            restoreCallingIdentity(identityToken);
            restoreCallingIdentity(identityToken);