127 lines
3.2 KiB
Bash
127 lines
3.2 KiB
Bash
|
|
#!/bin/sh
|
||
|
|
|
||
|
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||
|
|
# Copyright 2024 Jacob D Ludvigsen (contributions@ingeniorskap.no)
|
||
|
|
# https://gitlab.com/papiris/geobridge
|
||
|
|
# MODIFIED 2026 ethical_haquer
|
||
|
|
# https://github.com/waydroid/waydroid/issues/226#issuecomment-3733805954
|
||
|
|
# optimization and devbox setup additions by randogoth
|
||
|
|
|
||
|
|
# This script bridges basic geolocation info
|
||
|
|
# from Geoclue-2 running on the host system into Waydroid.
|
||
|
|
# Current location is parsed from the example "where-am-i" geoclue agent,
|
||
|
|
# and sent via adb to the mock location provider "appium"
|
||
|
|
# running in the Waydroid container.
|
||
|
|
|
||
|
|
find_where_am_i() {
|
||
|
|
# prefer PATH, then common locations (Nix and FHS installs)
|
||
|
|
if command -v where-am-i >/dev/null 2>&1; then
|
||
|
|
command -v where-am-i
|
||
|
|
return 0
|
||
|
|
fi
|
||
|
|
|
||
|
|
for candidate in \
|
||
|
|
/usr/libexec/geoclue-2.0/demos/where-am-i \
|
||
|
|
/nix/store/*geoclue*/libexec/geoclue-2.0/demos/where-am-i
|
||
|
|
do
|
||
|
|
if [ -x "$candidate" ]; then
|
||
|
|
printf '%s\n' "$candidate"
|
||
|
|
return 0
|
||
|
|
fi
|
||
|
|
done
|
||
|
|
|
||
|
|
return 1
|
||
|
|
}
|
||
|
|
|
||
|
|
extract_number() {
|
||
|
|
# return first numeric value from a line, stripping units/symbols
|
||
|
|
printf '%s\n' "$1" | awk '{
|
||
|
|
for (i = 1; i <= NF; i++) {
|
||
|
|
candidate = $i
|
||
|
|
gsub(/[^0-9.+-]/, "", candidate)
|
||
|
|
if (candidate ~ /^-?[0-9]+(\.[0-9]+)?$/) {
|
||
|
|
print candidate
|
||
|
|
exit
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}'
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
if [ "$1" = "--init" ]; then
|
||
|
|
# make sure you've connected host system adb to the Waydroid container before running this program
|
||
|
|
|
||
|
|
# download appium settings android app
|
||
|
|
wget https://github.com/appium/io.appium.settings/releases/download/v7.0.10/settings_apk-debug.apk \
|
||
|
|
-O /tmp/appium.apk
|
||
|
|
|
||
|
|
# install appium in Waydroid container,
|
||
|
|
# don't grant permissions
|
||
|
|
waydroid app install /tmp/appium.apk
|
||
|
|
|
||
|
|
# allow to set Android location via api
|
||
|
|
adb shell settings put global hidden_api_policy 1
|
||
|
|
# allow appium to set mock location
|
||
|
|
adb shell appops set io.appium.settings \
|
||
|
|
android:mock_location allow
|
||
|
|
# allow appium access to location data
|
||
|
|
adb shell pm grant io.appium.settings \
|
||
|
|
android.permission.ACCESS_FINE_LOCATION
|
||
|
|
|
||
|
|
echo initialized
|
||
|
|
fi
|
||
|
|
|
||
|
|
lat=
|
||
|
|
long=
|
||
|
|
alt=
|
||
|
|
|
||
|
|
where_am_i="$(find_where_am_i)" || {
|
||
|
|
echo "Cannot find where-am-i demo agent; install geoclue demo or adjust path." >&2
|
||
|
|
exit 1
|
||
|
|
}
|
||
|
|
|
||
|
|
while true
|
||
|
|
do
|
||
|
|
# long-running command
|
||
|
|
"$where_am_i" \
|
||
|
|
--timeout=30 \
|
||
|
|
--accuracy-level=8 |
|
||
|
|
while IFS= read -r line
|
||
|
|
do
|
||
|
|
# parse output from geoclue agent
|
||
|
|
case "$line" in
|
||
|
|
(New*)
|
||
|
|
lat=
|
||
|
|
long=
|
||
|
|
alt=
|
||
|
|
;;
|
||
|
|
(Latitude:*)
|
||
|
|
lat="$(extract_number "$line")"
|
||
|
|
;;
|
||
|
|
(Longitude:*)
|
||
|
|
long="$(extract_number "$line")"
|
||
|
|
;;
|
||
|
|
(Altitude:*)
|
||
|
|
alt="$(extract_number "$line")"
|
||
|
|
;;
|
||
|
|
esac
|
||
|
|
|
||
|
|
# check that all location values have been assigned
|
||
|
|
if [ -n "$long" ] && [ -n "$lat" ]; then
|
||
|
|
alt="${alt:-0}"
|
||
|
|
# start/update appium service in Waydroid container with location
|
||
|
|
adb shell am start-foreground-service --user 0 \
|
||
|
|
-n io.appium.settings/.LocationService \
|
||
|
|
--es longitude "$long" \
|
||
|
|
--es latitude "$lat" \
|
||
|
|
--es altitude "$alt" > /dev/null
|
||
|
|
|
||
|
|
echo "Location updated: $lat, $long (alt $alt)"
|
||
|
|
lat=
|
||
|
|
long=
|
||
|
|
alt=
|
||
|
|
fi
|
||
|
|
|
||
|
|
done
|
||
|
|
done
|