Loading packages/DocumentsUI/src/com/android/documentsui/QuickViewIntentBuilder.java +73 −33 Original line number Diff line number Diff line Loading @@ -33,16 +33,19 @@ import android.provider.DocumentsContract.Document; import android.support.annotation.Nullable; import android.text.TextUtils; import android.util.Log; import android.util.Range; import com.android.documentsui.dirlist.Model; import com.android.documentsui.model.DocumentInfo; import java.util.ArrayList; import java.util.List; /** * Provides support for gather a list of quick-viewable files into a quick view intent. */ final class QuickViewIntentBuilder { private static final int MAX_CLIP_ITEMS = 1000; private final DocumentInfo mDocument; private final Model mModel; Loading @@ -50,9 +53,6 @@ final class QuickViewIntentBuilder { private final PackageManager mPkgManager; private final Resources mResources; private ClipData mClipData; private int mDocumentLocation; public QuickViewIntentBuilder( PackageManager pkgManager, Resources resources, Loading Loading @@ -80,12 +80,28 @@ final class QuickViewIntentBuilder { intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.setPackage(trustedPkg); if (hasRegisteredHandler(intent)) { List<String> siblingIds = mModel.getModelIds(); for (int i = 0; i < siblingIds.size(); i++) { onNextItem(i, siblingIds); final ArrayList<Uri> uris = new ArrayList<Uri>(); final int documentLocation = collectViewableUris(uris); final Range<Integer> range = computeSiblingsRange(uris, documentLocation); ClipData clipData = null; ClipData.Item item; Uri uri; for (int i = range.getLower(); i <= range.getUpper(); i++) { uri = uris.get(i); item = new ClipData.Item(uri); if (DEBUG) Log.d(TAG, "Including file: " + uri); if (clipData == null) { clipData = new ClipData( "URIs", new String[] { ClipDescription.MIMETYPE_TEXT_URILIST }, item); } else { clipData.addItem(item); } intent.putExtra(Intent.EXTRA_INDEX, mDocumentLocation); intent.setClipData(mClipData); } intent.putExtra(Intent.EXTRA_INDEX, documentLocation); intent.setClipData(clipData); return intent; } else { Loading @@ -96,39 +112,63 @@ final class QuickViewIntentBuilder { return null; } private boolean hasRegisteredHandler(Intent intent) { // Try to resolve the intent. If a matching app isn't installed, it won't resolve. return intent.resolveActivity(mPkgManager) != null; } private int collectViewableUris(ArrayList<Uri> uris) { final List<String> siblingIds = mModel.getModelIds(); uris.ensureCapacity(siblingIds.size()); private void onNextItem(int index, List<String> siblingIds) { final Cursor cursor = mModel.getItem(siblingIds.get(index)); int documentLocation = 0; Cursor cursor; String mimeType; String id; String authority; Uri uri; if (cursor == null) { return; } // Cursor's are not guaranteed to be immutable. Hence, traverse it only once. for (int i = 0; i < siblingIds.size(); i++) { cursor = mModel.getItem(siblingIds.get(i)); String mimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE); mimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE); if (Document.MIME_TYPE_DIR.equals(mimeType)) { return; continue; } String id = getCursorString(cursor, Document.COLUMN_DOCUMENT_ID); String authority = getCursorString(cursor, RootCursorWrapper.COLUMN_AUTHORITY); Uri uri = DocumentsContract.buildDocumentUri(authority, id); if (DEBUG) Log.d(TAG, "Including file[" + id + "] @ " + uri); id = getCursorString(cursor, Document.COLUMN_DOCUMENT_ID); authority = getCursorString(cursor, RootCursorWrapper.COLUMN_AUTHORITY); uri = DocumentsContract.buildDocumentUri(authority, id); if (id.equals(mDocument.documentId)) { if (DEBUG) Log.d(TAG, "Found starting point for QV. " + index); mDocumentLocation = index; if (DEBUG) Log.d(TAG, "Found starting point for QV. " + i); documentLocation = i; } ClipData.Item item = new ClipData.Item(uri); if (mClipData == null) { mClipData = new ClipData( "URIs", new String[]{ClipDescription.MIMETYPE_TEXT_URILIST}, item); uris.add(uri); } return documentLocation; } private static Range<Integer> computeSiblingsRange(List<Uri> uris, int documentLocation) { // Restrict number of siblings to avoid hitting the IPC limit. // TODO: Remove this restriction once ClipData can hold an arbitrary number of // items. int firstSibling; int lastSibling; if (documentLocation < uris.size() / 2) { firstSibling = Math.max(0, documentLocation - MAX_CLIP_ITEMS / 2); lastSibling = Math.min(uris.size() - 1, firstSibling + MAX_CLIP_ITEMS - 1); } else { mClipData.addItem(item); lastSibling = Math.min(uris.size() - 1, documentLocation + MAX_CLIP_ITEMS / 2); firstSibling = Math.max(0, lastSibling - MAX_CLIP_ITEMS + 1); } if (DEBUG) Log.d(TAG, "Copmuted siblings from index: " + firstSibling + " to: " + lastSibling); return new Range(firstSibling, lastSibling); } private boolean hasRegisteredHandler(Intent intent) { // Try to resolve the intent. If a matching app isn't installed, it won't resolve. return intent.resolveActivity(mPkgManager) != null; } } Loading
packages/DocumentsUI/src/com/android/documentsui/QuickViewIntentBuilder.java +73 −33 Original line number Diff line number Diff line Loading @@ -33,16 +33,19 @@ import android.provider.DocumentsContract.Document; import android.support.annotation.Nullable; import android.text.TextUtils; import android.util.Log; import android.util.Range; import com.android.documentsui.dirlist.Model; import com.android.documentsui.model.DocumentInfo; import java.util.ArrayList; import java.util.List; /** * Provides support for gather a list of quick-viewable files into a quick view intent. */ final class QuickViewIntentBuilder { private static final int MAX_CLIP_ITEMS = 1000; private final DocumentInfo mDocument; private final Model mModel; Loading @@ -50,9 +53,6 @@ final class QuickViewIntentBuilder { private final PackageManager mPkgManager; private final Resources mResources; private ClipData mClipData; private int mDocumentLocation; public QuickViewIntentBuilder( PackageManager pkgManager, Resources resources, Loading Loading @@ -80,12 +80,28 @@ final class QuickViewIntentBuilder { intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.setPackage(trustedPkg); if (hasRegisteredHandler(intent)) { List<String> siblingIds = mModel.getModelIds(); for (int i = 0; i < siblingIds.size(); i++) { onNextItem(i, siblingIds); final ArrayList<Uri> uris = new ArrayList<Uri>(); final int documentLocation = collectViewableUris(uris); final Range<Integer> range = computeSiblingsRange(uris, documentLocation); ClipData clipData = null; ClipData.Item item; Uri uri; for (int i = range.getLower(); i <= range.getUpper(); i++) { uri = uris.get(i); item = new ClipData.Item(uri); if (DEBUG) Log.d(TAG, "Including file: " + uri); if (clipData == null) { clipData = new ClipData( "URIs", new String[] { ClipDescription.MIMETYPE_TEXT_URILIST }, item); } else { clipData.addItem(item); } intent.putExtra(Intent.EXTRA_INDEX, mDocumentLocation); intent.setClipData(mClipData); } intent.putExtra(Intent.EXTRA_INDEX, documentLocation); intent.setClipData(clipData); return intent; } else { Loading @@ -96,39 +112,63 @@ final class QuickViewIntentBuilder { return null; } private boolean hasRegisteredHandler(Intent intent) { // Try to resolve the intent. If a matching app isn't installed, it won't resolve. return intent.resolveActivity(mPkgManager) != null; } private int collectViewableUris(ArrayList<Uri> uris) { final List<String> siblingIds = mModel.getModelIds(); uris.ensureCapacity(siblingIds.size()); private void onNextItem(int index, List<String> siblingIds) { final Cursor cursor = mModel.getItem(siblingIds.get(index)); int documentLocation = 0; Cursor cursor; String mimeType; String id; String authority; Uri uri; if (cursor == null) { return; } // Cursor's are not guaranteed to be immutable. Hence, traverse it only once. for (int i = 0; i < siblingIds.size(); i++) { cursor = mModel.getItem(siblingIds.get(i)); String mimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE); mimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE); if (Document.MIME_TYPE_DIR.equals(mimeType)) { return; continue; } String id = getCursorString(cursor, Document.COLUMN_DOCUMENT_ID); String authority = getCursorString(cursor, RootCursorWrapper.COLUMN_AUTHORITY); Uri uri = DocumentsContract.buildDocumentUri(authority, id); if (DEBUG) Log.d(TAG, "Including file[" + id + "] @ " + uri); id = getCursorString(cursor, Document.COLUMN_DOCUMENT_ID); authority = getCursorString(cursor, RootCursorWrapper.COLUMN_AUTHORITY); uri = DocumentsContract.buildDocumentUri(authority, id); if (id.equals(mDocument.documentId)) { if (DEBUG) Log.d(TAG, "Found starting point for QV. " + index); mDocumentLocation = index; if (DEBUG) Log.d(TAG, "Found starting point for QV. " + i); documentLocation = i; } ClipData.Item item = new ClipData.Item(uri); if (mClipData == null) { mClipData = new ClipData( "URIs", new String[]{ClipDescription.MIMETYPE_TEXT_URILIST}, item); uris.add(uri); } return documentLocation; } private static Range<Integer> computeSiblingsRange(List<Uri> uris, int documentLocation) { // Restrict number of siblings to avoid hitting the IPC limit. // TODO: Remove this restriction once ClipData can hold an arbitrary number of // items. int firstSibling; int lastSibling; if (documentLocation < uris.size() / 2) { firstSibling = Math.max(0, documentLocation - MAX_CLIP_ITEMS / 2); lastSibling = Math.min(uris.size() - 1, firstSibling + MAX_CLIP_ITEMS - 1); } else { mClipData.addItem(item); lastSibling = Math.min(uris.size() - 1, documentLocation + MAX_CLIP_ITEMS / 2); firstSibling = Math.max(0, lastSibling - MAX_CLIP_ITEMS + 1); } if (DEBUG) Log.d(TAG, "Copmuted siblings from index: " + firstSibling + " to: " + lastSibling); return new Range(firstSibling, lastSibling); } private boolean hasRegisteredHandler(Intent intent) { // Try to resolve the intent. If a matching app isn't installed, it won't resolve. return intent.resolveActivity(mPkgManager) != null; } }