Merge "Add nullability annotations for some apis and update java doc"
diff --git a/api/current.txt b/api/current.txt
index cdadb86..3bb6957 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -37893,18 +37893,18 @@
     method public static android.provider.DocumentsContract.Path findDocumentPath(android.content.ContentInterface, android.net.Uri) throws java.io.FileNotFoundException;
     method @Deprecated public static android.provider.DocumentsContract.Path findDocumentPath(android.content.ContentResolver, android.net.Uri) throws java.io.FileNotFoundException;
     method public static String getDocumentId(android.net.Uri);
-    method public static android.os.Bundle getDocumentMetadata(android.content.ContentInterface, android.net.Uri) throws java.io.FileNotFoundException;
+    method @Nullable public static android.os.Bundle getDocumentMetadata(@NonNull android.content.ContentInterface, @NonNull android.net.Uri) throws java.io.FileNotFoundException;
     method @Deprecated public static android.os.Bundle getDocumentMetadata(android.content.ContentResolver, android.net.Uri) throws java.io.FileNotFoundException;
     method public static android.graphics.Bitmap getDocumentThumbnail(android.content.ContentInterface, android.net.Uri, android.graphics.Point, android.os.CancellationSignal) throws java.io.FileNotFoundException;
     method @Deprecated public static android.graphics.Bitmap getDocumentThumbnail(android.content.ContentResolver, android.net.Uri, android.graphics.Point, android.os.CancellationSignal) throws java.io.FileNotFoundException;
     method public static String getRootId(android.net.Uri);
     method public static String getSearchDocumentsQuery(android.net.Uri);
     method public static String getTreeDocumentId(android.net.Uri);
-    method public static boolean isChildDocument(android.content.ContentInterface, android.net.Uri, android.net.Uri) throws java.io.FileNotFoundException;
+    method public static boolean isChildDocument(@NonNull android.content.ContentInterface, @NonNull android.net.Uri, @NonNull android.net.Uri) throws java.io.FileNotFoundException;
     method @Deprecated public static boolean isChildDocument(android.content.ContentResolver, android.net.Uri, android.net.Uri) throws java.io.FileNotFoundException;
     method public static boolean isDocumentUri(android.content.Context, @Nullable android.net.Uri);
-    method public static boolean isRootUri(android.content.Context, @Nullable android.net.Uri);
-    method public static boolean isRootsUri(android.content.Context, @Nullable android.net.Uri);
+    method public static boolean isRootUri(@NonNull android.content.Context, @Nullable android.net.Uri);
+    method public static boolean isRootsUri(@NonNull android.content.Context, @Nullable android.net.Uri);
     method public static boolean isTreeUri(android.net.Uri);
     method public static android.net.Uri moveDocument(android.content.ContentInterface, android.net.Uri, android.net.Uri, android.net.Uri) throws java.io.FileNotFoundException;
     method @Deprecated public static android.net.Uri moveDocument(android.content.ContentResolver, android.net.Uri, android.net.Uri, android.net.Uri) throws java.io.FileNotFoundException;
@@ -37997,7 +37997,7 @@
     method public void deleteDocument(String) throws java.io.FileNotFoundException;
     method public void ejectRoot(String);
     method public android.provider.DocumentsContract.Path findDocumentPath(@Nullable String, String) throws java.io.FileNotFoundException;
-    method @Nullable public android.os.Bundle getDocumentMetadata(String) throws java.io.FileNotFoundException;
+    method @Nullable public android.os.Bundle getDocumentMetadata(@NonNull String) throws java.io.FileNotFoundException;
     method public String[] getDocumentStreamTypes(String, String);
     method public String getDocumentType(String) throws java.io.FileNotFoundException;
     method public final String getType(android.net.Uri);
@@ -38022,7 +38022,7 @@
     method public android.database.Cursor queryRecentDocuments(String, String[], @Nullable android.os.Bundle, @Nullable android.os.CancellationSignal) throws java.io.FileNotFoundException;
     method public abstract android.database.Cursor queryRoots(String[]) throws java.io.FileNotFoundException;
     method public android.database.Cursor querySearchDocuments(String, String, String[]) throws java.io.FileNotFoundException;
-    method public android.database.Cursor querySearchDocuments(String, String[], android.os.Bundle) throws java.io.FileNotFoundException;
+    method public android.database.Cursor querySearchDocuments(@NonNull String, @Nullable String[], @NonNull android.os.Bundle) throws java.io.FileNotFoundException;
     method public void removeDocument(String, String) throws java.io.FileNotFoundException;
     method public String renameDocument(String, String) throws java.io.FileNotFoundException;
     method public final void revokeDocumentPermission(String);
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index a323ed1..893a2ae 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -50,6 +50,8 @@
 import android.os.RemoteException;
 import android.util.Log;
 
+import com.android.internal.util.Preconditions;
+
 import dalvik.system.VMRuntime;
 
 import java.io.File;
@@ -1109,11 +1111,13 @@
     }
 
     /**
-     * Test if the given URI represents roots backed by {@link DocumentsProvider}.
+     * Test if the given URI represents all roots of the authority
+     * backed by {@link DocumentsProvider}.
      *
      * @see #buildRootsUri(String)
      */
-    public static boolean isRootsUri(Context context, @Nullable Uri uri) {
+    public static boolean isRootsUri(@NonNull Context context, @Nullable Uri uri) {
+        Preconditions.checkNotNull(context, "context can not be null");
         return isRootUri(context, uri, 1 /* pathSize */);
     }
 
@@ -1122,7 +1126,8 @@
      *
      * @see #buildRootUri(String, String)
      */
-    public static boolean isRootUri(Context context, @Nullable Uri uri) {
+    public static boolean isRootUri(@NonNull Context context, @Nullable Uri uri) {
+        Preconditions.checkNotNull(context, "context can not be null");
         return isRootUri(context, uri, 2 /* pathSize */);
     }
 
@@ -1215,6 +1220,7 @@
      * {@hide}
      */
     public static String getSearchDocumentsQuery(@NonNull Bundle bundle) {
+        Preconditions.checkNotNull(bundle, "bundle can not be null");
         return bundle.getString(QUERY_ARG_DISPLAY_NAME, "" /* defaultValue */);
     }
 
@@ -1315,8 +1321,12 @@
      * @return if given document is a descendant of the given parent.
      * @see Root#FLAG_SUPPORTS_IS_CHILD
      */
-    public static boolean isChildDocument(ContentInterface content, Uri parentDocumentUri,
-            Uri childDocumentUri) throws FileNotFoundException {
+    public static boolean isChildDocument(@NonNull ContentInterface content,
+            @NonNull Uri parentDocumentUri, @NonNull Uri childDocumentUri)
+            throws FileNotFoundException {
+        Preconditions.checkNotNull(content, "content can not be null");
+        Preconditions.checkNotNull(parentDocumentUri, "parentDocumentUri can not be null");
+        Preconditions.checkNotNull(childDocumentUri, "childDocumentUri can not be null");
         try {
             final Bundle in = new Bundle();
             in.putParcelable(DocumentsContract.EXTRA_URI, parentDocumentUri);
@@ -1325,7 +1335,7 @@
             final Bundle out = content.call(parentDocumentUri.getAuthority(),
                     METHOD_IS_CHILD_DOCUMENT, null, in);
             if (out == null) {
-                throw new RemoteException("Failed to get a reponse from isChildDocument query.");
+                throw new RemoteException("Failed to get a response from isChildDocument query.");
             }
             if (!out.containsKey(DocumentsContract.EXTRA_RESULT)) {
                 throw new RemoteException("Response did not include result field..");
@@ -1559,8 +1569,10 @@
      * @param documentUri a Document URI
      * @return a Bundle of Bundles.
      */
-    public static Bundle getDocumentMetadata(ContentInterface content, Uri documentUri)
-            throws FileNotFoundException {
+    public static @Nullable Bundle getDocumentMetadata(@NonNull ContentInterface content,
+            @NonNull Uri documentUri) throws FileNotFoundException {
+        Preconditions.checkNotNull(content, "content can not be null");
+        Preconditions.checkNotNull(documentUri, "documentUri can not be null");
         try {
             final Bundle in = new Bundle();
             in.putParcelable(EXTRA_URI, documentUri);
diff --git a/core/java/android/provider/DocumentsProvider.java b/core/java/android/provider/DocumentsProvider.java
index 70c84f8..d78442d 100644
--- a/core/java/android/provider/DocumentsProvider.java
+++ b/core/java/android/provider/DocumentsProvider.java
@@ -37,6 +37,7 @@
 
 import android.Manifest;
 import android.annotation.CallSuper;
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.AuthenticationRequiredException;
 import android.content.ClipDescription;
@@ -63,6 +64,8 @@
 import android.provider.DocumentsContract.Root;
 import android.util.Log;
 
+import com.android.internal.util.Preconditions;
+
 import libcore.io.IoUtils;
 
 import java.io.FileNotFoundException;
@@ -693,8 +696,10 @@
      * @see DocumentsContract#EXTRA_ERROR
      */
     @SuppressWarnings("unused")
-    public Cursor querySearchDocuments(String rootId, String[] projection, Bundle queryArgs)
-            throws FileNotFoundException {
+    public Cursor querySearchDocuments(@NonNull String rootId, @Nullable String[] projection,
+            @NonNull Bundle queryArgs) throws FileNotFoundException {
+        Preconditions.checkNotNull(rootId, "rootId can not be null");
+        Preconditions.checkNotNull(queryArgs, "queryArgs can not be null");
         return querySearchDocuments(rootId, DocumentsContract.getSearchDocumentsQuery(queryArgs),
                 projection);
     }
@@ -732,7 +737,7 @@
      * @return a Bundle of Bundles.
      * @see DocumentsContract#getDocumentMetadata(ContentResolver, Uri)
      */
-    public @Nullable Bundle getDocumentMetadata(String documentId)
+    public @Nullable Bundle getDocumentMetadata(@NonNull String documentId)
             throws FileNotFoundException {
         throw new UnsupportedOperationException("Metadata not supported");
     }