summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSudheer Shanka <sudheersai@google.com>2019-01-26 10:40:42 -0800
committerSudheer Shanka <sudheersai@google.com>2019-01-26 11:19:34 -0800
commita07b052eb4e210329a9f81e6783baed66533143f (patch)
tree8c3b2883e0ace6a6af4ff2a77c777ef4faeb57bf
parent2bfd202ec50bff7e94d178a63e35b77009ea915b (diff)
Add Cursor.{set,get}NotificationUris.
Bug: 120879205 Test: manual Test: atest cts/tests/tests/database/src/android/database/cts/AbstractCursorTest.java Change-Id: If3be228dc6b08ea58d24c9209822f9d8c2348082
-rw-r--r--api/current.txt2
-rw-r--r--core/java/android/database/AbstractCursor.java49
-rw-r--r--core/java/android/database/Cursor.java42
-rw-r--r--core/java/android/database/CursorWrapper.java12
-rw-r--r--test-mock/src/android/test/mock/MockCursor.java12
5 files changed, 108 insertions, 9 deletions
diff --git a/api/current.txt b/api/current.txt
index bb6dbeba2e7a..e397d3da8463 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -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
diff --git a/core/java/android/database/AbstractCursor.java b/core/java/android/database/AbstractCursor.java
index 8bcaa4526fa7..b44458a7d449 100644
--- a/core/java/android/database/AbstractCursor.java
+++ b/core/java/android/database/AbstractCursor.java
@@ -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;
}
}
@@ -424,6 +450,13 @@ public abstract class AbstractCursor implements CrossProcessCursor {
}
@Override
+ public List<Uri> getNotificationUris() {
+ synchronized (mSelfObserverLock) {
+ return mNotifyUris;
+ }
+ }
+
+ @Override
public boolean getWantsAllOnMoveCalls() {
return false;
}
diff --git a/core/java/android/database/Cursor.java b/core/java/android/database/Cursor.java
index 5a4280e997cd..1379138b37c0 100644
--- a/core/java/android/database/Cursor.java
+++ b/core/java/android/database/Cursor.java
@@ -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,7 +424,10 @@ 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.
@@ -429,6 +435,24 @@ public interface Cursor extends Closeable {
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}.
* @return Returns a URI that can be used with
@@ -439,6 +463,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().
*/
diff --git a/core/java/android/database/CursorWrapper.java b/core/java/android/database/CursorWrapper.java
index 0d27dfb872f0..c9cafafe4041 100644
--- a/core/java/android/database/CursorWrapper.java
+++ b/core/java/android/database/CursorWrapper.java
@@ -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.
@@ -241,11 +243,21 @@ public class CursorWrapper implements Cursor {
}
@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);
}
diff --git a/test-mock/src/android/test/mock/MockCursor.java b/test-mock/src/android/test/mock/MockCursor.java
index 576f24ad6384..f69db2c84111 100644
--- a/test-mock/src/android/test/mock/MockCursor.java
+++ b/test-mock/src/android/test/mock/MockCursor.java
@@ -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.
@@ -226,11 +228,21 @@ public class MockCursor implements Cursor {
}
@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");
}