Enable directory copying.

- Enable directory picking for copying.
- Implement recursive copying inside the CopyService.
  - Pretty up the notification (use an indeterminate notification while
    calculating copy size)
  - Do two recursive walks: one to determine the size of the copy job,
    and then another to actually copy the files.
- Switch to using ContentProviderClient instances, for better error
  detection and handling
- Disable copying from the Recents view.

Change-Id: Ieb38cca80edf84a487547b68f0d6b328fc4d7701
diff --git a/src/com/android/documentsui/DirectoryFragment.java b/src/com/android/documentsui/DirectoryFragment.java
index 83071bd..0e3016d 100644
--- a/src/com/android/documentsui/DirectoryFragment.java
+++ b/src/com/android/documentsui/DirectoryFragment.java
@@ -357,7 +357,12 @@
             return;
         }
 
-        Uri destination = data.getData();
+        // Because the destination picker is launched using an open tree intent, the URI returned is
+        // a tree URI. Convert it to a document URI.
+        // TODO: Remove this step when the destination picker returns a document URI.
+        final Uri destinationTree = data.getData();
+        final Uri destination = DocumentsContract.buildDocumentUriUsingTree(destinationTree,
+                DocumentsContract.getTreeDocumentId(destinationTree));
 
         List<DocumentInfo> docs = mSelectedDocumentsForCopy;
         Intent copyIntent = new Intent(context, CopyService.class);
@@ -506,8 +511,10 @@
             open.setVisible(!manageMode);
             share.setVisible(manageMode);
             delete.setVisible(manageMode);
-            // Hide the copy feature by default.
-            copy.setVisible(SystemProperties.getBoolean("debug.documentsui.enable_copy", false));
+            // Hide the copy menu item in the recents folder. For now, also hide it by default
+            // unless the debug flag is enabled.
+            copy.setVisible((mType != TYPE_RECENT_OPEN) &&
+                    SystemProperties.getBoolean("debug.documentsui.enable_copy", false));
 
             return true;
         }
@@ -575,9 +582,7 @@
                 if (cursor != null) {
                     final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
                     final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS);
-                    if (!Document.MIME_TYPE_DIR.equals(docMimeType)) {
-                        valid = isDocumentEnabled(docMimeType, docFlags);
-                    }
+                    valid = isDocumentEnabled(docMimeType, docFlags);
                 }
 
                 if (!valid) {
@@ -606,8 +611,17 @@
 
     private void onShareDocuments(List<DocumentInfo> docs) {
         Intent intent;
-        if (docs.size() == 1) {
-            final DocumentInfo doc = docs.get(0);
+
+        // Filter out directories - those can't be shared.
+        List<DocumentInfo> docsForSend = Lists.newArrayList();
+        for (DocumentInfo doc: docs) {
+            if (!Document.MIME_TYPE_DIR.equals(doc.mimeType)) {
+                docsForSend.add(doc);
+            }
+        }
+
+        if (docsForSend.size() == 1) {
+            final DocumentInfo doc = docsForSend.get(0);
 
             intent = new Intent(Intent.ACTION_SEND);
             intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
@@ -615,14 +629,14 @@
             intent.setType(doc.mimeType);
             intent.putExtra(Intent.EXTRA_STREAM, doc.derivedUri);
 
-        } else if (docs.size() > 1) {
+        } else if (docsForSend.size() > 1) {
             intent = new Intent(Intent.ACTION_SEND_MULTIPLE);
             intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
             intent.addCategory(Intent.CATEGORY_DEFAULT);
 
             final ArrayList<String> mimeTypes = Lists.newArrayList();
             final ArrayList<Uri> uris = Lists.newArrayList();
-            for (DocumentInfo doc : docs) {
+            for (DocumentInfo doc : docsForSend) {
                 mimeTypes.add(doc.mimeType);
                 uris.add(doc.derivedUri);
             }