mirror of
https://github.com/fankes/termux-app.git
synced 2025-09-07 03:05:18 +08:00
Added|Changed: Add support to switch to existing session instead of creating duplicate session for RUN_COMMAND
intent
This is done via addition of the `com.termux.RUN_COMMAND_SESSION_CREATE_MODE` extra, which currently supports two values. - `always` to always create a new session every time. - `no-session-with-name` to create a new session only if no existing session exits with the same terminal session name. The terminal session name will equal executable basename by default and dashes `-` in the basename will no longer be replaced with spaces when session name as done previously. The `com.termux.RUN_COMMAND_SESSION_NAME` extra can be used to set custom session name. Usage: You can use this with `Termux:Tasker` or `Termux:Widget`. For example for `Termux:Widget` - Create a wrapper script at `~/.shortcuts/tasks/my-script.sh` with following contents under `tasks` directory so that it runs in background app shell instead of a terminal session. Do not use terminal session runner for wrapper script, since it will open two sessions everytime otherwise, first for wrapper script, then for actual target executable. There would also be conflicts if both wrapper script and target executable have the same basename and it would be incorrectly assumed that session is already running. - Replace the `bash` executable with actual target executable that you want to run in the terminal session if its not already running. - Optionally set custom session name. By default it will set to executable basename and not the wrapper script name. To set it to wrapper script name, you can pass `$(basename "$0")`. - Launch the wrapper script with widget. On first launch, a new terminal session should open but on subsequent launches, same terminal session should open. Note that you can also pass `com.termux.RUN_COMMAND_SESSION_ACTION` to modify session action behaviour. Check https://github.com/termux/termux-app/wiki/RUN_COMMAND-Intent#run_command-intent-command-extras. ``` am startservice --user 0 -n com.termux/com.termux.app.RunCommandService \ -a com.termux.RUN_COMMAND \ --es com.termux.RUN_COMMAND_PATH '/data/data/com.termux/files/usr/bin/bash' \ --es com.termux.RUN_COMMAND_SESSION_CREATE_MODE 'no-session-with-name' \ --es com.termux.RUN_COMMAND_SESSION_NAME "custom-name" ```
This commit is contained in:
@@ -116,6 +116,8 @@ public class RunCommandService extends Service {
|
||||
|
||||
executionCommand.backgroundCustomLogLevel = IntentUtils.getIntegerExtraIfSet(intent, RUN_COMMAND_SERVICE.EXTRA_BACKGROUND_CUSTOM_LOG_LEVEL, null);
|
||||
executionCommand.sessionAction = intent.getStringExtra(RUN_COMMAND_SERVICE.EXTRA_SESSION_ACTION);
|
||||
executionCommand.sessionName = IntentUtils.getStringExtraIfSet(intent, RUN_COMMAND_SERVICE.EXTRA_SESSION_NAME, null);
|
||||
executionCommand.sessionCreateMode = IntentUtils.getStringExtraIfSet(intent, RUN_COMMAND_SERVICE.EXTRA_SESSION_CREATE_MODE, null);
|
||||
executionCommand.commandLabel = IntentUtils.getStringExtraIfSet(intent, RUN_COMMAND_SERVICE.EXTRA_COMMAND_LABEL, "RUN_COMMAND Execution Intent Command");
|
||||
executionCommand.commandDescription = IntentUtils.getStringExtraIfSet(intent, RUN_COMMAND_SERVICE.EXTRA_COMMAND_DESCRIPTION, null);
|
||||
executionCommand.commandHelp = IntentUtils.getStringExtraIfSet(intent, RUN_COMMAND_SERVICE.EXTRA_COMMAND_HELP, null);
|
||||
@@ -211,6 +213,8 @@ public class RunCommandService extends Service {
|
||||
execIntent.putExtra(TERMUX_SERVICE.EXTRA_RUNNER, executionCommand.runner);
|
||||
execIntent.putExtra(TERMUX_SERVICE.EXTRA_BACKGROUND_CUSTOM_LOG_LEVEL, DataUtils.getStringFromInteger(executionCommand.backgroundCustomLogLevel, null));
|
||||
execIntent.putExtra(TERMUX_SERVICE.EXTRA_SESSION_ACTION, executionCommand.sessionAction);
|
||||
execIntent.putExtra(TERMUX_SERVICE.EXTRA_SESSION_NAME, executionCommand.sessionName);
|
||||
execIntent.putExtra(TERMUX_SERVICE.EXTRA_SESSION_CREATE_MODE, executionCommand.sessionCreateMode);
|
||||
execIntent.putExtra(TERMUX_SERVICE.EXTRA_COMMAND_LABEL, executionCommand.commandLabel);
|
||||
execIntent.putExtra(TERMUX_SERVICE.EXTRA_COMMAND_DESCRIPTION, executionCommand.commandDescription);
|
||||
execIntent.putExtra(TERMUX_SERVICE.EXTRA_COMMAND_HELP, executionCommand.commandHelp);
|
||||
|
@@ -41,6 +41,7 @@ import com.termux.shared.android.PermissionUtils;
|
||||
import com.termux.shared.data.DataUtils;
|
||||
import com.termux.shared.shell.command.ExecutionCommand;
|
||||
import com.termux.shared.shell.command.ExecutionCommand.Runner;
|
||||
import com.termux.shared.shell.command.ExecutionCommand.SessionCreateMode;
|
||||
import com.termux.terminal.TerminalEmulator;
|
||||
import com.termux.terminal.TerminalSession;
|
||||
import com.termux.terminal.TerminalSessionClient;
|
||||
@@ -384,6 +385,8 @@ public final class TermuxService extends Service implements AppShell.AppShellCli
|
||||
executionCommand.workingDirectory = IntentUtils.getStringExtraIfSet(intent, TERMUX_SERVICE.EXTRA_WORKDIR, null);
|
||||
executionCommand.isFailsafe = intent.getBooleanExtra(TERMUX_ACTIVITY.EXTRA_FAILSAFE_SESSION, false);
|
||||
executionCommand.sessionAction = intent.getStringExtra(TERMUX_SERVICE.EXTRA_SESSION_ACTION);
|
||||
executionCommand.sessionName = IntentUtils.getStringExtraIfSet(intent, TERMUX_SERVICE.EXTRA_SESSION_NAME, null);
|
||||
executionCommand.sessionCreateMode = IntentUtils.getStringExtraIfSet(intent, TERMUX_SERVICE.EXTRA_SESSION_CREATE_MODE, null);
|
||||
executionCommand.commandLabel = IntentUtils.getStringExtraIfSet(intent, TERMUX_SERVICE.EXTRA_COMMAND_LABEL, "Execution Intent Command");
|
||||
executionCommand.commandDescription = IntentUtils.getStringExtraIfSet(intent, TERMUX_SERVICE.EXTRA_COMMAND_DESCRIPTION, null);
|
||||
executionCommand.commandHelp = IntentUtils.getStringExtraIfSet(intent, TERMUX_SERVICE.EXTRA_COMMAND_HELP, null);
|
||||
@@ -402,13 +405,13 @@ public final class TermuxService extends Service implements AppShell.AppShellCli
|
||||
mPendingPluginExecutionCommands.add(executionCommand);
|
||||
|
||||
if (Runner.APP_SHELL.equalsRunner(executionCommand.runner))
|
||||
executeTermuxTaskCommand(executionCommand);
|
||||
executeTermuxTaskCommand(executionCommand);
|
||||
else if (Runner.TERMINAL_SESSION.equalsRunner(executionCommand.runner))
|
||||
executeTermuxSessionCommand(executionCommand);
|
||||
executeTermuxSessionCommand(executionCommand);
|
||||
else {
|
||||
String errmsg = this.getString(R.string.error_termux_service_unsupported_execution_command_runner, executionCommand.runner);
|
||||
executionCommand.setStateFailed(Errno.ERRNO_FAILED.getCode(), errmsg);
|
||||
PluginUtils.processPluginExecutionCommandError(this, LOG_TAG, executionCommand, false);
|
||||
String errmsg = getString(R.string.error_termux_service_unsupported_execution_command_runner, executionCommand.runner);
|
||||
executionCommand.setStateFailed(Errno.ERRNO_FAILED.getCode(), errmsg);
|
||||
PluginUtils.processPluginExecutionCommandError(this, LOG_TAG, executionCommand, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -497,16 +500,39 @@ public final class TermuxService extends Service implements AppShell.AppShellCli
|
||||
private void executeTermuxSessionCommand(ExecutionCommand executionCommand) {
|
||||
if (executionCommand == null) return;
|
||||
|
||||
if (executionCommand.sessionCreateMode == null)
|
||||
executionCommand.sessionCreateMode = SessionCreateMode.ALWAYS.getMode();
|
||||
|
||||
Logger.logDebug(LOG_TAG, "Executing foreground \"" + executionCommand.getCommandIdAndLabelLogString() + "\" TermuxSession command");
|
||||
|
||||
String sessionName = null;
|
||||
|
||||
// Transform executable path to session name, e.g. "/bin/do-something.sh" => "do something.sh".
|
||||
if (executionCommand.executable != null) {
|
||||
sessionName = ShellUtils.getExecutableBasename(executionCommand.executable).replace('-', ' ');
|
||||
// Transform executable path to session name, e.g. "/bin/do-something.sh" => "do-something.sh".
|
||||
if (executionCommand.sessionName == null && executionCommand.executable != null) {
|
||||
executionCommand.sessionName = ShellUtils.getExecutableBasename(executionCommand.executable);
|
||||
}
|
||||
|
||||
TermuxSession newTermuxSession = createTermuxSession(executionCommand, sessionName);
|
||||
TermuxSession newTermuxSession = null;
|
||||
if (SessionCreateMode.ALWAYS.equalsMode(executionCommand.sessionCreateMode))
|
||||
; // Default
|
||||
else if (SessionCreateMode.NO_SESSION_WITH_NAME.equalsMode(executionCommand.sessionCreateMode))
|
||||
if (DataUtils.isNullOrEmpty(executionCommand.sessionName)) {
|
||||
String errmsg = getString(R.string.error_termux_service_execution_command_session_name_unset, executionCommand.sessionCreateMode);
|
||||
executionCommand.setStateFailed(Errno.ERRNO_FAILED.getCode(), errmsg);
|
||||
PluginUtils.processPluginExecutionCommandError(this, LOG_TAG, executionCommand, false);
|
||||
return;
|
||||
} else {
|
||||
newTermuxSession = getTermuxSessionForName(executionCommand.sessionName);
|
||||
if (newTermuxSession != null)
|
||||
Logger.logInfo(LOG_TAG, "Existing session with \"" + executionCommand.sessionName + "\" session name found");
|
||||
}
|
||||
else {
|
||||
String errmsg = getString(R.string.error_termux_service_unsupported_execution_command_session_create_mode, executionCommand.sessionCreateMode);
|
||||
executionCommand.setStateFailed(Errno.ERRNO_FAILED.getCode(), errmsg);
|
||||
PluginUtils.processPluginExecutionCommandError(this, LOG_TAG, executionCommand, false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (newTermuxSession == null)
|
||||
newTermuxSession = createTermuxSession(executionCommand);
|
||||
if (newTermuxSession == null) return;
|
||||
|
||||
handleSessionAction(DataUtils.getIntFromString(executionCommand.sessionAction,
|
||||
@@ -858,6 +884,18 @@ public final class TermuxService extends Service implements AppShell.AppShellCli
|
||||
return null;
|
||||
}
|
||||
|
||||
public synchronized TermuxSession getTermuxSessionForName(String name) {
|
||||
if (DataUtils.isNullOrEmpty(name)) return null;
|
||||
TermuxSession termuxSession;
|
||||
for (int i = 0, len = mTermuxSessions.size(); i < len; i++) {
|
||||
termuxSession = mTermuxSessions.get(i);
|
||||
TerminalSession terminalSession = termuxSession.getTerminalSession();
|
||||
if (terminalSession.mSessionName != null && terminalSession.mSessionName.equals(name))
|
||||
return termuxSession;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static synchronized int getNextExecutionId() {
|
||||
|
@@ -100,6 +100,8 @@
|
||||
Grants it from Settings -> Apps -> &TERMUX_APP_NAME; -> Advanced</string>
|
||||
<string name="error_termux_service_invalid_execution_command_runner">Invalid execution command runner to TermuxService: `%1$s`</string>
|
||||
<string name="error_termux_service_unsupported_execution_command_runner">Unsupported execution command runner to TermuxService: `%1$s`</string>
|
||||
<string name="error_termux_service_unsupported_execution_command_session_create_mode">Unsupported execution command session create mode to TermuxService: `%1$s`</string>
|
||||
<string name="error_termux_service_execution_command_session_name_unset">Session name not set but `%1$s` session create mode passed</string>
|
||||
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user