Improvements to Copy/Move flow.
- Always open drawer for copy/move operations.
- Set title to match operation.
- Update button to say "move" for move operations.
- Other minor fixes.
Also fix "Home" tests broken by ag/867110
Bug: 26506479
Change-Id: I3ccb4ddc72be0a21b91744bcb610c1ca490ac30c
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
index d0bb7e0..29bb5e4 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
@@ -134,9 +134,13 @@
}
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 @@
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 @@
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 @@
// 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
diff --git a/packages/DocumentsUI/src/com/android/documentsui/PickFragment.java b/packages/DocumentsUI/src/com/android/documentsui/PickFragment.java
index bbf4682..287c904 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/PickFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/PickFragment.java
@@ -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.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 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 @@
/**
* @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 @@
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:
diff --git a/packages/DocumentsUI/src/com/android/documentsui/State.java b/packages/DocumentsUI/src/com/android/documentsui/State.java
index 7dca8a7..81a0635 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/State.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/State.java
@@ -30,6 +30,7 @@
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 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();
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
index 4233b36..85a517a 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
@@ -101,6 +101,7 @@
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 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 @@
}
@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);
@@ -804,25 +815,43 @@
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
diff --git a/packages/DocumentsUI/src/com/android/documentsui/services/FileOperationService.java b/packages/DocumentsUI/src/com/android/documentsui/services/FileOperationService.java
index 3a025c2..05a3f11 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/services/FileOperationService.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/services/FileOperationService.java
@@ -71,11 +71,6 @@
// 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 @@
})
@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;
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/FilesActivityUiTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/FilesActivityUiTest.java
index 609dc0c..95515db 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/FilesActivityUiTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/FilesActivityUiTest.java
@@ -52,7 +52,7 @@
"Videos",
"Audio",
"Downloads",
- "Home",
+ "Documents",
ROOT_0_ID,
ROOT_1_ID);
}
@@ -64,11 +64,11 @@
bot.assertHasDocuments("file0.log", "file1.png", "file2.csv");
}
- public void testLoadsHomeByDefault() throws Exception {
+ public void testLoadsHomeDirectoryByDefault() throws Exception {
initTestFiles();
device.waitForIdle();
- bot.assertWindowTitle("Home");
+ bot.assertWindowTitle("Documents");
}
public void testRootClickSetsWindowTitle() throws Exception {