Skip to content

Commit c584fdc

Browse files
tobiasKaminskyAlvaroBrey
authored andcommitted
allow to create encrypted folder directly via bottom sheet dialog
Signed-off-by: tobiasKaminsky <tobias@kaminsky.me>
1 parent edec670 commit c584fdc

File tree

11 files changed

+139
-21
lines changed

11 files changed

+139
-21
lines changed

app/src/androidTest/java/com/owncloud/android/ui/dialog/DialogFragmentIT.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,11 @@ public void createFolder() {
314314

315315
}
316316

317+
@Override
318+
public void createEncryptedFolder() {
319+
320+
}
321+
317322
@Override
318323
public void uploadFromApp() {
319324

app/src/main/java/com/owncloud/android/operations/CreateFolderOperation.java

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,16 +65,31 @@ public class CreateFolderOperation extends SyncOperation implements OnRemoteOper
6565
private RemoteFile createdRemoteFolder;
6666
private User user;
6767
private Context context;
68+
private boolean encrypted;
6869

6970
/**
7071
* Constructor
7172
*/
72-
public CreateFolderOperation(String remotePath, User user, Context context, FileDataStorageManager storageManager) {
73+
public CreateFolderOperation(String remotePath,
74+
User user,
75+
Context context,
76+
FileDataStorageManager storageManager
77+
) {
78+
this(remotePath, false, user, context, storageManager);
79+
}
80+
81+
public CreateFolderOperation(String remotePath,
82+
boolean encrypted,
83+
User user,
84+
Context context,
85+
FileDataStorageManager storageManager
86+
) {
7387
super(storageManager);
7488

7589
this.remotePath = remotePath;
7690
this.user = user;
7791
this.context = context;
92+
this.encrypted = encrypted;
7893
}
7994

8095
@Override
@@ -102,7 +117,7 @@ protected RemoteOperationResult run(OwnCloudClient client) {
102117
if (encryptedAncestor) {
103118
return encryptedCreate(parent, client);
104119
} else {
105-
return normalCreate(client);
120+
return normalCreate(client, encrypted);
106121
}
107122
}
108123

@@ -283,7 +298,7 @@ private String createRandomFileName(DecryptedFolderMetadata metadata) {
283298
return encryptedFileName;
284299
}
285300

286-
private RemoteOperationResult normalCreate(OwnCloudClient client) {
301+
private RemoteOperationResult normalCreate(OwnCloudClient client, boolean encrypted) {
287302
RemoteOperationResult result = new CreateFolderRemoteOperation(remotePath, true).execute(client);
288303

289304
if (result.isSuccess()) {
@@ -292,6 +307,21 @@ private RemoteOperationResult normalCreate(OwnCloudClient client) {
292307

293308
createdRemoteFolder = (RemoteFile) remoteFolderOperationResult.getData().get(0);
294309
saveFolderInDB();
310+
311+
if (encrypted) {
312+
final OCFile folder = getStorageManager().getFileByDecryptedRemotePath(remotePath);
313+
314+
final RemoteOperationResult remoteOperationResult =
315+
new ToggleEncryptionRemoteOperation(folder.getLocalId(),
316+
remotePath,
317+
true)
318+
.execute(client);
319+
320+
if (remoteOperationResult.isSuccess()) {
321+
folder.setEncrypted(true);
322+
getStorageManager().saveFile(folder);
323+
}
324+
}
295325
} else {
296326
Log_OC.e(TAG, remotePath + " hasn't been created");
297327
}

app/src/main/java/com/owncloud/android/services/OperationsService.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ public class OperationsService extends Service {
9393
public static final String EXTRA_ACCOUNT = "ACCOUNT";
9494
public static final String EXTRA_SERVER_URL = "SERVER_URL";
9595
public static final String EXTRA_REMOTE_PATH = "REMOTE_PATH";
96+
public static final String EXTRA_ENCRYPTED = "ENCRYPTED";
9697
public static final String EXTRA_NEWNAME = "NEWNAME";
9798
public static final String EXTRA_REMOVE_ONLY_LOCAL = "REMOVE_LOCAL_COPY";
9899
public static final String EXTRA_SYNC_FILE_CONTENTS = "SYNC_FILE_CONTENTS";
@@ -685,7 +686,9 @@ private Pair<Target, RemoteOperation> newOperation(Intent operationIntent) {
685686

686687
case ACTION_CREATE_FOLDER:
687688
remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
689+
boolean encrypted = operationIntent.getBooleanExtra(EXTRA_ENCRYPTED, false);
688690
operation = new CreateFolderOperation(remotePath,
691+
encrypted,
689692
user,
690693
getApplicationContext(),
691694
fileDataStorageManager);

app/src/main/java/com/owncloud/android/ui/adapter/OCFileListAdapter.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,10 @@ private String generateFooterText(int filesCount, int foldersCount) {
538538

539539
public @Nullable
540540
OCFile getItem(int position) {
541+
if (position == -1) {
542+
return null;
543+
}
544+
541545
int newPosition = position;
542546

543547
if (shouldShowHeader() && position > 0) {

app/src/main/java/com/owncloud/android/ui/dialog/CreateFolderDialogFragment.java

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ public class CreateFolderDialogFragment
6262
extends DialogFragment implements DialogInterface.OnClickListener, Injectable {
6363

6464
private static final String ARG_PARENT_FOLDER = "PARENT_FOLDER";
65+
private static final String ARG_ENCRYPTED = "ENCRYPTED";
6566

6667
public static final String CREATE_FOLDER_FRAGMENT = "CREATE_FOLDER_FRAGMENT";
6768

@@ -70,8 +71,9 @@ public class CreateFolderDialogFragment
7071
@Inject KeyboardUtils keyboardUtils;
7172

7273

73-
private OCFile mParentFolder;
74+
private OCFile parentFolder;
7475
private Button positiveButton;
76+
private boolean encrypted;
7577

7678

7779
private EditBoxDialogBinding binding;
@@ -83,12 +85,16 @@ public class CreateFolderDialogFragment
8385
* @return Dialog ready to show.
8486
*/
8587
public static CreateFolderDialogFragment newInstance(OCFile parentFolder) {
88+
return newInstance(parentFolder, false);
89+
}
90+
91+
public static CreateFolderDialogFragment newInstance(OCFile parentFolder, boolean encrypted) {
8692
CreateFolderDialogFragment frag = new CreateFolderDialogFragment();
8793
Bundle args = new Bundle();
8894
args.putParcelable(ARG_PARENT_FOLDER, parentFolder);
95+
args.putBoolean(ARG_ENCRYPTED, encrypted);
8996
frag.setArguments(args);
9097
return frag;
91-
9298
}
9399

94100
@Override
@@ -114,7 +120,8 @@ public void onResume() {
114120
@NonNull
115121
@Override
116122
public Dialog onCreateDialog(Bundle savedInstanceState) {
117-
mParentFolder = getArguments().getParcelable(ARG_PARENT_FOLDER);
123+
parentFolder = getArguments().getParcelable(ARG_PARENT_FOLDER);
124+
encrypted = getArguments().getBoolean(ARG_ENCRYPTED);
118125

119126
// Inflate the layout for the dialog
120127
LayoutInflater inflater = requireActivity().getLayoutInflater();
@@ -204,9 +211,9 @@ public void onClick(DialogInterface dialog, int which) {
204211
return;
205212
}
206213

207-
String path = mParentFolder.getDecryptedRemotePath() + newFolderName + OCFile.PATH_SEPARATOR;
214+
String path = parentFolder.getDecryptedRemotePath() + newFolderName + OCFile.PATH_SEPARATOR;
208215

209-
((ComponentsGetter) getActivity()).getFileOperationsHelper().createFolder(path);
216+
((ComponentsGetter) getActivity()).getFileOperationsHelper().createFolder(path, encrypted);
210217
}
211218
}
212219
}

app/src/main/java/com/owncloud/android/ui/fragment/OCFileListBottomSheetActions.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,19 @@
2323
import com.owncloud.android.lib.common.Creator;
2424

2525
/**
26-
* Actions interface to be implemented by any class that makes use of
27-
* {@link com.owncloud.android.ui.fragment.OCFileListBottomSheetDialog}.
26+
* Actions interface to be implemented by any class that makes use of {@link com.owncloud.android.ui.fragment.OCFileListBottomSheetDialog}.
2827
*/
2928
public interface OCFileListBottomSheetActions {
3029
/**
3130
* creates a folder within the actual folder.
3231
*/
3332
void createFolder();
3433

34+
/**
35+
* creates an encrypted folder within the actual folder
36+
*/
37+
void createEncryptedFolder();
38+
3539
/**
3640
* offers a file upload with the Android OS file picker to the current folder.
3741
*/

app/src/main/java/com/owncloud/android/ui/fragment/OCFileListBottomSheetDialog.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,8 @@ protected void onCreate(Bundle savedInstanceState) {
9999
binding.addToCloud.setText(getContext().getResources().getString(R.string.add_to_cloud,
100100
themeUtils.getDefaultDisplayNameForRootFolder(getContext())));
101101

102-
OCCapability capability = fileActivity.getCapabilities();
103-
if (capability != null &&
104-
capability.getRichDocuments().isTrue() &&
102+
OCCapability capability = fileActivity.getStorageManager().getCapability(user.getAccountName());
103+
if (capability.getRichDocuments().isTrue() &&
105104
capability.getRichDocumentsDirectEditing().isTrue() &&
106105
capability.getRichDocumentsTemplatesAvailable().isTrue() &&
107106
!file.isEncrypted()) {
@@ -149,6 +148,12 @@ protected void onCreate(Bundle savedInstanceState) {
149148
binding.menuDirectCameraUpload.setVisibility(View.GONE);
150149
}
151150

151+
if (capability.getEndToEndEncryption().isTrue()) {
152+
binding.menuEncryptedMkdir.setVisibility(View.VISIBLE);
153+
} else {
154+
binding.menuEncryptedMkdir.setVisibility(View.GONE);
155+
}
156+
152157
// create rich workspace
153158
if (editorUtils.isEditorAvailable(user,
154159
MimeTypeUtil.MIMETYPE_TEXT_MARKDOWN) &&
@@ -183,6 +188,11 @@ private void setupClickListener() {
183188
dismiss();
184189
});
185190

191+
binding.menuEncryptedMkdir.setOnClickListener(v -> {
192+
actions.createEncryptedFolder();
193+
dismiss();
194+
});
195+
186196
binding.menuUploadFromApp.setOnClickListener(v -> {
187197
actions.uploadFromApp();
188198
dismiss();

app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,14 @@ public void createFolder() {
489489
.show(getActivity().getSupportFragmentManager(), DIALOG_CREATE_FOLDER);
490490
}
491491

492+
@Override
493+
public void createEncryptedFolder() {
494+
if (checkEncryptionIsSetup(null)) {
495+
CreateFolderDialogFragment.newInstance(mFile, true)
496+
.show(getActivity().getSupportFragmentManager(), DIALOG_CREATE_FOLDER);
497+
}
498+
}
499+
492500
@Override
493501
public void uploadFromApp() {
494502
Intent action = new Intent(Intent.ACTION_GET_CONTENT);
@@ -1102,9 +1110,11 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
11021110
int position = data.getIntExtra(SetupEncryptionDialogFragment.ARG_POSITION, -1);
11031111
OCFile file = mAdapter.getItem(position);
11041112

1105-
if (file != null) {
1106-
mContainerActivity.getFileOperationsHelper().toggleEncryption(file, true);
1113+
if (file == null) {
1114+
return;
11071115
}
1116+
1117+
encryptFolder(file.getLocalId(), file.getRemoteId(), file.getRemotePath(), true);
11081118

11091119
// update state and view of this fragment
11101120
searchFragment = false;
@@ -1681,6 +1691,12 @@ protected RemoteOperation getSearchRemoteOperation(final User currentUser, final
16811691

16821692
@Subscribe(threadMode = ThreadMode.BACKGROUND)
16831693
public void onMessageEvent(EncryptionEvent event) {
1694+
if (checkEncryptionIsSetup(event.remoteId)) {
1695+
encryptFolder(event.localId, event.remoteId, event.remotePath, event.shouldBeEncrypted);
1696+
}
1697+
}
1698+
1699+
private boolean checkEncryptionIsSetup(@Nullable String remoteId) {
16841700
final User user = accountManager.getUser();
16851701

16861702
// check if keys are stored
@@ -1691,16 +1707,20 @@ public void onMessageEvent(EncryptionEvent event) {
16911707
Log_OC.d(TAG, "no public key for " + user.getAccountName());
16921708

16931709
FileDataStorageManager storageManager = mContainerActivity.getStorageManager();
1694-
OCFile file = storageManager.getFileByRemoteId(event.remoteId);
16951710
int position = -1;
1696-
if (file != null) {
1697-
position = mAdapter.getItemPosition(file);
1711+
if (remoteId != null) {
1712+
OCFile file = storageManager.getFileByRemoteId(remoteId);
1713+
if (file != null) {
1714+
position = mAdapter.getItemPosition(file);
1715+
}
16981716
}
16991717
SetupEncryptionDialogFragment dialog = SetupEncryptionDialogFragment.newInstance(user, position);
17001718
dialog.setTargetFragment(this, SETUP_ENCRYPTION_REQUEST_CODE);
17011719
dialog.show(getParentFragmentManager(), SETUP_ENCRYPTION_DIALOG_TAG);
1720+
1721+
return false;
17021722
} else {
1703-
encryptFolder(event.localId, event.remoteId, event.remotePath, event.shouldBeEncrypted);
1723+
return true;
17041724
}
17051725
}
17061726

app/src/main/java/com/owncloud/android/ui/helpers/FileOperationsHelper.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -972,13 +972,17 @@ public void removeFiles(Collection<OCFile> files, boolean onlyLocalCopy, boolean
972972
}
973973
}
974974

975-
976975
public void createFolder(String remotePath) {
976+
createFolder(remotePath, false);
977+
}
978+
979+
public void createFolder(String remotePath, boolean encrypted) {
977980
// Create Folder
978981
Intent service = new Intent(fileActivity, OperationsService.class);
979982
service.setAction(OperationsService.ACTION_CREATE_FOLDER);
980983
service.putExtra(OperationsService.EXTRA_ACCOUNT, fileActivity.getAccount());
981984
service.putExtra(OperationsService.EXTRA_REMOTE_PATH, remotePath);
985+
service.putExtra(OperationsService.EXTRA_ENCRYPTED, encrypted);
982986
mWaitingForOpId = fileActivity.getOperationsServiceBinder().queueNewOperation(service);
983987

984988
fileActivity.showLoadingDialog(fileActivity.getString(R.string.wait_a_moment));

app/src/main/res/layout/file_list_actions_bottom_sheet_fragment.xml

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@
183183
android:layout_height="wrap_content"
184184
android:contentDescription="@null"
185185
android:src="@drawable/ic_action_create_dir"
186-
app:tint="@color/primary"/>
186+
app:tint="@color/primary" />
187187

188188
<TextView
189189
android:layout_width="wrap_content"
@@ -193,7 +193,37 @@
193193
android:text="@string/create_new_folder"
194194
android:textColor="@color/text_color"
195195
android:textSize="@dimen/bottom_sheet_text_size" />
196+
</LinearLayout>
197+
198+
<LinearLayout
199+
android:id="@+id/menu_encrypted_mkdir"
200+
android:layout_width="match_parent"
201+
android:layout_height="@dimen/bottom_sheet_item_height"
202+
android:orientation="horizontal"
203+
android:background="?android:attr/selectableItemBackground"
204+
android:gravity="center_vertical"
205+
android:paddingLeft="@dimen/standard_padding"
206+
android:paddingTop="@dimen/standard_half_padding"
207+
android:paddingRight="@dimen/standard_padding"
208+
android:paddingBottom="@dimen/standard_half_padding"
209+
tools:ignore="UseCompoundDrawables">
210+
211+
<ImageView
212+
android:id="@+id/menu_icon_encrypted_mkdir"
213+
android:layout_width="wrap_content"
214+
android:layout_height="wrap_content"
215+
android:contentDescription="@null"
216+
android:src="@drawable/folder_encrypted"
217+
app:tint="@color/primary" />
196218

219+
<TextView
220+
android:layout_width="wrap_content"
221+
android:layout_height="wrap_content"
222+
android:layout_gravity="center_vertical"
223+
android:layout_marginStart="@dimen/bottom_sheet_text_start_margin"
224+
android:text="@string/create_new_encrypted_folder"
225+
android:textColor="@color/text_color"
226+
android:textSize="@dimen/bottom_sheet_text_size" />
197227
</LinearLayout>
198228

199229
<LinearLayout

0 commit comments

Comments
 (0)