Feature: Now we can use system shell if base fail installation failed
This commit is contained in:
parent
4a44777c92
commit
35cd6f698e
@ -1,15 +1,11 @@
|
||||
package io.neoterm.installer;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.DialogInterface.OnClickListener;
|
||||
import android.os.Build;
|
||||
import android.system.Os;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
@ -27,11 +23,14 @@ import io.neoterm.backend.EmulatorDebug;
|
||||
import io.neoterm.preference.NeoTermPreference;
|
||||
|
||||
public final class BaseFileInstaller {
|
||||
public static interface ResultListener {
|
||||
void onResult(Exception error);
|
||||
}
|
||||
|
||||
public static void installBaseFiles(final Activity activity, final Runnable whenDone) {
|
||||
public static void installBaseFiles(final Activity activity, final ResultListener resultListener) {
|
||||
final File PREFIX_FILE = new File(NeoTermPreference.USR_PATH);
|
||||
if (PREFIX_FILE.isDirectory()) {
|
||||
whenDone.run();
|
||||
resultListener.onResult(null);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -102,7 +101,7 @@ public final class BaseFileInstaller {
|
||||
activity.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
whenDone.run();
|
||||
resultListener.onResult(null);
|
||||
}
|
||||
});
|
||||
} catch (final Exception e) {
|
||||
@ -111,21 +110,8 @@ public final class BaseFileInstaller {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
new AlertDialog.Builder(activity).setTitle("ERROR").setMessage(e.toString())
|
||||
.setNegativeButton("Abort", new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.dismiss();
|
||||
activity.finish();
|
||||
}
|
||||
}).setPositiveButton("Retry", new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.dismiss();
|
||||
BaseFileInstaller.installBaseFiles(activity, whenDone);
|
||||
}
|
||||
}).show();
|
||||
} catch (WindowManager.BadTokenException e) {
|
||||
resultListener.onResult(e);
|
||||
} catch (RuntimeException e) {
|
||||
// Activity already dismissed - ignore.
|
||||
}
|
||||
}
|
||||
@ -151,7 +137,7 @@ public final class BaseFileInstaller {
|
||||
return new URL("https://kernel19.cc/neoterm/boot/" + archName + ".zip");
|
||||
}
|
||||
|
||||
private static String determineArchName() {
|
||||
public static String determineArchName() {
|
||||
for (String androidArch : Build.SUPPORTED_ABIS) {
|
||||
switch (androidArch) {
|
||||
case "arm64-v8a":
|
||||
|
@ -87,7 +87,7 @@ object NeoTermPreference {
|
||||
return null
|
||||
}
|
||||
|
||||
fun buildEnvironment(cwd: String?): Array<String> {
|
||||
fun buildEnvironment(cwd: String?, systemShell: Boolean): Array<String> {
|
||||
var cwd = cwd
|
||||
File(HOME_PATH).mkdirs()
|
||||
|
||||
@ -99,14 +99,19 @@ object NeoTermPreference {
|
||||
val androidDataEnv = "ANDROID_DATA=" + System.getenv("ANDROID_DATA")
|
||||
val externalStorageEnv = "EXTERNAL_STORAGE=" + System.getenv("EXTERNAL_STORAGE")
|
||||
|
||||
val ps1Env = "PS1=$ "
|
||||
val ldEnv = "LD_LIBRARY_PATH=$USR_PATH/lib"
|
||||
val langEnv = "LANG=en_US.UTF-8"
|
||||
val pathEnv = "PATH=$USR_PATH/bin:$USR_PATH/bin/applets"
|
||||
val pwdEnv = "PWD=" + cwd
|
||||
val tmpdirEnv = "TMPDIR=$USR_PATH/tmp"
|
||||
if (systemShell) {
|
||||
val pathEnv = "PATH=" + System.getenv("PATH")
|
||||
return arrayOf(termEnv, homeEnv, androidRootEnv, androidDataEnv, externalStorageEnv, pathEnv)
|
||||
|
||||
return arrayOf(termEnv, homeEnv, ps1Env, ldEnv, langEnv, pathEnv, pwdEnv, androidRootEnv, androidDataEnv, externalStorageEnv, tmpdirEnv)
|
||||
} else {
|
||||
val ps1Env = "PS1=$ "
|
||||
val ldEnv = "LD_LIBRARY_PATH=$USR_PATH/lib"
|
||||
val langEnv = "LANG=en_US.UTF-8"
|
||||
val pathEnv = "PATH=$USR_PATH/bin:$USR_PATH/bin/applets"
|
||||
val pwdEnv = "PWD=" + cwd
|
||||
val tmpdirEnv = "TMPDIR=$USR_PATH/tmp"
|
||||
|
||||
return arrayOf(termEnv, homeEnv, ps1Env, ldEnv, langEnv, pathEnv, pwdEnv, androidRootEnv, androidDataEnv, externalStorageEnv, tmpdirEnv)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ class NeoTermService : Service() {
|
||||
val sessions: List<TerminalSession>
|
||||
get() = mTerminalSessions
|
||||
|
||||
fun createTermSession(executablePath: String?, arguments: Array<String>?, cwd: String?, env: Array<String>?, sessionCallback: TerminalSession.SessionChangedCallback?): TerminalSession {
|
||||
fun createTermSession(executablePath: String?, arguments: Array<String>?, cwd: String?, env: Array<String>?, sessionCallback: TerminalSession.SessionChangedCallback?, systemShell: Boolean): TerminalSession {
|
||||
var executablePath = executablePath
|
||||
var arguments = arguments
|
||||
|
||||
@ -77,14 +77,14 @@ class NeoTermService : Service() {
|
||||
}
|
||||
|
||||
if (executablePath == null) {
|
||||
executablePath = NeoTermPreference.USR_PATH + "/bin/bash"
|
||||
executablePath = if (systemShell) "/system/bin/sh" else NeoTermPreference.USR_PATH + "/bin/sh"
|
||||
}
|
||||
|
||||
if (arguments == null) {
|
||||
arguments = arrayOf<String>(executablePath)
|
||||
}
|
||||
|
||||
val session = TerminalSession(executablePath, cwd, arguments, env ?: NeoTermPreference.buildEnvironment(cwd), sessionCallback)
|
||||
val session = TerminalSession(executablePath, cwd, arguments, env ?: NeoTermPreference.buildEnvironment(cwd, systemShell), sessionCallback)
|
||||
mTerminalSessions.add(session)
|
||||
updateNotification()
|
||||
return session
|
||||
|
@ -31,6 +31,7 @@ import io.neoterm.view.tab.*
|
||||
|
||||
class NeoTermActivity : AppCompatActivity(), ServiceConnection {
|
||||
lateinit var tabSwitcher: TabSwitcher
|
||||
var systemShell = true
|
||||
var termService: NeoTermService? = null
|
||||
|
||||
override fun onServiceDisconnected(name: ComponentName?) {
|
||||
@ -46,17 +47,35 @@ class NeoTermActivity : AppCompatActivity(), ServiceConnection {
|
||||
return
|
||||
}
|
||||
|
||||
BaseFileInstaller.installBaseFiles(this, {
|
||||
if (!termService!!.sessions.isEmpty()) {
|
||||
for (session in termService!!.sessions) {
|
||||
addNewSession(session)
|
||||
var resultListener: BaseFileInstaller.ResultListener? = null
|
||||
resultListener = BaseFileInstaller.ResultListener { error ->
|
||||
if (error == null) {
|
||||
systemShell = false
|
||||
if (!termService!!.sessions.isEmpty()) {
|
||||
for (session in termService!!.sessions) {
|
||||
addNewSession(session)
|
||||
}
|
||||
switchToSession(getStoredCurrentSessionOrLast())
|
||||
} else {
|
||||
tabSwitcher.showSwitcher()
|
||||
addNewSession("NeoTerm #0", systemShell, createRevealAnimation())
|
||||
}
|
||||
switchToSession(getStoredCurrentSessionOrLast())
|
||||
} else {
|
||||
tabSwitcher.showSwitcher()
|
||||
addNewSession("NeoTerm #0", createRevealAnimation())
|
||||
AlertDialog.Builder(this@NeoTermActivity)
|
||||
.setTitle("Error")
|
||||
.setMessage(error.toString())
|
||||
.setNegativeButton("System Shell", { _, _ ->
|
||||
tabSwitcher.showSwitcher()
|
||||
addNewSession("NeoTerm #0", systemShell, createRevealAnimation())
|
||||
})
|
||||
.setPositiveButton("Retry", { dialog, _ ->
|
||||
dialog.dismiss()
|
||||
BaseFileInstaller.installBaseFiles(this@NeoTermActivity, resultListener)
|
||||
}).show()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
BaseFileInstaller.installBaseFiles(this, resultListener)
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
@ -189,11 +208,11 @@ class NeoTermActivity : AppCompatActivity(), ServiceConnection {
|
||||
switchToSession(tab)
|
||||
}
|
||||
|
||||
private fun addNewSession(sessionName: String?, animation: Animation) {
|
||||
private fun addNewSession(sessionName: String?, systemShell: Boolean, animation: Animation) {
|
||||
val tab = createTab(sessionName) as TermTab
|
||||
tab.sessionCallback = TermSessionChangedCallback()
|
||||
tab.viewClient = TermViewClient(this)
|
||||
tab.termSession = termService!!.createTermSession(null, null, null, null, tab.sessionCallback)
|
||||
tab.termSession = termService!!.createTermSession(null, null, null, null, tab.sessionCallback, systemShell)
|
||||
|
||||
if (sessionName != null) {
|
||||
tab.termSession!!.mSessionName = sessionName
|
||||
@ -255,7 +274,7 @@ class NeoTermActivity : AppCompatActivity(), ServiceConnection {
|
||||
fun createAddSessionListener(): View.OnClickListener {
|
||||
return View.OnClickListener {
|
||||
val index = tabSwitcher.count
|
||||
addNewSession("NeoTerm #" + index, createRevealAnimation())
|
||||
addNewSession("NeoTerm #" + index, systemShell, createRevealAnimation())
|
||||
}
|
||||
}
|
||||
|
||||
@ -271,7 +290,7 @@ class NeoTermActivity : AppCompatActivity(), ServiceConnection {
|
||||
tabSwitcher.showSwitcher()
|
||||
}
|
||||
val index = tabSwitcher.count
|
||||
addNewSession("NeoTerm #" + index, createRevealAnimation())
|
||||
addNewSession("NeoTerm #" + index, systemShell, createRevealAnimation())
|
||||
true
|
||||
}
|
||||
else -> false
|
||||
@ -283,16 +302,18 @@ class NeoTermActivity : AppCompatActivity(), ServiceConnection {
|
||||
val tab = TermTab(tabTitle ?: "NeoTerm")
|
||||
tab.closeTabProvider = object : CloseTabProvider {
|
||||
override fun closeTab(tab: Tab) {
|
||||
// FIXME: No Such Tab
|
||||
tabSwitcher.showSwitcher()
|
||||
tabSwitcher.removeTab(tab)
|
||||
|
||||
if (tabSwitcher.count > 1) {
|
||||
var index = tabSwitcher.indexOf(tab)
|
||||
// 关闭当前窗口后,向上一个窗口切换
|
||||
if (++index >= tabSwitcher.count) index = 0
|
||||
// 关闭当前窗口后,向下一个窗口切换
|
||||
// if (--index < 0) index = tabSwitcher.count - 1
|
||||
if (NeoTermPreference.loadBoolean(R.string.key_ui_next_tab_anim, false)) {
|
||||
// 关闭当前窗口后,向下一个窗口切换
|
||||
if (--index < 0) index = tabSwitcher.count - 1
|
||||
} else {
|
||||
// 关闭当前窗口后,向上一个窗口切换
|
||||
if (++index >= tabSwitcher.count) index = 0
|
||||
}
|
||||
switchToSession(tabSwitcher.getTab(index))
|
||||
}
|
||||
}
|
||||
@ -319,9 +340,9 @@ class NeoTermActivity : AppCompatActivity(), ServiceConnection {
|
||||
return RevealAnimation.Builder().setX(x).setY(y).create()
|
||||
}
|
||||
|
||||
private fun createPeekAnimation(): Animation {
|
||||
return PeekAnimation.Builder().setX(tabSwitcher.width / 2f).create()
|
||||
}
|
||||
// private fun createPeekAnimation(): Animation {
|
||||
// return PeekAnimation.Builder().setX(tabSwitcher.width / 2f).create()
|
||||
// }
|
||||
|
||||
private fun getNavigationMenuItem(): View? {
|
||||
val toolbars = tabSwitcher.toolbars
|
||||
|
@ -7,6 +7,7 @@
|
||||
<string name="key_ui_fullscreen" translatable="false">neoterm_ui_fullscreen</string>
|
||||
<string name="key_ui_font" translatable="false">neoterm_ui_font</string>
|
||||
<string name="key_ui_color_scheme" translatable="false">neoterm_ui_color_scheme</string>
|
||||
<string name="key_ui_next_tab_anim" translatable="false">neoterm_ui_next_tab_anim</string>
|
||||
|
||||
<string name="key_package_source" translatable="false">neoterm_package_source</string>
|
||||
</resources>
|
@ -24,5 +24,12 @@
|
||||
<string name="pref_ui_fullscreen">Full Screen</string>
|
||||
<string name="pref_ui_font">Font</string>
|
||||
<string name="pref_ui_color_scheme">Color Scheme</string>
|
||||
<string name="pref_ui_close_tab_anim_next_tab">Next tab animation</string>
|
||||
<string name="pref_ui_close_tab_anim_next_tab_desc">Switch to next tab instead of previous tab when closing tab</string>
|
||||
<string name="pref_package_source">Source</string>
|
||||
|
||||
<string-array name="pref_ui_color_scheme_entries">
|
||||
<item>Default</item>
|
||||
</string-array>
|
||||
|
||||
</resources>
|
||||
|
@ -2,6 +2,7 @@
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<EditTextPreference
|
||||
android:enabled="false"
|
||||
android:key="@string/key_package_source"
|
||||
android:title="@string/pref_package_source" />
|
||||
</PreferenceScreen>
|
@ -6,13 +6,20 @@
|
||||
android:key="@string/key_ui_fullscreen"
|
||||
android:title="@string/pref_ui_fullscreen" />
|
||||
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="false"
|
||||
android:key="@string/key_ui_next_tab_anim"
|
||||
android:summary="@string/pref_ui_close_tab_anim_next_tab_desc"
|
||||
android:title="@string/pref_ui_close_tab_anim_next_tab" />
|
||||
|
||||
<EditTextPreference
|
||||
android:key="@string/key_ui_font"
|
||||
android:title="@string/pref_ui_font" />
|
||||
|
||||
<ListPreference
|
||||
android:entries="@null"
|
||||
android:entryValues="@null"
|
||||
android:defaultValue="Default"
|
||||
android:entries="@array/pref_ui_color_scheme_entries"
|
||||
android:entryValues="@array/pref_ui_color_scheme_entries"
|
||||
android:key="@string/key_ui_color_scheme"
|
||||
android:title="@string/pref_ui_color_scheme" />
|
||||
</PreferenceScreen>
|
Loading…
Reference in New Issue
Block a user