Loading api/current.txt +9 −2 Original line number Original line Diff line number Diff line Loading @@ -9924,8 +9924,11 @@ package android.content { field public static final String EXTRA_REFRESH_SUPPORTED = "android.content.extra.REFRESH_SUPPORTED"; field public static final String EXTRA_REFRESH_SUPPORTED = "android.content.extra.REFRESH_SUPPORTED"; field public static final String EXTRA_SIZE = "android.content.extra.SIZE"; field public static final String EXTRA_SIZE = "android.content.extra.SIZE"; field public static final String EXTRA_TOTAL_COUNT = "android.content.extra.TOTAL_COUNT"; field public static final String EXTRA_TOTAL_COUNT = "android.content.extra.TOTAL_COUNT"; field public static final int NOTIFY_DELETE = 16; // 0x10 field public static final int NOTIFY_INSERT = 4; // 0x4 field public static final int NOTIFY_SKIP_NOTIFY_FOR_DESCENDANTS = 2; // 0x2 field public static final int NOTIFY_SKIP_NOTIFY_FOR_DESCENDANTS = 2; // 0x2 field public static final int NOTIFY_SYNC_TO_NETWORK = 1; // 0x1 field public static final int NOTIFY_SYNC_TO_NETWORK = 1; // 0x1 field public static final int NOTIFY_UPDATE = 8; // 0x8 field public static final String QUERY_ARG_GROUP_COLUMNS = "android:query-arg-group-columns"; field public static final String QUERY_ARG_GROUP_COLUMNS = "android:query-arg-group-columns"; field public static final String QUERY_ARG_LIMIT = "android:query-arg-limit"; field public static final String QUERY_ARG_LIMIT = "android:query-arg-limit"; field public static final String QUERY_ARG_OFFSET = "android:query-arg-offset"; field public static final String QUERY_ARG_OFFSET = "android:query-arg-offset"; Loading Loading @@ -12967,9 +12970,13 @@ package android.database { ctor public ContentObserver(android.os.Handler); ctor public ContentObserver(android.os.Handler); method public boolean deliverSelfNotifications(); method public boolean deliverSelfNotifications(); method @Deprecated public final void dispatchChange(boolean); method @Deprecated public final void dispatchChange(boolean); method public final void dispatchChange(boolean, android.net.Uri); method public final void dispatchChange(boolean, @Nullable android.net.Uri); method public final void dispatchChange(boolean, @Nullable android.net.Uri, int); method public final void dispatchChange(boolean, @NonNull Iterable<android.net.Uri>, int); method public void onChange(boolean); method public void onChange(boolean); method public void onChange(boolean, android.net.Uri); method public void onChange(boolean, @Nullable android.net.Uri); method public void onChange(boolean, @Nullable android.net.Uri, int); method public void onChange(boolean, @NonNull Iterable<android.net.Uri>, int); } } public interface CrossProcessCursor extends android.database.Cursor { public interface CrossProcessCursor extends android.database.Cursor { core/java/android/content/ContentResolver.java +34 −1 Original line number Original line Diff line number Diff line Loading @@ -629,7 +629,10 @@ public abstract class ContentResolver implements ContentInterface { /** @hide */ /** @hide */ @IntDef(flag = true, prefix = { "NOTIFY_" }, value = { @IntDef(flag = true, prefix = { "NOTIFY_" }, value = { NOTIFY_SYNC_TO_NETWORK, NOTIFY_SYNC_TO_NETWORK, NOTIFY_SKIP_NOTIFY_FOR_DESCENDANTS NOTIFY_SKIP_NOTIFY_FOR_DESCENDANTS, NOTIFY_INSERT, NOTIFY_UPDATE, NOTIFY_DELETE }) }) @Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE) public @interface NotifyFlags {} public @interface NotifyFlags {} Loading @@ -650,6 +653,36 @@ public abstract class ContentResolver implements ContentInterface { */ */ public static final int NOTIFY_SKIP_NOTIFY_FOR_DESCENDANTS = 1<<1; 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. * No exception, throttled by app standby normally. * @hide * @hide Loading core/java/android/database/ContentObserver.java +104 −59 Original line number Original line Diff line number Diff line Loading @@ -16,11 +16,17 @@ package android.database; package android.database; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.compat.annotation.UnsupportedAppUsage; import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentResolver.NotifyFlags; import android.net.Uri; import android.net.Uri; import android.os.Handler; import android.os.Handler; import android.os.UserHandle; import android.os.UserHandle; import java.util.Arrays; /** /** * Receives call backs for changes to content. * Receives call backs for changes to content. * Must be implemented by objects which are added to a {@link ContentObservable}. * Must be implemented by objects which are added to a {@link ContentObservable}. Loading Loading @@ -101,12 +107,10 @@ public abstract class ContentObserver { * This method is called when a content change occurs. * This method is called when a content change occurs. * Includes the changed content Uri when available. * Includes the changed content Uri when available. * <p> * <p> * Subclasses should override this method to handle content changes. * Subclasses should override this method to handle content changes. To * To ensure correct operation on older versions of the framework that * ensure correct operation on older versions of the framework that did not * did not provide a Uri argument, applications should also implement * provide richer arguments, applications should implement all overloads. * the {@link #onChange(boolean)} overload of this method whenever they * <p> * implement the {@link #onChange(boolean, Uri)} overload. * </p><p> * Example implementation: * Example implementation: * <pre><code> * <pre><code> * // Implement the onChange(boolean) method to delegate the change notification to * // Implement the onChange(boolean) method to delegate the change notification to Loading @@ -126,38 +130,63 @@ public abstract class ContentObserver { * </p> * </p> * * * @param selfChange True if this is a self-change notification. * @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); onChange(selfChange); } } /** /** * Dispatches a change notification to the observer. Includes the changed * This method is called when a content change occurs. Includes the changed * content Uri when available and also the user whose content 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 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. * @param userId The user whose content changed. Can be either a specific * @param flags Flags indicating details about this change. * user or {@link UserHandle#USER_ALL}. * * @hide */ */ public void onChange(boolean selfChange, Uri uri, int userId) { public void onChange(boolean selfChange, @Nullable Uri uri, @NotifyFlags int flags) { onChange(selfChange, uri); 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> * <p> * If a {@link Handler} was supplied to the {@link ContentObserver} constructor, * Subclasses should override this method to handle content changes. To * then a call to the {@link #onChange} method is posted to the handler's message queue. * ensure correct operation on older versions of the framework that did not * Otherwise, the {@link #onChange} method is invoked immediately on this thread. * provide richer arguments, applications should implement all overloads. * </p> * * * @param selfChange True if this is a self-change notification. * @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 @Deprecated public final void dispatchChange(boolean selfChange) { public final void dispatchChange(boolean selfChange) { Loading @@ -165,57 +194,66 @@ public abstract class ContentObserver { } } /** /** * Dispatches a change notification to the observer. * Dispatches a change notification to the observer. Includes the changed * Includes the changed content Uri when available. * content Uri when available. * <p> * <p> * If a {@link Handler} was supplied to the {@link ContentObserver} constructor, * If a {@link Handler} was supplied to the {@link ContentObserver} * then a call to the {@link #onChange} method is posted to the handler's message queue. * constructor, then a call to the {@link #onChange} method is posted to the * Otherwise, the {@link #onChange} method is invoked immediately on this thread. * handler's message queue. Otherwise, the {@link #onChange} method is * </p> * invoked immediately on this thread. * * * @param selfChange True if this is a self-change notification. * @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) { public final void dispatchChange(boolean selfChange, @Nullable Uri uri) { dispatchChange(selfChange, uri, UserHandle.getCallingUserId()); dispatchChange(selfChange, Arrays.asList(uri), 0, UserHandle.getCallingUserId()); } } /** /** * Dispatches a change notification to the observer. Includes the changed * 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> * <p> * If a {@link Handler} was supplied to the {@link ContentObserver} constructor, * If a {@link Handler} was supplied to the {@link ContentObserver} * then a call to the {@link #onChange} method is posted to the handler's message queue. * constructor, then a call to the {@link #onChange} method is posted to the * Otherwise, the {@link #onChange} method is invoked immediately on this thread. * handler's message queue. Otherwise, the {@link #onChange} method is * </p> * invoked immediately on this thread. * * * @param selfChange True if this is a self-change notification. * @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. * @param userId The user whose content changed. * @param flags Flags indicating details about this change. */ */ private void dispatchChange(boolean selfChange, Uri uri, int userId) { public final void dispatchChange(boolean selfChange, @Nullable Uri uri, if (mHandler == null) { @NotifyFlags int flags) { onChange(selfChange, uri, userId); dispatchChange(selfChange, Arrays.asList(uri), flags, UserHandle.getCallingUserId()); } else { mHandler.post(new NotificationRunnable(selfChange, uri, userId)); } } } 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; * Dispatches a change notification to the observer. Includes the changed mUri = uri; * content Uris when available. mUserId = userId; * <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()); } } @Override /** @hide */ public void run() { public final void dispatchChange(boolean selfChange, @NonNull Iterable<Uri> uris, ContentObserver.this.onChange(mSelfChange, mUri, mUserId); @NotifyFlags int flags, @UserIdInt int userId) { if (mHandler == null) { onChange(selfChange, uris, flags, userId); } else { mHandler.post(() -> { onChange(selfChange, uris, flags, userId); }); } } } } Loading @@ -228,9 +266,16 @@ public abstract class ContentObserver { @Override @Override public void onChange(boolean selfChange, Uri uri, int userId) { 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; ContentObserver contentObserver = mContentObserver; if (contentObserver != null) { if (contentObserver != null) { contentObserver.dispatchChange(selfChange, uri, userId); contentObserver.dispatchChange(selfChange, Arrays.asList(uris), flags, userId); } } } } Loading core/java/android/database/CursorToBulkCursorAdaptor.java +16 −2 Original line number Original line Diff line number Diff line Loading @@ -16,9 +16,14 @@ package android.database; package android.database; import android.annotation.NonNull; import android.annotation.UserIdInt; import android.content.ContentResolver.NotifyFlags; import android.net.Uri; import android.net.Uri; import android.os.*; import android.os.*; import java.util.ArrayList; /** /** * Wraps a BulkCursor around an existing Cursor making it remotable. * Wraps a BulkCursor around an existing Cursor making it remotable. Loading Loading @@ -76,9 +81,18 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative } } @Override @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 { try { mRemote.onChange(selfChange, uri, android.os.Process.myUid()); mRemote.onChangeEtc(selfChange, asArray, flags, userId); } catch (RemoteException ex) { } catch (RemoteException ex) { // Do nothing, the far side is dead // Do nothing, the far side is dead } } Loading core/java/android/database/IContentObserver.aidl +8 −2 Original line number Original line Diff line number Diff line Loading @@ -22,8 +22,7 @@ import android.net.Uri; /** /** * @hide * @hide */ */ interface IContentObserver interface IContentObserver { { /** /** * This method is called when an update occurs to the cursor that is being * 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 * observed. selfUpdate is true if the update was caused by a call to Loading @@ -31,4 +30,11 @@ interface IContentObserver */ */ @UnsupportedAppUsage @UnsupportedAppUsage oneway void onChange(boolean selfUpdate, in Uri uri, int userId); 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); } } Loading
api/current.txt +9 −2 Original line number Original line Diff line number Diff line Loading @@ -9924,8 +9924,11 @@ package android.content { field public static final String EXTRA_REFRESH_SUPPORTED = "android.content.extra.REFRESH_SUPPORTED"; field public static final String EXTRA_REFRESH_SUPPORTED = "android.content.extra.REFRESH_SUPPORTED"; field public static final String EXTRA_SIZE = "android.content.extra.SIZE"; field public static final String EXTRA_SIZE = "android.content.extra.SIZE"; field public static final String EXTRA_TOTAL_COUNT = "android.content.extra.TOTAL_COUNT"; field public static final String EXTRA_TOTAL_COUNT = "android.content.extra.TOTAL_COUNT"; field public static final int NOTIFY_DELETE = 16; // 0x10 field public static final int NOTIFY_INSERT = 4; // 0x4 field public static final int NOTIFY_SKIP_NOTIFY_FOR_DESCENDANTS = 2; // 0x2 field public static final int NOTIFY_SKIP_NOTIFY_FOR_DESCENDANTS = 2; // 0x2 field public static final int NOTIFY_SYNC_TO_NETWORK = 1; // 0x1 field public static final int NOTIFY_SYNC_TO_NETWORK = 1; // 0x1 field public static final int NOTIFY_UPDATE = 8; // 0x8 field public static final String QUERY_ARG_GROUP_COLUMNS = "android:query-arg-group-columns"; field public static final String QUERY_ARG_GROUP_COLUMNS = "android:query-arg-group-columns"; field public static final String QUERY_ARG_LIMIT = "android:query-arg-limit"; field public static final String QUERY_ARG_LIMIT = "android:query-arg-limit"; field public static final String QUERY_ARG_OFFSET = "android:query-arg-offset"; field public static final String QUERY_ARG_OFFSET = "android:query-arg-offset"; Loading Loading @@ -12967,9 +12970,13 @@ package android.database { ctor public ContentObserver(android.os.Handler); ctor public ContentObserver(android.os.Handler); method public boolean deliverSelfNotifications(); method public boolean deliverSelfNotifications(); method @Deprecated public final void dispatchChange(boolean); method @Deprecated public final void dispatchChange(boolean); method public final void dispatchChange(boolean, android.net.Uri); method public final void dispatchChange(boolean, @Nullable android.net.Uri); method public final void dispatchChange(boolean, @Nullable android.net.Uri, int); method public final void dispatchChange(boolean, @NonNull Iterable<android.net.Uri>, int); method public void onChange(boolean); method public void onChange(boolean); method public void onChange(boolean, android.net.Uri); method public void onChange(boolean, @Nullable android.net.Uri); method public void onChange(boolean, @Nullable android.net.Uri, int); method public void onChange(boolean, @NonNull Iterable<android.net.Uri>, int); } } public interface CrossProcessCursor extends android.database.Cursor { public interface CrossProcessCursor extends android.database.Cursor {
core/java/android/content/ContentResolver.java +34 −1 Original line number Original line Diff line number Diff line Loading @@ -629,7 +629,10 @@ public abstract class ContentResolver implements ContentInterface { /** @hide */ /** @hide */ @IntDef(flag = true, prefix = { "NOTIFY_" }, value = { @IntDef(flag = true, prefix = { "NOTIFY_" }, value = { NOTIFY_SYNC_TO_NETWORK, NOTIFY_SYNC_TO_NETWORK, NOTIFY_SKIP_NOTIFY_FOR_DESCENDANTS NOTIFY_SKIP_NOTIFY_FOR_DESCENDANTS, NOTIFY_INSERT, NOTIFY_UPDATE, NOTIFY_DELETE }) }) @Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE) public @interface NotifyFlags {} public @interface NotifyFlags {} Loading @@ -650,6 +653,36 @@ public abstract class ContentResolver implements ContentInterface { */ */ public static final int NOTIFY_SKIP_NOTIFY_FOR_DESCENDANTS = 1<<1; 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. * No exception, throttled by app standby normally. * @hide * @hide Loading
core/java/android/database/ContentObserver.java +104 −59 Original line number Original line Diff line number Diff line Loading @@ -16,11 +16,17 @@ package android.database; package android.database; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.compat.annotation.UnsupportedAppUsage; import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentResolver.NotifyFlags; import android.net.Uri; import android.net.Uri; import android.os.Handler; import android.os.Handler; import android.os.UserHandle; import android.os.UserHandle; import java.util.Arrays; /** /** * Receives call backs for changes to content. * Receives call backs for changes to content. * Must be implemented by objects which are added to a {@link ContentObservable}. * Must be implemented by objects which are added to a {@link ContentObservable}. Loading Loading @@ -101,12 +107,10 @@ public abstract class ContentObserver { * This method is called when a content change occurs. * This method is called when a content change occurs. * Includes the changed content Uri when available. * Includes the changed content Uri when available. * <p> * <p> * Subclasses should override this method to handle content changes. * Subclasses should override this method to handle content changes. To * To ensure correct operation on older versions of the framework that * ensure correct operation on older versions of the framework that did not * did not provide a Uri argument, applications should also implement * provide richer arguments, applications should implement all overloads. * the {@link #onChange(boolean)} overload of this method whenever they * <p> * implement the {@link #onChange(boolean, Uri)} overload. * </p><p> * Example implementation: * Example implementation: * <pre><code> * <pre><code> * // Implement the onChange(boolean) method to delegate the change notification to * // Implement the onChange(boolean) method to delegate the change notification to Loading @@ -126,38 +130,63 @@ public abstract class ContentObserver { * </p> * </p> * * * @param selfChange True if this is a self-change notification. * @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); onChange(selfChange); } } /** /** * Dispatches a change notification to the observer. Includes the changed * This method is called when a content change occurs. Includes the changed * content Uri when available and also the user whose content 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 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. * @param userId The user whose content changed. Can be either a specific * @param flags Flags indicating details about this change. * user or {@link UserHandle#USER_ALL}. * * @hide */ */ public void onChange(boolean selfChange, Uri uri, int userId) { public void onChange(boolean selfChange, @Nullable Uri uri, @NotifyFlags int flags) { onChange(selfChange, uri); 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> * <p> * If a {@link Handler} was supplied to the {@link ContentObserver} constructor, * Subclasses should override this method to handle content changes. To * then a call to the {@link #onChange} method is posted to the handler's message queue. * ensure correct operation on older versions of the framework that did not * Otherwise, the {@link #onChange} method is invoked immediately on this thread. * provide richer arguments, applications should implement all overloads. * </p> * * * @param selfChange True if this is a self-change notification. * @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 @Deprecated public final void dispatchChange(boolean selfChange) { public final void dispatchChange(boolean selfChange) { Loading @@ -165,57 +194,66 @@ public abstract class ContentObserver { } } /** /** * Dispatches a change notification to the observer. * Dispatches a change notification to the observer. Includes the changed * Includes the changed content Uri when available. * content Uri when available. * <p> * <p> * If a {@link Handler} was supplied to the {@link ContentObserver} constructor, * If a {@link Handler} was supplied to the {@link ContentObserver} * then a call to the {@link #onChange} method is posted to the handler's message queue. * constructor, then a call to the {@link #onChange} method is posted to the * Otherwise, the {@link #onChange} method is invoked immediately on this thread. * handler's message queue. Otherwise, the {@link #onChange} method is * </p> * invoked immediately on this thread. * * * @param selfChange True if this is a self-change notification. * @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) { public final void dispatchChange(boolean selfChange, @Nullable Uri uri) { dispatchChange(selfChange, uri, UserHandle.getCallingUserId()); dispatchChange(selfChange, Arrays.asList(uri), 0, UserHandle.getCallingUserId()); } } /** /** * Dispatches a change notification to the observer. Includes the changed * 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> * <p> * If a {@link Handler} was supplied to the {@link ContentObserver} constructor, * If a {@link Handler} was supplied to the {@link ContentObserver} * then a call to the {@link #onChange} method is posted to the handler's message queue. * constructor, then a call to the {@link #onChange} method is posted to the * Otherwise, the {@link #onChange} method is invoked immediately on this thread. * handler's message queue. Otherwise, the {@link #onChange} method is * </p> * invoked immediately on this thread. * * * @param selfChange True if this is a self-change notification. * @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. * @param userId The user whose content changed. * @param flags Flags indicating details about this change. */ */ private void dispatchChange(boolean selfChange, Uri uri, int userId) { public final void dispatchChange(boolean selfChange, @Nullable Uri uri, if (mHandler == null) { @NotifyFlags int flags) { onChange(selfChange, uri, userId); dispatchChange(selfChange, Arrays.asList(uri), flags, UserHandle.getCallingUserId()); } else { mHandler.post(new NotificationRunnable(selfChange, uri, userId)); } } } 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; * Dispatches a change notification to the observer. Includes the changed mUri = uri; * content Uris when available. mUserId = userId; * <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()); } } @Override /** @hide */ public void run() { public final void dispatchChange(boolean selfChange, @NonNull Iterable<Uri> uris, ContentObserver.this.onChange(mSelfChange, mUri, mUserId); @NotifyFlags int flags, @UserIdInt int userId) { if (mHandler == null) { onChange(selfChange, uris, flags, userId); } else { mHandler.post(() -> { onChange(selfChange, uris, flags, userId); }); } } } } Loading @@ -228,9 +266,16 @@ public abstract class ContentObserver { @Override @Override public void onChange(boolean selfChange, Uri uri, int userId) { 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; ContentObserver contentObserver = mContentObserver; if (contentObserver != null) { if (contentObserver != null) { contentObserver.dispatchChange(selfChange, uri, userId); contentObserver.dispatchChange(selfChange, Arrays.asList(uris), flags, userId); } } } } Loading
core/java/android/database/CursorToBulkCursorAdaptor.java +16 −2 Original line number Original line Diff line number Diff line Loading @@ -16,9 +16,14 @@ package android.database; package android.database; import android.annotation.NonNull; import android.annotation.UserIdInt; import android.content.ContentResolver.NotifyFlags; import android.net.Uri; import android.net.Uri; import android.os.*; import android.os.*; import java.util.ArrayList; /** /** * Wraps a BulkCursor around an existing Cursor making it remotable. * Wraps a BulkCursor around an existing Cursor making it remotable. Loading Loading @@ -76,9 +81,18 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative } } @Override @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 { try { mRemote.onChange(selfChange, uri, android.os.Process.myUid()); mRemote.onChangeEtc(selfChange, asArray, flags, userId); } catch (RemoteException ex) { } catch (RemoteException ex) { // Do nothing, the far side is dead // Do nothing, the far side is dead } } Loading
core/java/android/database/IContentObserver.aidl +8 −2 Original line number Original line Diff line number Diff line Loading @@ -22,8 +22,7 @@ import android.net.Uri; /** /** * @hide * @hide */ */ interface IContentObserver interface IContentObserver { { /** /** * This method is called when an update occurs to the cursor that is being * 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 * observed. selfUpdate is true if the update was caused by a call to Loading @@ -31,4 +30,11 @@ interface IContentObserver */ */ @UnsupportedAppUsage @UnsupportedAppUsage oneway void onChange(boolean selfUpdate, in Uri uri, int userId); 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); } }