From 6158752b8e346122de2c8edd6cc8e94fb8c9990e Mon Sep 17 00:00:00 2001 From: zt515 Date: Fri, 24 Nov 2017 00:59:03 +0800 Subject: [PATCH] Feature: Add X sessions --- .../io/neoterm/frontend/xorg/XParameter.java | 8 +++ .../java/io/neoterm/frontend/xorg/XSession.kt | 9 ++- .../io/neoterm/services/NeoTermService.kt | 32 ++++++++--- .../io/neoterm/ui/term/NeoTermActivity.kt | 57 ++++++++++++++++--- .../java/io/neoterm/ui/term/SessionRemover.kt | 17 +++++- ...TermTabDecorator.kt => NeoTabDecorator.kt} | 55 ++++++++++++++---- .../io/neoterm/ui/term/tab/XSessionTab.kt | 3 +- app/src/main/res/layout/ui_xorg.xml | 12 ++++ app/src/main/res/values-zh-rCN/strings.xml | 2 +- app/src/main/res/values-zh-rTW/strings.xml | 2 +- app/src/main/res/values/strings.xml | 2 +- 11 files changed, 165 insertions(+), 34 deletions(-) create mode 100644 app/src/main/java/io/neoterm/frontend/xorg/XParameter.java rename app/src/main/java/io/neoterm/ui/term/tab/{TermTabDecorator.kt => NeoTabDecorator.kt} (68%) create mode 100644 app/src/main/res/layout/ui_xorg.xml diff --git a/app/src/main/java/io/neoterm/frontend/xorg/XParameter.java b/app/src/main/java/io/neoterm/frontend/xorg/XParameter.java new file mode 100644 index 0000000..2740dfa --- /dev/null +++ b/app/src/main/java/io/neoterm/frontend/xorg/XParameter.java @@ -0,0 +1,8 @@ +package io.neoterm.frontend.xorg; + +/** + * @author kiva + */ + +public class XParameter { +} diff --git a/app/src/main/java/io/neoterm/frontend/xorg/XSession.kt b/app/src/main/java/io/neoterm/frontend/xorg/XSession.kt index b88855d..d48ca23 100644 --- a/app/src/main/java/io/neoterm/frontend/xorg/XSession.kt +++ b/app/src/main/java/io/neoterm/frontend/xorg/XSession.kt @@ -1,11 +1,18 @@ package io.neoterm.frontend.xorg +import android.content.Context import io.neoterm.backend.TerminalSession /** * @author kiva */ -class XSession { +class XSession private constructor() { + companion object { + fun createSession(context: Context, parameter: XParameter) : XSession { + return XSession() + } + } + var mSessionName = ""; } diff --git a/app/src/main/java/io/neoterm/services/NeoTermService.kt b/app/src/main/java/io/neoterm/services/NeoTermService.kt index 46971eb..429f484 100644 --- a/app/src/main/java/io/neoterm/services/NeoTermService.kt +++ b/app/src/main/java/io/neoterm/services/NeoTermService.kt @@ -10,14 +10,14 @@ import android.os.Build import android.os.IBinder import android.os.PowerManager import android.support.v4.app.NotificationCompat -import android.support.v4.content.WakefulBroadcastReceiver import io.neoterm.R import io.neoterm.backend.EmulatorDebug import io.neoterm.backend.TerminalSession import io.neoterm.frontend.shell.ShellParameter +import io.neoterm.frontend.xorg.XParameter +import io.neoterm.frontend.xorg.XSession import io.neoterm.ui.term.NeoTermActivity import io.neoterm.utils.TerminalUtils -import java.util.* /** @@ -31,6 +31,7 @@ class NeoTermService : Service() { private val serviceBinder = NeoTermBinder() private val mTerminalSessions = ArrayList() + private val mXSessions = ArrayList() private var mWakeLock: PowerManager.WakeLock? = null private var mWifiLock: WifiManager.WifiLock? = null @@ -58,11 +59,6 @@ class NeoTermService : Service() { ACTION_RELEASE_LOCK -> releaseLock() } - if (flags and Service.START_FLAG_REDELIVERY == 0) { - // Service is started by WBR, not restarted by system, so release the WakeLock from WBR. - WakefulBroadcastReceiver.completeWakefulIntent(intent) - } - return Service.START_NOT_STICKY } @@ -77,6 +73,9 @@ class NeoTermService : Service() { val sessions: List get() = mTerminalSessions + val xSessions: List + get() = mXSessions + fun createTermSession(parameter: ShellParameter): TerminalSession { val session = TerminalUtils.createShellSession(this, parameter) mTerminalSessions.add(session) @@ -93,6 +92,22 @@ class NeoTermService : Service() { return indexOfRemoved } + fun createXSession(parameter: XParameter): XSession { + val session = XSession.createSession(this, parameter) + mXSessions.add(session) + updateNotification() + return session + } + + fun removeXSession(sessionToRemove: XSession): Int { + val indexOfRemoved = mXSessions.indexOf(sessionToRemove) + if (indexOfRemoved >= 0) { + mXSessions.removeAt(indexOfRemoved) + updateNotification() + } + return indexOfRemoved + } + private fun updateNotification() { val service = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager service.notify(NOTIFICATION_ID, createNotification()) @@ -104,7 +119,8 @@ class NeoTermService : Service() { val pendingIntent = PendingIntent.getActivity(this, 0, notifyIntent, 0) val sessionCount = mTerminalSessions.size - var contentText = getString(R.string.service_status_text, sessionCount) + val xSessionCount = mXSessions.size + var contentText = getString(R.string.service_status_text, sessionCount, xSessionCount) val lockAcquired = mWakeLock != null if (lockAcquired) contentText += getString(R.string.service_lock_acquired) diff --git a/app/src/main/java/io/neoterm/ui/term/NeoTermActivity.kt b/app/src/main/java/io/neoterm/ui/term/NeoTermActivity.kt index 55a1eeb..dcc5bb5 100644 --- a/app/src/main/java/io/neoterm/ui/term/NeoTermActivity.kt +++ b/app/src/main/java/io/neoterm/ui/term/NeoTermActivity.kt @@ -24,15 +24,18 @@ import io.neoterm.component.setup.BaseFileInstaller import io.neoterm.frontend.client.TermSessionCallback import io.neoterm.frontend.client.TermViewClient import io.neoterm.frontend.client.event.* +import io.neoterm.frontend.logging.NLog import io.neoterm.frontend.preference.NeoPermission import io.neoterm.frontend.preference.NeoPreference import io.neoterm.frontend.shell.ShellParameter +import io.neoterm.frontend.xorg.XParameter +import io.neoterm.frontend.xorg.XSession import io.neoterm.services.NeoTermService import io.neoterm.ui.pm.PackageManagerActivity import io.neoterm.ui.settings.SettingActivity import io.neoterm.ui.setup.SetupActivity +import io.neoterm.ui.term.tab.NeoTabDecorator import io.neoterm.ui.term.tab.TermTab -import io.neoterm.ui.term.tab.TermTabDecorator import io.neoterm.ui.term.tab.XSessionTab import io.neoterm.utils.FullScreenHelper import io.neoterm.utils.RangedInt @@ -82,7 +85,7 @@ class NeoTermActivity : AppCompatActivity(), ServiceConnection, SharedPreference }) tabSwitcher = findViewById(R.id.tab_switcher) - tabSwitcher.decorator = TermTabDecorator(this) + tabSwitcher.decorator = NeoTabDecorator(this) ViewCompat.setOnApplyWindowInsetsListener(tabSwitcher, createWindowInsetsListener()) tabSwitcher.showToolbars(false) @@ -193,7 +196,9 @@ class NeoTermActivity : AppCompatActivity(), ServiceConnection, SharedPreference override fun onTabRemoved(tabSwitcher: TabSwitcher, index: Int, tab: Tab, animation: Animation) { if (tab is TermTab) { - closeTab(tab) + SessionRemover.removeSession(termService, tab) + } else if (tab is XSessionTab) { + SessionRemover.removeXSession(termService, tab) } } @@ -349,6 +354,10 @@ class NeoTermActivity : AppCompatActivity(), ServiceConnection, SharedPreference addNewSession(session) } + for (session in termService!!.xSessions) { + addXSession(session) + } + if (intent?.action == Intent.ACTION_RUN) { // app shortcuts addNewSession(null, @@ -446,13 +455,49 @@ class NeoTermActivity : AppCompatActivity(), ServiceConnection, SharedPreference } private fun addXSession() { + if (!tabSwitcher.isSwitcherShown) { + toggleSwitcher(showSwitcher = true, easterEgg = false) + } + // TODO: Start X server + val parameter = XParameter() + val session = termService!!.createXSession(parameter) + + session.mSessionName = generateXSessionName("X") + val tab = createXTab(session.mSessionName) as XSessionTab + tab.session = session + + addNewTab(tab, createRevealAnimation()) + switchToSession(tab) + } + + private fun addXSession(session: XSession?) { + if (session == null) { + return + } + + // Do not add the same session again + // Or app will crash when rotate + val tabCount = tabSwitcher.count + (0..(tabCount - 1)) + .map { tabSwitcher.getTab(it) } + .filter { it is XSessionTab && it.session == session } + .forEach { return } + + val tab = createXTab(session.mSessionName) as XSessionTab + + addNewTab(tab, createRevealAnimation()) + switchToSession(tab) } private fun generateSessionName(prefix: String): String { return "$prefix #${termService!!.sessions.size}" } + private fun generateXSessionName(prefix: String): String { + return "$prefix #${termService!!.xSessions.size}" + } + private fun switchToSession(session: TerminalSession?) { if (session == null) { return @@ -500,7 +545,7 @@ class NeoTermActivity : AppCompatActivity(), ServiceConnection, SharedPreference return postTabCreated(XSessionTab(tabTitle ?: "NeoTerm")) } - private fun postTabCreated(tab: T) : T { + private fun postTabCreated(tab: T): T { // We must create a Bundle for each tab // tabs can use them to store status. tab.parameters = Bundle() @@ -554,10 +599,6 @@ class NeoTermActivity : AppCompatActivity(), ServiceConnection, SharedPreference } } - private fun closeTab(tab: TermTab) { - SessionRemover.removeSession(termService, tab) - } - private fun toggleSwitcher(showSwitcher: Boolean, easterEgg: Boolean) { if (tabSwitcher.count == 0 && easterEgg) { App.get().easterEgg(this, "Stop! You don't know what you are doing!") diff --git a/app/src/main/java/io/neoterm/ui/term/SessionRemover.kt b/app/src/main/java/io/neoterm/ui/term/SessionRemover.kt index 1c23620..6896df5 100644 --- a/app/src/main/java/io/neoterm/ui/term/SessionRemover.kt +++ b/app/src/main/java/io/neoterm/ui/term/SessionRemover.kt @@ -1,8 +1,11 @@ package io.neoterm.ui.term import io.neoterm.backend.TerminalSession +import io.neoterm.frontend.logging.NLog +import io.neoterm.frontend.xorg.XSession import io.neoterm.services.NeoTermService import io.neoterm.ui.term.tab.TermTab +import io.neoterm.ui.term.tab.XSessionTab /** * @author kiva @@ -14,6 +17,10 @@ object SessionRemover { tab.cleanup() } + fun removeXSession(termService: NeoTermService?, tab: XSessionTab?) { + removeFinishedSession(termService, tab?.session) + } + private fun removeFinishedSession(termService: NeoTermService?, finishedSession: TerminalSession?) { if (termService == null || finishedSession == null) { return @@ -21,4 +28,12 @@ object SessionRemover { termService.removeTermSession(finishedSession) } -} \ No newline at end of file + + private fun removeFinishedSession(termService: NeoTermService?, finishedSession: XSession?) { + if (termService == null || finishedSession == null) { + return + } + + termService.removeXSession(finishedSession) + } +} diff --git a/app/src/main/java/io/neoterm/ui/term/tab/TermTabDecorator.kt b/app/src/main/java/io/neoterm/ui/term/tab/NeoTabDecorator.kt similarity index 68% rename from app/src/main/java/io/neoterm/ui/term/tab/TermTabDecorator.kt rename to app/src/main/java/io/neoterm/ui/term/tab/NeoTabDecorator.kt index a98932d..27fde5f 100644 --- a/app/src/main/java/io/neoterm/ui/term/tab/TermTabDecorator.kt +++ b/app/src/main/java/io/neoterm/ui/term/tab/NeoTabDecorator.kt @@ -22,25 +22,51 @@ import io.neoterm.utils.TerminalUtils /** * @author kiva */ -class TermTabDecorator(val context: NeoTermActivity) : TabSwitcherDecorator() { +class NeoTabDecorator(val context: NeoTermActivity) : TabSwitcherDecorator() { + companion object { + private val VIEW_TYPE_TERM = 1 + private val VIEW_TYPE_X = 2 + } + override fun onInflateView(inflater: LayoutInflater, parent: ViewGroup?, viewType: Int): View { - val view = inflater.inflate(R.layout.ui_term, parent, false) - return view + return when (viewType) { + VIEW_TYPE_TERM -> { + inflater.inflate(R.layout.ui_term, parent, false) + } + + VIEW_TYPE_X -> { + inflater.inflate(R.layout.ui_xorg, parent, false) + } + + else -> { + throw RuntimeException("Unknown view type") + } + } } override fun onShowTab(context: Context, tabSwitcher: TabSwitcher, view: View, tab: Tab, index: Int, viewType: Int, savedInstanceState: Bundle?) { - val toolbar = this@TermTabDecorator.context.toolbar + val toolbar = this@NeoTabDecorator.context.toolbar toolbar.title = if (tabSwitcher.isSwitcherShown) null else tab.title - if (tab is TermTab) { - tab.toolbar = toolbar - } + when (viewType) { + VIEW_TYPE_TERM -> { + val termTab = tab as TermTab + termTab.toolbar = toolbar + val terminalView = findViewById(R.id.terminal_view) + val extraKeysView = findViewById(R.id.extra_keys) + bindTerminalView(termTab, terminalView, extraKeysView) + terminalView.requestFocus() + } - val terminalView = findViewById(R.id.terminal_view) - val extraKeysView = findViewById(R.id.extra_keys) - bindTerminalView(tab, terminalView, extraKeysView) - terminalView.requestFocus() + VIEW_TYPE_X -> { + val xtab = tab as XSessionTab + bindXSessionView(tab) + } + } + } + + private fun bindXSessionView(tab: XSessionTab) { } private fun bindTerminalView(tab: Tab, view: TerminalView?, extraKeysView: ExtraKeysView?) { @@ -84,10 +110,15 @@ class TermTabDecorator(val context: NeoTermActivity) : TabSwitcherDecorator() { } override fun getViewTypeCount(): Int { - return 1 + return 2 } override fun getViewType(tab: Tab, index: Int): Int { + if (tab is TermTab) { + return VIEW_TYPE_TERM + } else if (tab is XSessionTab) { + return VIEW_TYPE_X + } return 0 } } \ No newline at end of file diff --git a/app/src/main/java/io/neoterm/ui/term/tab/XSessionTab.kt b/app/src/main/java/io/neoterm/ui/term/tab/XSessionTab.kt index dc29b7e..2c8aef5 100644 --- a/app/src/main/java/io/neoterm/ui/term/tab/XSessionTab.kt +++ b/app/src/main/java/io/neoterm/ui/term/tab/XSessionTab.kt @@ -1,10 +1,11 @@ package io.neoterm.ui.term.tab import de.mrapp.android.tabswitcher.Tab +import io.neoterm.frontend.xorg.XSession /** * @author kiva */ class XSessionTab(title: CharSequence) : Tab(title) { - + var session: XSession? = null } diff --git a/app/src/main/res/layout/ui_xorg.xml b/app/src/main/res/layout/ui_xorg.xml new file mode 100644 index 0000000..00d5142 --- /dev/null +++ b/app/src/main/res/layout/ui_xorg.xml @@ -0,0 +1,12 @@ + + + + + + diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index da72a9a..3766f47 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -75,7 +75,7 @@ 应用: %s 堆栈信息 我们正努力让这个 Activity 永不见天日… - %d 个会话 + %d 个会话, %d 个图形会话 (永不休眠) 取得休眠锁 释放休眠锁 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index e72bc1f..c2bb7ba 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -70,7 +70,7 @@ 程式: %s 錯誤訊息 我們正在努力讓這個 Activity 永不見天日… - %d 個會話 + %d 個會話, %d 個图形會話 (永不休眠) 開啟休眠鎖 關閉休眠鎖 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8fc847f..5ba2e02 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -7,7 +7,7 @@ Toggle Tabs New Session New System Shell - %d session(s) + %d session(s), %d X session(s) (Wake Locked) Acquire Lock Release Lock