Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 189e00a4 authored by Jeff Sharkey's avatar Jeff Sharkey Committed by Android (Google) Code Review
Browse files

Merge "Use flags to indicate reason for Uri changes." into rvc-dev

parents 9a967db5 d7032535
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -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_SIZE = "android.content.extra.SIZE";
    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_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_LIMIT = "android:query-arg-limit";
    field public static final String QUERY_ARG_OFFSET = "android:query-arg-offset";
@@ -12967,9 +12970,13 @@ package android.database {
    ctor public ContentObserver(android.os.Handler);
    method public boolean deliverSelfNotifications();
    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, 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 {
+34 −1
Original line number Diff line number Diff line
@@ -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 {}
@@ -650,6 +653,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
+104 −59
Original line number Diff line number Diff line
@@ -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());
    }
    }


    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;
    /**
     * 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());
    }

        @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);
            }
        }

+16 −2
Original line number Diff line number Diff line
@@ -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
            }
+8 −2
Original line number Diff line number Diff line
@@ -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);
}
Loading