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

Commit 932765b4 authored by Benjamin Franz's avatar Benjamin Franz Committed by Android Git Automerger
Browse files

am aa2b7910: am adb41d8f: am 01b079f7: Merge "Make ContentObservers work...

am aa2b7910: am adb41d8f: am 01b079f7: Merge "Make ContentObservers work across profiles" into mnc-dev

* commit 'aa2b7910':
  Make ContentObservers work across profiles
parents a1d9cd4b aa2b7910
Loading
Loading
Loading
Loading
+10 −2
Original line number Original line Diff line number Diff line
@@ -1593,7 +1593,11 @@ public abstract class ContentResolver {
            @NonNull ContentObserver observer) {
            @NonNull ContentObserver observer) {
        Preconditions.checkNotNull(uri, "uri");
        Preconditions.checkNotNull(uri, "uri");
        Preconditions.checkNotNull(observer, "observer");
        Preconditions.checkNotNull(observer, "observer");
        registerContentObserver(uri, notifyForDescendents, observer, UserHandle.myUserId());
        registerContentObserver(
                ContentProvider.getUriWithoutUserId(uri),
                notifyForDescendents,
                observer,
                ContentProvider.getUserIdFromUri(uri, UserHandle.myUserId()));
    }
    }


    /** @hide - designated user version */
    /** @hide - designated user version */
@@ -1659,7 +1663,11 @@ public abstract class ContentResolver {
    public void notifyChange(@NonNull Uri uri, @Nullable ContentObserver observer,
    public void notifyChange(@NonNull Uri uri, @Nullable ContentObserver observer,
            boolean syncToNetwork) {
            boolean syncToNetwork) {
        Preconditions.checkNotNull(uri, "uri");
        Preconditions.checkNotNull(uri, "uri");
        notifyChange(uri, observer, syncToNetwork, UserHandle.myUserId());
        notifyChange(
                ContentProvider.getUriWithoutUserId(uri),
                observer,
                syncToNetwork,
                ContentProvider.getUserIdFromUri(uri, UserHandle.myUserId()));
    }
    }


    /**
    /**
+27 −12
Original line number Original line Diff line number Diff line
@@ -23,12 +23,14 @@ import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Context;
import android.content.IContentService;
import android.content.IContentService;
import android.content.Intent;
import android.content.ISyncStatusObserver;
import android.content.ISyncStatusObserver;
import android.content.PeriodicSync;
import android.content.PeriodicSync;
import android.content.SyncAdapterType;
import android.content.SyncAdapterType;
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.IContentObserver;
import android.database.IContentObserver;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteException;
import android.net.Uri;
import android.net.Uri;
@@ -161,8 +163,9 @@ public final class ContentService extends IContentService.Stub {
     * Register a content observer tied to a specific user's view of the provider.
     * Register a content observer tied to a specific user's view of the provider.
     * @param userHandle the user whose view of the provider is to be observed.  May be
     * @param userHandle the user whose view of the provider is to be observed.  May be
     *     the calling user without requiring any permission, otherwise the caller needs to
     *     the calling user without requiring any permission, otherwise the caller needs to
     *     hold the INTERACT_ACROSS_USERS_FULL permission.  Pseudousers USER_ALL and
     *     hold the INTERACT_ACROSS_USERS_FULL permission or hold a read uri grant to the uri.
     *     USER_CURRENT are properly handled; all other pseudousers are forbidden.
     *     Pseudousers USER_ALL and USER_CURRENT are properly handled; all other pseudousers
     *     are forbidden.
     */
     */
    @Override
    @Override
    public void registerContentObserver(Uri uri, boolean notifyForDescendants,
    public void registerContentObserver(Uri uri, boolean notifyForDescendants,
@@ -171,8 +174,17 @@ public final class ContentService extends IContentService.Stub {
            throw new IllegalArgumentException("You must pass a valid uri and observer");
            throw new IllegalArgumentException("You must pass a valid uri and observer");
        }
        }


        final int uid = Binder.getCallingUid();
        final int pid = Binder.getCallingPid();
        final int callingUserHandle = UserHandle.getCallingUserId();
        // Registering an observer for any user other than the calling user requires uri grant or
        // cross user permission
        if (callingUserHandle != userHandle &&
                mContext.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_READ_URI_PERMISSION)
                        != PackageManager.PERMISSION_GRANTED) {
            enforceCrossUserPermission(userHandle,
            enforceCrossUserPermission(userHandle,
                    "no permission to observe other users' provider view");
                    "no permission to observe other users' provider view");
        }


        if (userHandle < 0) {
        if (userHandle < 0) {
            if (userHandle == UserHandle.USER_CURRENT) {
            if (userHandle == UserHandle.USER_CURRENT) {
@@ -185,7 +197,7 @@ public final class ContentService extends IContentService.Stub {


        synchronized (mRootNode) {
        synchronized (mRootNode) {
            mRootNode.addObserverLocked(uri, observer, notifyForDescendants, mRootNode,
            mRootNode.addObserverLocked(uri, observer, notifyForDescendants, mRootNode,
                    Binder.getCallingUid(), Binder.getCallingPid(), userHandle);
                    uid, pid, userHandle);
            if (false) Log.v(TAG, "Registered observer " + observer + " at " + uri +
            if (false) Log.v(TAG, "Registered observer " + observer + " at " + uri +
                    " with notifyForDescendants " + notifyForDescendants);
                    " with notifyForDescendants " + notifyForDescendants);
        }
        }
@@ -211,8 +223,9 @@ public final class ContentService extends IContentService.Stub {
     * Notify observers of a particular user's view of the provider.
     * Notify observers of a particular user's view of the provider.
     * @param userHandle the user whose view of the provider is to be notified.  May be
     * @param userHandle the user whose view of the provider is to be notified.  May be
     *     the calling user without requiring any permission, otherwise the caller needs to
     *     the calling user without requiring any permission, otherwise the caller needs to
     *     hold the INTERACT_ACROSS_USERS_FULL permission.  Pseudousers USER_ALL and
     *     hold the INTERACT_ACROSS_USERS_FULL permission or hold a write uri grant to the uri.
     *     USER_CURRENT are properly interpreted; no other pseudousers are allowed.
     *     Pseudousers USER_ALL and USER_CURRENT are properly interpreted; no other pseudousers are
     *     allowed.
     */
     */
    @Override
    @Override
    public void notifyChange(Uri uri, IContentObserver observer,
    public void notifyChange(Uri uri, IContentObserver observer,
@@ -223,11 +236,14 @@ public final class ContentService extends IContentService.Stub {
                    + " from observer " + observer + ", syncToNetwork " + syncToNetwork);
                    + " from observer " + observer + ", syncToNetwork " + syncToNetwork);
        }
        }


        // Notify for any user other than the caller's own requires permission.
        final int uid = Binder.getCallingUid();
        final int pid = Binder.getCallingPid();
        final int callingUserHandle = UserHandle.getCallingUserId();
        final int callingUserHandle = UserHandle.getCallingUserId();
        if (userHandle != callingUserHandle) {
        // Notify for any user other than the caller requires uri grant or cross user permission
            mContext.enforceCallingOrSelfPermission(Manifest.permission.INTERACT_ACROSS_USERS,
        if (callingUserHandle != userHandle &&
                    "no permission to notify other users");
                mContext.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
                        != PackageManager.PERMISSION_GRANTED) {
            enforceCrossUserPermission(userHandle, "no permission to notify other users");
        }
        }


        // We passed the permission check; resolve pseudouser targets as appropriate
        // We passed the permission check; resolve pseudouser targets as appropriate
@@ -240,7 +256,6 @@ public final class ContentService extends IContentService.Stub {
            }
            }
        }
        }


        final int uid = 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.
        long identityToken = clearCallingIdentity();
        long identityToken = clearCallingIdentity();