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

Commit 07197bb4 authored by Steve McKay's avatar Steve McKay Committed by android-build-merger
Browse files

Merge "Improvements to Copy/Move flow." into nyc-dev

am: 9a0fc1f6

* commit '9a0fc1f6':
  Improvements to Copy/Move flow.
parents 07801468 9a0fc1f6
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -134,9 +134,13 @@ public class DocumentsActivity extends BaseActivity {
        }

        if (state.action == ACTION_PICK_COPY_DESTINATION) {
            // Indicates that a copy operation (or move) includes a directory.
            // Why? Directory creation isn't supported by some roots (like Downloads).
            // This allows us to restrict available roots to just those with support.
            state.directoryCopy = intent.getBooleanExtra(
                    Shared.EXTRA_DIRECTORY_COPY, false);
            state.transferMode = intent.getIntExtra(FileOperationService.EXTRA_OPERATION,
            state.copyOperationSubType = intent.getIntExtra(
                    FileOperationService.EXTRA_OPERATION,
                    FileOperationService.OPERATION_COPY);
        }
    }
@@ -156,6 +160,9 @@ public class DocumentsActivity extends BaseActivity {
        if (external && mState.action == ACTION_GET_CONTENT) {
            showDrawer = true;
        }
        if (mState.action == ACTION_PICK_COPY_DESTINATION) {
            showDrawer = true;
        }

        if (showDrawer) {
            mNavigator.revealRootsDrawer(true);
@@ -307,7 +314,7 @@ public class DocumentsActivity extends BaseActivity {
            mState.action == ACTION_PICK_COPY_DESTINATION) {
            final PickFragment pick = PickFragment.get(fm);
            if (pick != null) {
                pick.setPickTarget(mState.action, mState.transferMode, cwd);
                pick.setPickTarget(mState.action, mState.copyOperationSubType, cwd);
            }
        }
    }
@@ -420,7 +427,7 @@ public class DocumentsActivity extends BaseActivity {
            // Picking a copy destination is only used internally by us, so we
            // don't need to extend permissions to the caller.
            intent.putExtra(Shared.EXTRA_STACK, (Parcelable) mState.stack);
            intent.putExtra(FileOperationService.EXTRA_OPERATION, mState.transferMode);
            intent.putExtra(FileOperationService.EXTRA_OPERATION, mState.copyOperationSubType);
        } else {
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
+11 −4
Original line number Diff line number Diff line
@@ -16,6 +16,10 @@

package com.android.documentsui;

import static com.android.documentsui.services.FileOperationService.OPERATION_COPY;
import static com.android.documentsui.services.FileOperationService.OPERATION_MOVE;
import static com.android.internal.util.Preconditions.checkArgument;

import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
@@ -27,6 +31,7 @@ import android.view.ViewGroup;
import android.widget.Button;

import com.android.documentsui.model.DocumentInfo;
import com.android.documentsui.services.FileOperationService.OpType;

/**
 * Display pick confirmation bar, usually for selecting a directory.
@@ -35,7 +40,7 @@ public class PickFragment extends Fragment {
    public static final String TAG = "PickFragment";

    private int mAction;
    private int mTransferMode;
    private @OpType int mOperationType;
    private DocumentInfo mPickTarget;
    private View mContainer;
    private Button mPick;
@@ -92,9 +97,10 @@ public class PickFragment extends Fragment {
    /**
     * @param action Which action defined in State is the picker shown for.
     */
    public void setPickTarget(int action, int transferMode, DocumentInfo pickTarget) {
    public void setPickTarget(int action, @OpType int operationType, DocumentInfo pickTarget) {
        checkArgument(operationType == OPERATION_COPY || operationType == OPERATION_MOVE);
        mAction = action;
        mTransferMode = transferMode;
        mOperationType = operationType;
        mPickTarget = pickTarget;
        if (mContainer != null) {
            updateView();
@@ -111,7 +117,8 @@ public class PickFragment extends Fragment {
                mCancel.setVisibility(View.GONE);
                break;
            case State.ACTION_PICK_COPY_DESTINATION:
                mPick.setText(R.string.button_copy);
                mPick.setText(mOperationType == OPERATION_MOVE
                        ? R.string.button_move : R.string.button_copy);
                mCancel.setVisibility(View.VISIBLE);
                break;
            default:
+11 −2
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import com.android.documentsui.model.DocumentInfo;
import com.android.documentsui.model.DocumentStack;
import com.android.documentsui.model.DurableUtils;
import com.android.documentsui.model.RootInfo;
import com.android.documentsui.services.FileOperationService.OpType;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -83,10 +84,18 @@ public class State implements android.os.Parcelable {
    public boolean forceAdvanced;
    public boolean showAdvanced;
    public boolean restored;

    // Indicates that a copy operation (or move) includes a directory.
    // Why? Directory creation isn't supported by some roots (like Downloads).
    // This allows us to restrict available roots to just those with support.
    public boolean directoryCopy;
    public boolean openableOnly;
    /** Transfer mode for file copy/move operations. */
    public int transferMode;

    /**
     * This is basically a sub-type for the copy operation. It can be either COPY or MOVE.
     * The only legal values are: OPERATION_COPY, OPERATION_MOVE.
     */
    public @OpType int copyOperationSubType;

    /** Current user navigation stack; empty implies recents. */
    public DocumentStack stack = new DocumentStack();
+43 −14
Original line number Diff line number Diff line
@@ -101,6 +101,7 @@ import com.android.documentsui.model.RootInfo;
import com.android.documentsui.services.FileOperationService;
import com.android.documentsui.services.FileOperationService.OpType;
import com.android.documentsui.services.FileOperations;

import com.google.common.collect.Lists;

import java.lang.annotation.Retention;
@@ -130,6 +131,11 @@ public class DirectoryFragment extends Fragment implements DocumentsAdapter.Envi
    public static final int ANIM_LEAVE = 3;
    public static final int ANIM_ENTER = 4;

    @IntDef(flag = true, value = {
            REQUEST_COPY_DESTINATION
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface RequestCode {}
    public static final int REQUEST_COPY_DESTINATION = 1;

    static final boolean DEBUG_ENABLE_DND = true;
@@ -377,19 +383,24 @@ public class DirectoryFragment extends Fragment implements DocumentsAdapter.Envi
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        // There's only one request code right now. Replace this with a switch statement or
        // something more scalable when more codes are added.
        if (requestCode != REQUEST_COPY_DESTINATION) {
            return;
    public void onActivityResult(@RequestCode int requestCode, int resultCode, Intent data) {
        switch(requestCode) {
            case REQUEST_COPY_DESTINATION:
                handleCopyResult(resultCode, data);
                break;
            default:
                throw new UnsupportedOperationException("Unknown request code: " + requestCode);
        }
    }

    private void handleCopyResult(int resultCode, Intent data) {
        if (resultCode == Activity.RESULT_CANCELED || data == null) {
            // User pressed the back button or otherwise cancelled the destination pick. Don't
            // proceed with the copy.
            return;
        }

        int operationType = data.getIntExtra(
        @OpType int operationType = data.getIntExtra(
                FileOperationService.EXTRA_OPERATION,
                FileOperationService.OPERATION_COPY);

@@ -808,25 +819,43 @@ public class DirectoryFragment extends Fragment implements DocumentsAdapter.Envi
                getActivity(),
                DocumentsActivity.class);

        // Set an appropriate title on the drawer when it is shown in the picker.
        // Coupled with the fact that we auto-open the drawer for copy/move operations
        // it should basically be the thing people see first.
        int drawerTitleId = mode == FileOperationService.OPERATION_MOVE
                ? R.string.menu_move : R.string.menu_copy;
        intent.putExtra(DocumentsContract.EXTRA_PROMPT, getResources().getString(drawerTitleId));

        new GetDocumentsTask() {
            @Override
            void onDocumentsReady(List<DocumentInfo> docs) {
                // TODO: Can this move to Fragment bundle state?
                getDisplayState().selectedDocumentsForCopy = docs;

                boolean directoryCopy = false;
                for (DocumentInfo info : docs) {
                    if (Document.MIME_TYPE_DIR.equals(info.mimeType)) {
                        directoryCopy = true;
                        break;
                    }
                }
                intent.putExtra(Shared.EXTRA_DIRECTORY_COPY, directoryCopy);
                // Determine if there is a directory in the set of documents
                // to be copied? Why? Directory creation isn't supported by some roots
                // (like Downloads). This informs DocumentsActivity (the "picker")
                // to restrict available roots to just those with support.
                intent.putExtra(Shared.EXTRA_DIRECTORY_COPY, hasDirectory(docs));
                intent.putExtra(FileOperationService.EXTRA_OPERATION, mode);

                // This just identifies the type of request...we'll check it
                // when we reveive a response.
                startActivityForResult(intent, REQUEST_COPY_DESTINATION);
            }

        }.execute(selected);
    }

    private static boolean hasDirectory(List<DocumentInfo> docs) {
        for (DocumentInfo info : docs) {
            if (Document.MIME_TYPE_DIR.equals(info.mimeType)) {
                return true;
            }
        }
        return false;
    }

    private void renameDocuments(Selection selected) {
        // Batch renaming not supported
        // Rename option is only available in menu when 1 document selected
+4 −5
Original line number Diff line number Diff line
@@ -71,11 +71,6 @@ public class FileOperationService extends Service implements Job.Listener {
    // such case, this needs to be replaced with pairs of parent and child.
    public static final String EXTRA_SRC_PARENT = "com.android.documentsui.SRC_PARENT";

    public static final int OPERATION_UNKNOWN = -1;
    public static final int OPERATION_COPY = 1;
    public static final int OPERATION_MOVE = 2;
    public static final int OPERATION_DELETE = 3;

    @IntDef(flag = true, value = {
            OPERATION_UNKNOWN,
            OPERATION_COPY,
@@ -84,6 +79,10 @@ public class FileOperationService extends Service implements Job.Listener {
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface OpType {}
    public static final int OPERATION_UNKNOWN = -1;
    public static final int OPERATION_COPY = 1;
    public static final int OPERATION_MOVE = 2;
    public static final int OPERATION_DELETE = 3;

    // TODO: Move it to a shared file when more operations are implemented.
    public static final int FAILURE_COPY = 1;
Loading