diff options
author | 2017-01-27 16:29:30 +0900 | |
---|---|---|
committer | 2017-01-31 13:21:58 +0900 | |
commit | 4f2254941c4e495e0653bd2773fc8a2ecc6daef3 (patch) | |
tree | ce32e51d771786997e3134d06a820334a0314589 | |
parent | a903c2cdad65d0fe163a4152faa6bd05e2888b22 (diff) |
Add boilerplate for compressing in DocumentsUI.
This CL adds strings, constants, and classes for compressing, which
for now do the same as copying.
Along the way it does the same to extracting.
Test: Tested manually.
Bug: 20822019
Change-Id: I9866166c635befae59b3fff13125bd563f71936a
-rw-r--r-- | res/menu/mode_directory.xml | 5 | ||||
-rw-r--r-- | res/values/strings.xml | 21 | ||||
-rw-r--r-- | src/com/android/documentsui/MenuManager.java | 5 | ||||
-rw-r--r-- | src/com/android/documentsui/Metrics.java | 56 | ||||
-rw-r--r-- | src/com/android/documentsui/OperationDialogFragment.java | 6 | ||||
-rw-r--r-- | src/com/android/documentsui/base/State.java | 6 | ||||
-rw-r--r-- | src/com/android/documentsui/dirlist/DirectoryFragment.java | 54 | ||||
-rw-r--r-- | src/com/android/documentsui/files/MenuManager.java | 8 | ||||
-rw-r--r-- | src/com/android/documentsui/picker/PickFragment.java | 26 | ||||
-rw-r--r-- | src/com/android/documentsui/services/FileOperation.java | 86 | ||||
-rw-r--r-- | src/com/android/documentsui/services/FileOperationService.java | 10 | ||||
-rw-r--r-- | src/com/android/documentsui/ui/DialogController.java | 6 | ||||
-rw-r--r-- | src/com/android/documentsui/ui/Snackbars.java | 10 | ||||
-rw-r--r-- | tests/common/com/android/documentsui/testing/TestMenu.java | 1 | ||||
-rw-r--r-- | tests/unit/com/android/documentsui/files/MenuManagerTest.java | 7 |
15 files changed, 289 insertions, 18 deletions
diff --git a/res/menu/mode_directory.xml b/res/menu/mode_directory.xml index 7880aea74..48944409d 100644 --- a/res/menu/mode_directory.xml +++ b/res/menu/mode_directory.xml @@ -39,6 +39,11 @@ android:showAsAction="never" android:visible="false" /> <item + android:id="@+id/menu_compress_to" + android:title="@string/menu_compress" + android:showAsAction="never" + android:visible="false" /> + <item android:id="@+id/menu_extract_to" android:icon="@drawable/ic_menu_extract" android:title="@string/menu_extract" diff --git a/res/values/strings.xml b/res/values/strings.xml index 0d9cadf66..f863a3169 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -52,6 +52,8 @@ <string name="menu_copy">Copy to\u2026</string> <!-- Menu item title that moves the selected documents [CHAR LIMIT=28] --> <string name="menu_move">Move to\u2026</string> + <!-- Menu item title that compresses the selected documents [CHAR LIMIT=28] --> + <string name="menu_compress">Compress to\u2026</string> <!-- Menu item title that extracts the selected documents [CHAR LIMIT=28] --> <string name="menu_extract">Extract to\u2026</string> <!-- Menu item that renames the selected document [CHAR LIMIT=28] --> @@ -79,6 +81,10 @@ <string name="button_select">Select</string> <!-- Button label that copies files to the current directory [CHAR LIMIT=24] --> <string name="button_copy">Copy</string> + <!-- Button label that compresses files to the current directory [CHAR LIMIT=24] --> + <string name="button_compress">Compress</string> + <!-- Button label that extracts files to the current directory [CHAR LIMIT=24] --> + <string name="button_extract">Extract</string> <!-- Button label that moves files to the current directory [CHAR LIMIT=24] --> <string name="button_move">Move</string> <!-- Button label that hides the error bar [CHAR LIMIT=24] --> @@ -153,6 +159,17 @@ <item quantity="one">Copying <xliff:g id="count" example="1">%1$d</xliff:g> file.</item> <item quantity="other">Copying <xliff:g id="count" example="3">%1$d</xliff:g> files.</item> </plurals> + <!-- Toast shown when a file compressing is kicked off --> + <plurals name="compress_begin"> + <item quantity="one">Compressing <xliff:g id="count" example="1">%1$d</xliff:g> file.</item> + <item quantity="other">Compressing <xliff:g id="count" example="3">%1$d</xliff:g> files.</item> + </plurals> + <!-- Toast shown when a file extracting is kicked off --> + <plurals name="extract_begin"> + <item quantity="one">Extracting <xliff:g id="count" example="1">%1$d</xliff:g> file.</item> + <item quantity="other">Extracting <xliff:g id="count" example="3">%1$d</xliff:g> files.</item> + </plurals> + <!-- Toast shown when a file move is kicked off --> <plurals name="move_begin"> <item quantity="one">Moving <xliff:g id="count" example="1">%1$d</xliff:g> file.</item> <item quantity="other">Moving <xliff:g id="count" example="3">%1$d</xliff:g> files.</item> @@ -193,6 +210,10 @@ <string name="close">Close</string> <!-- Contents of the copying failure alert dialog. [CHAR LIMIT=48] --> <string name="copy_failure_alert_content">These files weren\u2019t copied: <xliff:g id="list">%1$s</xliff:g></string> + <!-- Contents of the compressing failure alert dialog. [CHAR LIMIT=48] --> + <string name="compress_failure_alert_content">These files weren\u2019t compressed: <xliff:g id="list">%1$s</xliff:g></string> + <!-- Contents of the extracting failure alert dialog. [CHAR LIMIT=48] --> + <string name="extract_failure_alert_content">These files weren\u2019t extracted: <xliff:g id="list">%1$s</xliff:g></string> <!-- Contents of the moving failure alert dialog. [CHAR LIMIT=48] --> <string name="move_failure_alert_content">These files weren\u2019t moved: <xliff:g id="list">%1$s</xliff:g></string> <!-- Message shown to users when an operation to delete one or more files has failed. Presented in a dialog. [CHAR LIMIT=48] --> diff --git a/src/com/android/documentsui/MenuManager.java b/src/com/android/documentsui/MenuManager.java index 1aa78c2ae..17f86669a 100644 --- a/src/com/android/documentsui/MenuManager.java +++ b/src/com/android/documentsui/MenuManager.java @@ -60,6 +60,7 @@ public abstract class MenuManager { updateSelectAll(menu.findItem(R.id.menu_select_all)); updateMoveTo(menu.findItem(R.id.menu_move_to), selection); updateCopyTo(menu.findItem(R.id.menu_copy_to), selection); + updateCompressTo(menu.findItem(R.id.menu_compress_to), selection); updateExtractTo(menu.findItem(R.id.menu_extract_to), selection); Menus.disableHiddenItems(menu); @@ -270,6 +271,10 @@ public abstract class MenuManager { copyTo.setVisible(false); } + protected void updateCompressTo(MenuItem compressTo, SelectionDetails selectionDetails) { + compressTo.setVisible(false); + } + protected void updateExtractTo(MenuItem extractTo, SelectionDetails selectionDetails) { extractTo.setVisible(false); } diff --git a/src/com/android/documentsui/Metrics.java b/src/com/android/documentsui/Metrics.java index 425d125c1..b5d9fb0f1 100644 --- a/src/com/android/documentsui/Metrics.java +++ b/src/com/android/documentsui/Metrics.java @@ -163,10 +163,18 @@ public final class Metrics { // Do not change or rearrange these values, that will break historical data. Only add to the // list. // Do not use negative numbers or zero; clearcut only handles positive integers. + // + // Next available ID: 112 private static final int FILEOP_OTHER = 1; // any file operation not listed below private static final int FILEOP_COPY_INTRA_PROVIDER = 2; // Copy within a provider private static final int FILEOP_COPY_SYSTEM_PROVIDER = 3; // Copy to a system provider. private static final int FILEOP_COPY_EXTERNAL_PROVIDER = 4; // Copy to a 3rd-party provider. + private static final int FILEOP_COMPRESS_INTRA_PROVIDER = 106; // Compres within a provider + private static final int FILEOP_COMPRESS_SYSTEM_PROVIDER = 107; // Compress to a system provider. + private static final int FILEOP_COMPRESS_EXTERNAL_PROVIDER = 108; // Compress to a 3rd-party provider. + private static final int FILEOP_EXTRACT_INTRA_PROVIDER = 109; // Extract within a provider + private static final int FILEOP_EXTRACT_SYSTEM_PROVIDER = 110; // Extract to a system provider. + private static final int FILEOP_EXTRACT_EXTERNAL_PROVIDER = 111; // Extract to a 3rd-party provider. private static final int FILEOP_MOVE_INTRA_PROVIDER = 5; // Move within a provider. private static final int FILEOP_MOVE_SYSTEM_PROVIDER = 6; // Move to a system provider. private static final int FILEOP_MOVE_EXTERNAL_PROVIDER = 7; // Move to a 3rd-party provider. @@ -177,6 +185,8 @@ public final class Metrics { private static final int FILEOP_DELETE_ERROR = 101; private static final int FILEOP_MOVE_ERROR = 102; private static final int FILEOP_COPY_ERROR = 103; + private static final int FILEOP_COMPRESS_ERROR = 112; + private static final int FILEOP_EXTRACT_ERROR = 113; private static final int FILEOP_RENAME_ERROR = 104; private static final int FILEOP_CREATE_DIR_ERROR = 105; @@ -185,6 +195,12 @@ public final class Metrics { FILEOP_COPY_INTRA_PROVIDER, FILEOP_COPY_SYSTEM_PROVIDER, FILEOP_COPY_EXTERNAL_PROVIDER, + FILEOP_COMPRESS_INTRA_PROVIDER, + FILEOP_COMPRESS_SYSTEM_PROVIDER, + FILEOP_COMPRESS_EXTERNAL_PROVIDER, + FILEOP_EXTRACT_INTRA_PROVIDER, + FILEOP_EXTRACT_SYSTEM_PROVIDER, + FILEOP_EXTRACT_EXTERNAL_PROVIDER, FILEOP_MOVE_INTRA_PROVIDER, FILEOP_MOVE_SYSTEM_PROVIDER, FILEOP_MOVE_EXTERNAL_PROVIDER, @@ -193,6 +209,8 @@ public final class Metrics { FILEOP_CREATE_DIR, FILEOP_OTHER_ERROR, FILEOP_COPY_ERROR, + FILEOP_COMPRESS_ERROR, + FILEOP_EXTRACT_ERROR, FILEOP_MOVE_ERROR, FILEOP_DELETE_ERROR, FILEOP_RENAME_ERROR, @@ -206,14 +224,20 @@ public final class Metrics { // Do not change or rearrange these values, that will break historical data. Only add to the // list. // Do not use negative numbers or zero; clearcut only handles positive integers. + // + // Next available ID: 7 private static final int OPERATION_UNKNOWN = 1; private static final int OPERATION_COPY = 2; + private static final int OPERATION_COMPRESS = 5; + private static final int OPERATION_EXTRACT = 6; private static final int OPERATION_MOVE = 3; - private static final int OPERATION_DELETE= 4; + private static final int OPERATION_DELETE = 4; @IntDef(flag = true, value = { OPERATION_UNKNOWN, OPERATION_COPY, + OPERATION_COMPRESS, + OPERATION_EXTRACT, OPERATION_MOVE, OPERATION_DELETE }) @@ -267,6 +291,8 @@ public final class Metrics { // Do not change or rearrange these values, that will break historical data. Only add to the // list. // Do not use negative numbers or zero; clearcut only handles positive integers. + // + // Next available ID: 29 public static final int USER_ACTION_OTHER = 1; public static final int USER_ACTION_GRID = 2; public static final int USER_ACTION_LIST = 3; @@ -278,6 +304,8 @@ public final class Metrics { public static final int USER_ACTION_HIDE_SIZE = 9; public static final int USER_ACTION_SETTINGS = 10; public static final int USER_ACTION_COPY_TO = 11; + public static final int USER_ACTION_COMPRESS_TO = 27; + public static final int USER_ACTION_EXTRACT_TO = 28; public static final int USER_ACTION_MOVE_TO = 12; public static final int USER_ACTION_DELETE = 13; public static final int USER_ACTION_RENAME = 14; @@ -306,6 +334,8 @@ public final class Metrics { USER_ACTION_HIDE_SIZE, USER_ACTION_SETTINGS, USER_ACTION_COPY_TO, + USER_ACTION_COMPRESS_TO, + USER_ACTION_EXTRACT_TO, USER_ACTION_MOVE_TO, USER_ACTION_DELETE, USER_ACTION_RENAME, @@ -542,6 +572,12 @@ public final class Metrics { case FileOperationService.OPERATION_COPY: opCode = FILEOP_COPY_ERROR; break; + case FileOperationService.OPERATION_COMPRESS: + opCode = FILEOP_COMPRESS_ERROR; + break; + case FileOperationService.OPERATION_EXTRACT: + opCode = FILEOP_EXTRACT_ERROR; + break; case FileOperationService.OPERATION_DELETE: opCode = FILEOP_DELETE_ERROR; break; @@ -911,6 +947,24 @@ public final class Metrics { case PROVIDER_EXTERNAL: return FILEOP_COPY_EXTERNAL_PROVIDER; } + case FileOperationService.OPERATION_COMPRESS: + switch (providerType) { + case PROVIDER_INTRA: + return FILEOP_COMPRESS_INTRA_PROVIDER; + case PROVIDER_SYSTEM: + return FILEOP_COMPRESS_SYSTEM_PROVIDER; + case PROVIDER_EXTERNAL: + return FILEOP_COMPRESS_EXTERNAL_PROVIDER; + } + case FileOperationService.OPERATION_EXTRACT: + switch (providerType) { + case PROVIDER_INTRA: + return FILEOP_EXTRACT_INTRA_PROVIDER; + case PROVIDER_SYSTEM: + return FILEOP_EXTRACT_SYSTEM_PROVIDER; + case PROVIDER_EXTERNAL: + return FILEOP_EXTRACT_EXTERNAL_PROVIDER; + } case FileOperationService.OPERATION_MOVE: switch (providerType) { case PROVIDER_INTRA: diff --git a/src/com/android/documentsui/OperationDialogFragment.java b/src/com/android/documentsui/OperationDialogFragment.java index 6a763128d..9aa00692e 100644 --- a/src/com/android/documentsui/OperationDialogFragment.java +++ b/src/com/android/documentsui/OperationDialogFragment.java @@ -102,6 +102,12 @@ public class OperationDialogFragment extends DialogFragment { case FileOperationService.OPERATION_COPY: messageFormat = getString(R.string.copy_failure_alert_content); break; + case FileOperationService.OPERATION_COMPRESS: + messageFormat = getString(R.string.compress_failure_alert_content); + break; + case FileOperationService.OPERATION_EXTRACT: + messageFormat = getString(R.string.extract_failure_alert_content); + break; case FileOperationService.OPERATION_DELETE: messageFormat = getString(R.string.delete_failure_alert_content); break; diff --git a/src/com/android/documentsui/base/State.java b/src/com/android/documentsui/base/State.java index 43740ad18..cbadacd7d 100644 --- a/src/com/android/documentsui/base/State.java +++ b/src/com/android/documentsui/base/State.java @@ -92,8 +92,10 @@ public class State implements android.os.Parcelable { public boolean openableOnly; /** - * This is basically a sub-type for the copy operation. It can be either COPY or MOVE. - * The only legal values, if set, are: OPERATION_COPY, OPERATION_MOVE. Other pick + * This is basically a sub-type for the copy operation. It can be either COPY, + * COMPRESS, EXTRACT or MOVE. + * The only legal values, if set, are: OPERATION_COPY, OPERATION_COMPRESS, + * OPERATION_EXTRACT and OPERATION_MOVE. Other pick * operations don't use this. In those cases OPERATION_UNKNOWN is also legal. */ public @OpType int copyOperationSubType = FileOperationService.OPERATION_UNKNOWN; diff --git a/src/com/android/documentsui/dirlist/DirectoryFragment.java b/src/com/android/documentsui/dirlist/DirectoryFragment.java index 7360dc28b..9fad491be 100644 --- a/src/com/android/documentsui/dirlist/DirectoryFragment.java +++ b/src/com/android/documentsui/dirlist/DirectoryFragment.java @@ -614,14 +614,26 @@ public class DirectoryFragment extends Fragment return true; case R.id.menu_copy_to: - // TODO: Add a separate OPERATION_EXTRACT. - case R.id.menu_extract_to: transferDocuments(selection, FileOperationService.OPERATION_COPY); // TODO: Only finish selection mode if copy-to is not canceled. // Need to plum down into handling the way we do with deleteDocuments. mActionModeController.finishActionMode(); return true; + case R.id.menu_compress_to: + transferDocuments(selection, FileOperationService.OPERATION_COMPRESS); + // TODO: Only finish selection mode if compress-to is not canceled. + // Need to plum down into handling the way we do with deleteDocuments. + mActionModeController.finishActionMode(); + return true; + + case R.id.menu_extract_to: + transferDocuments(selection, FileOperationService.OPERATION_EXTRACT); + // TODO: Only finish selection mode if compress-to is not canceled. + // Need to plum down into handling the way we do with deleteDocuments. + mActionModeController.finishActionMode(); + return true; + case R.id.menu_move_to: // Exit selection mode first, so we avoid deselecting deleted documents. mActionModeController.finishActionMode(); @@ -710,10 +722,19 @@ public class DirectoryFragment extends Fragment } private void transferDocuments(final Selection selected, final @OpType int mode) { - if (mode == FileOperationService.OPERATION_COPY) { - Metrics.logUserAction(getContext(), Metrics.USER_ACTION_COPY_TO); - } else if (mode == FileOperationService.OPERATION_MOVE) { - Metrics.logUserAction(getContext(), Metrics.USER_ACTION_MOVE_TO); + switch (mode) { + case FileOperationService.OPERATION_COPY: + Metrics.logUserAction(getContext(), Metrics.USER_ACTION_COPY_TO); + break; + case FileOperationService.OPERATION_COMPRESS: + Metrics.logUserAction(getContext(), Metrics.USER_ACTION_COMPRESS_TO); + break; + case FileOperationService.OPERATION_EXTRACT: + Metrics.logUserAction(getContext(), Metrics.USER_ACTION_EXTRACT_TO); + break; + case FileOperationService.OPERATION_MOVE: + Metrics.logUserAction(getContext(), Metrics.USER_ACTION_MOVE_TO); + break; } // Pop up a dialog to pick a destination. This is inadequate but works for now. @@ -728,7 +749,7 @@ public class DirectoryFragment extends Fragment try { ClipStore clipStorage = DocumentsApplication.getClipStore(getContext()); srcs = UrisSupplier.create(selected, mModel::getItemUri, clipStorage); - } catch(IOException e) { + } catch (IOException e) { throw new RuntimeException("Failed to create uri supplier.", e); } @@ -742,8 +763,23 @@ public class DirectoryFragment extends Fragment // 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; + int drawerTitleId; + switch (mode) { + case FileOperationService.OPERATION_COPY: + drawerTitleId = R.string.menu_copy; + break; + case FileOperationService.OPERATION_COMPRESS: + drawerTitleId = R.string.menu_compress; + break; + case FileOperationService.OPERATION_EXTRACT: + drawerTitleId = R.string.menu_extract; + break; + case FileOperationService.OPERATION_MOVE: + drawerTitleId = R.string.menu_copy; + break; + default: + throw new UnsupportedOperationException("Unknown mode: " + mode); + } intent.putExtra(DocumentsContract.EXTRA_PROMPT, getResources().getString(drawerTitleId)); // Model must be accessed in UI thread, since underlying cursor is not threadsafe. diff --git a/src/com/android/documentsui/files/MenuManager.java b/src/com/android/documentsui/files/MenuManager.java index 75c02e6d8..f0acb3f7f 100644 --- a/src/com/android/documentsui/files/MenuManager.java +++ b/src/com/android/documentsui/files/MenuManager.java @@ -174,6 +174,14 @@ public final class MenuManager extends com.android.documentsui.MenuManager { } @Override + protected void updateCompressTo(MenuItem compressTo, SelectionDetails selectionDetails) { + compressTo.setVisible(true); + // Do not allow to compress already compressed files for simplicity. + compressTo.setEnabled(!selectionDetails.containsPartialFiles() && + !selectionDetails.canExtract()); + } + + @Override protected void updateExtractTo(MenuItem extractTo, SelectionDetails selectionDetails) { extractTo.setVisible(selectionDetails.canExtract()); } diff --git a/src/com/android/documentsui/picker/PickFragment.java b/src/com/android/documentsui/picker/PickFragment.java index 8eb3b4c51..23679364b 100644 --- a/src/com/android/documentsui/picker/PickFragment.java +++ b/src/com/android/documentsui/picker/PickFragment.java @@ -17,6 +17,9 @@ package com.android.documentsui.picker; import static com.android.documentsui.services.FileOperationService.OPERATION_DELETE; +import static com.android.documentsui.services.FileOperationService.OPERATION_COPY; +import static com.android.documentsui.services.FileOperationService.OPERATION_COMPRESS; +import static com.android.documentsui.services.FileOperationService.OPERATION_EXTRACT; import static com.android.documentsui.services.FileOperationService.OPERATION_MOVE; import static com.android.documentsui.services.FileOperationService.OPERATION_UNKNOWN; @@ -64,7 +67,8 @@ public class PickFragment extends Fragment { }; private int mAction; - // Only legal values are OPERATION_COPY, OPERATION_MOVE, and unset (OPERATION_UNKNOWN). + // Only legal values are OPERATION_COPY, OPERATION_COMPRESS, OPERATION_EXTRACT, + // OPERATION_MOVE, and unset (OPERATION_UNKNOWN). private @OpType int mCopyOperationSubType = OPERATION_UNKNOWN; private DocumentInfo mPickTarget; private View mContainer; @@ -148,8 +152,24 @@ public class PickFragment extends Fragment { mCancel.setVisibility(View.GONE); break; case State.ACTION_PICK_COPY_DESTINATION: - mPick.setText(mCopyOperationSubType == OPERATION_MOVE - ? R.string.button_move : R.string.button_copy); + int titleId; + switch (mCopyOperationSubType) { + case OPERATION_COPY: + titleId = R.string.button_copy; + break; + case OPERATION_COMPRESS: + titleId = R.string.button_compress; + break; + case OPERATION_EXTRACT: + titleId = R.string.button_extract; + break; + case OPERATION_MOVE: + titleId = R.string.button_move; + break; + default: + throw new UnsupportedOperationException(); + } + mPick.setText(titleId); mCancel.setVisibility(View.VISIBLE); break; default: diff --git a/src/com/android/documentsui/services/FileOperation.java b/src/com/android/documentsui/services/FileOperation.java index b2e40ea63..f5a3e2679 100644 --- a/src/com/android/documentsui/services/FileOperation.java +++ b/src/com/android/documentsui/services/FileOperation.java @@ -17,6 +17,8 @@ package com.android.documentsui.services; import static com.android.documentsui.services.FileOperationService.OPERATION_COPY; +import static com.android.documentsui.services.FileOperationService.OPERATION_COMPRESS; +import static com.android.documentsui.services.FileOperationService.OPERATION_EXTRACT; import static com.android.documentsui.services.FileOperationService.OPERATION_DELETE; import static com.android.documentsui.services.FileOperationService.OPERATION_MOVE; import static com.android.documentsui.services.FileOperationService.OPERATION_UNKNOWN; @@ -137,6 +139,86 @@ public abstract class FileOperation implements Parcelable { }; } + public static class CompressOperation extends FileOperation { + private CompressOperation(UrisSupplier srcs, DocumentStack destination) { + super(OPERATION_COMPRESS, srcs, destination); + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + + builder.append("CompressOperation{"); + super.appendInfoTo(builder); + builder.append("}"); + + return builder.toString(); + } + + // TODO: Replace CopyJob with CompressJob. + CopyJob createJob(Context service, Job.Listener listener, String id) { + throw new UnsupportedOperationException("Compressing not yet supported."); + } + + private CompressOperation(Parcel in) { + super(in); + } + + public static final Parcelable.Creator<CompressOperation> CREATOR = + new Parcelable.Creator<CompressOperation>() { + + @Override + public CompressOperation createFromParcel(Parcel source) { + return new CompressOperation(source); + } + + @Override + public CompressOperation[] newArray(int size) { + return new CompressOperation[size]; + } + }; + } + + public static class ExtractOperation extends FileOperation { + private ExtractOperation(UrisSupplier srcs, DocumentStack destination) { + super(OPERATION_EXTRACT, srcs, destination); + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + + builder.append("ExtractOperation{"); + super.appendInfoTo(builder); + builder.append("}"); + + return builder.toString(); + } + + // TODO: Replace CopyJob with ExtractJob. + CopyJob createJob(Context service, Job.Listener listener, String id) { + return new CopyJob(service, listener, id, getDestination(), getSrc()); + } + + private ExtractOperation(Parcel in) { + super(in); + } + + public static final Parcelable.Creator<ExtractOperation> CREATOR = + new Parcelable.Creator<ExtractOperation>() { + + @Override + public ExtractOperation createFromParcel(Parcel source) { + return new ExtractOperation(source); + } + + @Override + public ExtractOperation[] newArray(int size) { + return new ExtractOperation[size]; + } + }; + } + public static class MoveDeleteOperation extends FileOperation { private final @Nullable Uri mSrcParent; @@ -230,6 +312,10 @@ public abstract class FileOperation implements Parcelable { switch (mOpType) { case OPERATION_COPY: return new CopyOperation(mSrcs, mDestination); + case OPERATION_COMPRESS: + return new CompressOperation(mSrcs, mDestination); + case OPERATION_EXTRACT: + return new ExtractOperation(mSrcs, mDestination); case OPERATION_MOVE: case OPERATION_DELETE: return new MoveDeleteOperation(mOpType, mSrcs, mDestination, mSrcParent); diff --git a/src/com/android/documentsui/services/FileOperationService.java b/src/com/android/documentsui/services/FileOperationService.java index 18190c3e5..d9745f0be 100644 --- a/src/com/android/documentsui/services/FileOperationService.java +++ b/src/com/android/documentsui/services/FileOperationService.java @@ -67,6 +67,8 @@ public class FileOperationService extends Service implements Job.Listener { @IntDef(flag = true, value = { OPERATION_UNKNOWN, OPERATION_COPY, + OPERATION_COMPRESS, + OPERATION_EXTRACT, OPERATION_MOVE, OPERATION_DELETE }) @@ -74,8 +76,10 @@ public class FileOperationService extends Service implements Job.Listener { 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; + public static final int OPERATION_EXTRACT = 2; + public static final int OPERATION_COMPRESS = 3; + public static final int OPERATION_MOVE = 4; + public static final int OPERATION_DELETE = 5; // TODO: Move it to a shared file when more operations are implemented. public static final int FAILURE_COPY = 1; @@ -231,6 +235,8 @@ public class FileOperationService extends Service implements Job.Listener { private ExecutorService getExecutorService(@OpType int operationType) { switch (operationType) { case OPERATION_COPY: + case OPERATION_COMPRESS: + case OPERATION_EXTRACT: case OPERATION_MOVE: return executor; case OPERATION_DELETE: diff --git a/src/com/android/documentsui/ui/DialogController.java b/src/com/android/documentsui/ui/DialogController.java index 852887e1c..8e75b1eb8 100644 --- a/src/com/android/documentsui/ui/DialogController.java +++ b/src/com/android/documentsui/ui/DialogController.java @@ -129,6 +129,12 @@ public interface DialogController { case FileOperationService.OPERATION_COPY: Snackbars.showCopy(mActivity, docCount); break; + case FileOperationService.OPERATION_COMPRESS: + Snackbars.showCompress(mActivity, docCount); + break; + case FileOperationService.OPERATION_EXTRACT: + Snackbars.showExtract(mActivity, docCount); + break; case FileOperationService.OPERATION_DELETE: Snackbars.showDelete(mActivity, docCount); break; diff --git a/src/com/android/documentsui/ui/Snackbars.java b/src/com/android/documentsui/ui/Snackbars.java index a3519e12c..9ea34b18f 100644 --- a/src/com/android/documentsui/ui/Snackbars.java +++ b/src/com/android/documentsui/ui/Snackbars.java @@ -43,6 +43,16 @@ public final class Snackbars { makeSnackbar(activity, message, Snackbar.LENGTH_SHORT).show(); } + public static final void showCompress(Activity activity, int docCount) { + CharSequence message = Shared.getQuantityString(activity, R.plurals.compress_begin, docCount); + makeSnackbar(activity, message, Snackbar.LENGTH_SHORT).show(); + } + + public static final void showExtract(Activity activity, int docCount) { + CharSequence message = Shared.getQuantityString(activity, R.plurals.extract_begin, docCount); + makeSnackbar(activity, message, Snackbar.LENGTH_SHORT).show(); + } + public static final void showDelete(Activity activity, int docCount) { CharSequence message = Shared.getQuantityString(activity, R.plurals.deleting, docCount); makeSnackbar(activity, message, Snackbar.LENGTH_SHORT).show(); diff --git a/tests/common/com/android/documentsui/testing/TestMenu.java b/tests/common/com/android/documentsui/testing/TestMenu.java index 75d8bd6a7..5f9ca9918 100644 --- a/tests/common/com/android/documentsui/testing/TestMenu.java +++ b/tests/common/com/android/documentsui/testing/TestMenu.java @@ -43,6 +43,7 @@ public abstract class TestMenu implements Menu { R.id.menu_rename, R.id.menu_move_to, R.id.menu_copy_to, + R.id.menu_compress_to, R.id.menu_extract_to, R.id.menu_cut_to_clipboard, R.id.menu_copy_to_clipboard, diff --git a/tests/unit/com/android/documentsui/files/MenuManagerTest.java b/tests/unit/com/android/documentsui/files/MenuManagerTest.java index 968111fad..a15fe9302 100644 --- a/tests/unit/com/android/documentsui/files/MenuManagerTest.java +++ b/tests/unit/com/android/documentsui/files/MenuManagerTest.java @@ -49,6 +49,7 @@ public final class MenuManagerTest { private TestMenuItem selectAll; private TestMenuItem moveTo; private TestMenuItem copyTo; + private TestMenuItem compressTo; private TestMenuItem extractTo; private TestMenuItem share; private TestMenuItem delete; @@ -81,6 +82,7 @@ public final class MenuManagerTest { selectAll = testMenu.findItem(R.id.menu_select_all); moveTo = testMenu.findItem(R.id.menu_move_to); copyTo = testMenu.findItem(R.id.menu_copy_to); + compressTo = testMenu.findItem(R.id.menu_compress_to); extractTo = testMenu.findItem(R.id.menu_extract_to); share = testMenu.findItem(R.id.menu_share); delete = testMenu.findItem(R.id.menu_delete); @@ -121,6 +123,7 @@ public final class MenuManagerTest { delete.assertVisible(); share.assertVisible(); copyTo.assertEnabled(); + compressTo.assertEnabled(); extractTo.assertInvisible(); moveTo.assertEnabled(); } @@ -133,6 +136,7 @@ public final class MenuManagerTest { rename.assertDisabled(); share.assertInvisible(); copyTo.assertDisabled(); + compressTo.assertDisabled(); extractTo.assertDisabled(); moveTo.assertDisabled(); } @@ -173,12 +177,13 @@ public final class MenuManagerTest { } @Test - public void testActionMenu_canExtract_hidesCopyTo() { + public void testActionMenu_canExtract_hidesCopyToAndCompressTo() { selectionDetails.canExtract = true; mgr.updateActionMenu(testMenu, selectionDetails); extractTo.assertEnabled(); copyTo.assertDisabled(); + compressTo.assertDisabled(); } @Test |