Closed Freed-Wu closed 2 years ago
Check for existence of termux-api binary: [ -x $PREFIX/libexec/termux-api ] && do_something
Sorry for late. :(
it cannot work for me.
❯ tsu
❯ [ -x $PREFIX/libexec/termux-api ] && echo 1
1
# it will hang
❯ termux-wifi-connectioninfo
^C
Why are you running it as root? There is no reason to do so, I guess that is the cause of the issue
[ -x $PREFIX/libexec/termux-api ]
is not the right way to check whether Termux:API is installed. It consists of 2 sides, client (termux-api binary) and backend which is Termux:API add-on application. If the latter one doesn't exist, termux-api
will hang.
Running pm path com.termux.api
should give you the apk installation path for Termux:API
and is the reliable way to know for sure. It exits with exit code 1
if not found. But on newer android versions, you will get cmd: Failure calling service package: Failed transaction
error since normal apps users can't run it, but privileged users like shell
(use adb
from android-tools
package) or root
can.
if pm path com.termux.api 1>/dev/null; then
echo installed
fi
if su -c 'pm path com.termux.api 1>/dev/null'; then
echo installed
fi
When running with adb
, ensure you have already run adb connect
. Also run adb devices
and use the serial found for your current device and pass that as -s
to adb shell
command, otherwise if more than one devices found, adb
command will fail with adb: more than one device/emulator
.
if adb -s emulator-5554 shell 'pm path com.termux.api 1>/dev/null'; then
echo installed
fi
Moreover, above way is also slow, since it has to make a call to the android package manager. Faster but slightly unreliable way would be to check if the /data/data/com.termux.api
path exists which android should create at android app installation time and wouldn't require shell
or root
user since termux-app
should be able to access the path due to sharedUserId
(and technically without it too. Running [ -d /data/data/com.android.chrome ] && echo 1
works to check if directory exists but you can't access the contents with ls
. Any app can check if another app is installed with this without any extra privileges if it knows the package name.)
[ -d /data/data/com.termux.api ] && echo 1
if [ -d /data/data/com.termux.api ]; then
echo installed
fi
however, for non-termux user (as for me, it is u0_a205), Termux:API will hang whatever i do. why this phenomenon happen?
and if it cannot work for non-termux user, why it must hang not return a non-zero value?
thanks.
This issue is being misunderstood I think. The replies are about detecting whether it's installed, but it seems the issue is that the process hangs.
I have a similar (or the same?) problem. Not everything hangs, for example reading the camera info works fine, but the sensors hang indefinitely when I just try to list them. Running $PREFIX/libexec/termux-api
says an argument was expected, and when I do (no matter what it is) it just hangs forever. Running termux-sensor
gives a help text, but termux-sensor -l
hangs indefinitely. Using strace -f termux-sensor -l
, there's a ton of output that I frankly can't understand (sometimes I see something helpful like waiting for a file or I can trace that it waits for a network packet) and it ends up hanging on accept4(3,
. Not sure if that's an identical problem as what OP describes or a different one.
Edit: Oh hey it works if I run it from the terminal rather than from a computer via ssh. I double-checked logcat and this time spotted the stack trace, with accompanying messages, that I must have overlooked last time:
08-24 00:29:25.784 26649 26649 D AndroidRuntime: >>>>>> START com.android.internal.os.RuntimeInit uid 10159 <<<<<<
08-24 00:29:25.792 26649 26649 E libc : Access denied finding property "persist.device_config.runtime_native_boot.profilebootclasspath"
08-24 00:29:25.792 26649 26649 E libc : Access denied finding property "persist.device_config.runtime_native_boot.enable_apex_image"
08-24 00:29:25.792 26649 26649 I AndroidRuntime: Using default boot image
08-24 00:29:25.792 26649 26649 E libc : Access denied finding property "persist.device_config.runtime_native_boot.disable_lock_profiling"
08-24 00:29:25.792 26649 26649 I AndroidRuntime: Leaving lock profiling enabled
08-24 00:29:25.792 26649 26649 E libc : Access denied finding property "persist.device_config.runtime_native_boot.enable_generational_cc"
08-24 00:29:25.797 26649 26649 I app_process: Core platform API reporting enabled, enforcing=false
08-24 00:29:25.959 26649 26649 D app_process: Time zone APEX ICU file found: /apex/com.android.tzdata/etc/icu/icu_tzdata.dat
08-24 00:29:25.959 26649 26649 D app_process: I18n APEX ICU file found: /apex/com.android.i18n/etc/icu/icudt66l.dat
08-24 00:29:26.019 26649 26649 W app_process: JNI RegisterNativeMethods: attempt to register 0 native methods for android.media.AudioAttributes
08-24 00:29:26.033 26649 26649 D AndroidRuntime: Calling main entry com.termux.termuxam.Am
08-24 00:29:26.059 11455 11509 D CompatibilityChangeReporter: Compat change id reported: 135634846; UID 10159; state: DISABLED
08-24 00:29:26.061 11455 11510 D CompatibilityChangeReporter: Compat change id reported: 143937733; UID 10159; state: DISABLED
08-24 00:29:26.095 11325 11325 D Zygote : Forked child process 26663
08-24 00:29:26.099 11455 11510 I ActivityManager: Start proc 26663:com.termux.api/u0a159 for broadcast {com.termux.api/com.termux.api.TermuxApiReceiver}
08-24 00:29:26.157 962 992 I adbd : jdwp connection from 26663
08-24 00:29:26.212 26663 26663 D ApplicationLoaders: Returning zygote-cached class loader: /system/framework/android.test.base.jar
08-24 00:29:26.241 26663 26663 D NetworkSecurityConfig: No Network Security Config specified, using platform default
08-24 00:29:26.250 11455 12666 W ActivityManager: Background start not allowed: service Intent { act=list cmp=com.termux.api/.SensorAPI$SensorReaderService (has extras) } to com.termux.api/.SensorAPI$SensorReaderService from pid=26663 uid=10159 pkg=com.termux.api startFg?=false
08-24 00:29:26.242 26663 26663 D NetworkSecurityConfig: No Network Security Config specified, using platform default
08-24 00:29:26.253 26663 26663 E termux-api: Error in TermuxApiReceiver
08-24 00:29:26.253 26663 26663 E termux-api: java.lang.IllegalStateException: Not allowed to start service Intent { act=list cmp=com.termux.api/.SensorAPI$SensorReaderService (has extras) }: app is in background uid UidRecord{9cef9ac u0a159 RCVR bg:+1h2m30s337ms idle change:uncached procs:2 seq(0,0,0)}
08-24 00:29:26.253 26663 26663 E termux-api: at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1715)
08-24 00:29:26.253 26663 26663 E termux-api: at android.app.ContextImpl.startService(ContextImpl.java:1670)
08-24 00:29:26.253 26663 26663 E termux-api: at android.content.ContextWrapper.startService(ContextWrapper.java:720)
08-24 00:29:26.253 26663 26663 E termux-api: at android.content.ContextWrapper.startService(ContextWrapper.java:720)
08-24 00:29:26.253 26663 26663 E termux-api: at com.termux.api.SensorAPI.onReceive(SensorAPI.java:40)
08-24 00:29:26.253 26663 26663 E termux-api: at com.termux.api.TermuxApiReceiver.doWork(TermuxApiReceiver.java:143)
08-24 00:29:26.253 26663 26663 E termux-api: at com.termux.api.TermuxApiReceiver.onReceive(TermuxApiReceiver.java:21)
08-24 00:29:26.253 26663 26663 E termux-api: at android.app.ActivityThread.handleReceiver(ActivityThread.java:4026)
08-24 00:29:26.253 26663 26663 E termux-api: at android.app.ActivityThread.access$1400(ActivityThread.java:237)
08-24 00:29:26.253 26663 26663 E termux-api: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1924)
08-24 00:29:26.253 26663 26663 E termux-api: at android.os.Handler.dispatchMessage(Handler.java:106)
08-24 00:29:26.253 26663 26663 E termux-api: at android.os.Looper.loop(Looper.java:223)
08-24 00:29:26.253 26663 26663 E termux-api: at android.app.ActivityThread.main(ActivityThread.java:7664)
08-24 00:29:26.253 26663 26663 E termux-api: at java.lang.reflect.Method.invoke(Native Method)
08-24 00:29:26.253 26663 26663 E termux-api: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
08-24 00:29:26.253 26663 26663 E termux-api: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
08-24 00:29:26.256 11455 12666 I ActivityManager: Killing 24284:com.android.shell/2000 (adj 995): empty #17
08-24 00:29:26.256 26649 26649 D AndroidRuntime: Shutting down VM
08-24 00:29:26.351 11325 11325 I Zygote : Process 24284 exited due to signal 9 (Killed)
Running it in the foreground instead works. Rather annoying though, the point of automating this is that I am not typing that stuff in manually.
@Freed-Wu did you check (adb) logcat?
This issue is being misunderstood I think. The replies are about detecting whether it's installed, but it seems the issue is that the process hangs.
I have a similar (or the same?) problem. Not everything hangs...
I agree with you. I met the hang problem in both adb shell and terminal (after su). I have not done more researches about it. I feel confused by this situation...
@Freed-Wu Check logcat if you have the same error.
Also I might recommend deepl.com for translation since you seem to not have understood my message fully. It is also hard to understand you. Deepl's english<>dutch translation is really good and it looks like they support chinese as well.
@Freed-Wu 检查logcat,如果你有同样的错误。
另外我可能会推荐deepl.com进行翻译,因为你似乎没有完全理解我的信息。我也很难理解你。Deepl的英语<>荷兰语翻译真的很好,而且看起来他们也支持中文。
and if it cannot work for non-termux user, why it must hang not return a non-zero value?
The termux-api
binary interacts with the Termux:API
app via sockets, the app isn't running with root, so communications isn't possible, the app can't send back the result, hence command hangs. There are no checks in place in termux-api
for whether caller is a non-termux user or not, so that a command isn't even sent to the app. Some commands like apt
do have checks.
2021-08-07 18:13:34.651 8606-8637/com.termux.api E/termux-api: Error in ResultReturner
java.io.IOException: Permission denied
at android.net.LocalSocketImpl.connectLocal(Native Method)
at android.net.LocalSocketImpl.connect(LocalSocketImpl.java:296)
at android.net.LocalSocket.connect(LocalSocket.java:147)
at com.termux.api.util.ResultReturner.lambda$returnData$0(ResultReturner.java:122)
at com.termux.api.util.-$$Lambda$ResultReturner$oCU8JqHW5HLMrNZa40ThjAWcwzo.run(Unknown Source:8)
at java.lang.Thread.run(Thread.java:919)
Basically, do not run with root. Running something like su 10xxx -c 'termux-wifi-connectioninfo'
to run as termux user will fail as well, due to wrong capabilities/privileges, you will need something like this to work, which requires patching selinux policy as well. ~Moreover, termux doesn't provide setpriv
and the mirrors for the one in stackexchange comment have expired, but attaching it. The one I compiled for termux from termux-packages
was failing on android 7
, but seemed to work on android 10
rooted emulator but magisk root script doesn't install supolicy
so can't fully test it. Will look into it in future.~
setpriv_static_aarch64_v2.33.296-14690.zip
Update:
Termux util-linux
package v2.37.2-1
provides setpriv
now. Requires libcap-ng
v0.8.3~pre1
or higher.
https://github.com/termux/termux-packages/pull/8198
E termux-api: java.lang.IllegalStateException: Not allowed to start service Intent { act=list cmp=com.termux.api/.SensorAPI$SensorReaderService (has extras) }: app is in background uid UidRecord{9cef9ac u0a159 RCVR bg:+1h2m30s337ms idle change:uncached procs:2 seq(0,0,0)}
Have you disabled battery optimizations for termux-api AND termux app? https://dontkillmyapp.com/
Although, if running with root
, then sending RUN_COMMAND
intent in background mode that stores results in files should work. That way, termux app process would initiate the sockets so should work. In your root script, just wait for the result to be written to the output files in a while loop. Check https://github.com/termux/termux-app/wiki/RUN_COMMAND-Intent and termux/termux-app@2aafcf84
The termux-api binary interacts with the Termux:API app via sockets, the app isn't running with root, so communications isn't possible, the app can't send back the result, hence command hangs.
Thanks for your answer!
There are no checks in place in termux-api for whether caller is a non-termux user or not, so that a command isn't even sent to the app. Some commands like apt do have checks.
I know. If there are checks in termux-api, it will be great.
Basically, do not run with root... Will look into it in future.
Thanks!
Although, if running with root, then sending RUN_COMMAND intent in background mode that stores results in files should work.
Great. Thanks for your answer.
https://github.com/romkatv/powerlevel10k/pull/1289#issuecomment-792236680
is there any way to judge a temux-api can work normally not hang?
Thanks!