summaryrefslogtreecommitdiff
path: root/core/java/android
diff options
context:
space:
mode:
authorJeff Sharkey <jsharkey@google.com>2020-03-06 00:04:24 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2020-03-06 00:04:24 +0000
commit189e00a46bcd9273dbb928ab6791426f7bc766bc (patch)
treea183df97cf8730503fbe22d0f491b644a61957db /core/java/android
parent9a967db5750d62581c02038126e84dceacd240e6 (diff)
parentd70325359ed681dbe90ab5d0e6562f795c73417a (diff)
Merge "Use flags to indicate reason for Uri changes." into rvc-dev
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/content/ContentResolver.java35
-rw-r--r--core/java/android/database/ContentObserver.java163
-rw-r--r--core/java/android/database/CursorToBulkCursorAdaptor.java18
-rw-r--r--core/java/android/database/IContentObserver.aidl10
4 files changed, 162 insertions, 64 deletions
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index c7f42cb85943..ae786aa30ae0 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -629,7 +629,10 @@ public abstract class ContentResolver implements ContentInterface {
/** @hide */
@IntDef(flag = true, prefix = { "NOTIFY_" }, value = {
NOTIFY_SYNC_TO_NETWORK,
- NOTIFY_SKIP_NOTIFY_FOR_DESCENDANTS
+ NOTIFY_SKIP_NOTIFY_FOR_DESCENDANTS,
+ NOTIFY_INSERT,
+ NOTIFY_UPDATE,
+ NOTIFY_DELETE
})
@Retention(RetentionPolicy.SOURCE)
public @interface NotifyFlags {}
@@ -651,6 +654,36 @@ public abstract class ContentResolver implements ContentInterface {
public static final int NOTIFY_SKIP_NOTIFY_FOR_DESCENDANTS = 1<<1;
/**
+ * Flag for {@link #notifyChange(Uri, ContentObserver, int)}: typically set
+ * by a {@link ContentProvider} to indicate that this notification is the
+ * result of an {@link ContentProvider#insert} call.
+ * <p>
+ * Sending these detailed flags are optional, but providers are strongly
+ * recommended to send them.
+ */
+ public static final int NOTIFY_INSERT = 1 << 2;
+
+ /**
+ * Flag for {@link #notifyChange(Uri, ContentObserver, int)}: typically set
+ * by a {@link ContentProvider} to indicate that this notification is the
+ * result of an {@link ContentProvider#update} call.
+ * <p>
+ * Sending these detailed flags are optional, but providers are strongly
+ * recommended to send them.
+ */
+ public static final int NOTIFY_UPDATE = 1 << 3;
+
+ /**
+ * Flag for {@link #notifyChange(Uri, ContentObserver, int)}: typically set
+ * by a {@link ContentProvider} to indicate that this notification is the
+ * result of a {@link ContentProvider#delete} call.
+ * <p>
+ * Sending these detailed flags are optional, but providers are strongly
+ * recommended to send them.
+ */
+ public static final int NOTIFY_DELETE = 1 << 4;
+
+ /**
* No exception, throttled by app standby normally.
* @hide
*/
diff --git a/core/java/android/database/ContentObserver.java b/core/java/android/database/ContentObserver.java
index 69ca581e1559..ede264d042ce 100644
--- a/core/java/android/database/ContentObserver.java
+++ b/core/java/android/database/ContentObserver.java
@@ -16,11 +16,17 @@
package android.database;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.UserIdInt;
import android.compat.annotation.UnsupportedAppUsage;
+import android.content.ContentResolver.NotifyFlags;
import android.net.Uri;
import android.os.Handler;
import android.os.UserHandle;
+import java.util.Arrays;
+
/**
* Receives call backs for changes to content.
* Must be implemented by objects which are added to a {@link ContentObservable}.
@@ -101,12 +107,10 @@ public abstract class ContentObserver {
* This method is called when a content change occurs.
* Includes the changed content Uri 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 a Uri argument, applications should also implement
- * the {@link #onChange(boolean)} overload of this method whenever they
- * implement the {@link #onChange(boolean, Uri)} overload.
- * </p><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.
+ * <p>
* Example implementation:
* <pre><code>
* // Implement the onChange(boolean) method to delegate the change notification to
@@ -126,38 +130,63 @@ public abstract class ContentObserver {
* </p>
*
* @param selfChange True if this is a self-change notification.
- * @param uri The Uri of the changed content, or null if unknown.
+ * @param uri The Uri of the changed content.
*/
- public void onChange(boolean selfChange, Uri uri) {
+ public void onChange(boolean selfChange, @Nullable Uri uri) {
onChange(selfChange);
}
/**
- * Dispatches a change notification to the observer. Includes the changed
- * content Uri when available and also the user whose content changed.
+ * This method is called when a content change occurs. Includes the changed
+ * content Uri 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 uri The Uri of the changed content, or null if unknown.
- * @param userId The user whose content changed. Can be either a specific
- * user or {@link UserHandle#USER_ALL}.
- *
- * @hide
+ * @param uri The Uri of the changed content.
+ * @param flags Flags indicating details about this change.
*/
- public void onChange(boolean selfChange, Uri uri, int userId) {
+ public void onChange(boolean selfChange, @Nullable Uri uri, @NotifyFlags int flags) {
onChange(selfChange, uri);
}
/**
- * Dispatches a change notification to the observer.
+ * This method is called when a content change occurs. Includes the changed
+ * content Uris when available.
* <p>
- * If a {@link Handler} was supplied to the {@link ContentObserver} constructor,
- * then a call to the {@link #onChange} method is posted to the handler's message queue.
- * Otherwise, the {@link #onChange} method is invoked immediately on this thread.
- * </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.
+ */
+ public void onChange(boolean selfChange, @NonNull Iterable<Uri> uris, @NotifyFlags int flags) {
+ for (Uri uri : uris) {
+ onChange(selfChange, uri, flags);
+ }
+ }
+
+ /** @hide */
+ public void onChange(boolean selfChange, @NonNull Iterable<Uri> uris, @NotifyFlags int flags,
+ @UserIdInt int userId) {
+ onChange(selfChange, uris, flags);
+ }
+
+ /**
+ * Dispatches a change notification to the observer.
+ * <p>
+ * If a {@link Handler} was supplied to the {@link ContentObserver}
+ * constructor, then a call to the {@link #onChange} method is posted to the
+ * handler's message queue. Otherwise, the {@link #onChange} method is
+ * invoked immediately on this thread.
*
- * @deprecated Use {@link #dispatchChange(boolean, Uri)} instead.
+ * @deprecated Callers should migrate towards using a richer overload that
+ * provides more details about the change, such as
+ * {@link #dispatchChange(boolean, Iterable, int)}.
*/
@Deprecated
public final void dispatchChange(boolean selfChange) {
@@ -165,57 +194,66 @@ public abstract class ContentObserver {
}
/**
- * Dispatches a change notification to the observer.
- * Includes the changed content Uri when available.
+ * Dispatches a change notification to the observer. Includes the changed
+ * content Uri when available.
* <p>
- * If a {@link Handler} was supplied to the {@link ContentObserver} constructor,
- * then a call to the {@link #onChange} method is posted to the handler's message queue.
- * Otherwise, the {@link #onChange} method is invoked immediately on this thread.
- * </p>
+ * If a {@link Handler} was supplied to the {@link ContentObserver}
+ * constructor, then a call to the {@link #onChange} method is posted to the
+ * handler's message queue. Otherwise, the {@link #onChange} method is
+ * invoked immediately on this thread.
*
* @param selfChange True if this is a self-change notification.
- * @param uri The Uri of the changed content, or null if unknown.
+ * @param uri The Uri of the changed content.
*/
- public final void dispatchChange(boolean selfChange, Uri uri) {
- dispatchChange(selfChange, uri, UserHandle.getCallingUserId());
+ public final void dispatchChange(boolean selfChange, @Nullable Uri uri) {
+ dispatchChange(selfChange, Arrays.asList(uri), 0, UserHandle.getCallingUserId());
}
/**
* Dispatches a change notification to the observer. Includes the changed
- * content Uri when available and also the user whose content changed.
+ * content Uri when available.
* <p>
- * If a {@link Handler} was supplied to the {@link ContentObserver} constructor,
- * then a call to the {@link #onChange} method is posted to the handler's message queue.
- * Otherwise, the {@link #onChange} method is invoked immediately on this thread.
- * </p>
+ * If a {@link Handler} was supplied to the {@link ContentObserver}
+ * constructor, then a call to the {@link #onChange} method is posted to the
+ * handler's message queue. Otherwise, the {@link #onChange} method is
+ * invoked immediately on this thread.
*
* @param selfChange True if this is a self-change notification.
- * @param uri The Uri of the changed content, or null if unknown.
- * @param userId The user whose content changed.
+ * @param uri The Uri of the changed content.
+ * @param flags Flags indicating details about this change.
*/
- private void dispatchChange(boolean selfChange, Uri uri, int userId) {
- if (mHandler == null) {
- onChange(selfChange, uri, userId);
- } else {
- mHandler.post(new NotificationRunnable(selfChange, uri, userId));
- }
+ public final void dispatchChange(boolean selfChange, @Nullable Uri uri,
+ @NotifyFlags int flags) {
+ dispatchChange(selfChange, Arrays.asList(uri), flags, UserHandle.getCallingUserId());
}
+ /**
+ * Dispatches a change notification to the observer. Includes the changed
+ * content Uris when available.
+ * <p>
+ * If a {@link Handler} was supplied to the {@link ContentObserver}
+ * constructor, then a call to the {@link #onChange} method is posted to the
+ * handler's message queue. Otherwise, the {@link #onChange} method is
+ * invoked immediately on this thread.
+ *
+ * @param selfChange True if this is a self-change notification.
+ * @param uris The Uri of the changed content.
+ * @param flags Flags indicating details about this change.
+ */
+ public final void dispatchChange(boolean selfChange, @NonNull Iterable<Uri> uris,
+ @NotifyFlags int flags) {
+ dispatchChange(selfChange, uris, flags, UserHandle.getCallingUserId());
+ }
- private final class NotificationRunnable implements Runnable {
- private final boolean mSelfChange;
- private final Uri mUri;
- private final int mUserId;
-
- public NotificationRunnable(boolean selfChange, Uri uri, int userId) {
- mSelfChange = selfChange;
- mUri = uri;
- mUserId = userId;
- }
-
- @Override
- public void run() {
- ContentObserver.this.onChange(mSelfChange, mUri, mUserId);
+ /** @hide */
+ public final void dispatchChange(boolean selfChange, @NonNull Iterable<Uri> uris,
+ @NotifyFlags int flags, @UserIdInt int userId) {
+ if (mHandler == null) {
+ onChange(selfChange, uris, flags, userId);
+ } else {
+ mHandler.post(() -> {
+ onChange(selfChange, uris, flags, userId);
+ });
}
}
@@ -228,9 +266,16 @@ public abstract class ContentObserver {
@Override
public void onChange(boolean selfChange, Uri uri, int userId) {
+ // This is kept intact purely for apps using hidden APIs, to
+ // redirect to the updated implementation
+ onChangeEtc(selfChange, new Uri[] { uri }, 0, userId);
+ }
+
+ @Override
+ public void onChangeEtc(boolean selfChange, Uri[] uris, int flags, int userId) {
ContentObserver contentObserver = mContentObserver;
if (contentObserver != null) {
- contentObserver.dispatchChange(selfChange, uri, userId);
+ contentObserver.dispatchChange(selfChange, Arrays.asList(uris), flags, userId);
}
}
diff --git a/core/java/android/database/CursorToBulkCursorAdaptor.java b/core/java/android/database/CursorToBulkCursorAdaptor.java
index 02eddf239dca..1855dd254ad4 100644
--- a/core/java/android/database/CursorToBulkCursorAdaptor.java
+++ b/core/java/android/database/CursorToBulkCursorAdaptor.java
@@ -16,9 +16,14 @@
package android.database;
+import android.annotation.NonNull;
+import android.annotation.UserIdInt;
+import android.content.ContentResolver.NotifyFlags;
import android.net.Uri;
import android.os.*;
+import java.util.ArrayList;
+
/**
* Wraps a BulkCursor around an existing Cursor making it remotable.
@@ -76,9 +81,18 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative
}
@Override
- public void onChange(boolean selfChange, Uri uri) {
+ public void onChange(boolean selfChange, @NonNull Iterable<Uri> uris,
+ @NotifyFlags int flags, @UserIdInt int userId) {
+ // Since we deliver changes from the most-specific to least-specific
+ // overloads, we only need to redirect from the most-specific local
+ // method to the most-specific remote method
+
+ final ArrayList<Uri> asList = new ArrayList<>();
+ uris.forEach(asList::add);
+ final Uri[] asArray = asList.toArray(new Uri[asList.size()]);
+
try {
- mRemote.onChange(selfChange, uri, android.os.Process.myUid());
+ mRemote.onChangeEtc(selfChange, asArray, flags, userId);
} catch (RemoteException ex) {
// Do nothing, the far side is dead
}
diff --git a/core/java/android/database/IContentObserver.aidl b/core/java/android/database/IContentObserver.aidl
index 623556695341..19284cf40617 100644
--- a/core/java/android/database/IContentObserver.aidl
+++ b/core/java/android/database/IContentObserver.aidl
@@ -22,8 +22,7 @@ import android.net.Uri;
/**
* @hide
*/
-interface IContentObserver
-{
+interface IContentObserver {
/**
* This method is called when an update occurs to the cursor that is being
* observed. selfUpdate is true if the update was caused by a call to
@@ -31,4 +30,11 @@ interface IContentObserver
*/
@UnsupportedAppUsage
oneway void onChange(boolean selfUpdate, in Uri uri, int userId);
+
+ /**
+ * This method is called when an update occurs to the cursor that is being
+ * observed. selfUpdate is true if the update was caused by a call to
+ * commit on the cursor that is being observed.
+ */
+ oneway void onChangeEtc(boolean selfUpdate, in Uri[] uri, int flags, int userId);
}