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

Commit aeb82438 authored by Automerger Merge Worker's avatar Automerger Merge Worker
Browse files

Merge "Use flags to indicate reason for Uri changes." into rvc-dev am: 189e00a4

Change-Id: If1054201221605ec8e8eecbc0f1cae561c5b775f
parents d067c05e 189e00a4
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