diff --git a/app/src/androidTest/java/com/owncloud/android/ui/dialog/SetupEncryptionDialogFragmentIT.kt b/app/src/androidTest/java/com/owncloud/android/ui/dialog/SetupEncryptionDialogFragmentIT.kt index 7f2717688a76..576b11515063 100644 --- a/app/src/androidTest/java/com/owncloud/android/ui/dialog/SetupEncryptionDialogFragmentIT.kt +++ b/app/src/androidTest/java/com/owncloud/android/ui/dialog/SetupEncryptionDialogFragmentIT.kt @@ -28,7 +28,7 @@ class SetupEncryptionDialogFragmentIT : AbstractIT() { launchActivity().use { scenario -> var sut: SetupEncryptionDialogFragment? = null scenario.onActivity { activity -> - sut = SetupEncryptionDialogFragment.newInstance(user, 0) + sut = SetupEncryptionDialogFragment.newInstance(user, null) sut.show(activity.supportFragmentManager, "1") val keyWords = arrayListOf( "ability", @@ -64,7 +64,7 @@ class SetupEncryptionDialogFragmentIT : AbstractIT() { launchActivity().use { scenario -> var sut: SetupEncryptionDialogFragment? = null scenario.onActivity { activity -> - sut = SetupEncryptionDialogFragment.newInstance(user, 0) + sut = SetupEncryptionDialogFragment.newInstance(user, null) sut.show(activity.supportFragmentManager, "1") sut.errorSavingKeys() } diff --git a/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt b/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt index 2b22bdb8f58f..d4ee59f4d27e 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt +++ b/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt @@ -3003,24 +3003,20 @@ class FileDisplayActivity : } fun showFile(selectedFile: OCFile?, message: String?) { - dismissLoadingDialog() - getOCFileListFragmentFromFile(object : TransactionInterface { - override fun onOCFileListFragmentComplete(listOfFiles: OCFileListFragment) { - if (TextUtils.isEmpty(message)) { - val temp = file - file = getCurrentDir() - listOfFiles.listDirectory(getCurrentDir(), temp, MainApp.isOnlyOnDevice()) + override fun onOCFileListFragmentComplete(fragment: OCFileListFragment) { + dismissLoadingDialog() + + if (message.isNullOrEmpty()) { + val current = getCurrentDir() + fragment.listDirectory(current, file, MainApp.isOnlyOnDevice()) + file = current updateActionBarTitleAndHomeButton(null) } else { - val view = listOfFiles.view - if (view != null) { - DisplayUtils.showSnackMessage(view, message) - } - } - if (selectedFile != null) { - listOfFiles.onItemClicked(selectedFile) + fragment.view?.let { DisplayUtils.showSnackMessage(it, message) } } + + selectedFile?.let(fragment::onItemClicked) } }) } diff --git a/app/src/main/java/com/owncloud/android/ui/activity/SetupEncryptionActivity.kt b/app/src/main/java/com/owncloud/android/ui/activity/SetupEncryptionActivity.kt index d5388c0d9995..65f438fa5c56 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/SetupEncryptionActivity.kt +++ b/app/src/main/java/com/owncloud/android/ui/activity/SetupEncryptionActivity.kt @@ -27,7 +27,7 @@ class SetupEncryptionActivity : AppCompatActivity() { finish() } - val setupEncryptionDialogFragment = SetupEncryptionDialogFragment.newInstance(user, -1) + val setupEncryptionDialogFragment = SetupEncryptionDialogFragment.newInstance(user, null) supportFragmentManager.setFragmentResultListener( SetupEncryptionDialogFragment.RESULT_REQUEST_KEY, this @@ -52,8 +52,8 @@ class SetupEncryptionActivity : AppCompatActivity() { result.getBoolean(SetupEncryptionDialogFragment.SUCCESS) ) intent.putExtra( - SetupEncryptionDialogFragment.ARG_POSITION, - result.getInt(SetupEncryptionDialogFragment.ARG_POSITION) + SetupEncryptionDialogFragment.ARG_FILE_PATH, + result.getInt(SetupEncryptionDialogFragment.ARG_FILE_PATH) ) return intent } diff --git a/app/src/main/java/com/owncloud/android/ui/adapter/OCFileListAdapter.java b/app/src/main/java/com/owncloud/android/ui/adapter/OCFileListAdapter.java index c93624ba352c..716ed87d544a 100644 --- a/app/src/main/java/com/owncloud/android/ui/adapter/OCFileListAdapter.java +++ b/app/src/main/java/com/owncloud/android/ui/adapter/OCFileListAdapter.java @@ -335,9 +335,21 @@ public int getItemCount() { @Nullable public OCFile getItem(int position) { + if (mFiles == null || mFiles.isEmpty()) { + return null; + } + + if (position < 0) { + return null; + } + int newPosition = position; - if (shouldShowHeader() && position > 0) { + if (shouldShowHeader()) { + if (position == 0) { + // Header position — no file here + return null; + } newPosition = position - 1; } diff --git a/app/src/main/java/com/owncloud/android/ui/dialog/setupEncryption/SetupEncryptionDialogFragment.kt b/app/src/main/java/com/owncloud/android/ui/dialog/setupEncryption/SetupEncryptionDialogFragment.kt index 427d2c9b75e2..057873270a5e 100644 --- a/app/src/main/java/com/owncloud/android/ui/dialog/setupEncryption/SetupEncryptionDialogFragment.kt +++ b/app/src/main/java/com/owncloud/android/ui/dialog/setupEncryption/SetupEncryptionDialogFragment.kt @@ -9,7 +9,6 @@ package com.owncloud.android.ui.dialog.setupEncryption import android.accounts.AccountManager import android.app.Dialog import android.content.DialogInterface -import android.content.Intent import android.os.Bundle import android.view.View import androidx.annotation.VisibleForTesting @@ -44,7 +43,6 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import java.io.IOException import java.lang.ref.WeakReference -import java.util.Arrays import javax.inject.Inject /* @@ -215,7 +213,7 @@ class SetupEncryptionDialogFragment : ) val secondKey = EncryptionUtils.decodeStringToBase64Bytes(decryptedString) - if (!Arrays.equals(firstKey, secondKey)) { + if (!firstKey.contentEquals(secondKey)) { EncryptionUtils.reportE2eError(arbitraryDataProvider, user) throw Exception("Keys do not match") } @@ -223,7 +221,7 @@ class SetupEncryptionDialogFragment : notifyResult() } catch (e: Exception) { binding.encryptionStatus.setText(R.string.end_to_end_encryption_wrong_password) - Log_OC.d(TAG, "Error while decrypting private key: " + e.message) + Log_OC.e(TAG, "Error while decrypting private key: " + e.message) } } @@ -240,27 +238,14 @@ class SetupEncryptionDialogFragment : } private fun notifyResult() { - val targetFragment = targetFragment - targetFragment?.onActivityResult( - targetRequestCode, - SETUP_ENCRYPTION_RESULT_CODE, - resultIntent - ) parentFragmentManager.setFragmentResult(RESULT_REQUEST_KEY, resultBundle) } - private val resultIntent: Intent - get() { - return Intent().apply { - putExtra(SUCCESS, true) - putExtra(ARG_POSITION, requireArguments().getInt(ARG_POSITION)) - } - } private val resultBundle: Bundle get() { return Bundle().apply { putBoolean(SUCCESS, true) - putInt(ARG_POSITION, requireArguments().getInt(ARG_POSITION)) + putString(ARG_FILE_PATH, requireArguments().getString(ARG_FILE_PATH)) } } @@ -544,9 +529,8 @@ class SetupEncryptionDialogFragment : companion object { const val SUCCESS = "SUCCESS" const val SETUP_ENCRYPTION_RESULT_CODE = 101 - const val SETUP_ENCRYPTION_REQUEST_CODE = 100 const val SETUP_ENCRYPTION_DIALOG_TAG = "SETUP_ENCRYPTION_DIALOG_TAG" - const val ARG_POSITION = "ARG_POSITION" + const val ARG_FILE_PATH = "ARG_FILE_PATH" const val RESULT_REQUEST_KEY = "RESULT_REQUEST" const val RESULT_KEY_CANCELLED = "IS_CANCELLED" private const val NUMBER_OF_WORDS = 12 @@ -557,16 +541,11 @@ class SetupEncryptionDialogFragment : private const val KEY_FAILED = "KEY_FAILED" private const val KEY_GENERATE = "KEY_GENERATE" - /** - * Public factory method to create new SetupEncryptionDialogFragment instance - * - * @return Dialog ready to show. - */ @JvmStatic - fun newInstance(user: User?, position: Int): SetupEncryptionDialogFragment { + fun newInstance(user: User?, filePath: String?): SetupEncryptionDialogFragment { val bundle = Bundle().apply { putParcelable(ARG_USER, user) - putInt(ARG_POSITION, position) + putString(ARG_FILE_PATH, filePath) } return SetupEncryptionDialogFragment().apply { diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java index 828aca199a55..bb5a065114c4 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java +++ b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java @@ -148,7 +148,6 @@ import static com.owncloud.android.datamodel.OCFile.ROOT_PATH; import static com.owncloud.android.ui.dialog.setupEncryption.SetupEncryptionDialogFragment.SETUP_ENCRYPTION_DIALOG_TAG; -import static com.owncloud.android.ui.dialog.setupEncryption.SetupEncryptionDialogFragment.SETUP_ENCRYPTION_REQUEST_CODE; import static com.owncloud.android.ui.fragment.SearchType.FAVORITE_SEARCH; import static com.owncloud.android.ui.fragment.SearchType.FILE_SEARCH; import static com.owncloud.android.ui.fragment.SearchType.NO_SEARCH; @@ -254,6 +253,12 @@ public void onCreate(Bundle savedInstanceState) { searchFragment = currentSearchType != null && isSearchEventSet(searchEvent); } + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + listenSetupEncryptionDialogResult(); + } + @Override public void onResume() { // Don't handle search events if we're coming back from back stack @@ -1132,8 +1137,7 @@ private void folderOnItemClick(OCFile file, int position) { if (fragmentManager.findFragmentByTag(SETUP_ENCRYPTION_DIALOG_TAG) == null && requireActivity() instanceof FileActivity fileActivity) { fileActivity.connectivityService.isNetworkAndServerAvailable(result -> { if (result) { - SetupEncryptionDialogFragment dialog = SetupEncryptionDialogFragment.newInstance(user, position); - dialog.setTargetFragment(this, SETUP_ENCRYPTION_REQUEST_CODE); + SetupEncryptionDialogFragment dialog = SetupEncryptionDialogFragment.newInstance(user, file.getRemotePath()); dialog.show(fragmentManager, SETUP_ENCRYPTION_DIALOG_TAG); } else { DisplayUtils.showSnackMessage(fileActivity, R.string.internet_connection_required_for_encrypted_folder_setup); @@ -1255,30 +1259,38 @@ private void browseToFolder(OCFile file, int position) { saveIndexAndTopPosition(position); } - @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { - if (requestCode == SETUP_ENCRYPTION_REQUEST_CODE && - resultCode == SetupEncryptionDialogFragment.SETUP_ENCRYPTION_RESULT_CODE && - data.getBooleanExtra(SetupEncryptionDialogFragment.SUCCESS, false)) { + private void listenSetupEncryptionDialogResult() { + getParentFragmentManager().setFragmentResultListener( + SetupEncryptionDialogFragment.RESULT_REQUEST_KEY, + this, + (requestKey, bundle) -> { + boolean result = bundle.getBoolean(SetupEncryptionDialogFragment.SUCCESS, false); + if (!result) { + Log_OC.d(TAG, "setup encryption dialog is dismissed"); + return; + } - int position = data.getIntExtra(SetupEncryptionDialogFragment.ARG_POSITION, -1); - OCFile file = mAdapter.getItem(position); + String fileRemotePath = bundle.getString(SetupEncryptionDialogFragment.ARG_FILE_PATH, null); + if (fileRemotePath == null) { + Log_OC.e(TAG, "file path is null"); + return; + } + + OCFile file = mContainerActivity.getStorageManager().getFileByDecryptedRemotePath(fileRemotePath); + if (file == null) { + Log_OC.e(TAG,"file is null, cannot toggle encryption"); + return; + } - if (file != null) { mContainerActivity.getFileOperationsHelper().toggleEncryption(file, true); mAdapter.setEncryptionAttributeForItemID(file.getRemoteId(), true); - } + searchFragment = false; + listDirectory(file, MainApp.isOnlyOnDevice()); + mContainerActivity.onBrowsedDownTo(file); - // update state and view of this fragment - searchFragment = false; - listDirectory(file, MainApp.isOnlyOnDevice()); - // then, notify parent activity to let it update its state and view - mContainerActivity.onBrowsedDownTo(file); - // save index and top position - saveIndexAndTopPosition(position); - } else { - super.onActivityResult(requestCode, resultCode, data); - } + int position = mAdapter.getItemPosition(file); + saveIndexAndTopPosition(position); + }); } /** @@ -1924,16 +1936,9 @@ public void onMessageEvent(EncryptionEvent event) { if (publicKey.isEmpty() || privateKey.isEmpty()) { Log_OC.d(TAG, "no public key for " + user.getAccountName()); - int position; - if (file != null) { - position = mAdapter.getItemPosition(file); - } else { - position = -1; - } requireActivity().runOnUiThread(() -> { - SetupEncryptionDialogFragment dialog = SetupEncryptionDialogFragment.newInstance(user, position); - dialog.setTargetFragment(OCFileListFragment.this, SETUP_ENCRYPTION_REQUEST_CODE); + SetupEncryptionDialogFragment dialog = SetupEncryptionDialogFragment.newInstance(user, file.getRemotePath()); dialog.show(getParentFragmentManager(), SETUP_ENCRYPTION_DIALOG_TAG); }); } else { diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/UnifiedSearchFragment.kt b/app/src/main/java/com/owncloud/android/ui/fragment/UnifiedSearchFragment.kt index 7c8bd588807f..437e9e410262 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/UnifiedSearchFragment.kt +++ b/app/src/main/java/com/owncloud/android/ui/fragment/UnifiedSearchFragment.kt @@ -352,18 +352,13 @@ class UnifiedSearchFragment : } } - private fun showFile(file: OCFile, showFileActions: Boolean) { - activity.let { - if (activity is FileDisplayActivity) { - val fda = activity as FileDisplayActivity - fda.file = file - - if (showFileActions) { - fda.showFileActions(file) - } else { - fda.showFile(file, "") - } + private fun showFile(file: OCFile, showFileActions: Boolean, updateCurrentFile: Boolean = true) { + (activity as? FileDisplayActivity)?.apply { + if (updateCurrentFile) { + this.file = file } + + if (showFileActions) showFileActions(file) else showFile(file, "") } } @@ -407,7 +402,15 @@ class UnifiedSearchFragment : override fun onSearchResultClicked(searchResultEntry: SearchResultEntry) { showMoreActions = false - vm.openResult(searchResultEntry) + + val remotePath = searchResultEntry.remotePath() + OCFile.PATH_SEPARATOR + val file = storageManager.getFileByDecryptedRemotePath(remotePath) + + if (file?.isEncrypted == true) { + showFile(file, showMoreActions, updateCurrentFile = false) + } else { + vm.openResult(searchResultEntry) + } } override fun onLoadMoreClicked(providerID: ProviderID) {