Merge "Add Cursor.{set,get}NotificationUris."
This commit is contained in:
committed by
Android (Google) Code Review
commit
b6c8094b45
@@ -12512,6 +12512,7 @@ package android.database {
|
||||
method public int getInt(int);
|
||||
method public long getLong(int);
|
||||
method public android.net.Uri getNotificationUri();
|
||||
method public default java.util.List<android.net.Uri> getNotificationUris();
|
||||
method public int getPosition();
|
||||
method public short getShort(int);
|
||||
method public String getString(int);
|
||||
@@ -12535,6 +12536,7 @@ package android.database {
|
||||
method public android.os.Bundle respond(android.os.Bundle);
|
||||
method public void setExtras(android.os.Bundle);
|
||||
method public void setNotificationUri(android.content.ContentResolver, android.net.Uri);
|
||||
method public default void setNotificationUris(@NonNull android.content.ContentResolver, @NonNull java.util.List<android.net.Uri>);
|
||||
method public void unregisterContentObserver(android.database.ContentObserver);
|
||||
method public void unregisterDataSetObserver(android.database.DataSetObserver);
|
||||
field public static final int FIELD_TYPE_BLOB = 4; // 0x4
|
||||
|
||||
@@ -16,17 +16,20 @@
|
||||
|
||||
package android.database;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.UnsupportedAppUsage;
|
||||
import android.content.ContentResolver;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@@ -72,6 +75,7 @@ public abstract class AbstractCursor implements CrossProcessCursor {
|
||||
|
||||
@UnsupportedAppUsage
|
||||
private Uri mNotifyUri;
|
||||
private List<Uri> mNotifyUris;
|
||||
|
||||
private final Object mSelfObserverLock = new Object();
|
||||
private ContentObserver mSelfObserver;
|
||||
@@ -155,7 +159,11 @@ public abstract class AbstractCursor implements CrossProcessCursor {
|
||||
@Override
|
||||
public boolean requery() {
|
||||
if (mSelfObserver != null && mSelfObserverRegistered == false) {
|
||||
mContentResolver.registerContentObserver(mNotifyUri, true, mSelfObserver);
|
||||
final int size = mNotifyUris.size();
|
||||
for (int i = 0; i < size; ++i) {
|
||||
final Uri notifyUri = mNotifyUris.get(i);
|
||||
mContentResolver.registerContentObserver(notifyUri, true, mSelfObserver);
|
||||
}
|
||||
mSelfObserverRegistered = true;
|
||||
}
|
||||
mDataSetObservable.notifyChanged();
|
||||
@@ -384,8 +392,12 @@ public abstract class AbstractCursor implements CrossProcessCursor {
|
||||
protected void onChange(boolean selfChange) {
|
||||
synchronized (mSelfObserverLock) {
|
||||
mContentObservable.dispatchChange(selfChange, null);
|
||||
if (mNotifyUri != null && selfChange) {
|
||||
mContentResolver.notifyChange(mNotifyUri, mSelfObserver);
|
||||
if (mNotifyUris != null && selfChange) {
|
||||
final int size = mNotifyUris.size();
|
||||
for (int i = 0; i < size; ++i) {
|
||||
final Uri notifyUri = mNotifyUris.get(i);
|
||||
mContentResolver.notifyChange(notifyUri, mSelfObserver);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -399,19 +411,33 @@ public abstract class AbstractCursor implements CrossProcessCursor {
|
||||
*/
|
||||
@Override
|
||||
public void setNotificationUri(ContentResolver cr, Uri notifyUri) {
|
||||
setNotificationUri(cr, notifyUri, cr.getUserId());
|
||||
setNotificationUris(cr, Arrays.asList(notifyUri));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNotificationUris(@NonNull ContentResolver cr, @NonNull List<Uri> notifyUris) {
|
||||
Preconditions.checkNotNull(cr);
|
||||
Preconditions.checkNotNull(notifyUris);
|
||||
|
||||
setNotificationUris(cr, notifyUris, cr.getUserId());
|
||||
}
|
||||
|
||||
/** @hide - set the notification uri but with an observer for a particular user's view */
|
||||
public void setNotificationUri(ContentResolver cr, Uri notifyUri, int userHandle) {
|
||||
public void setNotificationUris(ContentResolver cr, List<Uri> notifyUris, int userHandle) {
|
||||
synchronized (mSelfObserverLock) {
|
||||
mNotifyUri = notifyUri;
|
||||
mNotifyUris = notifyUris;
|
||||
mNotifyUri = mNotifyUris.get(0);
|
||||
mContentResolver = cr;
|
||||
if (mSelfObserver != null) {
|
||||
mContentResolver.unregisterContentObserver(mSelfObserver);
|
||||
}
|
||||
mSelfObserver = new SelfContentObserver(this);
|
||||
mContentResolver.registerContentObserver(mNotifyUri, true, mSelfObserver, userHandle);
|
||||
final int size = mNotifyUris.size();
|
||||
for (int i = 0; i < size; ++i) {
|
||||
final Uri notifyUri = mNotifyUris.get(i);
|
||||
mContentResolver.registerContentObserver(
|
||||
notifyUri, true, mSelfObserver, userHandle);
|
||||
}
|
||||
mSelfObserverRegistered = true;
|
||||
}
|
||||
}
|
||||
@@ -423,6 +449,13 @@ public abstract class AbstractCursor implements CrossProcessCursor {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Uri> getNotificationUris() {
|
||||
synchronized (mSelfObserverLock) {
|
||||
return mNotifyUris;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getWantsAllOnMoveCalls() {
|
||||
return false;
|
||||
|
||||
@@ -16,11 +16,14 @@
|
||||
|
||||
package android.database;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.content.ContentResolver;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This interface provides random read-write access to the result set returned
|
||||
@@ -421,13 +424,34 @@ public interface Cursor extends Closeable {
|
||||
/**
|
||||
* Register to watch a content URI for changes. This can be the URI of a specific data row (for
|
||||
* example, "content://my_provider_type/23"), or a a generic URI for a content type.
|
||||
*
|
||||
*
|
||||
* <p>Calling this overrides any previous call to
|
||||
* {@link #setNotificationUris(ContentResolver, List)}.
|
||||
*
|
||||
* @param cr The content resolver from the caller's context. The listener attached to
|
||||
* this resolver will be notified.
|
||||
* @param uri The content URI to watch.
|
||||
*/
|
||||
void setNotificationUri(ContentResolver cr, Uri uri);
|
||||
|
||||
/**
|
||||
* Similar to {@link #setNotificationUri(ContentResolver, Uri)}, except this version allows
|
||||
* to watch multiple content URIs for changes.
|
||||
*
|
||||
* <p>If this is not implemented, this is equivalent to calling
|
||||
* {@link #setNotificationUri(ContentResolver, Uri)} with the first URI in {@code uris}.
|
||||
*
|
||||
* <p>Calling this overrides any previous call to
|
||||
* {@link #setNotificationUri(ContentResolver, Uri)}.
|
||||
*
|
||||
* @param cr The content resolver from the caller's context. The listener attached to
|
||||
* this resolver will be notified.
|
||||
* @param uris The content URIs to watch.
|
||||
*/
|
||||
default void setNotificationUris(@NonNull ContentResolver cr, @NonNull List<Uri> uris) {
|
||||
setNotificationUri(cr, uris.get(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the URI at which notifications of changes in this Cursor's data
|
||||
* will be delivered, as previously set by {@link #setNotificationUri}.
|
||||
@@ -438,6 +462,22 @@ public interface Cursor extends Closeable {
|
||||
*/
|
||||
Uri getNotificationUri();
|
||||
|
||||
/**
|
||||
* Return the URIs at which notifications of changes in this Cursor's data
|
||||
* will be delivered, as previously set by {@link #setNotificationUris}.
|
||||
*
|
||||
* <p>If this is not implemented, this is equivalent to calling {@link #getNotificationUri()}.
|
||||
*
|
||||
* @return Returns URIs that can be used with
|
||||
* {@link ContentResolver#registerContentObserver(android.net.Uri, boolean, ContentObserver)
|
||||
* ContentResolver.registerContentObserver} to find out about changes to this Cursor's
|
||||
* data. May be null if no notification URI has been set.
|
||||
*/
|
||||
default List<Uri> getNotificationUris() {
|
||||
final Uri notifyUri = getNotificationUri();
|
||||
return notifyUri == null ? null : Arrays.asList(notifyUri);
|
||||
}
|
||||
|
||||
/**
|
||||
* onMove() will only be called across processes if this method returns true.
|
||||
* @return whether all cursor movement should result in a call to onMove().
|
||||
|
||||
@@ -21,6 +21,8 @@ import android.content.ContentResolver;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Wrapper class for Cursor that delegates all calls to the actual cursor object. The primary
|
||||
* use for this class is to extend a cursor while overriding only a subset of its methods.
|
||||
@@ -240,11 +242,21 @@ public class CursorWrapper implements Cursor {
|
||||
mCursor.setNotificationUri(cr, uri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNotificationUris(ContentResolver cr, List<Uri> uris) {
|
||||
mCursor.setNotificationUris(cr, uris);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri getNotificationUri() {
|
||||
return mCursor.getNotificationUri();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Uri> getNotificationUris() {
|
||||
return mCursor.getNotificationUris();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterContentObserver(ContentObserver observer) {
|
||||
mCursor.unregisterContentObserver(observer);
|
||||
|
||||
@@ -24,6 +24,8 @@ import android.database.DataSetObserver;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A mock {@link android.database.Cursor} class that isolates the test code from real
|
||||
* Cursor implementation.
|
||||
@@ -225,11 +227,21 @@ public class MockCursor implements Cursor {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNotificationUris(ContentResolver cr, List<Uri> uris) {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri getNotificationUri() {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Uri> getNotificationUris() {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterContentObserver(ContentObserver observer) {
|
||||
throw new UnsupportedOperationException("unimplemented mock method");
|
||||
|
||||
Reference in New Issue
Block a user