Add @SystemApi registerContentObserverForAllUsers in ContentResolver

Also add ContentObserver#onChange(boolean, Collection, int, UserHandle) so
clients can know the corresponding UserHandle for the notification.

Bug: 203606981
Test: atest CtsContentTestCases and manual testing to verify the observer can get notifications for
all the users.

Change-Id: Icec7e70b71d7de1c15faf1736539f169856304a8
This commit is contained in:
Xiaoyu Jin
2021-10-28 04:52:44 +00:00
parent 420679dea6
commit c06b02ddba
3 changed files with 64 additions and 1 deletions

View File

@@ -2405,6 +2405,7 @@ package android.content {
method @NonNull public static java.io.File encodeToFile(@NonNull android.net.Uri);
method @Nullable @RequiresPermission("android.permission.CACHE_CONTENT") public android.os.Bundle getCache(@NonNull android.net.Uri);
method @RequiresPermission("android.permission.CACHE_CONTENT") public void putCache(@NonNull android.net.Uri, @Nullable android.os.Bundle);
method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public final void registerContentObserverForAllUsers(@NonNull android.net.Uri, boolean, @NonNull android.database.ContentObserver);
}
public abstract class Context {
@@ -3147,6 +3148,14 @@ package android.content.rollback {
}
package android.database {
public abstract class ContentObserver {
method public void onChange(boolean, @NonNull java.util.Collection<android.net.Uri>, int, @NonNull android.os.UserHandle);
}
}
package android.debug {
public class AdbManager {

View File

@@ -2664,6 +2664,38 @@ public abstract class ContentResolver implements ContentInterface {
ContentProvider.getUserIdFromUri(uri, mContext.getUserId()));
}
/**
* Same as {@link #registerContentObserver(Uri, boolean, ContentObserver)}, but the observer
* registered will get content change notifications from all users.
* {@link ContentObserver#onChange(boolean, Collection, int, UserHandle)} should be
* overwritten to get the corresponding {@link UserHandle} for that notification.
*
* @param uri The URI to watch for changes. This can be a specific row URI,
* or a base URI for a whole class of content.
* @param notifyForDescendants When false, the observer will be notified
* whenever a change occurs to the exact URI specified by
* <code>uri</code> or to one of the URI's ancestors in the path
* hierarchy. When true, the observer will also be notified
* whenever a change occurs to the URI's descendants in the path
* hierarchy.
* @param observer The object that receives callbacks when changes occur.
* @hide
* @see #unregisterContentObserver
*/
@RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
@SystemApi
public final void registerContentObserverForAllUsers(@NonNull Uri uri,
boolean notifyForDescendants,
@NonNull ContentObserver observer) {
Objects.requireNonNull(uri, "uri");
Objects.requireNonNull(observer, "observer");
registerContentObserver(
ContentProvider.getUriWithoutUserId(uri),
notifyForDescendants,
observer,
UserHandle.USER_ALL);
}
/** @hide - designated user version */
@UnsupportedAppUsage
public final void registerContentObserver(Uri uri, boolean notifyForDescendents,

View File

@@ -18,6 +18,7 @@ package android.database;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.UserIdInt;
import android.app.compat.CompatChanges;
import android.compat.annotation.ChangeId;
@@ -188,6 +189,27 @@ public abstract class ContentObserver {
}
}
/**
* This method is called when a content change occurs. Includes the changed
* content Uris when available.
* <p>
* Subclasses should override this method to handle content changes. To
* ensure correct operation on older versions of the framework that did not
* provide richer arguments, applications should implement all overloads.
*
* @param selfChange True if this is a self-change notification.
* @param uris The Uris of the changed content.
* @param flags Flags indicating details about this change.
* @param user The corresponding {@link UserHandle} for the current notification.
*
* @hide
*/
@SystemApi
public void onChange(boolean selfChange, @NonNull Collection<Uri> uris,
@NotifyFlags int flags, @NonNull UserHandle user) {
onChange(selfChange, uris, user.getIdentifier());
}
/** @hide */
public void onChange(boolean selfChange, @NonNull Collection<Uri> uris,
@NotifyFlags int flags, @UserIdInt int userId) {
@@ -197,7 +219,7 @@ public abstract class ContentObserver {
if (!CompatChanges.isChangeEnabled(ADD_CONTENT_OBSERVER_FLAGS)
|| android.os.Process.myUid() == android.os.Process.SYSTEM_UID) {
// Deliver userId through argument to preserve hidden API behavior
onChange(selfChange, uris, userId);
onChange(selfChange, uris, flags, UserHandle.of(userId));
} else {
onChange(selfChange, uris, flags);
}