New queryRecentDocs in MediaDocumentsProvider

This implements the new DocumentsProvider#queryRecentDocuments API that
supports flexible limit for max number of recent documents returned.

Bug: 111288304
Test: manual test (patched the DocumentsProvider CL, and test calling
the new API):
1. Test that passing Bundle with QUERY_ARG_LIMIT=5 is honored and
returned is limited to 5.
2. Test that passing null will release the limit to default 64.
3. Test that removing MediaProvider implementation for new method and
implement the old method will automatically redirect the call to old
method (backward compatible with old providers).

Change-Id: Ia42e8aeac62379b35b85af848698eb3ece3f7947
diff --git a/src/com/android/providers/media/MediaDocumentsProvider.java b/src/com/android/providers/media/MediaDocumentsProvider.java
index c5af9db..18a9461 100644
--- a/src/com/android/providers/media/MediaDocumentsProvider.java
+++ b/src/com/android/providers/media/MediaDocumentsProvider.java
@@ -625,12 +625,31 @@
     }
 
     @Override
-    public Cursor queryRecentDocuments(String rootId, String[] projection)
+    public Cursor queryRecentDocuments(
+            String rootId, String[] projection, @Nullable Bundle queryArgs,
+      @Nullable CancellationSignal signal)
             throws FileNotFoundException {
         final ContentResolver resolver = getContext().getContentResolver();
         final MatrixCursor result = new MatrixCursor(resolveDocumentProjection(projection));
 
         final long token = Binder.clearCallingIdentity();
+
+        int limit = -1;
+        if (queryArgs != null) {
+            limit = queryArgs.getInt(ContentResolver.QUERY_ARG_LIMIT, -1);
+        }
+        if (limit < 0) {
+            // Use default value, and no QUERY_ARG* is honored.
+            limit = 64;
+        } else {
+            // We are honoring the QUERY_ARG_LIMIT.
+            Bundle extras = new Bundle();
+            result.setExtras(extras);
+            extras.putStringArray(ContentResolver.EXTRA_HONORED_ARGS, new String[]{
+                ContentResolver.QUERY_ARG_LIMIT
+            });
+        }
+
         Cursor cursor = null;
         try {
             if (TYPE_IMAGES_ROOT.equals(rootId)) {
@@ -638,7 +657,7 @@
                 cursor = resolver.query(Images.Media.EXTERNAL_CONTENT_URI,
                         ImageQuery.PROJECTION, null, null, ImageColumns.DATE_MODIFIED + " DESC");
                 copyNotificationUri(result, cursor);
-                while (cursor.moveToNext() && result.getCount() < 64) {
+                while (cursor.moveToNext() && result.getCount() < limit) {
                     includeImage(result, cursor);
                 }
             } else if (TYPE_VIDEOS_ROOT.equals(rootId)) {
@@ -646,7 +665,7 @@
                 cursor = resolver.query(Video.Media.EXTERNAL_CONTENT_URI,
                         VideoQuery.PROJECTION, null, null, VideoColumns.DATE_MODIFIED + " DESC");
                 copyNotificationUri(result, cursor);
-                while (cursor.moveToNext() && result.getCount() < 64) {
+                while (cursor.moveToNext() && result.getCount() < limit) {
                     includeVideo(result, cursor);
                 }
             } else {