diff --git a/app/src/main/kotlin/com/simplemobiletools/filemanager/dialogs/CreateNewItemDialog.kt b/app/src/main/kotlin/com/simplemobiletools/filemanager/dialogs/CreateNewItemDialog.kt index f1ef9329..a68615f1 100644 --- a/app/src/main/kotlin/com/simplemobiletools/filemanager/dialogs/CreateNewItemDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/filemanager/dialogs/CreateNewItemDialog.kt @@ -2,14 +2,15 @@ package com.simplemobiletools.filemanager.dialogs import android.support.v7.app.AlertDialog import android.view.View -import com.simplemobiletools.commons.activities.BaseSimpleActivity import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.filemanager.R +import com.simplemobiletools.filemanager.activities.SimpleActivity +import com.simplemobiletools.filemanager.helpers.RootHelpers import kotlinx.android.synthetic.main.dialog_create_new.view.* import java.io.File import java.io.IOException -class CreateNewItemDialog(val activity: BaseSimpleActivity, val path: String, val callback: (success: Boolean) -> Unit) { +class CreateNewItemDialog(val activity: SimpleActivity, val path: String, val callback: (success: Boolean) -> Unit) { private val view = activity.layoutInflater.inflate(R.layout.dialog_create_new, null) init { @@ -60,29 +61,44 @@ class CreateNewItemDialog(val activity: BaseSimpleActivity, val path: String, va documentFile.createDirectory(path.getFilenameFromPath()) success(alertDialog) } - File(path).mkdirs() -> { - success(alertDialog) + path.startsWith(activity.internalStoragePath, true) -> { + if (File(path).mkdirs()) { + success(alertDialog) + } } - else -> callback(false) } } private fun createFile(path: String, alertDialog: AlertDialog, callback: (Boolean) -> Unit) { try { - if (activity.needsStupidWritePermissions(path)) { - activity.handleSAFDialog(path) { - val documentFile = activity.getDocumentFile(path.getParentPath()) - if (documentFile == null) { - val error = String.format(activity.getString(R.string.could_not_create_file), path) - activity.showErrorToast(error) - callback(false) - return@handleSAFDialog + when { + activity.needsStupidWritePermissions(path) -> { + activity.handleSAFDialog(path) { + val documentFile = activity.getDocumentFile(path.getParentPath()) + if (documentFile == null) { + val error = String.format(activity.getString(R.string.could_not_create_file), path) + activity.showErrorToast(error) + callback(false) + return@handleSAFDialog + } + documentFile.createFile(path.getMimeType(), path.getFilenameFromPath()) + success(alertDialog) + } + } + path.startsWith(activity.internalStoragePath, true) -> { + if (File(path).createNewFile()) { + success(alertDialog) + } + } + else -> { + RootHelpers().createFile(activity, path) { + if (it) { + success(alertDialog) + } else { + callback(false) + } } - documentFile.createFile(path.getMimeType(), path.getFilenameFromPath()) - success(alertDialog) } - } else if (File(path).createNewFile()) { - success(alertDialog) } } catch (exception: IOException) { activity.showErrorToast(exception) diff --git a/app/src/main/kotlin/com/simplemobiletools/filemanager/helpers/RootHelpers.kt b/app/src/main/kotlin/com/simplemobiletools/filemanager/helpers/RootHelpers.kt index 49e4825c..d9777127 100644 --- a/app/src/main/kotlin/com/simplemobiletools/filemanager/helpers/RootHelpers.kt +++ b/app/src/main/kotlin/com/simplemobiletools/filemanager/helpers/RootHelpers.kt @@ -129,4 +129,82 @@ class RootHelpers { activity.showErrorToast(e) } } + + fun createFile(activity: SimpleActivity, path: String, callback: (success: Boolean) -> Unit) { + tryMountAsRW(activity, path) { + val mountPoint = it + val targetPath = path.trim('/') + val cmd = "touch \"/$targetPath\"" + val command = object : Command(0, cmd) { + override fun commandCompleted(id: Int, exitcode: Int) { + callback(exitcode == 0) + mountAsRO(activity, mountPoint) + super.commandCompleted(id, exitcode) + } + } + + runCommand(activity, command) + } + } + + private fun mountAsRO(activity: SimpleActivity, mountPoint: String?) { + if (mountPoint != null) { + val cmd = "umount -r \"$mountPoint\"" + val command = object : Command(0, cmd) {} + runCommand(activity, command) + } + } + + // inspired by Amaze File Manager + private fun tryMountAsRW(activity: SimpleActivity, path: String, callback: (mountPoint: String?) -> Unit) { + val mountPoints = ArrayList() + + val command = object : Command(0, "mount") { + override fun commandOutput(id: Int, line: String) { + mountPoints.add(line) + super.commandOutput(id, line) + } + + override fun commandCompleted(id: Int, exitcode: Int) { + var mountPoint = "" + var types: String? = null + for (line in mountPoints) { + val words = line.split(" ").filter { it.isNotEmpty() } + + if (path.contains(words[2])) { + if (words[2].length > mountPoint.length) { + mountPoint = words[2] + types = words[5] + } + } + } + + if (mountPoint != "" && types != null) { + if (types.contains("rw")) { + callback(null) + } else if (types.contains("ro")) { + val mountCommand = "mount -o rw,remount $mountPoint" + mountAsRW(activity, mountCommand) { + callback(it) + } + } + } + + super.commandCompleted(id, exitcode) + } + } + + runCommand(activity, command) + } + + private fun mountAsRW(activity: SimpleActivity, commandString: String, callback: (mountPoint: String) -> Unit) { + val command = object : Command(0, commandString) { + override fun commandOutput(id: Int, line: String) { + callback(line) + super.commandOutput(id, line) + } + } + + runCommand(activity, command) + } }