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

Commit f04429b9 authored by Rhed Jao's avatar Rhed Jao Committed by Android (Google) Code Review
Browse files

Merge "Enforce package visibility to the callbacks of the sync status"

parents 81def7e7 650cb7a9
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -3192,6 +3192,21 @@ public abstract class ContentResolver implements ContentInterface {
        }
    }

    /**
     * Returns the package name of the syncadapter that matches a given account type, authority
     * and user.
     * @hide
     */
    @Nullable
    public static String getSyncAdapterPackageAsUser(@NonNull String accountType,
            @NonNull String authority, @UserIdInt int userId) {
        try {
            return getContentService().getSyncAdapterPackageAsUser(accountType, authority, userId);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Check if the provider should be synced when a network tickle is received
     * <p>This method requires the caller to hold the permission
+1 −0
Original line number Diff line number Diff line
@@ -150,6 +150,7 @@ interface IContentService {
    SyncAdapterType[] getSyncAdapterTypesAsUser(int userId);

    String[] getSyncAdapterPackagesForAuthorityAsUser(String authority, int userId);
    String getSyncAdapterPackageAsUser(String accountType, String authority, int userId);

    /**
     * Returns true if there is currently a operation for the given account/authority or service
+17 −1
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.accounts.Account;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.app.AppGlobals;
@@ -822,6 +823,21 @@ public final class ContentService extends IContentService.Stub {
        }
    }

    @Override
    public String getSyncAdapterPackageAsUser(@NonNull String accountType,
            @NonNull String authority, @UserIdInt int userId) {
        enforceCrossUserPermission(userId,
                "no permission to read sync settings for user " + userId);
        final int callingUid = Binder.getCallingUid();
        final long identityToken = clearCallingIdentity();
        try {
            return getSyncManager().getSyncAdapterPackageAsUser(accountType, authority,
                    callingUid, userId);
        } finally {
            restoreCallingIdentity(identityToken);
        }
    }

    @Override
    public boolean getSyncAutomatically(Account account, String providerName) {
        return getSyncAutomaticallyAsUser(account, providerName, UserHandle.getCallingUserId());
@@ -1205,7 +1221,7 @@ public final class ContentService extends IContentService.Stub {
            SyncManager syncManager = getSyncManager();
            if (syncManager != null && callback != null) {
                syncManager.getSyncStorageEngine().addStatusChangeListener(
                        mask, UserHandle.getUserId(callingUid), callback);
                        mask, callingUid, callback);
            }
        } finally {
            restoreCallingIdentity(identityToken);
+22 −2
Original line number Diff line number Diff line
@@ -1245,6 +1245,26 @@ public class SyncManager {
        return filteredResult.toArray(new String[] {});
    }

    public String getSyncAdapterPackageAsUser(String accountType, String authority,
            int callingUid, int userId) {
        if (accountType == null || authority == null) {
            return null;
        }
        final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo =
                mSyncAdapters.getServiceInfo(
                        SyncAdapterType.newKey(authority, accountType),
                        userId);
        if (syncAdapterInfo == null) {
            return null;
        }
        final String packageName = syncAdapterInfo.type.getPackageName();
        if (TextUtils.isEmpty(packageName) || mPackageManagerInternal.filterAppAccess(
                packageName, callingUid, userId)) {
            return null;
        }
        return packageName;
    }

    private void sendSyncFinishedOrCanceledMessage(ActiveSyncContext syncContext,
            SyncResult syncResult) {
        if (Log.isLoggable(TAG, Log.VERBOSE)) Slog.v(TAG, "sending MESSAGE_SYNC_FINISHED");
@@ -3402,7 +3422,7 @@ public class SyncManager {

            scheduleSyncOperationH(op);
            mSyncStorageEngine.reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS,
                    target.userId);
                    op.owningPackage, target.userId);
        }

        /**
@@ -3921,7 +3941,7 @@ public class SyncManager {
                    syncOperation.toEventLog(SyncStorageEngine.EVENT_STOP));
            mSyncStorageEngine.stopSyncEvent(rowId, elapsedTime,
                    resultMessage, downstreamActivity, upstreamActivity,
                    syncOperation.target.userId);
                    syncOperation.owningPackage, syncOperation.target.userId);
        }
    }

+49 −24
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import android.content.SyncInfo;
import android.content.SyncRequest;
import android.content.SyncStatusInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
@@ -59,6 +60,7 @@ import android.util.proto.ProtoOutputStream;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.IntPair;
import com.android.server.LocalServices;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -166,6 +168,8 @@ public class SyncStorageEngine {
    private static HashMap<String, String> sAuthorityRenames;
    private static PeriodicSyncAddedListener mPeriodicSyncAddedListener;

    private final PackageManagerInternal mPackageManagerInternal;

    private volatile boolean mIsClockValid;

    static {
@@ -525,6 +529,8 @@ public class SyncStorageEngine {
        mDefaultMasterSyncAutomatically = mContext.getResources().getBoolean(
                com.android.internal.R.bool.config_syncstorageengine_masterSyncAutomatically);

        mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);

        File systemDir = new File(dataDir, "system");
        mSyncDir = new File(systemDir, SYNC_DIR_NAME);
        mSyncDir.mkdirs();
@@ -609,9 +615,9 @@ public class SyncStorageEngine {
        return mSyncRandomOffset;
    }

    public void addStatusChangeListener(int mask, int userId, ISyncStatusObserver callback) {
    public void addStatusChangeListener(int mask, int callingUid, ISyncStatusObserver callback) {
        synchronized (mAuthorities) {
            final long cookie = IntPair.of(userId, mask);
            final long cookie = IntPair.of(callingUid, mask);
            mChangeListeners.register(callback, cookie);
        }
    }
@@ -644,16 +650,32 @@ public class SyncStorageEngine {
        }
    }

    void reportChange(int which, int callingUserId) {
    void reportChange(int which, EndPoint target) {
        final String syncAdapterPackageName;
        if (target.account == null || target.provider == null) {
            syncAdapterPackageName = null;
        } else {
            syncAdapterPackageName = ContentResolver.getSyncAdapterPackageAsUser(
                    target.account.type, target.provider, target.userId);
        }
        reportChange(which, syncAdapterPackageName, target.userId);
    }

    void reportChange(int which, String callingPackageName, int callingUserId) {
        ArrayList<ISyncStatusObserver> reports = null;
        synchronized (mAuthorities) {
            int i = mChangeListeners.beginBroadcast();
            while (i > 0) {
                i--;
                final long cookie = (long) mChangeListeners.getBroadcastCookie(i);
                final int userId = IntPair.first(cookie);
                final int registerUid = IntPair.first(cookie);
                final int registerUserId = UserHandle.getUserId(registerUid);
                final int mask = IntPair.second(cookie);
                if ((which & mask) == 0 || callingUserId != userId) {
                if ((which & mask) == 0 || callingUserId != registerUserId) {
                    continue;
                }
                if (callingPackageName != null && mPackageManagerInternal.filterAppAccess(
                        callingPackageName, registerUid, callingUserId)) {
                    continue;
                }
                if (reports == null) {
@@ -716,9 +738,9 @@ public class SyncStorageEngine {
                " cuid=", callingUid,
                " cpid=", callingPid
        );
        final AuthorityInfo authority;
        synchronized (mAuthorities) {
            AuthorityInfo authority =
                    getOrCreateAuthorityLocked(
            authority = getOrCreateAuthorityLocked(
                    new EndPoint(account, providerName, userId),
                    -1 /* ident */,
                    false);
@@ -743,7 +765,7 @@ public class SyncStorageEngine {
                    new Bundle(),
                    syncExemptionFlag, callingUid, callingPid);
        }
        reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS, userId);
        reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS, authority.target);
        queueBackup();
    }

@@ -811,7 +833,7 @@ public class SyncStorageEngine {
            requestSync(aInfo, SyncOperation.REASON_IS_SYNCABLE, new Bundle(),
                    ContentResolver.SYNC_EXEMPTION_NONE, callingUid, callingPid);
        }
        reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS, target.userId);
        reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS, target);
    }

    public Pair<Long, Long> getBackoff(EndPoint info) {
@@ -857,7 +879,7 @@ public class SyncStorageEngine {
            }
        }
        if (changed) {
            reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS, info.userId);
            reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS, info);
        }
    }

@@ -919,7 +941,8 @@ public class SyncStorageEngine {
        }

        for (int i = changedUserIds.size() - 1; i > 0; i--) {
            reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS, changedUserIds.valueAt(i));
            reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS,
                    null /* callingPackageName */, changedUserIds.valueAt(i));
        }
    }

@@ -945,7 +968,7 @@ public class SyncStorageEngine {
            }
            authority.delayUntil = delayUntil;
        }
        reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS, info.userId);
        reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS, info);
    }

    /**
@@ -988,7 +1011,8 @@ public class SyncStorageEngine {
                    new Bundle(),
                    syncExemptionFlag, callingUid, callingPid);
        }
        reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS, userId);
        reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS,
                null /* callingPackageName */, userId);
        mContext.sendBroadcast(ContentResolver.ACTION_SYNC_CONN_STATUS_CHANGED);
        queueBackup();
    }
@@ -1039,7 +1063,7 @@ public class SyncStorageEngine {
            SyncStatusInfo status = getOrCreateSyncStatusLocked(authority.ident);
            status.pending = pendingValue;
        }
        reportChange(ContentResolver.SYNC_OBSERVER_TYPE_PENDING, info.userId);
        reportChange(ContentResolver.SYNC_OBSERVER_TYPE_PENDING, info);
    }

    /**
@@ -1129,7 +1153,7 @@ public class SyncStorageEngine {
                    activeSyncContext.mStartTime);
            getCurrentSyncs(authorityInfo.target.userId).add(syncInfo);
        }
        reportActiveChange(activeSyncContext.mSyncOperation.target.userId);
        reportActiveChange(activeSyncContext.mSyncOperation.target);
        return syncInfo;
    }

@@ -1146,14 +1170,14 @@ public class SyncStorageEngine {
            getCurrentSyncs(userId).remove(syncInfo);
        }

        reportActiveChange(userId);
        reportActiveChange(new EndPoint(syncInfo.account, syncInfo.authority, userId));
    }

    /**
     * To allow others to send active change reports, to poke clients.
     */
    public void reportActiveChange(int userId) {
        reportChange(ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE, userId);
    public void reportActiveChange(EndPoint target) {
        reportChange(ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE, target);
    }

    /**
@@ -1188,12 +1212,13 @@ public class SyncStorageEngine {
            if (Log.isLoggable(TAG, Log.VERBOSE)) Slog.v(TAG, "returning historyId " + id);
        }

        reportChange(ContentResolver.SYNC_OBSERVER_TYPE_STATUS, op.target.userId);
        reportChange(ContentResolver.SYNC_OBSERVER_TYPE_STATUS, op.owningPackage, op.target.userId);
        return id;
    }

    public void stopSyncEvent(long historyId, long elapsedTime, String resultMessage,
                              long downstreamActivity, long upstreamActivity, int userId) {
                              long downstreamActivity, long upstreamActivity, String opPackageName,
                              int userId) {
        synchronized (mAuthorities) {
            if (Log.isLoggable(TAG, Log.VERBOSE)) {
                Slog.v(TAG, "stopSyncEvent: historyId=" + historyId);
@@ -1333,7 +1358,7 @@ public class SyncStorageEngine {
            }
        }

        reportChange(ContentResolver.SYNC_OBSERVER_TYPE_STATUS, userId);
        reportChange(ContentResolver.SYNC_OBSERVER_TYPE_STATUS, opPackageName, userId);
    }

    /**