From 7271f3e4cb516c410358f12215578aeafc7e6dcf Mon Sep 17 00:00:00 2001 From: Svet Ganov Date: Thu, 23 Apr 2015 10:16:53 -0700 Subject: Return an empty cursor when a content provider app op is disabled bug:17446599 Change-Id: Ic1790c9afbee5eec1dc28e1d53ce82288d4b4f86 --- core/java/android/content/ContentProvider.java | 35 ++++++-------------------- 1 file changed, 8 insertions(+), 27 deletions(-) (limited to 'core/java/android/content/ContentProvider.java') diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java index 393cf8e..fd65d56 100644 --- a/core/java/android/content/ContentProvider.java +++ b/core/java/android/content/ContentProvider.java @@ -26,6 +26,7 @@ import android.content.pm.ProviderInfo; import android.content.res.AssetFileDescriptor; import android.content.res.Configuration; import android.database.Cursor; +import android.database.MatrixCursor; import android.database.SQLException; import android.net.Uri; import android.os.AsyncTask; @@ -204,8 +205,13 @@ public abstract class ContentProvider implements ComponentCallbacks2 { validateIncomingUri(uri); uri = getUriWithoutUserId(uri); if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) { - return rejectQuery(uri, projection, selection, selectionArgs, sortOrder, - CancellationSignal.fromTransport(cancellationSignal)); + // The caller has no access to the data, so return an empty cursor with + // the columns in the requested order. The caller may ask for an invalid + // column and we would not catch that but this is not a problem in practice. + // We do not call ContentProvider#query with a modified where clause since + // the implementation is not guaranteed to be backed by a SQL database, hence + // it may not handle properly the tautology where clause we would have created. + return new MatrixCursor(projection, 0); } final String original = setCallingPackage(callingPkg); try { @@ -817,31 +823,6 @@ 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 selection 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.isEmpty()) { - 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 * Processes -- cgit v1.1