Address API Council feedback.

Bug: 37422306, 37419881
Test: Build and read docs.
Change-Id: Id6c8bad6ad6b311017094ce5dbd66cfd72c477ad
(cherry picked from commit d74a3bd7d1d3175856f450a9e77dabb89f2e5060)
diff --git a/api/current.txt b/api/current.txt
index 7a01e1a..50c1cb7 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -8719,17 +8719,17 @@
     field public static final java.lang.String EXTRA_HONORED_ARGS = "android.content.extra.HONORED_ARGS";
     field public static final java.lang.String EXTRA_REFRESH_SUPPORTED = "android.content.extra.REFRESH_SUPPORTED";
     field public static final java.lang.String EXTRA_SIZE = "android.content.extra.SIZE";
-    field public static final java.lang.String EXTRA_TOTAL_SIZE = "android.content.extra.TOTAL_SIZE";
+    field public static final java.lang.String EXTRA_TOTAL_COUNT = "android.content.extra.TOTAL_COUNT";
     field public static final int NOTIFY_SKIP_NOTIFY_FOR_DESCENDANTS = 2; // 0x2
     field public static final int NOTIFY_SYNC_TO_NETWORK = 1; // 0x1
-    field public static final java.lang.String QUERY_ARG_LIMIT = "android:query-page-limit";
-    field public static final java.lang.String QUERY_ARG_OFFSET = "android:query-page-offset";
-    field public static final java.lang.String QUERY_ARG_SORT_COLLATION = "android:query-sort-collation";
-    field public static final java.lang.String QUERY_ARG_SORT_COLUMNS = "android:query-sort-columns";
-    field public static final java.lang.String QUERY_ARG_SORT_DIRECTION = "android:query-sort-direction";
-    field public static final java.lang.String QUERY_ARG_SQL_SELECTION = "android:query-sql-selection";
-    field public static final java.lang.String QUERY_ARG_SQL_SELECTION_ARGS = "android:query-sql-selection-args";
-    field public static final java.lang.String QUERY_ARG_SQL_SORT_ORDER = "android:query-sql-sort-order";
+    field public static final java.lang.String QUERY_ARG_LIMIT = "android:query-arg-limit";
+    field public static final java.lang.String QUERY_ARG_OFFSET = "android:query-arg-offset";
+    field public static final java.lang.String QUERY_ARG_SORT_COLLATION = "android:query-arg-sort-collation";
+    field public static final java.lang.String QUERY_ARG_SORT_COLUMNS = "android:query-arg-sort-columns";
+    field public static final java.lang.String QUERY_ARG_SORT_DIRECTION = "android:query-arg-sort-direction";
+    field public static final java.lang.String QUERY_ARG_SQL_SELECTION = "android:query-arg-sql-selection";
+    field public static final java.lang.String QUERY_ARG_SQL_SELECTION_ARGS = "android:query-arg-sql-selection-args";
+    field public static final java.lang.String QUERY_ARG_SQL_SORT_ORDER = "android:query-arg-sql-sort-order";
     field public static final int QUERY_SORT_DIRECTION_ASCENDING = 0; // 0x0
     field public static final int QUERY_SORT_DIRECTION_DESCENDING = 1; // 0x1
     field public static final java.lang.String SCHEME_ANDROID_RESOURCE = "android.resource";
diff --git a/api/system-current.txt b/api/system-current.txt
index 6c5931e..38b9307 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -9216,17 +9216,17 @@
     field public static final java.lang.String EXTRA_HONORED_ARGS = "android.content.extra.HONORED_ARGS";
     field public static final java.lang.String EXTRA_REFRESH_SUPPORTED = "android.content.extra.REFRESH_SUPPORTED";
     field public static final java.lang.String EXTRA_SIZE = "android.content.extra.SIZE";
-    field public static final java.lang.String EXTRA_TOTAL_SIZE = "android.content.extra.TOTAL_SIZE";
+    field public static final java.lang.String EXTRA_TOTAL_COUNT = "android.content.extra.TOTAL_COUNT";
     field public static final int NOTIFY_SKIP_NOTIFY_FOR_DESCENDANTS = 2; // 0x2
     field public static final int NOTIFY_SYNC_TO_NETWORK = 1; // 0x1
-    field public static final java.lang.String QUERY_ARG_LIMIT = "android:query-page-limit";
-    field public static final java.lang.String QUERY_ARG_OFFSET = "android:query-page-offset";
-    field public static final java.lang.String QUERY_ARG_SORT_COLLATION = "android:query-sort-collation";
-    field public static final java.lang.String QUERY_ARG_SORT_COLUMNS = "android:query-sort-columns";
-    field public static final java.lang.String QUERY_ARG_SORT_DIRECTION = "android:query-sort-direction";
-    field public static final java.lang.String QUERY_ARG_SQL_SELECTION = "android:query-sql-selection";
-    field public static final java.lang.String QUERY_ARG_SQL_SELECTION_ARGS = "android:query-sql-selection-args";
-    field public static final java.lang.String QUERY_ARG_SQL_SORT_ORDER = "android:query-sql-sort-order";
+    field public static final java.lang.String QUERY_ARG_LIMIT = "android:query-arg-limit";
+    field public static final java.lang.String QUERY_ARG_OFFSET = "android:query-arg-offset";
+    field public static final java.lang.String QUERY_ARG_SORT_COLLATION = "android:query-arg-sort-collation";
+    field public static final java.lang.String QUERY_ARG_SORT_COLUMNS = "android:query-arg-sort-columns";
+    field public static final java.lang.String QUERY_ARG_SORT_DIRECTION = "android:query-arg-sort-direction";
+    field public static final java.lang.String QUERY_ARG_SQL_SELECTION = "android:query-arg-sql-selection";
+    field public static final java.lang.String QUERY_ARG_SQL_SELECTION_ARGS = "android:query-arg-sql-selection-args";
+    field public static final java.lang.String QUERY_ARG_SQL_SORT_ORDER = "android:query-arg-sql-sort-order";
     field public static final int QUERY_SORT_DIRECTION_ASCENDING = 0; // 0x0
     field public static final int QUERY_SORT_DIRECTION_DESCENDING = 1; // 0x1
     field public static final java.lang.String SCHEME_ANDROID_RESOURCE = "android.resource";
diff --git a/api/test-current.txt b/api/test-current.txt
index c00795d..5ac5228 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -8751,17 +8751,17 @@
     field public static final java.lang.String EXTRA_HONORED_ARGS = "android.content.extra.HONORED_ARGS";
     field public static final java.lang.String EXTRA_REFRESH_SUPPORTED = "android.content.extra.REFRESH_SUPPORTED";
     field public static final java.lang.String EXTRA_SIZE = "android.content.extra.SIZE";
-    field public static final java.lang.String EXTRA_TOTAL_SIZE = "android.content.extra.TOTAL_SIZE";
+    field public static final java.lang.String EXTRA_TOTAL_COUNT = "android.content.extra.TOTAL_COUNT";
     field public static final int NOTIFY_SKIP_NOTIFY_FOR_DESCENDANTS = 2; // 0x2
     field public static final int NOTIFY_SYNC_TO_NETWORK = 1; // 0x1
-    field public static final java.lang.String QUERY_ARG_LIMIT = "android:query-page-limit";
-    field public static final java.lang.String QUERY_ARG_OFFSET = "android:query-page-offset";
-    field public static final java.lang.String QUERY_ARG_SORT_COLLATION = "android:query-sort-collation";
-    field public static final java.lang.String QUERY_ARG_SORT_COLUMNS = "android:query-sort-columns";
-    field public static final java.lang.String QUERY_ARG_SORT_DIRECTION = "android:query-sort-direction";
-    field public static final java.lang.String QUERY_ARG_SQL_SELECTION = "android:query-sql-selection";
-    field public static final java.lang.String QUERY_ARG_SQL_SELECTION_ARGS = "android:query-sql-selection-args";
-    field public static final java.lang.String QUERY_ARG_SQL_SORT_ORDER = "android:query-sql-sort-order";
+    field public static final java.lang.String QUERY_ARG_LIMIT = "android:query-arg-limit";
+    field public static final java.lang.String QUERY_ARG_OFFSET = "android:query-arg-offset";
+    field public static final java.lang.String QUERY_ARG_SORT_COLLATION = "android:query-arg-sort-collation";
+    field public static final java.lang.String QUERY_ARG_SORT_COLUMNS = "android:query-arg-sort-columns";
+    field public static final java.lang.String QUERY_ARG_SORT_DIRECTION = "android:query-arg-sort-direction";
+    field public static final java.lang.String QUERY_ARG_SQL_SELECTION = "android:query-arg-sql-selection";
+    field public static final java.lang.String QUERY_ARG_SQL_SELECTION_ARGS = "android:query-arg-sql-selection-args";
+    field public static final java.lang.String QUERY_ARG_SQL_SORT_ORDER = "android:query-arg-sql-sort-order";
     field public static final int QUERY_SORT_DIRECTION_ASCENDING = 0; // 0x0
     field public static final int QUERY_SORT_DIRECTION_DESCENDING = 1; // 0x1
     field public static final java.lang.String SCHEME_ANDROID_RESOURCE = "android.resource";
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index d75c2ee0..9d46da1 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -46,6 +46,7 @@
 import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.Log;
+import android.util.MathUtils;
 
 import java.io.File;
 import java.io.FileDescriptor;
@@ -1066,14 +1067,65 @@
      * <li>{@link ContentResolver#QUERY_ARG_SQL_SELECTION_ARGS}
      * <li>{@link ContentResolver#QUERY_ARG_SQL_SORT_ORDER}
      *
+     * <p>This method can be called from multiple threads, as described in
+     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
+     * and Threads</a>.
+     *
+     * <p>
+     * Example client call:<p>
+     * <pre>// Request 20 records starting at row index 30.
+       Bundle queryArgs = new Bundle();
+       queryArgs.putInt(ContentResolver.QUERY_ARG_OFFSET, 30);
+       queryArgs.putInt(ContentResolver.QUERY_ARG_LIMIT, 20);
+
+       Cursor cursor = getContentResolver().query(
+                contentUri,    // Content Uri is specific to individual content providers.
+                projection,    // String[] describing which columns to return.
+                queryArgs,     // Query arguments.
+                null);         // Cancellation signal.</pre>
+     *
+     * Example implementation:<p>
+     * <pre>
+
+        int recordsetSize = 0x1000;  // Actual value is implementation specific.
+        queryArgs = queryArgs != null ? queryArgs : Bundle.EMPTY;  // ensure queryArgs is non-null
+
+        int offset = queryArgs.getInt(ContentResolver.QUERY_ARG_OFFSET, 0);
+        int limit = queryArgs.getInt(ContentResolver.QUERY_ARG_LIMIT, Integer.MIN_VALUE);
+
+        MatrixCursor c = new MatrixCursor(PROJECTION, limit);
+
+        // Calculate the number of items to include in the cursor.
+        int numItems = MathUtils.constrain(recordsetSize - offset, 0, limit);
+
+        // Build the paged result set....
+        for (int i = offset; i < offset + numItems; i++) {
+            // populate row from your data.
+        }
+
+        Bundle extras = new Bundle();
+        c.setExtras(extras);
+
+        // Any QUERY_ARG_* key may be included if honored.
+        // In an actual implementation, include only keys that are both present in queryArgs
+        // and reflected in the Cursor output. For example, if QUERY_ARG_OFFSET were included
+        // in queryArgs, but was ignored because it contained an invalid value (like –273),
+        // then QUERY_ARG_OFFSET should be omitted.
+        extras.putStringArray(ContentResolver.EXTRA_HONORED_ARGS, new String[] {
+            ContentResolver.QUERY_ARG_OFFSET,
+            ContentResolver.QUERY_ARG_LIMIT
+        });
+
+        extras.putInt(ContentResolver.EXTRA_TOTAL_COUNT, recordsetSize);
+
+        cursor.setNotificationUri(getContext().getContentResolver(), uri);
+
+        return cursor;</pre>
+     * <p>
      * @see #query(Uri, String[], String, String[], String, CancellationSignal) for
      *     implementation details.
      *
      * @param uri The URI to query. This will be the full URI sent by the client.
-     *            TODO: Me wonders about this use case, and how we adapt it.
-     *            If the client is requesting a specific record, the URI will end
-     *            in a record number that the implementation should parse and add
-     *            to a WHERE or HAVING clause, specifying that _id value.
      * @param projection The list of columns to put into the cursor.
      *            If {@code null} provide a default set of columns.
      * @param queryArgs A Bundle containing all additional information necessary for the query.
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 98ae132..28cfd33 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -214,10 +214,12 @@
      *
      * <p><b>Apps targeting {@link android.os.Build.VERSION_CODES#O} or higher are strongly
      * encourage to use structured query arguments in lieu of opaque SQL query clauses.</b>
-     * See: {@link #QUERY_ARG_SORT_COLUMNS}, {@link #QUERY_ARG_SORT_DIRECTION}, and
-     * {@link #QUERY_ARG_SORT_COLLATION}.
+     *
+     * @see #QUERY_ARG_SORT_COLUMNS
+     * @see #QUERY_ARG_SORT_DIRECTION
+     * @see #QUERY_ARG_SORT_COLLATION
      */
-    public static final String QUERY_ARG_SQL_SELECTION = "android:query-sql-selection";
+    public static final String QUERY_ARG_SQL_SELECTION = "android:query-arg-sql-selection";
 
     /**
      * Key for SQL selection string arguments list.
@@ -229,10 +231,13 @@
      *
      * <p><b>Apps targeting {@link android.os.Build.VERSION_CODES#O} or higher are strongly
      * encourage to use structured query arguments in lieu of opaque SQL query clauses.</b>
-     * See: {@link #QUERY_ARG_SORT_COLUMNS}, {@link #QUERY_ARG_SORT_DIRECTION}, and
-     * {@link #QUERY_ARG_SORT_COLLATION}.
+     *
+     * @see #QUERY_ARG_SORT_COLUMNS
+     * @see #QUERY_ARG_SORT_DIRECTION
+     * @see #QUERY_ARG_SORT_COLLATION
      */
-    public static final String QUERY_ARG_SQL_SELECTION_ARGS = "android:query-sql-selection-args";
+    public static final String QUERY_ARG_SQL_SELECTION_ARGS =
+            "android:query-arg-sql-selection-args";
 
     /**
      * Key for an SQL style sort string that may be present in the query Bundle argument
@@ -241,10 +246,12 @@
      *
      * <p><b>Apps targeting {@link android.os.Build.VERSION_CODES#O} or higher are strongly
      * encourage to use structured query arguments in lieu of opaque SQL query clauses.</b>
-     * See: {@link #QUERY_ARG_SORT_COLUMNS}, {@link #QUERY_ARG_SORT_DIRECTION}, and
-     * {@link #QUERY_ARG_SORT_COLLATION}.
+     *
+     * @see #QUERY_ARG_SORT_COLUMNS
+     * @see #QUERY_ARG_SORT_DIRECTION
+     * @see #QUERY_ARG_SORT_COLLATION
      */
-    public static final String QUERY_ARG_SQL_SORT_ORDER = "android:query-sql-sort-order";
+    public static final String QUERY_ARG_SQL_SORT_ORDER = "android:query-arg-sql-sort-order";
 
     /**
      * Specifies the list of columns against which to sort results. When first column values
@@ -255,16 +262,17 @@
      *
      * <p>Apps targeting {@link android.os.Build.VERSION_CODES#O} or higher:
      *
-     * <li>When supplying data using a ContentProvider, it is strongly recommended that
-     * an entry be included in the {@link Cursor} extras {@link Bundle} under this same key
-     * (@link QUERY_ARG_SORT_COLUMNS}) to indicate which column sorting was applied
-     * to the recordset, if any.
+     * <li>{@link ContentProvider} implementations: When preparing data in
+     * {@link ContentProvider#query(Uri, String[], Bundle, CancellationSignal)}, if sort columns
+     * is reflected in the returned Cursor, it is  strongly recommended that
+     * {@link #QUERY_ARG_SORT_COLUMNS} then be included in the array of honored arguments
+     * reflected in {@link Cursor} extras {@link Bundle} under {@link #EXTRA_HONORED_ARGS}.
      *
      * <li>When querying a provider, where no QUERY_ARG_SQL* otherwise exists in the
      * arguments {@link Bundle}, the Content framework will attempt to synthesize
      * an QUERY_ARG_SQL* argument using the corresponding QUERY_ARG_SORT* values.
      */
-    public static final String QUERY_ARG_SORT_COLUMNS = "android:query-sort-columns";
+    public static final String QUERY_ARG_SORT_COLUMNS = "android:query-arg-sort-columns";
 
     /**
      * Specifies desired sort order. When unspecified a provider may provide a default
@@ -272,50 +280,58 @@
      *
      * <p>Apps targeting {@link android.os.Build.VERSION_CODES#O} or higher:
      *
-     * <li>When supplying data using a ContentProvider, it is strongly recommended that
-     * an entry be included in the {@link Cursor} extras {@link Bundle} under this same key
-     * (@link QUERY_ARG_SORT_DIRECTION}) to indicate that sort direction was applied
-     * to the recordset.
+     * <li>{@link ContentProvider} implementations: When preparing data in
+     * {@link ContentProvider#query(Uri, String[], Bundle, CancellationSignal)}, if sort direction
+     * is reflected in the returned Cursor, it is  strongly recommended that
+     * {@link #QUERY_ARG_SORT_DIRECTION} then be included in the array of honored arguments
+     * reflected in {@link Cursor} extras {@link Bundle} under {@link #EXTRA_HONORED_ARGS}.
      *
      * <li>When querying a provider, where no QUERY_ARG_SQL* otherwise exists in the
      * arguments {@link Bundle}, the Content framework will attempt to synthesize
-     * an QUERY_ARG_SQL* argument using the corresponding QUERY_ARG_SORT* values.
+     * a QUERY_ARG_SQL* argument using the corresponding QUERY_ARG_SORT* values.
      *
      * @see #QUERY_SORT_DIRECTION_ASCENDING
      * @see #QUERY_SORT_DIRECTION_DESCENDING
      */
-    public static final String QUERY_ARG_SORT_DIRECTION = "android:query-sort-direction";
+    public static final String QUERY_ARG_SORT_DIRECTION = "android:query-arg-sort-direction";
 
     /**
-     * Allows client to specify a hint to the provider as to which collation
+     * Allows client to specify a hint to the provider declaring which collation
      * to use when sorting text values.
      *
-     * <p>Providers may provide their own collators. When selecting a custom collator
-     * the value will be determined by the Provider.
+     * <p>Providers may support custom collators. When specifying a custom collator
+     * the value is determined by the Provider.
      *
-     * <li>When supplying data using a ContentProvider, it is strongly recommended that
-     * an entry be included in the {@link Cursor} extras {@link Bundle} under this same key
-     * (@link QUERY_ARG_SORT_COLLATION}) to indicate that sort collation was applied
-     * to the recordset.
+     * <li>{@link ContentProvider} implementations: When preparing data in
+     * {@link ContentProvider#query(Uri, String[], Bundle, CancellationSignal)}, if sort collation
+     * is reflected in the returned Cursor, it is  strongly recommended that
+     * {@link #QUERY_ARG_SORT_COLLATION} then be included in the array of honored arguments
+     * reflected in {@link Cursor} extras {@link Bundle} under {@link #EXTRA_HONORED_ARGS}.
      *
-     * <p>When querying a provider, where no QUERY_ARG_SQL* otherwise exists in the
+     * <li>When querying a provider, where no QUERY_ARG_SQL* otherwise exists in the
      * arguments {@link Bundle}, the Content framework will attempt to synthesize
-     * an QUERY_ARG_SQL* argument using the corresponding QUERY_ARG_SORT* values.
+     * a QUERY_ARG_SQL* argument using the corresponding QUERY_ARG_SORT* values.
      *
-     * @see java.text.Collator#PRIMARY, java.text.Collator#SECONDARY,
-     *     java.text.Collator#TERTIARY, and java.text.Collator#IDENTICAL.
+     * @see java.text.Collator#PRIMARY
+     * @see java.text.Collator#SECONDARY
+     * @see java.text.Collator#TERTIARY
+     * @see java.text.Collator#IDENTICAL
      */
-    public static final String QUERY_ARG_SORT_COLLATION = "android:query-sort-collation";
+    public static final String QUERY_ARG_SORT_COLLATION = "android:query-arg-sort-collation";
 
     /**
-     * Allows provider to report back to client which keys were honored.
+     * Allows provider to report back to client which query keys are honored in a Cursor.
      *
-     * Key identifying a {@code String[]} containing all QUERY_ARG_SORT* arguments
+     * <p>Key identifying a {@code String[]} containing all QUERY_ARG_SORT* arguments
      * honored by the provider. Include this in {@link Cursor} extras {@link Bundle}
      * when any QUERY_ARG_SORT* value was honored during the preparation of the
      * results {@link Cursor}.
      *
-     * @see #QUERY_ARG_SORT_COLUMNS, #QUERY_ARG_SORT_DIRECTION, #QUERY_ARG_SORT_COLLATION.
+     * <p>If present, ALL honored arguments are enumerated in this extra’s payload.
+     *
+     * @see #QUERY_ARG_SORT_COLUMNS
+     * @see #QUERY_ARG_SORT_DIRECTION
+     * @see #QUERY_ARG_SORT_COLLATION
      */
     public static final String EXTRA_HONORED_ARGS = "android.content.extra.HONORED_ARGS";
 
@@ -343,41 +359,27 @@
     public @interface QueryCollator {}
 
     /**
-     * Specifies the offset from which to load a recordset. Records prior to this
-     * position should be omitted from results.
-     *
-     * <p>Providers are recommended to create a content notification Uri
-     * that encapsulates QUERY_ARG_OFFSET and QUERY_ARG_LIMITS values reflected
-     * in the recordset. This will allow a provider to notify clients of changes
-     * to an individual recordset.
+     * Specifies the offset row index within a Cursor.
      */
-    public static final String QUERY_ARG_OFFSET = "android:query-page-offset";
+    public static final String QUERY_ARG_OFFSET = "android:query-arg-offset";
 
     /**
-     * Specifies the max number of records to include in a recordset with respect
-     * to the starting offset, which by default is 0. Records beyond starting offset + limit
-     * should be omitted from results.
-     *
-     * <p>Providers are recommended to create a content notification Uri
-     * that encapsulates QUERY_ARG_OFFSET and QUERY_ARG_LIMITS values reflected
-     * in the recordset. This will allow a provider to notify clients of changes
-     * to an individual recordset.
+     * Specifies the max number of rows to include in a Cursor.
      */
-    public static final String QUERY_ARG_LIMIT = "android:query-page-limit";
+    public static final String QUERY_ARG_LIMIT = "android:query-arg-limit";
 
     /**
-     * Added to {@link Cursor} extras {@link Bundle} to indicate total size of
-     * recordset when paging is active. Providers must include this when
+     * Added to {@link Cursor} extras {@link Bundle} to indicate total row count of
+     * recordset when paging is supported. Providers must include this when
      * implementing paging support.
      *
-     * <p>When full size of the recordset is unknown a provider may return -1
-     * to indicate this.
+     * <p>A provider may return -1 that row count of the recordset is unknown.
      *
      * <p>Providers having returned -1 in a previous query are recommended to
      * send content change notification once (if) full recordset size becomes
      * known.
      */
-    public static final String EXTRA_TOTAL_SIZE = "android.content.extra.TOTAL_SIZE";
+    public static final String EXTRA_TOTAL_COUNT = "android.content.extra.TOTAL_COUNT";
 
     /**
      * This is the Android platform's base MIME type for a content: URI