Merge "Improvements to Copy/Move flow." into nyc-dev
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user