From 9a640c802c0bc554c435bb0f53caff3d6077e936 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ensar=20Saraj=C4=8Di=C4=87?= Date: Fri, 7 Jul 2023 13:09:51 +0200 Subject: [PATCH 1/7] Add support for creating password protected zips --- app/build.gradle | 3 +- .../filemanager/pro/adapters/ItemsAdapter.kt | 32 ++++++++++++------- .../pro/dialogs/CompressAsDialog.kt | 20 +++++++++--- .../main/res/layout/dialog_compress_as.xml | 31 ++++++++++++++++++ 4 files changed, 69 insertions(+), 17 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 6bf0bc9d..27fdbdfa 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -64,7 +64,7 @@ android { } dependencies { - implementation 'com.github.SimpleMobileTools:Simple-Commons:84c71fdcc1' + implementation 'com.github.SimpleMobileTools:Simple-Commons:db25f91be3' implementation 'com.github.tibbi:AndroidPdfViewer:e6a533125b' implementation 'com.github.Stericson:RootTools:df729dcb13' implementation 'com.github.Stericson:RootShell:1.6' @@ -72,4 +72,5 @@ dependencies { implementation 'androidx.documentfile:documentfile:1.0.1' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' implementation 'me.grantland:autofittextview:0.2.1' + implementation 'net.lingala.zip4j:zip4j:2.11.5' } diff --git a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/adapters/ItemsAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/adapters/ItemsAdapter.kt index ef24564b..70603dbd 100644 --- a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/adapters/ItemsAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/adapters/ItemsAdapter.kt @@ -44,13 +44,14 @@ import kotlinx.android.synthetic.main.item_file_dir_list.view.item_icon import kotlinx.android.synthetic.main.item_file_dir_list.view.item_name import kotlinx.android.synthetic.main.item_file_grid.view.* import kotlinx.android.synthetic.main.item_section.view.* +import net.lingala.zip4j.io.outputstream.ZipOutputStream +import net.lingala.zip4j.model.ZipParameters import java.io.BufferedInputStream import java.io.Closeable import java.io.File import java.util.* import java.util.zip.ZipEntry import java.util.zip.ZipInputStream -import java.util.zip.ZipOutputStream class ItemsAdapter( activity: SimpleActivity, var listItems: MutableList, val listener: ItemOperationsListener?, recyclerView: MyRecyclerView, @@ -482,8 +483,7 @@ class ItemsAdapter( return } - CompressAsDialog(activity, firstPath) { - val destination = it + CompressAsDialog(activity, firstPath) { destination, password -> activity.handleAndroidSAFDialog(firstPath) { granted -> if (!granted) { return@handleAndroidSAFDialog @@ -496,7 +496,7 @@ class ItemsAdapter( activity.toast(R.string.compressing) val paths = getSelectedFileDirItems().map { it.path } ensureBackgroundThread { - if (compressPaths(paths, destination)) { + if (compressPaths(paths, destination, password)) { activity.runOnUiThread { activity.toast(R.string.compression_successful) listener?.refreshFragment() @@ -643,13 +643,17 @@ class ItemsAdapter( } @SuppressLint("NewApi") - private fun compressPaths(sourcePaths: List, targetPath: String): Boolean { + private fun compressPaths(sourcePaths: List, targetPath: String, password: String? = null): Boolean { val queue = LinkedList() val fos = activity.getFileOutputStreamSync(targetPath, "application/zip") ?: return false - val zout = ZipOutputStream(fos) + val zout = password?.let { ZipOutputStream(fos, password.toCharArray()) } ?: ZipOutputStream(fos) var res: Closeable = fos + fun zipEntry(name: String) = ZipParameters().also { + it.fileNameInZip = name + } + try { sourcePaths.forEach { currentPath -> var name: String @@ -659,7 +663,11 @@ class ItemsAdapter( queue.push(mainFilePath) if (activity.getIsPathDirectory(mainFilePath)) { name = "${mainFilePath.getFilenameFromPath()}/" - zout.putNextEntry(ZipEntry(name)) + zout.putNextEntry( + ZipParameters().also { + it.fileNameInZip = name + } + ) } while (!queue.isEmpty()) { @@ -672,9 +680,9 @@ class ItemsAdapter( if (activity.getIsPathDirectory(file.path)) { queue.push(file.path) name = "${name.trimEnd('/')}/" - zout.putNextEntry(ZipEntry(name)) + zout.putNextEntry(zipEntry(name)) } else { - zout.putNextEntry(ZipEntry(name)) + zout.putNextEntry(zipEntry(name)) activity.getFileInputStreamSync(file.path)!!.copyTo(zout) zout.closeEntry() } @@ -687,9 +695,9 @@ class ItemsAdapter( if (activity.getIsPathDirectory(file.absolutePath)) { queue.push(file.absolutePath) name = "${name.trimEnd('/')}/" - zout.putNextEntry(ZipEntry(name)) + zout.putNextEntry(zipEntry(name)) } else { - zout.putNextEntry(ZipEntry(name)) + zout.putNextEntry(zipEntry(name)) activity.getFileInputStreamSync(file.path)!!.copyTo(zout) zout.closeEntry() } @@ -698,7 +706,7 @@ class ItemsAdapter( } else { name = if (base == currentPath) currentPath.getFilenameFromPath() else mainFilePath.relativizeWith(base) - zout.putNextEntry(ZipEntry(name)) + zout.putNextEntry(zipEntry(name)) activity.getFileInputStreamSync(mainFilePath)!!.copyTo(zout) zout.closeEntry() } diff --git a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/dialogs/CompressAsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/dialogs/CompressAsDialog.kt index 29ab70de..a49febc4 100644 --- a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/dialogs/CompressAsDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/dialogs/CompressAsDialog.kt @@ -7,10 +7,9 @@ import com.simplemobiletools.commons.dialogs.FilePickerDialog import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.filemanager.pro.R import com.simplemobiletools.filemanager.pro.extensions.config -import kotlinx.android.synthetic.main.dialog_compress_as.view.filename_value -import kotlinx.android.synthetic.main.dialog_compress_as.view.folder +import kotlinx.android.synthetic.main.dialog_compress_as.view.* -class CompressAsDialog(val activity: BaseSimpleActivity, val path: String, val callback: (destination: String) -> Unit) { +class CompressAsDialog(val activity: BaseSimpleActivity, val path: String, val callback: (destination: String, password: String?) -> Unit) { private val view = activity.layoutInflater.inflate(R.layout.dialog_compress_as, null) init { @@ -29,6 +28,10 @@ class CompressAsDialog(val activity: BaseSimpleActivity, val path: String, val c realPath = it } } + + password_protect.setOnCheckedChangeListener { _, _ -> + enter_password_hint.beVisibleIf(password_protect.isChecked) + } } activity.getAlertDialogBuilder() @@ -39,6 +42,14 @@ class CompressAsDialog(val activity: BaseSimpleActivity, val path: String, val c alertDialog.showKeyboard(view.filename_value) alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(View.OnClickListener { val name = view.filename_value.value + var password: String? = null + if (view.password_protect.isChecked) { + password = view.password.value + if (password.isEmpty()) { + activity.toast(R.string.empty_password) + return@OnClickListener + } + } when { name.isEmpty() -> activity.toast(R.string.empty_name) name.isAValidFilename() -> { @@ -49,8 +60,9 @@ class CompressAsDialog(val activity: BaseSimpleActivity, val path: String, val c } alertDialog.dismiss() - callback(newPath) + callback(newPath, password) } + else -> activity.toast(R.string.invalid_name) } }) diff --git a/app/src/main/res/layout/dialog_compress_as.xml b/app/src/main/res/layout/dialog_compress_as.xml index e6642758..48b763d6 100644 --- a/app/src/main/res/layout/dialog_compress_as.xml +++ b/app/src/main/res/layout/dialog_compress_as.xml @@ -27,6 +27,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/folder_hint" + android:layout_marginBottom="@dimen/activity_margin" android:hint="@string/filename_without_zip"> + + + + + + + + From caf2788356813a0c862352d714ef7bb080a16f16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ensar=20Saraj=C4=8Di=C4=87?= Date: Fri, 7 Jul 2023 13:41:02 +0200 Subject: [PATCH 2/7] Properly set encryption method when compressing --- .../filemanager/pro/adapters/ItemsAdapter.kt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/adapters/ItemsAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/adapters/ItemsAdapter.kt index 70603dbd..37bb5ff9 100644 --- a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/adapters/ItemsAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/adapters/ItemsAdapter.kt @@ -46,6 +46,7 @@ import kotlinx.android.synthetic.main.item_file_grid.view.* import kotlinx.android.synthetic.main.item_section.view.* import net.lingala.zip4j.io.outputstream.ZipOutputStream import net.lingala.zip4j.model.ZipParameters +import net.lingala.zip4j.model.enums.EncryptionMethod import java.io.BufferedInputStream import java.io.Closeable import java.io.File @@ -652,6 +653,10 @@ class ItemsAdapter( fun zipEntry(name: String) = ZipParameters().also { it.fileNameInZip = name + if (password != null) { + it.isEncryptFiles = true + it.encryptionMethod = EncryptionMethod.AES + } } try { From 21949ef028f3d33f624b3fa7eecf6888f556e3ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ensar=20Saraj=C4=8Di=C4=87?= Date: Sat, 15 Jul 2023 16:21:55 +0200 Subject: [PATCH 3/7] Update password strings on compression dialog --- app/build.gradle | 2 +- .../filemanager/pro/dialogs/CompressAsDialog.kt | 2 +- app/src/main/res/layout/dialog_compress_as.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 12820f5d..e4f8ddfe 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -64,7 +64,7 @@ android { } dependencies { - implementation 'com.github.SimpleMobileTools:Simple-Commons:f54d4f7606' + implementation 'com.github.esensar:Simple-Commons:enter-password-dialog-improvements-SNAPSHOT' implementation 'com.github.tibbi:AndroidPdfViewer:e6a533125b' implementation 'com.github.Stericson:RootTools:df729dcb13' implementation 'com.github.Stericson:RootShell:1.6' diff --git a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/dialogs/CompressAsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/dialogs/CompressAsDialog.kt index a49febc4..e56aaca6 100644 --- a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/dialogs/CompressAsDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/dialogs/CompressAsDialog.kt @@ -46,7 +46,7 @@ class CompressAsDialog(val activity: BaseSimpleActivity, val path: String, val c if (view.password_protect.isChecked) { password = view.password.value if (password.isEmpty()) { - activity.toast(R.string.empty_password) + activity.toast(R.string.empty_password_new) return@OnClickListener } } diff --git a/app/src/main/res/layout/dialog_compress_as.xml b/app/src/main/res/layout/dialog_compress_as.xml index 48b763d6..bdd6a8d2 100644 --- a/app/src/main/res/layout/dialog_compress_as.xml +++ b/app/src/main/res/layout/dialog_compress_as.xml @@ -1,5 +1,6 @@ + android:text="@string/add_password" /> Date: Sat, 15 Jul 2023 16:22:12 +0200 Subject: [PATCH 4/7] Add eye icon to compression password entry field --- app/src/main/res/layout/dialog_compress_as.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/layout/dialog_compress_as.xml b/app/src/main/res/layout/dialog_compress_as.xml index bdd6a8d2..f5229ff1 100644 --- a/app/src/main/res/layout/dialog_compress_as.xml +++ b/app/src/main/res/layout/dialog_compress_as.xml @@ -56,6 +56,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/password_protect" + app:passwordToggleEnabled="true" android:hint="@string/password" android:visibility="gone"> From 37945290736f4d2fe006de980713d4cbc9443491 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ensar=20Saraj=C4=8Di=C4=87?= Date: Sat, 15 Jul 2023 16:46:56 +0200 Subject: [PATCH 5/7] Update Simple-Commons ref --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index e4f8ddfe..14d62b63 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -64,7 +64,7 @@ android { } dependencies { - implementation 'com.github.esensar:Simple-Commons:enter-password-dialog-improvements-SNAPSHOT' + implementation 'com.github.SimpleMobileToold:Simple-Commons:b7163c550c' implementation 'com.github.tibbi:AndroidPdfViewer:e6a533125b' implementation 'com.github.Stericson:RootTools:df729dcb13' implementation 'com.github.Stericson:RootShell:1.6' From 83e06a9646b251f8da06185899ed3648e6c5109e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ensar=20Saraj=C4=8Di=C4=87?= Date: Sat, 15 Jul 2023 16:48:09 +0200 Subject: [PATCH 6/7] Fix typo in build.gradle --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 14d62b63..78c86f0c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -64,7 +64,7 @@ android { } dependencies { - implementation 'com.github.SimpleMobileToold:Simple-Commons:b7163c550c' + implementation 'com.github.SimpleMobileTools:Simple-Commons:b7163c550c' implementation 'com.github.tibbi:AndroidPdfViewer:e6a533125b' implementation 'com.github.Stericson:RootTools:df729dcb13' implementation 'com.github.Stericson:RootShell:1.6' From 4bf66d7049be8924aa09d86a32cf60b58b424dd2 Mon Sep 17 00:00:00 2001 From: Tibor Kaputa Date: Sat, 15 Jul 2023 19:57:42 +0200 Subject: [PATCH 7/7] updating commons --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 78c86f0c..a6f6f09d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -64,7 +64,7 @@ android { } dependencies { - implementation 'com.github.SimpleMobileTools:Simple-Commons:b7163c550c' + implementation 'com.github.SimpleMobileTools:Simple-Commons:79b117a9ba' implementation 'com.github.tibbi:AndroidPdfViewer:e6a533125b' implementation 'com.github.Stericson:RootTools:df729dcb13' implementation 'com.github.Stericson:RootShell:1.6'