diff options
| author | Jeff Sharkey <jsharkey@google.com> | 2020-03-06 00:04:24 +0000 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2020-03-06 00:04:24 +0000 |
| commit | 189e00a46bcd9273dbb928ab6791426f7bc766bc (patch) | |
| tree | a183df97cf8730503fbe22d0f491b644a61957db /core/java/android | |
| parent | 9a967db5750d62581c02038126e84dceacd240e6 (diff) | |
| parent | d70325359ed681dbe90ab5d0e6562f795c73417a (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.java | 35 | ||||
| -rw-r--r-- | core/java/android/database/ContentObserver.java | 163 | ||||
| -rw-r--r-- | core/java/android/database/CursorToBulkCursorAdaptor.java | 18 | ||||
| -rw-r--r-- | core/java/android/database/IContentObserver.aidl | 10 |
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); } |
