Skip to content

Commit d2b6ea1

Browse files
committed
Allow to create encrypted folder directly via bottom sheet dialog
as per NC PR: nextcloud#10782
1 parent 6f88750 commit d2b6ea1

10 files changed

Lines changed: 130 additions & 17 deletions

File tree

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

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,16 +64,31 @@ public class CreateFolderOperation extends SyncOperation implements OnRemoteOper
6464
private RemoteFile createdRemoteFolder;
6565
private User user;
6666
private Context context;
67+
private boolean encrypted;
6768

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

7488
this.remotePath = remotePath;
7589
this.user = user;
7690
this.context = context;
91+
this.encrypted = encrypted;
7792
}
7893

7994
@Override
@@ -101,7 +116,7 @@ protected RemoteOperationResult run(OwnCloudClient client) {
101116
if (encryptedAncestor) {
102117
return encryptedCreate(parent, client);
103118
} else {
104-
return normalCreate(client);
119+
return normalCreate(client, encrypted);
105120
}
106121
}
107122

@@ -282,7 +297,7 @@ private String createRandomFileName(DecryptedFolderMetadata metadata) {
282297
return encryptedFileName;
283298
}
284299

285-
private RemoteOperationResult normalCreate(OwnCloudClient client) {
300+
private RemoteOperationResult normalCreate(OwnCloudClient client, boolean encrypted) {
286301
RemoteOperationResult result = new CreateFolderRemoteOperation(remotePath, true).execute(client);
287302

288303
if (result.isSuccess()) {
@@ -291,6 +306,20 @@ private RemoteOperationResult normalCreate(OwnCloudClient client) {
291306

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

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ public class OperationsService extends Service {
9595
public static final String EXTRA_ACCOUNT = "ACCOUNT";
9696
public static final String EXTRA_SERVER_URL = "SERVER_URL";
9797
public static final String EXTRA_REMOTE_PATH = "REMOTE_PATH";
98+
public static final String EXTRA_ENCRYPTED = "ENCRYPTED";
9899
public static final String EXTRA_NEWNAME = "NEWNAME";
99100
public static final String EXTRA_REMOVE_ONLY_LOCAL = "REMOVE_LOCAL_COPY";
100101
public static final String EXTRA_SYNC_FILE_CONTENTS = "SYNC_FILE_CONTENTS";
@@ -690,7 +691,9 @@ private Pair<Target, RemoteOperation> newOperation(Intent operationIntent) {
690691

691692
case ACTION_CREATE_FOLDER:
692693
remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
694+
boolean encrypted = operationIntent.getBooleanExtra(EXTRA_ENCRYPTED, false);
693695
operation = new CreateFolderOperation(remotePath,
696+
encrypted,
694697
user,
695698
getApplicationContext(),
696699
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
@@ -521,6 +521,10 @@ private String generateFooterText(int filesCount, int foldersCount) {
521521

522522
public @Nullable
523523
OCFile getItem(int position) {
524+
if (position == -1) {
525+
return null;
526+
}
527+
524528
int newPosition = position;
525529

526530
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
@@ -63,12 +63,14 @@ public class CreateFolderDialogFragment
6363
extends DialogFragment implements DialogInterface.OnClickListener, Injectable {
6464

6565
private static final String ARG_PARENT_FOLDER = "PARENT_FOLDER";
66+
private static final String ARG_ENCRYPTED = "ENCRYPTED";
6667

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

6970
@Inject FileDataStorageManager fileDataStorageManager;
70-
private OCFile mParentFolder;
71+
private OCFile parentFolder;
7172
private Button positiveButton;
73+
private boolean encrypted;
7274

7375
/**
7476
* Public factory method to create new CreateFolderDialogFragment instances.
@@ -77,12 +79,16 @@ public class CreateFolderDialogFragment
7779
* @return Dialog ready to show.
7880
*/
7981
public static CreateFolderDialogFragment newInstance(OCFile parentFolder) {
82+
return newInstance(parentFolder, false);
83+
}
84+
85+
public static CreateFolderDialogFragment newInstance(OCFile parentFolder, boolean encrypted) {
8086
CreateFolderDialogFragment frag = new CreateFolderDialogFragment();
8187
Bundle args = new Bundle();
8288
args.putParcelable(ARG_PARENT_FOLDER, parentFolder);
89+
args.putBoolean(ARG_ENCRYPTED, encrypted);
8390
frag.setArguments(args);
8491
return frag;
85-
8692
}
8793

8894
@Override
@@ -100,7 +106,8 @@ public void onStart() {
100106
@NonNull
101107
@Override
102108
public Dialog onCreateDialog(Bundle savedInstanceState) {
103-
mParentFolder = getArguments().getParcelable(ARG_PARENT_FOLDER);
109+
parentFolder = getArguments().getParcelable(ARG_PARENT_FOLDER);
110+
encrypted = getArguments().getBoolean(ARG_ENCRYPTED);
104111

105112
// Inflate the layout for the dialog
106113
LayoutInflater inflater = requireActivity().getLayoutInflater();
@@ -193,8 +200,8 @@ public void onClick(DialogInterface dialog, int which) {
193200
return;
194201
}
195202

196-
String path = mParentFolder.getDecryptedRemotePath() + newFolderName + OCFile.PATH_SEPARATOR;
197-
((ComponentsGetter) getActivity()).getFileOperationsHelper().createFolder(path);
203+
String path = parentFolder.getDecryptedRemotePath() + newFolderName + OCFile.PATH_SEPARATOR;
204+
((ComponentsGetter) getActivity()).getFileOperationsHelper().createFolder(path, encrypted);
198205
}
199206
}
200207
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ public interface OCFileListBottomSheetActions {
3232
*/
3333
void createFolder();
3434

35+
/**
36+
* creates an encrypted folder within the actual folder
37+
*/
38+
void createEncryptedFolder();
39+
3540
/**
3641
* offers a file upload with the Android OS file picker to the current folder.
3742
*/

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
@@ -83,9 +83,8 @@ protected void onCreate(Bundle savedInstanceState) {
8383
getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
8484
}
8585

86-
OCCapability capability = fileActivity.getCapabilities();
87-
if (capability != null &&
88-
capability.getRichDocuments().isTrue() &&
86+
OCCapability capability = fileActivity.getStorageManager().getCapability(user.getAccountName());
87+
if (capability.getRichDocuments().isTrue() &&
8988
capability.getRichDocumentsDirectEditing().isTrue() &&
9089
capability.getRichDocumentsTemplatesAvailable().isTrue() &&
9190
!file.isEncrypted()) {
@@ -134,6 +133,12 @@ protected void onCreate(Bundle savedInstanceState) {
134133
binding.menuScanDocument.setVisibility(View.GONE);
135134
}
136135

136+
if (capability.getEndToEndEncryption().isTrue()) {
137+
binding.menuEncryptedMkdir.setVisibility(View.VISIBLE);
138+
} else {
139+
binding.menuEncryptedMkdir.setVisibility(View.GONE);
140+
}
141+
137142
//check if scanbot sdk licence is valid or not
138143
//hide the view if license is not valid
139144
if (!ScanBotSdkUtils.isScanBotLicenseValid(fileActivity)) {
@@ -180,6 +185,11 @@ private void setupClickListener() {
180185
dismiss();
181186
});
182187

188+
binding.menuEncryptedMkdir.setOnClickListener(v -> {
189+
actions.createEncryptedFolder();
190+
dismiss();
191+
});
192+
183193
binding.menuUploadFromApp.setOnClickListener(v -> {
184194
actions.uploadFromApp();
185195
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
@@ -505,6 +505,14 @@ public void createFolder() {
505505
.show(getActivity().getSupportFragmentManager(), DIALOG_CREATE_FOLDER);
506506
}
507507

508+
@Override
509+
public void createEncryptedFolder() {
510+
if (checkEncryptionIsSetup(null)) {
511+
CreateFolderDialogFragment.newInstance(mFile, true)
512+
.show(getActivity().getSupportFragmentManager(), DIALOG_CREATE_FOLDER);
513+
}
514+
}
515+
508516
@Override
509517
public void uploadFromApp() {
510518
Intent action = new Intent(Intent.ACTION_GET_CONTENT);
@@ -1133,10 +1141,12 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
11331141
int position = data.getIntExtra(SetupEncryptionDialogFragment.ARG_POSITION, -1);
11341142
OCFile file = mAdapter.getItem(position);
11351143

1136-
if (file != null) {
1137-
mContainerActivity.getFileOperationsHelper().toggleEncryption(file, true);
1144+
if (file == null) {
1145+
return;
11381146
}
11391147

1148+
encryptFolder(file.getLocalId(), file.getRemoteId(), file.getRemotePath(), true);
1149+
11401150
// update state and view of this fragment
11411151
searchFragment = false;
11421152
listDirectory(file, MainApp.isOnlyOnDevice(), false);
@@ -1814,6 +1824,12 @@ protected RemoteOperation getSearchRemoteOperation(final User currentUser, final
18141824

18151825
@Subscribe(threadMode = ThreadMode.BACKGROUND)
18161826
public void onMessageEvent(EncryptionEvent event) {
1827+
if (checkEncryptionIsSetup(event.remoteId)) {
1828+
encryptFolder(event.localId, event.remoteId, event.remotePath, event.shouldBeEncrypted);
1829+
}
1830+
}
1831+
1832+
private boolean checkEncryptionIsSetup(@Nullable String remoteId) {
18171833
final User user = accountManager.getUser();
18181834

18191835
// check if keys are stored
@@ -1827,16 +1843,20 @@ public void onMessageEvent(EncryptionEvent event) {
18271843
Log_OC.d(TAG, "no public key for " + user.getAccountName());
18281844

18291845
FileDataStorageManager storageManager = mContainerActivity.getStorageManager();
1830-
OCFile file = storageManager.getFileByRemoteId(event.remoteId);
18311846
int position = -1;
1832-
if (file != null) {
1833-
position = mAdapter.getItemPosition(file);
1847+
if (remoteId != null) {
1848+
OCFile file = storageManager.getFileByRemoteId(remoteId);
1849+
if (file != null) {
1850+
position = mAdapter.getItemPosition(file);
1851+
}
18341852
}
18351853
SetupEncryptionDialogFragment dialog = SetupEncryptionDialogFragment.newInstance(user, position);
18361854
dialog.setTargetFragment(this, SetupEncryptionDialogFragment.SETUP_ENCRYPTION_REQUEST_CODE);
18371855
dialog.show(getParentFragmentManager(), SetupEncryptionDialogFragment.SETUP_ENCRYPTION_DIALOG_TAG);
1856+
1857+
return false;
18381858
} else {
1839-
encryptFolder(event.localId, event.remoteId, event.remotePath, event.shouldBeEncrypted);
1859+
return true;
18401860
}
18411861
}
18421862

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -995,11 +995,16 @@ public void removeFiles(Collection<OCFile> files, boolean onlyLocalCopy, boolean
995995

996996

997997
public void createFolder(String remotePath) {
998+
createFolder(remotePath, false);
999+
}
1000+
1001+
public void createFolder(String remotePath, boolean encrypted) {
9981002
// Create Folder
9991003
Intent service = new Intent(fileActivity, OperationsService.class);
10001004
service.setAction(OperationsService.ACTION_CREATE_FOLDER);
10011005
service.putExtra(OperationsService.EXTRA_ACCOUNT, fileActivity.getAccount());
10021006
service.putExtra(OperationsService.EXTRA_REMOTE_PATH, remotePath);
1007+
service.putExtra(OperationsService.EXTRA_ENCRYPTED, encrypted);
10031008
mWaitingForOpId = fileActivity.getOperationsServiceBinder().queueNewOperation(service);
10041009

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

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,35 @@
201201

202202
</LinearLayout>
203203

204+
<LinearLayout
205+
android:id="@+id/menu_encrypted_mkdir"
206+
android:layout_width="match_parent"
207+
android:layout_height="wrap_content"
208+
android:orientation="horizontal"
209+
android:background="?android:attr/selectableItemBackground"
210+
android:paddingLeft="@dimen/standard_padding"
211+
android:paddingTop="@dimen/standard_half_padding"
212+
android:paddingRight="@dimen/standard_padding"
213+
android:paddingBottom="@dimen/standard_half_padding"
214+
tools:ignore="UseCompoundDrawables">
215+
216+
<ImageView
217+
android:id="@+id/menu_icon_encrypted_mkdir"
218+
android:layout_width="wrap_content"
219+
android:layout_height="wrap_content"
220+
android:contentDescription="@null"
221+
android:src="@drawable/ic_action_create_dir" />
222+
223+
<TextView
224+
android:layout_width="wrap_content"
225+
android:layout_height="wrap_content"
226+
android:layout_gravity="center_vertical"
227+
android:layout_marginStart="@dimen/standard_margin"
228+
android:text="@string/create_new_encrypted_folder"
229+
android:textColor="@color/bottom_sheet_txt_color"
230+
android:textSize="@dimen/bottom_sheet_text_size" />
231+
</LinearLayout>
232+
204233
<View
205234
android:layout_width="match_parent"
206235
android:layout_height="1dp"

app/src/main/res/values/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -769,6 +769,7 @@
769769
<string name="upload_scan_document">Scan Document</string>
770770
<string name="upload_content_from_other_apps">Upload content from other apps</string>
771771
<string name="create_new_folder">Create new folder</string>
772+
<string name="create_new_encrypted_folder">Create new encrypted folder</string>
772773
<string name="uploads_view_upload_status_virus_detected">Virus detected. Upload cannot be completed!</string>
773774
<string name="tags">Tags</string>
774775
<string name="sharee_add_failed">Adding sharee failed</string>

0 commit comments

Comments
 (0)