diff options
| author | Dianne Hackborn <hackbod@google.com> | 2013-01-29 18:55:48 -0800 |
|---|---|---|
| committer | Dianne Hackborn <hackbod@google.com> | 2013-01-29 18:55:48 -0800 |
| commit | d7960d19c1e5dfdbe8c793472ce792e8526c0e40 (patch) | |
| tree | 0b27556dc9ca9094770eb517b2c0e54a05c76275 /core/java/android/content/ContentProvider.java | |
| parent | d4d9364019ed071509213b9ce772f4a5904d2847 (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.java | 56 |
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. |
