Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 46d57bd8 authored by Steve McKay's avatar Steve McKay Committed by Android (Google) Code Review
Browse files

Merge "Do more work off main thread."

parents 1e9d0601 ab7865cd
Loading
Loading
Loading
Loading
+138 −104
Original line number Diff line number Diff line
@@ -516,37 +516,39 @@ public class DirectoryFragment extends Fragment {
        @Override
        public boolean onActionItemClicked(final ActionMode mode, MenuItem item) {

            // TODO: Call `getSelectedDocuments` in an AsyncTask to avoid UI jank.
            List<DocumentInfo> docs = getSelectedDocuments();
            // ListView returns a reference to its internal selection container,
            // which will get cleared when we cancel action mode. So we
            // make a defensive clone here.
            final SparseBooleanArray selected = mCurrentView.getCheckedItemPositions().clone();

            final int id = item.getItemId();
            if (id == R.id.menu_open) {
                BaseActivity.get(DirectoryFragment.this).onDocumentsPicked(docs);
                openDocuments(selected);
                mode.finish();
                return true;

            } else if (id == R.id.menu_share) {
                onShareDocuments(docs);
                shareDocuments(selected);
                mode.finish();
                return true;

            } else if (id == R.id.menu_delete) {
                onDeleteDocuments(docs);
                deleteDocuments(selected);
                mode.finish();
                return true;

            } else if (id == R.id.menu_copy_to) {
                onTransferDocuments(docs, CopyService.TRANSFER_MODE_COPY);
                transferDocuments(selected, CopyService.TRANSFER_MODE_COPY);
                mode.finish();
                return true;

            } else if (id == R.id.menu_move_to) {
                onTransferDocuments(docs, CopyService.TRANSFER_MODE_MOVE);
                transferDocuments(selected, CopyService.TRANSFER_MODE_MOVE);
                mode.finish();
                return true;

            } else if (id == R.id.menu_copy_to_clipboard) {
                copySelectedToClipboard();
                copySelectionToClipboard(selected);
                mode.finish();
                return true;

@@ -602,7 +604,20 @@ public class DirectoryFragment extends Fragment {
        }
    };

    private void onShareDocuments(List<DocumentInfo> docs) {
    private void openDocuments(final SparseBooleanArray selected) {
        new GetDocumentsTask() {
            @Override
            void onDocumentsReady(List<DocumentInfo> docs) {
                // TODO: Implement support in standalone for opening multiple docs.
                BaseActivity.get(DirectoryFragment.this).onDocumentsPicked(docs);
            }
        }.execute(selected);
    }

    private void shareDocuments(final SparseBooleanArray selected) {
        new GetDocumentsTask() {
            @Override
            void onDocumentsReady(List<DocumentInfo> docs) {
                Intent intent;

                // Filter out directories - those can't be shared.
@@ -644,11 +659,16 @@ public class DirectoryFragment extends Fragment {
                intent = Intent.createChooser(intent, getActivity().getText(R.string.share_via));
                startActivity(intent);
            }
        }.execute(selected);
    }

    private void onDeleteDocuments(List<DocumentInfo> docs) {
    private void deleteDocuments(final SparseBooleanArray selected) {
        final Context context = getActivity();
        final ContentResolver resolver = context.getContentResolver();

        new GetDocumentsTask() {
            @Override
            void onDocumentsReady(List<DocumentInfo> docs) {
                boolean hadTrouble = false;
                for (DocumentInfo doc : docs) {
                    if (!doc.isDeleteSupported()) {
@@ -671,13 +691,16 @@ public class DirectoryFragment extends Fragment {
                }

                if (hadTrouble) {
            Toast.makeText(context, R.string.toast_failed_delete, Toast.LENGTH_SHORT).show();
                    Toast.makeText(
                            context,
                            R.string.toast_failed_delete,
                            Toast.LENGTH_SHORT).show();
                }
            }
        }.execute(selected);
    }

    private void onTransferDocuments(List<DocumentInfo> docs, int mode) {
        getDisplayState(this).selectedDocumentsForCopy = docs;

    private void transferDocuments(final SparseBooleanArray selected, final int mode) {
        // Pop up a dialog to pick a destination.  This is inadequate but works for now.
        // TODO: Implement a picker that is to spec.
        final Intent intent = new Intent(
@@ -685,6 +708,12 @@ public class DirectoryFragment extends Fragment {
                Uri.EMPTY,
                getActivity(),
                DocumentsActivity.class);

        new GetDocumentsTask() {
            @Override
            void onDocumentsReady(List<DocumentInfo> docs) {
                getDisplayState(DirectoryFragment.this).selectedDocumentsForCopy = docs;

                boolean directoryCopy = false;
                for (DocumentInfo info : docs) {
                    if (Document.MIME_TYPE_DIR.equals(info.mimeType)) {
@@ -696,6 +725,8 @@ public class DirectoryFragment extends Fragment {
                intent.putExtra(CopyService.EXTRA_TRANSFER_MODE, mode);
                startActivityForResult(intent, REQUEST_COPY_DESTINATION);
            }
        }.execute(selected);
    }

    private static State getDisplayState(Fragment fragment) {
        return ((BaseActivity) fragment.getActivity()).getDisplayState();
@@ -1309,34 +1340,21 @@ public class DirectoryFragment extends Fragment {
    }

    void copySelectedToClipboard() {
        // ListView returns a reference to its internal selection container,
        // which will get cleared when we cancel action mode. So we
        // make a defensive clone here.
        //
        // Furthermore, we don't want to call this from within the async task for
        // basically the same reason...when mode is cancelled, selection is cleared.
        final SparseBooleanArray selection = mCurrentView.getCheckedItemPositions().clone();
        copySelectionToClipboard(mCurrentView.getCheckedItemPositions().clone());
    }

        new AsyncTask<Void, Void, List<DocumentInfo>>() {
            protected List<DocumentInfo> doInBackground(Void... params) {
                List<DocumentInfo> docs = getItemsAsDocuments(selection);
                if (!docs.isEmpty()) {
    void copySelectionToClipboard(SparseBooleanArray selected) {
        new GetDocumentsTask() {
            @Override
            void onDocumentsReady(List<DocumentInfo> docs) {
                mClipper.clipDocuments(docs);
                }
                return docs;
            };
            protected void onPostExecute(List<DocumentInfo> docs) {
                if (docs.isEmpty()) {
                    Log.i(TAG, "Skipped populating clipboard with empty selection.");
                    return;
                }
                Activity activity = getActivity();
                Toast.makeText(activity,
                        activity.getResources().getQuantityString(
                                R.plurals.clipboard_files_clipped, docs.size(), docs.size()),
                                Toast.LENGTH_SHORT).show();
            };
        }.execute();
            }
        }.execute(selected);
    }

    void pasteFromClipboard() {
@@ -1344,10 +1362,6 @@ public class DirectoryFragment extends Fragment {
        getActivity().invalidateOptionsMenu();
    }

    private ClipboardManager getClipboardManager() {
        return (ClipboardManager)getActivity().getSystemService(Context.CLIPBOARD_SERVICE);
    }

    /**
     * Returns true if the list of files can be copied to destination. Note that this
     * is a policy check only. Currently the method does not attempt to verify
@@ -1526,6 +1540,26 @@ public class DirectoryFragment extends Fragment {
        void updateActionMenu(Menu menu, int dirType);
    }

    /**
     * Abstract task providing support for loading documents *off*
     * the main thread. And if it isn't obvious, creating a list
     * of documents (especially large lists) can be pretty expensive.
     */
    private abstract class GetDocumentsTask
            extends AsyncTask<SparseBooleanArray, Void, List<DocumentInfo>> {
        @Override
        protected final List<DocumentInfo> doInBackground(SparseBooleanArray... selected) {
            return getItemsAsDocuments(selected[0]);
        }

        @Override
        protected final void onPostExecute(List<DocumentInfo> docs) {
            onDocumentsReady(docs);
        }

        abstract void onDocumentsReady(List<DocumentInfo> docs);
    }

    /**
     * Provides support for Platform specific specializations of DirectoryFragment.
     */