From 34473cbf1ca2f7586ab6e1ceba397f79fd2243d9 Mon Sep 17 00:00:00 2001 From: Archenoth Date: Mon, 2 Dec 2019 01:45:36 -0700 Subject: [PATCH] Set the output of %stdout %stderr and %result from executed tasks This commit adds the ability to return data from the termux-app TermuxService with a PendingIntent response It also provides a simple implementation of using it to return the process exit status, stdout and stderr outputs of the executed command for Tasker to use --- app/src/main/AndroidManifest.xml | 1 + .../tasker/EditConfigurationActivity.java | 25 ++++++++++++++ .../java/com/termux/tasker/FireReceiver.java | 15 +++++++++ .../com/termux/tasker/ResultsService.java | 33 +++++++++++++++++++ 4 files changed, 74 insertions(+) create mode 100644 app/src/main/java/com/termux/tasker/ResultsService.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3b5fcc7..145a411 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -48,6 +48,7 @@ + diff --git a/app/src/main/java/com/termux/tasker/EditConfigurationActivity.java b/app/src/main/java/com/termux/tasker/EditConfigurationActivity.java index d264955..c8d1b49 100644 --- a/app/src/main/java/com/termux/tasker/EditConfigurationActivity.java +++ b/app/src/main/java/com/termux/tasker/EditConfigurationActivity.java @@ -134,6 +134,31 @@ public void finish() { resultIntent.putExtra(com.twofortyfouram.locale.Intent.EXTRA_BUNDLE, resultBundle); resultIntent.putExtra(com.twofortyfouram.locale.Intent.EXTRA_STRING_BLURB, blurb); + + // Configuration information for Tasker variables returned from the executed task + // + // Not run if we are opening a terminal because the user might not care about this + // if they are running something that will literally pop up in front of them (Plus + // getting that information requires additional work for now) + if(!inTerminal) { + if (TaskerPlugin.hostSupportsRelevantVariables(getIntent().getExtras())) { + TaskerPlugin.addRelevantVariableList(resultIntent, new String[]{ + "%stdout\nStandard Output\nThe output of running the command", + "%stderr\nStandard Error\nThe error output of running the command", + "%result\nExit Code\nThe exit code set by the command upon completion.\n" + + "0 often means success and anything else is usually a failure of some sort" + }); + } + + // To use variables, we can't have a timeout of 0, but if someone doesn't pay + // attention to this and runs a task that never ends, 10 seconds seems like a + // reasonable timeout. If they need more time, or want this to run entirely + // asynchronously, that can be set + if (TaskerPlugin.Setting.hostSupportsSynchronousExecution(getIntent().getExtras())) { + TaskerPlugin.Setting.requestTimeoutMS(resultIntent, 10000); + } + } + setResult(RESULT_OK, resultIntent); } } diff --git a/app/src/main/java/com/termux/tasker/FireReceiver.java b/app/src/main/java/com/termux/tasker/FireReceiver.java index 8543356..b77e95e 100644 --- a/app/src/main/java/com/termux/tasker/FireReceiver.java +++ b/app/src/main/java/com/termux/tasker/FireReceiver.java @@ -1,5 +1,6 @@ package com.termux.tasker; +import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -23,6 +24,8 @@ public final class FireReceiver extends BroadcastReceiver { public static final String TERMUX_SERVICE = "com.termux.app.TermuxService"; public static final String ACTION_EXECUTE = "com.termux.service_execute"; + public static final String ORIGINAL_INTENT = "originalIntent"; + public void onReceive(final Context context, final Intent intent) { if (!com.twofortyfouram.locale.Intent.ACTION_FIRE_SETTING.equals(intent.getAction())) { Log.e(Constants.LOG_TAG, "Unexpected intent action: " + intent.getAction()); @@ -60,6 +63,18 @@ public void onReceive(final Context context, final Intent intent) { if (!inTerminal) executeIntent.putExtra("com.termux.execute.background", true); executeIntent.putExtra(PluginBundleManager.EXTRA_ARGUMENTS, list.toArray(new String[list.size()])); + // Do we have a timeout other than 0 to set variables? + if (isOrderedBroadcast()) { + // If so, we set this so we can return the variables from a PendingIntent we'll send to termux for it to call + setResultCode(TaskerPlugin.Setting.RESULT_CODE_PENDING); + + Intent resultsService = new Intent(context, ResultsService.class); + resultsService.putExtra(ORIGINAL_INTENT, intent); + + PendingIntent pending = PendingIntent.getService(context, 1, resultsService, PendingIntent.FLAG_ONE_SHOT); + executeIntent.putExtra("pendingIntent", pending); + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // https://developer.android.com/about/versions/oreo/background.html context.startForegroundService(executeIntent); diff --git a/app/src/main/java/com/termux/tasker/ResultsService.java b/app/src/main/java/com/termux/tasker/ResultsService.java new file mode 100644 index 0000000..f6c4a69 --- /dev/null +++ b/app/src/main/java/com/termux/tasker/ResultsService.java @@ -0,0 +1,33 @@ +package com.termux.tasker; + +import android.app.IntentService; +import android.content.Intent; +import android.os.Bundle; +import android.support.annotation.Nullable; + +/** + * A service to handle the results sent back from Termux-app when it finishes executing a command we + * want to set Tasker variables with + * + * Expects an "originalIntent" ParcelableExtra containing the original {@link Intent} (Sent with the + * {@link android.app.PendingIntent} from the {@link FireReceiver}) and a {@link Bundle} object extra + * at "result" containing the keys "stdout" (String), "stderr" (String), and "exitCode" (Integer). + */ +public class ResultsService extends IntentService { + public ResultsService(){ + super("ResultsService"); + } + + @Override + protected void onHandleIntent(@Nullable Intent intent) { + final Bundle result = intent.getBundleExtra("result"); + final Intent originalIntent = intent.getParcelableExtra(FireReceiver.ORIGINAL_INTENT); + final Bundle varsBundle = new Bundle(); + + varsBundle.putString("%stdout", result.getString("stdout", "")); + varsBundle.putString("%stderr", result.getString("stderr", "")); + varsBundle.putString("%result", Integer.toString(result.getInt("exitCode"))); + + TaskerPlugin.Setting.signalFinish(this, originalIntent, TaskerPlugin.Setting.RESULT_CODE_OK, varsBundle); + } +}