summaryrefslogtreecommitdiff
path: root/core/java/android/content/ContentProvider.java
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2013-01-29 18:55:48 -0800
committerDianne Hackborn <hackbod@google.com>2013-01-29 18:55:48 -0800
commitd7960d19c1e5dfdbe8c793472ce792e8526c0e40 (patch)
tree0b27556dc9ca9094770eb517b2c0e54a05c76275 /core/java/android/content/ContentProvider.java
parentd4d9364019ed071509213b9ce772f4a5904d2847 (diff)
Improve revoking access to content providers.
Providers can now hook into the revoked query and insert calls, and the default implementation of query is a little better. Change-Id: I29592a579aaf4a98686c6cf43e57f73275c58922
Diffstat (limited to 'core/java/android/content/ContentProvider.java')
-rw-r--r--core/java/android/content/ContentProvider.java56
1 files changed, 45 insertions, 11 deletions
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index 4b977ab5fe1d..e66efd525ba8 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -191,11 +191,8 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
String selection, String[] selectionArgs, String sortOrder,
ICancellationSignal cancellationSignal) {
if (enforceReadPermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
- // The read is not allowed... to fake it out, we replace the given
- // selection statement with a dummy one that will always be false.
- // This way we will get a cursor back that has the correct structure
- // but contains no rows.
- selection = "'A' = 'B'";
+ return rejectQuery(uri, projection, selection, selectionArgs, sortOrder,
+ CancellationSignal.fromTransport(cancellationSignal));
}
return ContentProvider.this.query(uri, projection, selection, selectionArgs, sortOrder,
CancellationSignal.fromTransport(cancellationSignal));
@@ -209,12 +206,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
@Override
public Uri insert(String callingPkg, Uri uri, ContentValues initialValues) {
if (enforceWritePermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
- // If not allowed, we need to return some reasonable URI. Maybe the
- // content provider should be responsible for this, but for now we
- // will just return the base URI with a dummy '0' tagged on to it.
- // You shouldn't be able to read if you can't write, anyway, so it
- // shouldn't matter much what is returned.
- return uri.buildUpon().appendPath("0").build();
+ return rejectInsert(uri, initialValues);
}
return ContentProvider.this.insert(uri, initialValues);
}
@@ -592,6 +584,31 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
}
/**
+ * @hide
+ * Implementation when a caller has performed a query on the content
+ * provider, but that call has been rejected for the operation given
+ * to {@link #setAppOps(int, int)}. The default implementation
+ * rewrites the <var>selection</var> argument to include a condition
+ * that is never true (so will always result in an empty cursor)
+ * and calls through to {@link #query(android.net.Uri, String[], String, String[],
+ * String, android.os.CancellationSignal)} with that.
+ */
+ public Cursor rejectQuery(Uri uri, String[] projection,
+ String selection, String[] selectionArgs, String sortOrder,
+ CancellationSignal cancellationSignal) {
+ // The read is not allowed... to fake it out, we replace the given
+ // selection statement with a dummy one that will always be false.
+ // This way we will get a cursor back that has the correct structure
+ // but contains no rows.
+ if (selection == null) {
+ selection = "'A' = 'B'";
+ } else {
+ selection = "'A' = 'B' AND (" + selection + ")";
+ }
+ return query(uri, projection, selection, selectionArgs, sortOrder, cancellationSignal);
+ }
+
+ /**
* Implement this to handle query requests from clients.
* This method can be called from multiple threads, as described in
* <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
@@ -739,6 +756,23 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
public abstract String getType(Uri uri);
/**
+ * @hide
+ * Implementation when a caller has performed an insert on the content
+ * provider, but that call has been rejected for the operation given
+ * to {@link #setAppOps(int, int)}. The default implementation simply
+ * returns a dummy URI that is the base URI with a 0 path element
+ * appended.
+ */
+ public Uri rejectInsert(Uri uri, ContentValues values) {
+ // If not allowed, we need to return some reasonable URI. Maybe the
+ // content provider should be responsible for this, but for now we
+ // will just return the base URI with a dummy '0' tagged on to it.
+ // You shouldn't be able to read if you can't write, anyway, so it
+ // shouldn't matter much what is returned.
+ return uri.buildUpon().appendPath("0").build();
+ }
+
+ /**
* Implement this to handle requests to insert a new row.
* As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyChange()}
* after inserting.