From dc694aad9cdc269918b1e30476a08b7ae885406d Mon Sep 17 00:00:00 2001 From: imkiva Date: Sat, 8 May 2021 16:41:20 +0800 Subject: [PATCH] MISC: enhance code step 2 (runApt) --- .../frontend/floating/TerminalDialog.kt | 18 ++--- .../neoterm/ui/pm/PackageManagerActivity.kt | 73 +++++-------------- .../ui/settings/GeneralSettingsActivity.kt | 14 +--- .../java/io/neoterm/ui/setup/SetupActivity.kt | 12 +-- app/src/main/java/io/neoterm/utils/utils.kt | 48 +++++------- 5 files changed, 55 insertions(+), 110 deletions(-) diff --git a/app/src/main/java/io/neoterm/frontend/floating/TerminalDialog.kt b/app/src/main/java/io/neoterm/frontend/floating/TerminalDialog.kt index 918f569..a62bf20 100644 --- a/app/src/main/java/io/neoterm/frontend/floating/TerminalDialog.kt +++ b/app/src/main/java/io/neoterm/frontend/floating/TerminalDialog.kt @@ -11,28 +11,24 @@ import io.neoterm.frontend.session.shell.client.BasicSessionCallback import io.neoterm.frontend.session.shell.client.BasicViewClient import io.neoterm.utils.Terminals +typealias DialogSessionFinished = (TerminalDialog, TerminalSession?) -> Unit + /** * @author kiva */ class TerminalDialog(val context: Context) { - - interface SessionFinishedCallback { - fun onSessionFinished(dialog: TerminalDialog, finishedSession: TerminalSession?) - } - - private var termWindowView = WindowTermView(context) - private var terminalSessionCallback: BasicSessionCallback + private val termWindowView = WindowTermView(context) + private val terminalSessionCallback: BasicSessionCallback private var dialog: AlertDialog? = null private var terminalSession: TerminalSession? = null - private var sessionFinishedCallback: SessionFinishedCallback? = null + private var sessionFinishedCallback: DialogSessionFinished? = null private var cancelListener: DialogInterface.OnCancelListener? = null init { termWindowView.setTerminalViewClient(BasicViewClient(termWindowView.terminalView)) - terminalSessionCallback = object : BasicSessionCallback(termWindowView.terminalView) { override fun onSessionFinished(finishedSession: TerminalSession?) { - sessionFinishedCallback?.onSessionFinished(this@TerminalDialog, finishedSession) + sessionFinishedCallback?.let { it(this@TerminalDialog, finishedSession) } super.onSessionFinished(finishedSession) } } @@ -74,7 +70,7 @@ class TerminalDialog(val context: Context) { return this } - fun onFinish(finishedCallback: SessionFinishedCallback): TerminalDialog { + fun onFinish(finishedCallback: DialogSessionFinished): TerminalDialog { this.sessionFinishedCallback = finishedCallback return this } diff --git a/app/src/main/java/io/neoterm/ui/pm/PackageManagerActivity.kt b/app/src/main/java/io/neoterm/ui/pm/PackageManagerActivity.kt index 725e64b..aef7095 100644 --- a/app/src/main/java/io/neoterm/ui/pm/PackageManagerActivity.kt +++ b/app/src/main/java/io/neoterm/ui/pm/PackageManagerActivity.kt @@ -16,12 +16,9 @@ import androidx.core.view.MenuItemCompat import androidx.recyclerview.widget.LinearLayoutManager import com.github.wrdlbrnft.sortedlistadapter.SortedListAdapter import io.neoterm.R -import io.neoterm.backend.TerminalSession import io.neoterm.component.pm.* import io.neoterm.frontend.component.ComponentManager import io.neoterm.frontend.config.NeoPreference -import io.neoterm.frontend.config.NeoTermPath -import io.neoterm.frontend.floating.TerminalDialog import io.neoterm.ui.pm.adapter.PackageAdapter import io.neoterm.ui.pm.model.PackageModel import io.neoterm.ui.pm.utils.StringDistance @@ -57,9 +54,9 @@ class PackageManagerActivity : AppCompatActivity(), SearchView.OnQueryTextListen AlertDialog.Builder(this@PackageManagerActivity) .setTitle(model.packageInfo.packageName) .setMessage(model.getPackageDetails(this@PackageManagerActivity)) - .setPositiveButton(R.string.install, { _, _ -> + .setPositiveButton(R.string.install) { _, _ -> installPackage(model.packageInfo.packageName) - }) + } .setNegativeButton(android.R.string.no, null) .show() } @@ -74,21 +71,9 @@ class PackageManagerActivity : AppCompatActivity(), SearchView.OnQueryTextListen refreshPackageList() } - private fun installPackage(packageName: String?) { - if (packageName != null) { - TerminalDialog(this@PackageManagerActivity) - .execute( - NeoTermPath.APT_BIN_PATH, - arrayOf("apt", "install", "-y", packageName) - ) - .onFinish(object : TerminalDialog.SessionFinishedCallback { - override fun onSessionFinished(dialog: TerminalDialog, finishedSession: TerminalSession?) { - dialog.setTitle(getString(R.string.done)) - } - }) - .imeEnabled(true) - .show("Installing $packageName") - Toast.makeText(this, R.string.installing_topic, Toast.LENGTH_LONG).show() + private fun installPackage(packageName: String?) = packageName?.let { + runApt("install", "-y", it, autoClose = false) { + it.onSuccess { it.setTitle(getString(R.string.done)) } } } @@ -115,18 +100,15 @@ class PackageManagerActivity : AppCompatActivity(), SearchView.OnQueryTextListen val sourceManager = ComponentManager.getComponent().sourceManager val sourceList = sourceManager.getAllSources() + val items = sourceList.map { "${it.url} :: ${it.repo}" }.toTypedArray() + val selection = sourceList.map { it.enabled }.toBooleanArray() AlertDialog.Builder(this) .setTitle(R.string.pref_package_source) - .setMultiChoiceItems(sourceList.map { "${it.url} :: ${it.repo}" }.toTypedArray(), - sourceList.map { it.enabled }.toBooleanArray(), { dialog, which, isChecked -> - sourceList[which].enabled = isChecked - }) - .setPositiveButton(android.R.string.yes, { _, _ -> - changeSourceInternal(sourceManager, sourceList) - }) - .setNeutralButton(R.string.new_source, { _, _ -> - changeSourceToUserInput(sourceManager) - }) + .setMultiChoiceItems(items, selection) { _, which, isChecked -> + sourceList[which].enabled = isChecked + } + .setPositiveButton(android.R.string.yes) { _, _ -> changeSourceInternal(sourceManager, sourceList) } + .setNeutralButton(R.string.new_source) { _, _ -> changeSourceToUserInput(sourceManager) } .setNegativeButton(android.R.string.no, null) .show() } @@ -145,7 +127,7 @@ class PackageManagerActivity : AppCompatActivity(), SearchView.OnQueryTextListen .setTitle(R.string.pref_package_source) .setView(view) .setNegativeButton(android.R.string.no, null) - .setPositiveButton(android.R.string.yes, { _, _ -> + .setPositiveButton(android.R.string.yes) { _, _ -> val url = urlEditor.text.toString() val repo = repoEditor.text.toString() var errored = false @@ -163,7 +145,7 @@ class PackageManagerActivity : AppCompatActivity(), SearchView.OnQueryTextListen val source = urlEditor.text.toString() sourceManager.addSource(source, repo, true) postChangeSource(sourceManager) - }) + } .show() } @@ -179,30 +161,15 @@ class PackageManagerActivity : AppCompatActivity(), SearchView.OnQueryTextListen executeAptUpdate() } - private fun executeAptUpdate() = runApt("update", null) { exitStatus, dialog -> - if (exitStatus != 0) { - dialog.setTitle(getString(R.string.error)) - return@runApt - } - Toast.makeText(this, R.string.apt_update_ok, Toast.LENGTH_SHORT).show() - dialog.dismiss() - refreshPackageList() + private fun executeAptUpdate() = runApt("update") { + it.onSuccess { refreshPackageList() } } - private fun executeAptUpgrade() = runApt("update", null) { exitStatus, dialog -> - if (exitStatus != 0) { - dialog.setTitle(getString(R.string.error)) - return@runApt - } - dialog.dismiss() - - runApt("upgrade", arrayOf("-y")) aptUpgrade@{ exitStatus, dialog -> - if (exitStatus != 0) { - dialog.setTitle(getString(R.string.error)) - return@aptUpgrade + private fun executeAptUpgrade() = runApt("update") { update -> + update.onSuccess { + runApt("upgrade", "-y") { + it.onSuccess { Toast.makeText(this, R.string.apt_upgrade_ok, Toast.LENGTH_SHORT).show() } } - Toast.makeText(this, R.string.apt_upgrade_ok, Toast.LENGTH_SHORT).show() - dialog.dismiss() } } diff --git a/app/src/main/java/io/neoterm/ui/settings/GeneralSettingsActivity.kt b/app/src/main/java/io/neoterm/ui/settings/GeneralSettingsActivity.kt index 361f167..5a33efa 100644 --- a/app/src/main/java/io/neoterm/ui/settings/GeneralSettingsActivity.kt +++ b/app/src/main/java/io/neoterm/ui/settings/GeneralSettingsActivity.kt @@ -40,17 +40,12 @@ class GeneralSettingsActivity : BasePreferenceActivity() { .setTitle(getString(R.string.shell_not_found, shellName)) .setMessage(R.string.shell_not_found_message) .setPositiveButton(R.string.install) { _, _ -> - runApt("install", arrayOf("-y", shellName)) { exitStatus, dialog -> - if (exitStatus == 0) { - dialog.dismiss() - postChangeShell(shellName) - } else dialog.setTitle(getString(R.string.error)) + runApt("install", "-y", shellName) { + it.onSuccess { postChangeShell(shellName) } } } .setNegativeButton(android.R.string.no, null) - .setOnDismissListener { - postChangeShell(currentShell) - } + .setOnDismissListener { postChangeShell(currentShell) } .show() } @@ -59,8 +54,7 @@ class GeneralSettingsActivity : BasePreferenceActivity() { override fun onOptionsItemSelected(item: MenuItem?): Boolean { when (item?.itemId) { - android.R.id.home -> - finish() + android.R.id.home -> finish() } return super.onOptionsItemSelected(item) } diff --git a/app/src/main/java/io/neoterm/ui/setup/SetupActivity.kt b/app/src/main/java/io/neoterm/ui/setup/SetupActivity.kt index 982bf01..fec5832 100644 --- a/app/src/main/java/io/neoterm/ui/setup/SetupActivity.kt +++ b/app/src/main/java/io/neoterm/ui/setup/SetupActivity.kt @@ -234,11 +234,11 @@ class SetupActivity : AppCompatActivity(), View.OnClickListener, ResultListener } } - private fun executeAptUpdate() = runApt("update") - .onSuccess { executeAptUpgrade() } - .onFailure { Toast.makeText(this, R.string.error, Toast.LENGTH_SHORT).show() } + private fun executeAptUpdate() = runApt("update") { + it.onSuccess { executeAptUpgrade() } + } - private fun executeAptUpgrade() = runApt("upgrade", "-y") - .onSuccess { finish() } - .onFailure { Toast.makeText(this, R.string.error, Toast.LENGTH_SHORT).show() } + private fun executeAptUpgrade() = runApt("upgrade", "-y") { + it.onSuccess { finish() } + } } diff --git a/app/src/main/java/io/neoterm/utils/utils.kt b/app/src/main/java/io/neoterm/utils/utils.kt index 73d8015..5fbc81b 100644 --- a/app/src/main/java/io/neoterm/utils/utils.kt +++ b/app/src/main/java/io/neoterm/utils/utils.kt @@ -6,7 +6,7 @@ import android.net.Uri import android.os.Environment import android.provider.DocumentsContract import android.provider.MediaStore -import io.neoterm.backend.TerminalSession +import io.neoterm.R import io.neoterm.frontend.config.NeoTermPath import io.neoterm.frontend.floating.TerminalDialog import java.io.File @@ -49,23 +49,23 @@ fun Context.extractAssetsDir(dirName: String, extractDir: String) { } } -fun Context.runApt(subCommand: String, vararg extraArgs: String): Result = runAsyncCatching { - val args = arrayOf(NeoTermPath.APT_BIN_PATH, subCommand, *extraArgs) - TerminalDialog(this) - .onFinish(object : TerminalDialog.SessionFinishedCallback { - override fun onSessionFinished(dialog: TerminalDialog, finishedSession: TerminalSession?) { - val exit = finishedSession?.exitStatus ?: 1 - if (exit == 0) { - dialog.dismiss() - throw SuccessResult(dialog) - } - else throw RuntimeException() - } - }) - .imeEnabled(true) - .execute(NeoTermPath.APT_BIN_PATH, args) - .show("apt $subCommand") -} +fun Context.runApt( + subCommand: String, vararg extraArgs: String, + autoClose: Boolean = true, block: (Result) -> Unit +) = TerminalDialog(this) + .execute(NeoTermPath.APT_BIN_PATH, arrayOf(NeoTermPath.APT_BIN_PATH, subCommand, *extraArgs)) + .imeEnabled(true) + .onFinish { dialog, session -> + val exit = session?.exitStatus ?: 1 + if (exit == 0) { + if (autoClose) dialog.dismiss() + block(Result.success(dialog)) + } else { + dialog.setTitle(getString(R.string.error)) + block(Result.failure(RuntimeException())) + } + } + .show("apt $subCommand") /** * Get a file path from a Uri. This will get the the path for Storage Access @@ -121,15 +121,3 @@ private fun getDataColumn(context: Context, uri: Uri, selection: String?, select private fun isExternalStorageDocument(uri: Uri) = "com.android.externalstorage.documents" == uri.authority private fun isDownloadsDocument(uri: Uri) = "com.android.providers.downloads.documents" == uri.authority private fun isMediaDocument(uri: Uri) = "com.android.providers.media.documents" == uri.authority - -data class SuccessResult(val data: Any) : RuntimeException() - -inline fun runAsyncCatching(block: () -> Unit): Result = try { - block() - Result.failure(IllegalStateException()) -} catch (s: SuccessResult) { - if (s.data is R) Result.success(s.data) - else Result.failure(ClassCastException()) -} catch (e: Throwable) { - Result.failure(e) -}