Loading packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java +10 −3 Original line number Diff line number Diff line Loading @@ -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); } } Loading @@ -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); Loading Loading @@ -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); } } } Loading Loading @@ -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 Loading packages/DocumentsUI/src/com/android/documentsui/PickFragment.java +11 −4 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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. Loading @@ -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; Loading Loading @@ -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(); Loading @@ -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: Loading packages/DocumentsUI/src/com/android/documentsui/State.java +11 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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(); Loading packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java +43 −14 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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 Loading packages/DocumentsUI/src/com/android/documentsui/services/FileOperationService.java +4 −5 Original line number Diff line number Diff line Loading @@ -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, Loading @@ -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 Loading
packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java +10 −3 Original line number Diff line number Diff line Loading @@ -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); } } Loading @@ -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); Loading Loading @@ -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); } } } Loading Loading @@ -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 Loading
packages/DocumentsUI/src/com/android/documentsui/PickFragment.java +11 −4 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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. Loading @@ -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; Loading Loading @@ -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(); Loading @@ -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: Loading
packages/DocumentsUI/src/com/android/documentsui/State.java +11 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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(); Loading
packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java +43 −14 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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 Loading
packages/DocumentsUI/src/com/android/documentsui/services/FileOperationService.java +4 −5 Original line number Diff line number Diff line Loading @@ -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, Loading @@ -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