From 8761289ba6ff3639e9b9c6af0d2d267e01dfccdb Mon Sep 17 00:00:00 2001 From: agnostic-apollo Date: Tue, 29 Aug 2023 08:47:34 +0500 Subject: [PATCH] Fixed: Use `/system/bin/am` for broadcast commands on Android `>= 14` instead of TermuxAm Using TermuxAm for broadcast commands will trigger the `Sending broadcast with resultTo requires resultToApp` exception and will hang the app_process command forever. Reproducible on Android 14 revision 8 AVD. Related comment https://github.com/termux/TermuxAm/issues/9#issuecomment-1649867810 --- am-libexec-packaged | 39 +++++++++++++++++++ .../termux/termuxam/IActivityManagerTest.java | 6 +++ 2 files changed, 45 insertions(+) diff --git a/am-libexec-packaged b/am-libexec-packaged index 9798f79..a080e83 100755 --- a/am-libexec-packaged +++ b/am-libexec-packaged @@ -2,6 +2,45 @@ AM_APK_PATH="@TERMUX_PREFIX@/libexec/termux-am/am.apk" +is_int() { + case "$1" in + ''|*[!0-9]*) return 1;; + *) return 0;; + esac +} + +# If sdk version is not exported by app, then get value with getprop instead. +if ! is_int "$ANDROID__BUILD_VERSION_SDK"; then + ANDROID__BUILD_VERSION_SDK="$(getprop "ro.build.version.sdk")" + if ! is_int "$ANDROID__BUILD_VERSION_SDK"; then + echo "Failed to get android build version sdk with getprop" 1>&2 + exit 1 + fi +fi + +# Do not use TermuxAm for broadcast commands on Android >= 14 since it +# will trigger the `Sending broadcast with resultTo requires resultToApp` +# exception in logcat by ActivityManagerService and will hang the +# app_process command forever since no result callback is received +# by TermuxAm `IIntentReceiver.performReceive()`. +# - https://github.com/termux/TermuxAm/issues/9#issuecomment-1649867810 +if [ "$ANDROID__BUILD_VERSION_SDK" -ge 34 ] && [ "$1" = "broadcast" ]; then + is_int "$TERMUX__USER_ID" || TERMUX__USER_ID=0 + shift 1 # Remove the first `broadcast` argument + + # Use a subshell with specified redirection to prevent + # `cmd: Failure calling service activity` error on Android >= 8 + # due to selinux restrictions where the `system_server` source + # domain does not have access to `untrusted_app_all_devpts` + # `pty` devices when a source transition is made from `untrusted_app*` + # domain when `/system/bin/am` is executed. + # - https://github.com/termux/termux-packages/discussions/8292#discussioncomment-5102555 + output="$(/system/bin/am broadcast --user "$TERMUX__USER_ID" "$@" 2>&1 = 14 since it will trigger diff --git a/app/src/androidTest/java/com/termux/termuxam/IActivityManagerTest.java b/app/src/androidTest/java/com/termux/termuxam/IActivityManagerTest.java index 8b62f75..df007cb 100644 --- a/app/src/androidTest/java/com/termux/termuxam/IActivityManagerTest.java +++ b/app/src/androidTest/java/com/termux/termuxam/IActivityManagerTest.java @@ -5,6 +5,7 @@ import android.content.IIntentReceiver; import android.content.Intent; import android.content.ServiceConnection; +import android.os.Build; import android.os.Bundle; import android.os.IBinder; @@ -95,6 +96,11 @@ public void testStartActivity() throws Exception { @Test public void testBroadcastIntent() throws Exception { + // Do not run on Android `>= 14` since it will trigger the + // `Sending broadcast with resultTo requires resultToApp` exception in logcat by + // ActivityManagerService and will hang the test forever + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.TIRAMISU) return; + final CountDownLatch latch = new CountDownLatch(1); final Intent[] outIntent = new Intent[1]; final String[] outData = new String[1];