implement root file creation

This commit is contained in:
tibbi 2018-04-16 12:28:04 +02:00
parent c17b7e885c
commit cdedabddbb
2 changed files with 111 additions and 17 deletions

View File

@ -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)

View File

@ -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<String>()
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)
}
}