[multi-part] Eliminate 1k selection limit

* Save selection to disk, delete old selections on app startup.
* Do clipper work in background for copy/cut.
* Pull DragShadowBuilder out of DirFragment.
* Reorganize selection handling to avoid creation of large lists of objects.
* Eliminate getAll from selection, make it iterable, remove unused method.
* Avoid creating DocumentInfo instances for full selection when initiating drag and drop.

Next step will be to pass selection tokens to FileOperationService.

Change-Id: Ia3e30a88ebf328e5b045d06b0df15dbd26a01a42
diff --git a/src/com/android/documentsui/dirlist/Model.java b/src/com/android/documentsui/dirlist/Model.java
index 0a2960f..5c15228 100644
--- a/src/com/android/documentsui/dirlist/Model.java
+++ b/src/com/android/documentsui/dirlist/Model.java
@@ -25,6 +25,7 @@
 
 import android.database.Cursor;
 import android.database.MergeCursor;
+import android.net.Uri;
 import android.os.Bundle;
 import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Document;
@@ -39,7 +40,6 @@
 import com.android.documentsui.model.DocumentInfo;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -389,15 +389,15 @@
         return mIsLoading;
     }
 
-    List<DocumentInfo> getDocuments(Selection items) {
-        final int size = (items != null) ? items.size() : 0;
+    List<DocumentInfo> getDocuments(Selection selection) {
+        final int size = (selection != null) ? selection.size() : 0;
 
         final List<DocumentInfo> docs =  new ArrayList<>(size);
-        for (String modelId: items.getAll()) {
+        // NOTE: That as this now iterates over only final (non-provisional) selection.
+        for (String modelId: selection) {
             final Cursor cursor = getItem(modelId);
             if (cursor == null) {
-                Log.w(TAG,
-                        "Skipping document. Unabled to obtain cursor for modelId: " + modelId);
+                Log.w(TAG, "Skipping document. Unabled to obtain cursor for modelId: " + modelId);
                 continue;
             }
             docs.add(DocumentInfo.fromDirectoryCursor(cursor));
@@ -405,6 +405,11 @@
         return docs;
     }
 
+    public Uri getItemUri(String modelId) {
+        final Cursor cursor = getItem(modelId);
+        return DocumentInfo.getUri(cursor);
+    }
+
     void addUpdateListener(UpdateListener listener) {
         mUpdateListeners.add(listener);
     }