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 Original line 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_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";
@@ -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 {
+34 −1
Original line number Original line Diff line number Diff line
@@ -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 {}
@@ -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
+104 −59
Original line number Original line Diff line number Diff line
@@ -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}.
@@ -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
@@ -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) {
@@ -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);
            });
        }
        }
    }
    }


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


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