Fix copying files from archives with a keyboard shortcut.

This stopped working, and we started requiring to acquire archives
before performing operations on them. In case of Job.java, we were
resolving the Uris before acquiring, which would fail if the archive
wasn't acquired (in this case users left the archive directory to get
to the destination).

This CL resolves this issue by acquiring archives before constructing
DocumentInfo.

Test: Tested manually by trying to CTRL+C and CTRL+V from archives
      to Downloads.
Bug: 35852761

Change-Id: I9a36d74f37dcf9001a1e3e01ce42aa90be29c806
diff --git a/src/com/android/documentsui/services/Job.java b/src/com/android/documentsui/services/Job.java
index 61f1c38..a72b528 100644
--- a/src/com/android/documentsui/services/Job.java
+++ b/src/com/android/documentsui/services/Job.java
@@ -181,21 +181,25 @@
         return Uri.parse(String.format("data,%s-%s", tag, id));
     }
 
-    ContentProviderClient getClient(DocumentInfo doc) throws RemoteException {
-        ContentProviderClient client = mClients.get(doc.authority);
+    ContentProviderClient getClient(Uri uri) throws RemoteException {
+        ContentProviderClient client = mClients.get(uri.getAuthority());
         if (client == null) {
             // Acquire content providers.
             client = acquireUnstableProviderOrThrow(
                     getContentResolver(),
-                    doc.authority);
+                    uri.getAuthority());
 
-            mClients.put(doc.authority, client);
+            mClients.put(uri.getAuthority(), client);
         }
 
         assert(client != null);
         return client;
     }
 
+    ContentProviderClient getClient(DocumentInfo doc) throws RemoteException {
+        return getClient(doc.derivedUri);
+    }
+
     final void cleanup() {
         for (ContentProviderClient client : mClients.values()) {
             ContentProviderClient.releaseQuietly(client);
diff --git a/src/com/android/documentsui/services/ResolvedResourcesJob.java b/src/com/android/documentsui/services/ResolvedResourcesJob.java
index b4934b0..b67316b 100644
--- a/src/com/android/documentsui/services/ResolvedResourcesJob.java
+++ b/src/com/android/documentsui/services/ResolvedResourcesJob.java
@@ -44,7 +44,7 @@
     private static final String TAG = "ResolvedResourcesJob";
 
     final List<DocumentInfo> mResolvedDocs;
-    final List<DocumentInfo> mAcquiredArchivedDocs = new ArrayList<>();
+    final List<Uri> mAcquiredArchivedUris = new ArrayList<>();
 
     ResolvedResourcesJob(Context service, Listener listener, String id, @OpType int opType,
             DocumentStack destination, UrisSupplier srcs) {
@@ -61,6 +61,25 @@
             return false;
         }
 
+        // Acquire all source archived documents, so they are not gone while copying from.
+        try {
+            Iterable<Uri> uris = mResourceUris.getUris(appContext);
+            for (Uri uri : uris) {
+                try {
+                    if (ArchivesProvider.AUTHORITY.equals(uri.getAuthority())) {
+                        ArchivesProvider.acquireArchive(getClient(uri), uri);
+                        mAcquiredArchivedUris.add(uri);
+                    }
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Failed to acquire an archive.");
+                    return false;
+                }
+            }
+        } catch (IOException e) {
+            Log.e(TAG, "Failed to read list of target resource Uris. Cannot continue.", e);
+            return false;
+        }
+
         int docsResolved = buildDocumentList();
         if (!isCanceled() && docsResolved < mResourceUris.getItemCount()) {
             if (docsResolved == 0) {
@@ -71,29 +90,15 @@
             }
         }
 
-        // Acquire all source archived documents, so they are not gone while copying from.
-        try {
-            for (DocumentInfo doc : mResolvedDocs) {
-                if (doc.isInArchive()) {
-                    final ContentProviderClient client = getClient(doc);
-                    ArchivesProvider.acquireArchive(client, doc.derivedUri);
-                    mAcquiredArchivedDocs.add(doc);
-                }
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to acquire an archive.");
-            return false;
-        }
-
         return true;
     }
 
     @Override
     void finish() {
         // Release all archived documents.
-        for (DocumentInfo doc : mAcquiredArchivedDocs) {
+        for (Uri uri : mAcquiredArchivedUris) {
             try {
-                ArchivesProvider.releaseArchive(getClient(doc), doc.derivedUri);
+                ArchivesProvider.releaseArchive(getClient(uri), uri);
             } catch (RemoteException e) {
                 Log.e(TAG, "Failed to release an archived document.");
             }