From 07b75a5fe1a3f32bd87d1d00f8aa036ba7c580d9 Mon Sep 17 00:00:00 2001 From: tibbi Date: Wed, 24 Jan 2018 21:38:23 +0100 Subject: [PATCH] rewrite root folders handling, do not use "awk" command --- app/build.gradle | 2 +- .../filemanager/activities/MainActivity.kt | 2 +- .../activities/SettingsActivity.kt | 2 +- .../filemanager/fragments/ItemsFragment.kt | 14 +-- .../filemanager/helpers/Config.kt | 4 - .../filemanager/helpers/RootHelpers.kt | 110 +++++++++++++----- 6 files changed, 91 insertions(+), 43 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index fd8dec94..b84ccfc2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -42,7 +42,7 @@ ext { } dependencies { - implementation 'com.simplemobiletools:commons:3.8.7' + implementation 'com.simplemobiletools:commons:3.8.8' implementation files('../libs/RootTools.jar') diff --git a/app/src/main/kotlin/com/simplemobiletools/filemanager/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/filemanager/activities/MainActivity.kt index 308f7714..9d573e2c 100644 --- a/app/src/main/kotlin/com/simplemobiletools/filemanager/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/filemanager/activities/MainActivity.kt @@ -284,7 +284,7 @@ class MainActivity : SimpleActivity() { Thread { config.isRootAvailable = RootTools.isRootAvailable() if (config.isRootAvailable && config.enableRootAccess) { - RootHelpers().askRootIFNeeded(this) { + RootHelpers().askRootIfNeeded(this) { config.enableRootAccess = it } } diff --git a/app/src/main/kotlin/com/simplemobiletools/filemanager/activities/SettingsActivity.kt b/app/src/main/kotlin/com/simplemobiletools/filemanager/activities/SettingsActivity.kt index 531bee5e..5be50cb1 100644 --- a/app/src/main/kotlin/com/simplemobiletools/filemanager/activities/SettingsActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/filemanager/activities/SettingsActivity.kt @@ -119,7 +119,7 @@ class SettingsActivity : SimpleActivity() { settings_enable_root_access.isChecked = config.enableRootAccess settings_enable_root_access_holder.setOnClickListener { if (!config.enableRootAccess) { - RootHelpers().askRootIFNeeded(this) { + RootHelpers().askRootIfNeeded(this) { toggleRootAccess(it) } } else { diff --git a/app/src/main/kotlin/com/simplemobiletools/filemanager/fragments/ItemsFragment.kt b/app/src/main/kotlin/com/simplemobiletools/filemanager/fragments/ItemsFragment.kt index 5f37b78f..7a4954a4 100644 --- a/app/src/main/kotlin/com/simplemobiletools/filemanager/fragments/ItemsFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/filemanager/fragments/ItemsFragment.kt @@ -122,15 +122,15 @@ class ItemsFragment : Fragment(), ItemOperationsListener, Breadcrumbs.Breadcrumb scrollStates[currentPath] = getScrollState() currentPath = realPath showHidden = context!!.config.shouldShowHidden - getItems(currentPath) { - if (!isAdded) { + getItems(currentPath) { originalPath, fileDirItems -> + if (currentPath != originalPath || !isAdded) { return@getItems } FileDirItem.sorting = context!!.config.getFolderSorting(currentPath) - it.sort() + fileDirItems.sort() activity!!.runOnUiThread { - addItems(it) + addItems(fileDirItems) } } } @@ -170,7 +170,7 @@ class ItemsFragment : Fragment(), ItemOperationsListener, Breadcrumbs.Breadcrumb private fun getRecyclerLayoutManager() = (mView.items_list.layoutManager as LinearLayoutManager) - private fun getItems(path: String, callback: (items: ArrayList) -> Unit) { + private fun getItems(path: String, callback: (originalPath: String, items: ArrayList) -> Unit) { skipItemUpdating = false Thread { if (activity?.isActivityDestroyed() == false) { @@ -183,7 +183,7 @@ class ItemsFragment : Fragment(), ItemOperationsListener, Breadcrumbs.Breadcrumb }.start() } - private fun getRegularItemsOf(path: String, callback: (items: ArrayList) -> Unit) { + private fun getRegularItemsOf(path: String, callback: (originalPath: String, items: ArrayList) -> Unit) { val items = ArrayList() val files = File(path).listFiles()?.filterNotNull() if (files != null) { @@ -200,7 +200,7 @@ class ItemsFragment : Fragment(), ItemOperationsListener, Breadcrumbs.Breadcrumb items.add(fileDirItem) } } - callback(items) + callback(path, items) } private fun getChildrenCount(file: File): Int { diff --git a/app/src/main/kotlin/com/simplemobiletools/filemanager/helpers/Config.kt b/app/src/main/kotlin/com/simplemobiletools/filemanager/helpers/Config.kt index c8bf4fa1..2844f534 100644 --- a/app/src/main/kotlin/com/simplemobiletools/filemanager/helpers/Config.kt +++ b/app/src/main/kotlin/com/simplemobiletools/filemanager/helpers/Config.kt @@ -75,8 +75,4 @@ class Config(context: Context) : BaseConfig(context) { var enableRootAccess: Boolean get() = prefs.getBoolean(ENABLE_ROOT_ACCESS, false) set(enableRootAccess) = prefs.edit().putBoolean(ENABLE_ROOT_ACCESS, enableRootAccess).apply() - - var lsHasHardLinksColumn: Boolean - get() = prefs.getBoolean(LS_HAS_HARD_LINKS_COLUMN, false) - set(lsHasHardLinksColumn) = prefs.edit().putBoolean(LS_HAS_HARD_LINKS_COLUMN, lsHasHardLinksColumn).apply() } 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 5c4bcc1f..41c3132f 100644 --- a/app/src/main/kotlin/com/simplemobiletools/filemanager/helpers/RootHelpers.kt +++ b/app/src/main/kotlin/com/simplemobiletools/filemanager/helpers/RootHelpers.kt @@ -1,6 +1,5 @@ package com.simplemobiletools.filemanager.helpers -import android.text.TextUtils import com.simplemobiletools.commons.extensions.areDigitsOnly import com.simplemobiletools.commons.extensions.showErrorToast import com.simplemobiletools.commons.models.FileDirItem @@ -8,13 +7,13 @@ import com.simplemobiletools.filemanager.activities.SimpleActivity import com.simplemobiletools.filemanager.extensions.config import com.stericson.RootShell.execution.Command import com.stericson.RootTools.RootTools +import java.io.File import java.util.* class RootHelpers { - fun askRootIFNeeded(activity: SimpleActivity, callback: (success: Boolean) -> Unit) { - val command = object : Command(0, "ls -la | awk '{ print $2 }'") { + fun askRootIfNeeded(activity: SimpleActivity, callback: (success: Boolean) -> Unit) { + val command = object : Command(0, "ls -lA") { override fun commandOutput(id: Int, line: String) { - activity.config.lsHasHardLinksColumn = line.areDigitsOnly() callback(true) super.commandOutput(id, line) } @@ -28,43 +27,96 @@ class RootHelpers { } } - fun getFiles(activity: SimpleActivity, path: String, callback: (fileDirItems: ArrayList) -> Unit) { + fun getFiles(activity: SimpleActivity, path: String, callback: (originalPath: String, fileDirItems: ArrayList) -> Unit) { val files = ArrayList() - val showHidden = activity.config.shouldShowHidden - val sizeColumnIndex = if (activity.config.lsHasHardLinksColumn) 5 else 4 + val hiddenArgument = if (activity.config.shouldShowHidden) "-A " else "" + val cmd = "ls $hiddenArgument$path" - val cmd = "ls -la $path | awk '{ system(\"echo \"\$1\" \"\$$sizeColumnIndex\" `find ${path.trimEnd('/')}/\"\$NF\" -mindepth 1 -maxdepth 1 | wc -l` \"\$NF\" \")}'" val command = object : Command(0, cmd) { override fun commandOutput(id: Int, line: String) { - val parts = line.split(" ") - if (parts.size >= 4) { - val permissions = parts[0].trim() - val isDirectory = permissions.startsWith("d") - val isFile = permissions.startsWith("-") - val size = if (isFile) parts[1].trim() else "0" - val childrenCnt = if (isFile) "0" else parts[2].trim() - val filename = TextUtils.join(" ", parts.subList(3, parts.size)).trimStart('/') - - if ((!showHidden && filename.startsWith(".")) || (!isDirectory && !isFile) || !size.areDigitsOnly() || !childrenCnt.areDigitsOnly()) { - super.commandOutput(id, line) - return - } - - val fileSize = size.toLong() - val filePath = "${path.trimEnd('/')}/$filename" - val fileDirItem = FileDirItem(filePath, filename, isDirectory, childrenCnt.toInt(), fileSize) - files.add(fileDirItem) - } - + val file = File(path, line) + val isDirectory = file.isDirectory + val fileDirItem = FileDirItem(file.absolutePath, line, isDirectory, 0, 0) + files.add(fileDirItem) super.commandOutput(id, line) } override fun commandCompleted(id: Int, exitcode: Int) { - callback(files) + getChildrenCount(activity, files, path, callback) super.commandCompleted(id, exitcode) } } + runCommand(activity, command) + } + + private fun getChildrenCount(activity: SimpleActivity, files: ArrayList, path: String, callback: (originalPath: String, fileDirItems: ArrayList) -> Unit) { + val hiddenArgument = if (activity.config.shouldShowHidden) "-A " else "" + var cmd = "" + files.forEach { + cmd += if (it.isDirectory) { + "ls $hiddenArgument${it.path} |wc -l;" + } else { + "echo 0;" + } + } + cmd = cmd.trimEnd(';') + " | cat" + + val lines = ArrayList() + val command = object : Command(0, cmd) { + override fun commandOutput(id: Int, line: String) { + lines.add(line) + super.commandOutput(id, line) + } + + override fun commandCompleted(id: Int, exitcode: Int) { + files.forEachIndexed { index, fileDirItem -> + val childrenCount = lines[index] + if (childrenCount.areDigitsOnly()) { + fileDirItem.children = childrenCount.toInt() + } + } + getFileSizes(activity, files, path, callback) + super.commandCompleted(id, exitcode) + } + } + + runCommand(activity, command) + } + + private fun getFileSizes(activity: SimpleActivity, files: ArrayList, path: String, callback: (originalPath: String, fileDirItems: ArrayList) -> Unit) { + var cmd = "" + files.forEach { + cmd += if (it.isDirectory) { + "echo 0;" + } else { + "stat -c %s ${it.path};" + } + } + + val lines = ArrayList() + val command = object : Command(0, cmd) { + override fun commandOutput(id: Int, line: String) { + lines.add(line) + super.commandOutput(id, line) + } + + override fun commandCompleted(id: Int, exitcode: Int) { + files.forEachIndexed { index, fileDirItem -> + val childrenCount = lines[index] + if (childrenCount.areDigitsOnly()) { + fileDirItem.size = childrenCount.toLong() + } + } + callback(path, files) + super.commandCompleted(id, exitcode) + } + } + + runCommand(activity, command) + } + + private fun runCommand(activity: SimpleActivity, command: Command) { try { RootTools.getShell(true).add(command) } catch (e: Exception) {