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

This commit is contained in:
Steve McKay
2016-02-17 23:40:58 +00:00
committed by Android (Google) Code Review
6 changed files with 82 additions and 31 deletions

View File

@@ -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

View File

@@ -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:

View File

@@ -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();

View File

@@ -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

View File

@@ -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;

View File

@@ -52,7 +52,7 @@ public class FilesActivityUiTest extends ActivityTest<FilesActivity> {
"Videos",
"Audio",
"Downloads",
"Home",
"Documents",
ROOT_0_ID,
ROOT_1_ID);
}
@@ -64,11 +64,11 @@ public class FilesActivityUiTest extends ActivityTest<FilesActivity> {
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 {