Feature: Now we can use system shell if base fail installation failed

This commit is contained in:
zt515 2017-06-13 20:52:17 +08:00
parent 4a44777c92
commit 35cd6f698e
8 changed files with 84 additions and 56 deletions

View File

@ -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":

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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