-
-
Save ktnr74/ac6b34f11d1e781db089 to your computer and use it in GitHub Desktop.
#!/bin/bash | |
ADBShell () { adb ${2+-s }$2 shell "$1" | tr -d '\r' | |
} | |
GetAndroidVersion () { | |
local ALL_TAGS=$(wget -qO - "$GOOGLE_SOURCE/$REPO/+refs/tags/?format=text" | \ | |
tr -d '^{}' | cut -d/ -f3 | sort -u | grep -vE -- '-(cts|sdk)-' | grep -v "_r0") | |
TAG=${1:-$(ADBShell 'getprop ro.build.version.release')} | |
echo -e "ANDROID_SERIAL=$ANDROID_SERIAL\nro.build.version.release=$TAG" 1>&2 | |
TAG=$(echo "$ALL_TAGS" | grep -- "android-${TAG//./\.}" | head -n 1) | |
echo -e "TAG=$TAG" 1>&2 | |
[ "-$TAG" != "-" ] && return 0 | |
echo -e "TAG not valid!\n\nList of valid tags: "$ALL_TAGS 1>&2 | |
exit 1 | |
} | |
GetServicePackageName () { | |
SERVICE_PACKAGE=$(ADBShell 'service list' | grep "\s$1: \[" | head -n 1 | tr '[]' '""' | cut -d\" -f2) | |
echo -e "SERVICE=$1\nSERVICE_PACKAGE=$SERVICE_PACKAGE" 1>&2 | |
} | |
GetGoogleSourceFile () { | |
#echo -e "\t\E[31mdownloading\E[0m $GOOGLE_SOURCE/$REPO/+/$1/$2" 1>&2 | |
[ "-$1" == "-" ] && return 1 | |
wget -qO - "$GOOGLE_SOURCE/$REPO/+/$1/$2?format=text" | base64 -d | |
} | |
GetAllServices () { | |
ALL_SERVICES=$(GetGoogleSourceFile "$TAG" "Android.mk" | tr -d ' \\\t' | grep "\.aidl$" | \ | |
sort -u | grep -v "^gen:") | |
} | |
ParseServiceAIDL () { | |
GetGoogleSourceFile "$TAG" $(echo "$ALL_SERVICES" | grep "${SERVICE_PACKAGE//.//}\.aidl$" | head -n 1) | \ | |
gcc -P -E - | tr '{};\n\r' '\n\n\n ' | grep -v ^$ | sed -e '1,/interface\s/ d' | cat -n | |
} | |
AbortIfExecutableMissing () { | |
BIN=($@) | |
MISSINGBIN=$(for B in ${BIN[@]}; do [ "$(which $B 2>/dev/null)-" == "-" ] && echo $B; done) | |
[ "${MISSINGBIN}-" == "-" ] && return 0 | |
echo -e "Can't find the following executables: "$MISSINGBIN | |
exit 1 | |
} | |
AbortIfExecutableMissing "adb wget gcc tr sed awk cut grep basename dirname head base64" | |
GOOGLE_SOURCE="https://android.googlesource.com" | |
REPO="platform/frameworks/base" | |
GetAndroidVersion | |
GetAllServices | |
GetServicePackageName $1 | |
ParseServiceAIDL | |
exit 0 |
Check out mine and sergey1369's forks for alternative fixes to add compatibility for devices running Android version 9 and above. Mine appears to have marginally better performance and doesn't add a dependency, but both should work.
Based on your guys' work, I wrote a small utility to make it easier to find and call service methods etc: https://github.com/T-vK/android-svc
Now you can simply do
android-svc call 'android.media.IAudioService.setMasterMute(false, 0, "com.termux", 0);'
#or
android-svc call 'audio.setMasterMute(false, 0, "com.termux", 0);'
instead of
service call audio 11 i32 0 i32 0 s16 'com.termux' i32 0
Works both from a Linux host over adb as well as on an Android device directly. I can't verify if it works from a Mac OS machine though.
Just FYI, you (that includes all forks) have what I would call a critical bug in your ParseServiceAIDL function. That caused the incorrect method index to be returned in some cases. I have fixed that in my GetMethodIndex. Feel free to copy whatever you need.
In Android 9 you can parse Android.bp instead of Android.mk for the aidl sources. Starting with Android 11 you have to actually search through the entire directory tree to find them all. I got that working in android-svc here:
No longer working on Android 9.0. I tried my best to debug it, but haven't been able to figure it out.
Edit: This appears to be a major factor in the failure:
https://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-cts-9.0_r7/Android.mk