这是indexloc提供的服务,不要输入任何密码
Skip to content

Commit fecba50

Browse files
Added: Add support for waiting for foreground session commands
Previously configured actions will behave the same, i.e wait for only background commands. For new or edited actions, the `Wait for result for commands` toggle value will be used to decide whether to wait for result of commands. It will apply to both foreground session and background commands. Note that for foreground commands, only the session transcript is returned which will contain both `stdout` and `stderr` combined in `%stdout` variable, basically anything sent to the the pseudo terminal `/dev/pts`, including `PS1` prefixes for interactive sessions. For foreground commands that exited with failure will require `termux-app` version `>=0.118` for sessions to automatically close without waiting for user to press enter as per termux/termux-app@162a430b. Closes #39
1 parent 1c1567f commit fecba50

File tree

6 files changed

+128
-75
lines changed

6 files changed

+128
-75
lines changed

app/src/main/java/com/termux/tasker/EditConfigurationActivity.java

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.io.File;
2929
import java.util.ArrayList;
3030
import java.util.Arrays;
31+
import java.util.List;
3132

3233
/**
3334
* This is the "Edit" activity for a Locale Plug-in.
@@ -45,6 +46,7 @@ public final class EditConfigurationActivity extends AbstractPluginActivity {
4546
private TextInputEditText mArgumentsText;
4647
private AutoCompleteTextView mWorkingDirectoryPathText;
4748
private CheckBox mInTerminalCheckbox;
49+
private CheckBox mWaitForResult;
4850
private TextView mExecutableAbsolutePathText;
4951
private TextView mWorkingDirectoryAbsolutePathText;
5052
private TextView mTermuxAppFilesPathInaccessibleWarning;
@@ -82,6 +84,7 @@ protected void onCreate(final Bundle savedInstanceState) {
8284
mArgumentsText = findViewById(R.id.arguments);
8385
mWorkingDirectoryPathText = findViewById(R.id.working_directory_path);
8486
mInTerminalCheckbox = findViewById(R.id.in_terminal);
87+
mWaitForResult = findViewById(R.id.wait_for_result);
8588
mExecutableAbsolutePathText = findViewById(R.id.executable_absolute_path);
8689
mWorkingDirectoryAbsolutePathText = findViewById(R.id.working_directory_absolute_path);
8790
mTermuxAppFilesPathInaccessibleWarning = findViewById(R.id.termux_app_files_path_inaccessible_warning);
@@ -127,7 +130,7 @@ public void afterTextChanged(Editable editable) {
127130
if (localeBundle != null) {
128131
String errmsg;
129132
// If bundle is valid, then load values from bundle
130-
errmsg = PluginBundleManager.isBundleValid(this, localeBundle);
133+
errmsg = PluginBundleManager.parseBundle(this, localeBundle);
131134
if (errmsg == null) {
132135
final String selectedExecutable = localeBundle.getString(PluginBundleManager.EXTRA_EXECUTABLE);
133136
mExecutablePathText.setText(selectedExecutable);
@@ -137,6 +140,8 @@ public void afterTextChanged(Editable editable) {
137140
mWorkingDirectoryPathText.setText(selectedWorkingDirectory);
138141
final boolean inTerminal = localeBundle.getBoolean(PluginBundleManager.EXTRA_TERMINAL);
139142
mInTerminalCheckbox.setChecked(inTerminal);
143+
final boolean waitForResult = localeBundle.getBoolean(PluginBundleManager.EXTRA_WAIT_FOR_RESULT);
144+
mWaitForResult.setChecked(waitForResult);
140145
} else {
141146
Logger.logError(LOG_TAG, errmsg);
142147
}
@@ -170,6 +175,7 @@ public void finish() {
170175
final String arguments = mArgumentsText.getText() == null ? null : mArgumentsText.getText().toString();
171176
final String workingDirectory = mWorkingDirectoryPathText.getText() == null ? null : mWorkingDirectoryPathText.getText().toString();
172177
final boolean inTerminal = mInTerminalCheckbox.isChecked();
178+
final boolean waitForResult = mWaitForResult.isChecked();
173179

174180
if (executable != null && executable.length() > 0) {
175181
final Intent resultIntent = new Intent();
@@ -182,10 +188,11 @@ public void finish() {
182188
* Android platform objects (A Serializable class private to this plug-in's APK cannot be
183189
* stored in the Bundle, as Locale's classloader will not recognize it).
184190
*/
185-
final Bundle resultBundle = PluginBundleManager.generateBundle(getApplicationContext(), executable, arguments, workingDirectory, inTerminal);
191+
final Bundle resultBundle = PluginBundleManager.generateBundle(getApplicationContext(),
192+
executable, arguments, workingDirectory, inTerminal, waitForResult);
186193

187194
// The blurb is a concise status text to be displayed in the host's UI.
188-
final String blurb = generateBlurb(executable, arguments, inTerminal);
195+
final String blurb = generateBlurb(executable, arguments, inTerminal, waitForResult);
189196

190197
// If host supports variable replacement when running plugin action, then
191198
// request it to replace variables in following fields
@@ -201,20 +208,24 @@ public void finish() {
201208
resultIntent.putExtra(com.twofortyfouram.locale.Intent.EXTRA_STRING_BLURB, blurb);
202209

203210
// Configuration information for Tasker variables returned from the executed task
204-
//
205-
// Do not run if we are opening a terminal, because the user might not care about this
206-
// if they are running something that will literally pop up in front of them (Plus
207-
// getting that information requires additional work for now)
208-
if(!inTerminal) {
211+
if(waitForResult) {
212+
List<String> relevantVariableList = new ArrayList<>();
213+
relevantVariableList.add(PluginUtils.PLUGIN_VARIABLE_STDOUT + "\nStandard Output\nThe <B>stdout</B> of the command.");
214+
relevantVariableList.add(PluginUtils.PLUGIN_VARIABLE_STDOUT_ORIGINAL_LENGTH + "\nStandard Output Original Length\nThe original length of <B>stdout</B>.");
215+
216+
// For foreground commands, the session transcript is returned which will contain
217+
// both stdout and stderr combined, basically anything sent to the the pseudo
218+
// terminal /dev/pts, including PS1 prefixes for interactive sessions.
219+
if (!inTerminal) {
220+
relevantVariableList.add(PluginUtils.PLUGIN_VARIABLE_STDERR + "\nStandard Error\nThe <B>stderr</B> of the command.");
221+
relevantVariableList.add(PluginUtils.PLUGIN_VARIABLE_STDERR_ORIGINAL_LENGTH + "\nStandard Error Original Length\nThe original length of <B>stderr</B>.");
222+
}
223+
224+
relevantVariableList.add(PluginUtils.PLUGIN_VARIABLE_EXIT_CODE + "\nExit Code\nThe <B>exit code</B> of the command." +
225+
"0 often means success and anything else is usually a failure of some sort.");
226+
209227
if (TaskerPlugin.hostSupportsRelevantVariables(getIntent().getExtras())) {
210-
TaskerPlugin.addRelevantVariableList(resultIntent, new String[]{
211-
PluginUtils.PLUGIN_VARIABLE_STDOUT + "\nStandard Output\nThe <B>stdout</B> of the command.",
212-
PluginUtils.PLUGIN_VARIABLE_STDOUT_ORIGINAL_LENGTH + "\nStandard Output Original Length\nThe original length of <B>stdout</B>.",
213-
PluginUtils.PLUGIN_VARIABLE_STDERR + "\nStandard Error\nThe <B>stderr</B> of the command.",
214-
PluginUtils.PLUGIN_VARIABLE_STDERR_ORIGINAL_LENGTH + "\nStandard Error Original Length\nThe original length of <B>stderr</B>.",
215-
PluginUtils.PLUGIN_VARIABLE_EXIT_CODE + "\nExit Code\nThe <B>exit code</B> of the command. " +
216-
"0 often means success and anything else is usually a failure of some sort."
217-
});
228+
TaskerPlugin.addRelevantVariableList(resultIntent, relevantVariableList.toArray(new String[0]));
218229
}
219230
}
220231

@@ -239,13 +250,18 @@ public void finish() {
239250
* @param executable value set for the action.
240251
* @param arguments value set for the action.
241252
* @param inTerminal value set for the action.
253+
* @param waitForResult value set for the action.
242254
* @return A blurb for the plug-in.
243255
*/
244-
String generateBlurb(final String executable, final String arguments, boolean inTerminal) {
245-
final int stringResource = inTerminal ? R.string.blurb_in_terminal : R.string.blurb_in_background;
246-
final String message = getString(stringResource, executable, arguments);
247-
final int maxBlurbLength = 60; // R.integer.twofortyfouram_locale_maximum_blurb_length.
248-
return (message.length() > maxBlurbLength) ? message.substring(0, maxBlurbLength) : message;
256+
String generateBlurb(final String executable, final String arguments, boolean inTerminal, boolean waitForResult) {
257+
StringBuilder builder = new StringBuilder();
258+
builder.append(getString(R.string.blurb_executable_and_arguments, executable, arguments));
259+
builder.append("\n\n").append(getString(inTerminal ? R.string.blurb_in_terminal : R.string.blurb_not_in_terminal));
260+
builder.append("\n").append(getString(waitForResult ? R.string.blurb_wait_for_result : R.string.blurb_no_wait_for_result));
261+
262+
String blurb = builder.toString();
263+
final int maxBlurbLength = 60; // R.integer.twofortyfouram_locale_maximum_blurb_length
264+
return (blurb.length() > maxBlurbLength) ? blurb.substring(0, maxBlurbLength) : blurb;
249265
}
250266

251267
@Override

app/src/main/java/com/termux/tasker/FireReceiver.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public void onReceive(final Context context, final Intent intent) {
5858
BundleScrubber.scrub(bundle);
5959

6060
// If bundle is not valid, then return RESULT_CODE_FAILED to plugin host app
61-
errmsg = PluginBundleManager.isBundleValid(context, bundle);
61+
errmsg = PluginBundleManager.parseBundle(context, bundle);
6262
if (errmsg != null) {
6363
Logger.logError(LOG_TAG, errmsg);
6464
PluginUtils.sendImmediateResultToPluginHostApp(this, intent, TaskerPlugin.Setting.RESULT_CODE_FAILED, errmsg);
@@ -71,6 +71,8 @@ public void onReceive(final Context context, final Intent intent) {
7171
final String arguments_string = bundle.getString(PluginBundleManager.EXTRA_ARGUMENTS);
7272
executionCommand.workingDirectory = IntentUtils.getStringExtraIfSet(intent, PluginBundleManager.EXTRA_WORKDIR, null);
7373
executionCommand.inBackground = !(intent.getBooleanExtra(PluginBundleManager.EXTRA_TERMINAL, false));
74+
final boolean waitForResult = bundle.getBoolean(PluginBundleManager.EXTRA_WAIT_FOR_RESULT, true);
75+
7476

7577

7678
// If Termux app is not installed, enabled or accessible with current context or if
@@ -166,6 +168,7 @@ public void onReceive(final Context context, final Intent intent) {
166168

167169

168170
Logger.logVerboseExtended(LOG_TAG, executionCommand.toString());
171+
Logger.logVerbose(LOG_TAG, "Wait For Result: `" + waitForResult + "`");
169172

170173
// Create execution intent with the action TERMUX_SERVICE#ACTION_SERVICE_EXECUTE to be sentto the TERMUX_SERVICE
171174
Intent executionIntent = new Intent(TERMUX_SERVICE.ACTION_SERVICE_EXECUTE, executionCommand.executableUri);
@@ -177,7 +180,7 @@ public void onReceive(final Context context, final Intent intent) {
177180
executionIntent.putExtra(TERMUX_SERVICE.EXTRA_BACKGROUND, executionCommand.inBackground);
178181

179182
// Send execution intent to TERMUX_SERVICE
180-
PluginUtils.sendExecuteIntentToExecuteService(context, this, intent, executionIntent, executionCommand.inBackground);
183+
PluginUtils.sendExecuteIntentToExecuteService(context, this, intent, executionIntent, waitForResult);
181184
}
182185

183186
}

app/src/main/java/com/termux/tasker/PluginBundleManager.java

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.termux.tasker;
22

3+
import android.annotation.SuppressLint;
34
import android.content.Context;
45
import android.os.Bundle;
56
import android.text.TextUtils;
@@ -10,40 +11,25 @@
1011
/**
1112
* Class for managing the {@link com.twofortyfouram.locale.Intent#EXTRA_BUNDLE} for this plug-in.
1213
*/
13-
final class PluginBundleManager {
14+
public class PluginBundleManager {
1415

15-
/**
16-
* Type: {@code String}.
17-
*
18-
* The path to the executable to execute.
19-
*/
16+
/** The {@code String} extra for the path to the executable to execute. */
2017
public static final String EXTRA_EXECUTABLE = TermuxConstants.TERMUX_TASKER_PACKAGE_NAME + ".extra.EXECUTABLE"; // Default: "com.termux.tasker.extra.EXECUTABLE"
2118

22-
/**
23-
* Type: {@code sting}.
24-
*
25-
* The arguments to pass to the script.
26-
*/
19+
/** The {@code String} extra for the arguments to pass to the executable. */
2720
public static final String EXTRA_ARGUMENTS = TermuxConstants.TERMUX_PACKAGE_NAME + ".execute.arguments"; // Default: "com.termux.execute.arguments"
2821

29-
/**
30-
* Type: {@code String}.
31-
*
32-
* The path to current working directory for execution.
33-
*/
22+
/** The {@code String} extra for path to current working directory for execution. */
3423
public static final String EXTRA_WORKDIR = TermuxConstants.TERMUX_TASKER_PACKAGE_NAME + ".extra.WORKDIR"; // Default: "com.termux.tasker.extra.WORKDIR"
3524

36-
/**
37-
* Type: {@code boolean}.
38-
*
39-
* If the executable should be run inside a terminal.
40-
*/
25+
/** The {@code boolean} extra for whether the executable should be run inside a terminal. */
4126
public static final String EXTRA_TERMINAL = TermuxConstants.TERMUX_TASKER_PACKAGE_NAME + ".extra.TERMINAL"; // Default: "com.termux.tasker.extra.TERMINAL"
4227

28+
/** The {@code boolean} extra for whether plugin action should wait for result of commands or not. */
29+
public static final String EXTRA_WAIT_FOR_RESULT = TermuxConstants.TERMUX_TASKER_PACKAGE_NAME + ".extra.WAIT_FOR_RESULT"; // Default: "com.termux.tasker.extra.WAIT_FOR_RESULT"
30+
4331
/**
44-
* Type: {@code int}.
45-
* <p>
46-
* versionCode of the plug-in that saved the Bundle.
32+
* The {@code int} extra for the versionCode of the plugin app that saved the Bundle.
4733
*
4834
* This extra is not strictly required, however it makes backward and forward compatibility significantly
4935
* easier. For example, suppose a bug is found in how some version of the plug-in stored its Bundle. By
@@ -60,7 +46,8 @@ final class PluginBundleManager {
6046
* @param bundle The {@link Bundle} to verify. May be {@code null}, which will always return {@code false}.
6147
* @return Returns the {@code errmsg} if Bundle is not valid, otherwise {@code null}.
6248
*/
63-
public static String isBundleValid(final Context context, final Bundle bundle) {
49+
@SuppressLint("DefaultLocale")
50+
public static String parseBundle(final Context context, final Bundle bundle) {
6451
if (bundle == null) return context.getString(R.string.error_null_or_empty_executable);
6552

6653
/*
@@ -72,6 +59,7 @@ public static String isBundleValid(final Context context, final Bundle bundle) {
7259
* The bundle may optionally contain:
7360
* - EXTRA_WORKDIR
7461
* - EXTRA_TERMINAL
62+
* - EXTRA_WAIT_FOR_RESULT
7563
* - VARIABLE_REPLACE_KEYS
7664
*/
7765

@@ -88,13 +76,13 @@ public static String isBundleValid(final Context context, final Bundle bundle) {
8876
}
8977

9078
/*
91-
* Check if bundle contains at least 3 keys but no more than 6.
79+
* Check if bundle contains at least 3 keys but no more than 7.
9280
* Run this test after checking for required Bundle extras above so that the error message
9381
* is more useful. (E.g. the caller will see what extras are missing, rather than just a
9482
* message that there is the wrong number).
9583
*/
96-
if (bundle.keySet().size() < 3 || bundle.keySet().size() > 6) {
97-
return String.format("The bundle must contain 3-6 keys, but currently contains %d keys.", bundle.keySet().size());
84+
if (bundle.keySet().size() < 3 || bundle.keySet().size() > 7) {
85+
return String.format("The bundle must contain 3-7 keys, but currently contains %d keys.", bundle.keySet().size());
9886
}
9987

10088
if (TextUtils.isEmpty(bundle.getString(EXTRA_EXECUTABLE))) {
@@ -105,15 +93,27 @@ public static String isBundleValid(final Context context, final Bundle bundle) {
10593
return String.format("The bundle extra %s appears to be the wrong type. It must be an int.", BUNDLE_EXTRA_INT_VERSION_CODE);
10694
}
10795

96+
if (!bundle.containsKey(EXTRA_WAIT_FOR_RESULT)) {
97+
// Termux:Tasker <= v0.5 did not have the EXTRA_WAIT_FOR_RESULT key so we only wait
98+
// for results for background commands
99+
if (bundle.containsKey(EXTRA_TERMINAL))
100+
bundle.putBoolean(EXTRA_WAIT_FOR_RESULT, !bundle.getBoolean(EXTRA_TERMINAL));
101+
else
102+
bundle.putBoolean(EXTRA_WAIT_FOR_RESULT, true);
103+
}
104+
108105
return null;
109106
}
110107

111-
public static Bundle generateBundle(final Context context, final String executable, final String arguments, final String workingDirectory, final boolean inTerminal) {
108+
public static Bundle generateBundle(final Context context, final String executable,
109+
final String arguments, final String workingDirectory,
110+
final boolean inTerminal, final boolean waitForResult) {
112111
final Bundle result = new Bundle();
113112
result.putString(EXTRA_EXECUTABLE, executable);
114113
result.putString(EXTRA_ARGUMENTS,arguments);
115114
result.putString(EXTRA_WORKDIR, workingDirectory);
116115
result.putBoolean(EXTRA_TERMINAL, inTerminal);
116+
result.putBoolean(EXTRA_WAIT_FOR_RESULT, waitForResult);
117117
result.putInt(BUNDLE_EXTRA_INT_VERSION_CODE, PackageUtils.getVersionCodeForPackage(context));
118118
return result;
119119
}

0 commit comments

Comments
 (0)