Loading core/java/android/content/ContentResolver.java +10 −2 Original line number Original line Diff line number Diff line Loading @@ -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 */ Loading Loading @@ -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())); } } /** /** Loading services/core/java/com/android/server/content/ContentService.java +27 −12 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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, Loading @@ -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) { Loading @@ -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); } } Loading @@ -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, Loading @@ -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 Loading @@ -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(); Loading Loading
core/java/android/content/ContentResolver.java +10 −2 Original line number Original line Diff line number Diff line Loading @@ -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 */ Loading Loading @@ -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())); } } /** /** Loading
services/core/java/com/android/server/content/ContentService.java +27 −12 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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, Loading @@ -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) { Loading @@ -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); } } Loading @@ -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, Loading @@ -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 Loading @@ -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(); Loading