From cb8bb758aaf5298818b2df085f627eb7ada645c9 Mon Sep 17 00:00:00 2001 From: regulad Date: Sun, 2 Mar 2025 16:17:06 -0500 Subject: [PATCH 1/2] Commit working progress thus far Ubuntu documentation docker attempt perfect 4-architecture building dist_archive building Test GitHub actions Test GitHub actions Test GitHub actions Test GitHub actions Test GitHub actions Test GitHub actions Test GitHub actions properly implemented caching --- .github/workflows/test.yml | 97 ++++++++++++ .gitignore | 1 + DEVELOPING.md | 145 ++++++++++++++++++ Dockerfile | 22 +++ Makefile | 2 +- dmake | 50 ++++++ recipes/codec2/__init__.py | 18 ++- recipes/codec2/generate_codebook | Bin 16456 -> 0 bytes recipes/opusfile/__init__.py | 2 - sbapp/Makefile | 122 ++++++++++++--- sbapp/buildozer.spec | 6 +- sbapp/main.py | 19 +++ .../main/java/io/unsigned/sideband/.gitkeep | 0 .../main/res/xml}/device_filter.xml | 0 .../main/res/xml}/file_paths.xml | 0 15 files changed, 455 insertions(+), 29 deletions(-) create mode 100644 .github/workflows/test.yml create mode 100644 DEVELOPING.md create mode 100644 Dockerfile create mode 100755 dmake delete mode 100755 recipes/codec2/generate_codebook create mode 100644 sbapp/src/main/java/io/unsigned/sideband/.gitkeep rename sbapp/{patches => src/main/res/xml}/device_filter.xml (100%) rename sbapp/{patches => src/main/res/xml}/file_paths.xml (100%) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..8c9cc52 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,97 @@ +on: + pull_request: + types: [opened, synchronize] + push: + branches: ["**"] + +jobs: + test-compile: + runs-on: ubuntu-latest + name: "Test P4A Compiling" + + steps: + - name: Clone LXMF + run: git clone https://github.com/markqvist/LXMF $GITHUB_WORKSPACE/LXMF + + - name: Clone LXST + run: git clone https://github.com/markqvist/LXST $GITHUB_WORKSPACE/LXST + + - name: Clone rnsh + run: git clone https://github.com/acehoss/rnsh $GITHUB_WORKSPACE/rnsh + + - name: Clone Reticulum + run: git clone https://github.com/markqvist/Reticulum $GITHUB_WORKSPACE/Reticulum + + - name: Clone rnode-flasher + run: git clone https://github.com/liamcottle/rnode-flasher $GITHUB_WORKSPACE/rnode-flasher + + - name: Clone NomadNet + run: git clone https://github.com/markqvist/nomadnet $GITHUB_WORKSPACE/NomadNet + + - name: Clone reticulum_website + run: git clone https://github.com/markqvist/reticulum_website $GITHUB_WORKSPACE/reticulum_website + + - name: Checkout Sideband + uses: actions/checkout@v3 + with: + path: Sideband/ + + # Set up caching for general cache directory + - name: Cache pip build cache + uses: actions/cache@v3 + with: + path: ~/.cache + key: ${{ runner.os }}-build-cache-${{ hashFiles('**/buildozer.spec') }} + restore-keys: | + ${{ runner.os }}-build-cache- + + # Set up caching for buildozer directories + - name: Cache buildozer + uses: actions/cache@v3 + with: + path: | + ~/.buildozer + ${{ github.workspace }}/**/.buildozer + ${{ github.workspace }}/**/.buildozer-container + key: ${{ runner.os }}-buildozer-${{ hashFiles('**/buildozer.spec') }} + restore-keys: | + ${{ runner.os }}-buildozer- + + # Set up caching for Gradle + - name: Cache Gradle files + uses: actions/cache@v3 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + ~/.gradle/daemon + ~/.gradle/native + key: ${{ runner.os }}-gradle-${{ hashFiles('**/buildozer.spec') }} + restore-keys: | + ${{ runner.os }}-gradle- + + - name: Create Android SDK directory + run: mkdir -p ~/.android + + - name: Generate debug keystore + run: | + keytool -genkeypair \ + -keystore ~/.android/debug.keystore \ + -storepass android \ + -keypass android \ + -alias androiddebugkey \ + -keyalg RSA \ + -keysize 2048 \ + -validity 10000 \ + -dname "CN=Android Debug,O=Android,C=US" + + - name: Attempt to build Sideband for Android (Debug) + run: | + cd $GITHUB_WORKSPACE/Sideband + ./dmake devapk + + - name: Upload built APK + uses: actions/upload-artifact@v4 + with: + name: android-debug + path: ${{ github.workspace }}/Sideband/sbapp/bin/*.apk diff --git a/.gitignore b/.gitignore index 7750d9e..08598db 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,4 @@ dist docs/build sideband*.egg-info sbapp*.egg-info +Sideband.iml diff --git a/DEVELOPING.md b/DEVELOPING.md new file mode 100644 index 0000000..fa2cdc0 --- /dev/null +++ b/DEVELOPING.md @@ -0,0 +1,145 @@ +# Establishing a Development environment + +Looking to contribute some code to Sideband? Awesome! Follow the guide below to get the repository building on your machine. + +## Creating folders + +Sideband relies on a certain folder structure to achieve a psuedo-monorepo structure with the other Reticulum projects. + +To make sure that the `getrns` target runs successfully, make sure your directory tree looks like this: + +``` +repositories/ +├─ LXMF/ +├─ LXST/ +├─ rnsh/ +├─ rnode-flasher/ +├─ Reticulum/ +├─ NomadNet/ +├─ reticulum_website/ +└─ Sideband/ +``` + +Below are the git repositories for some of the above folders: + +- `LXMF`: https://github.com/markqvist/LXMF +- `LXST`: https://github.com/markqvist/LXST +- `rnsh`: https://github.com/acehoss/rnsh +- `Reticulum`: https://github.com/markqvist/Reticulum +- `rnode-flasher`: https://github.com/liamcottle/rnode-flasher +- `NomadNet`: https://github.com/markqvist/nomadnet +- `reticulum_website`: https://github.com/markqvist/reticulum_website + +> Please note: in order for the docker script and `createshare` make target to work correctly, your directory **must** be laid out like this. + +## Required dependencies for development (Docker) + +If you have a Fedora-based Linux system (see [Addendum: Fedora](#addendum-fedora)) or simply would not like to install all of P4A's dependencies manually, you may choose to use the containerized build. + +This method requires that you have Docker installed on your system: https://docs.docker.com/engine/install/ + +Additionally, [rootless Docker](https://docs.docker.com/engine/install/) should be used to minimize any possible attack surface on your system. Never run a script you haven't vetted with sudo! The `./dmake.sh` script uses `set -ex` and is designed to be used with rootless docker. + +After configuring docker, you can replace any use of the `make` command with `dmake` (i.e. `./dmake devapk`) to run make commands in the container, building it on demand if needed. + +Example: + +``` +./dmake devapk +``` + +(or if running in sbapp, it is smart enough to run itself in Sideband regardless of where it is called from) + +``` +../dmake devapk +``` + +## Required dependencies for development (Native) + +Until this repository has a `flake.nix` added, you will need to manually download the following dependencies using your Operating System's package manager. + +- `make` +- `adb` (available as a part of the `android-tools` package on Fedora, `adb` on Debian/Ubuntu, `android-platform-tools` on Brew Casks) +- `python3`/`python3-dev(el)` (must be available as `python`, on Ubuntu try `apt install python-is-python3`) +- `patchelf` +- `patch` +- `perl` +- `portaudio19-dev` +- `libopus-dev` +- `libogg-dev` +- `buildozer` (see https://buildozer.readthedocs.io/en/latest/installation.html) + - buildozer's PyPI hosted version is very far behind, therefore you should install from source at https://github.com/kivy/buildozer.git; this is easy with pipx `pipx install git+https://github.com/kivy/buildozer.git`. + - buildozer needs `wheel` to run, but it is not currently marked as a dependency. If you are using pipx, you will need to inject it with `pipx inject buildozer wheel`. +- all of buildozer's Android dependencies + - Ubuntu 22.04 LTS packages `git zip unzip openjdk-17-jdk python3-pip autoconf libtool pkg-config zlib1g-dev libncurses5-dev libncursesw5-dev libtinfo5 cmake libffi-dev libssl-dev` + - Ubuntu 24.04 LTS packages `git zip unzip openjdk-17-jdk python3-pip autoconf libtool pkg-config zlib1g-dev libncurses-dev libtinfo6 cmake libffi-dev libssl-dev` + - Fedora 41 `git zip unzip java-17-openjdk java-17-openjdk-devel python3-pip autoconf libtool pkgconf-pkg-config ghc-zlib-devel ncurses-devel ncurses-compat-libs cmake libffi-devel openssl-devel` + +In the root directory of the repository, use `pip install .` to install the package from `setup.py`. The use of a `venv` is strongly recommended. + +Make sure you manually install `Cython<3.0` into your Python install or `venv`, as buildozer will need it for Android. + +### Addendum: Fedora + +As many users of Kivy have noted before, some of Python4Android's recipes do not compile correctly on Fedora/RHEL. For this project, one package of interest is [`freetype-py` and its native dependency](https://github.com/kivy/python-for-android/blob/develop/pythonforandroid/recipes/freetype/__init__.py), which is a direct dependency of pillow, the ubiquitous Python image editing library. + +This is due to the fact that Fedora and several other distros include default versions of toolchains, which prompts python4android to abstain from downloading its own. [This issue has been encountered by many other users.](https://groups.google.com/g/kivy-users/c/z46lSJXgbjY/m/M1UoWwtWAgAJ) + +If you can't use Docker, use of Ubuntu 24.04 LTS is therefore recommended for developing this project. Ubuntu 22.04 LTS is not supported, as its `cmake` version (even with backports) is below the minimum 3.24. + +Sideband does run fine on Fedora, however. + +## Compiling and testing Sideband on an Android device + +With a correctly configured environment, run the following command to create a development APK. + +``` +make devapk +``` + +You can then install it to a connected device with + +``` +make devinstall +``` + +If you would like your release to be signed for release, you must configure the following four environment variables: + +- `P4A_RELEASE_KEYALIAS` +- `P4A_RELEASE_KEYSTORE_PASSWD` +- `P4A_RELEASE_KEYSTORE` +- `P4A_RELEASE_KEYALIAS_PASSWD` + +With `./dmake`, omitting any of these values will cause it to default to the `debug.keystore` generated with each install of the Android SDK. + +After it is configured correctly, you may build it with + +``` +make apk +``` + +and install it to a connected device with + +``` +make install +``` + +The output will be placed in `./sbapp/bin/sideband-*.apk`. + +If you have multiple devices connected at once (for example, while developing the BLE interface between devices), you may use `devinstall-multi` or `install-multi` in place of `devinstall` and `install` respectively. + +If using an Android that provides the ability to toggle DCL via storage (like GrapheneOS), make sure to enable it for Sideband, as it must load its Cython executables. + +## Compiling and testing Sideband for other platforms + +For Windows, use the following command: (make sure you have `PyInstaller` in your venv, and you are on Windows, as PyInstaller removed cross-compilation) + +``` +make build_win_exe +``` + +Wheels for other platforms can be built with + +``` +make build_wheel +``` diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..59c91b8 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,22 @@ +# exercise extreme caution when bumping this docker image to the newest ubuntu LTS version +FROM ubuntu:24.04 + +# for rationale behind each of these dependencies, consult the native section of DEVELOPING.md +RUN DEBIAN_FRONTEND=noninteractive \ + apt update \ + && DEBIAN_FRONTEND=noninteractive apt install -y curl git libffi-dev python-is-python3 python3-dev python3-wheel python3-setuptools python3-virtualenv libssl-dev autoconf openjdk-17-jdk cmake libtool libssl-dev libncurses5-dev libsqlite3-dev libreadline-dev libtk8.6 libgdm-dev libpcap-dev unzip zip wget apksigner build-essential libopus-dev libogg-dev portaudio19-dev patchelf pipx \ + && apt install --reinstall python3 \ + && rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/* + +# need to run as root for a rootless docker runtime +# the repository folders owned by 1000 on the host are mounted to 0 on the container; this is intentional and unchangable + +# add pipx +ENV PATH=$PATH:/root/.local/bin + +# install & inject wheel +RUN pipx install git+https://github.com/kivy/buildozer.git@abc2d7e66c8abe096a95ed58befe6617f7efdad0 +RUN pipx inject buildozer wheel + +# needed for some transitive deps, like rnsh +RUN pipx install poetry==2.1.1 diff --git a/Makefile b/Makefile index 6f5ed59..1914718 100644 --- a/Makefile +++ b/Makefile @@ -40,4 +40,4 @@ upload: @echo Ready to publish release, hit enter to continue @read VOID @echo Uploading to PyPi... - twine upload dist/sbapp-* \ No newline at end of file + twine upload dist/sbapp-* diff --git a/dmake b/dmake new file mode 100755 index 0000000..ae8b253 --- /dev/null +++ b/dmake @@ -0,0 +1,50 @@ +#!/bin/bash + +set -ex + +# any of the tasks that require adb should be run on the host, not the guest docker container +# ad-hoc docker usb passthrough sounds miserable... +if [ $1 == "install" ] || [ $1 == "devinstall" ] || [ $1 == "install-multi" ] || [ $1 == "devinstall-multi" ]; then + echo "Command requiring adb detected, running on host..." + # shellcheck disable=SC2068 # goal is to re-split + make -C sbapp $@ + exit 0 +fi + +if [[ -z $P4A_RELEASE_KEYSTORE ]]; then + echo "P4A_RELEASE_KEYSTORE is not set correctly! Using default debug keystore..." + P4A_RELEASE_KEYSTORE=$(realpath ~/.android/debug.keystore) + P4A_RELEASE_KEYALIAS=androiddebugkey + P4A_RELEASE_KEYSTORE_PASSWD=android + P4A_RELEASE_KEYALIAS_PASSWD=android +fi + +# will hit caches automatically, unless the dockerfile was changed +# buildozer writes to its own venv, so it can't be --read-only even though it really should be +# /root/.buildozer has some build artifacts that are reused, and since they are dependent on the libraries available at compile-time, they must be isolated from ~/.buildozer as these may have different fingerprints +# ~/.cache, on the other hand, may be reused because pip is smart enough to download/rebuild native dependencies if they wouldn't be compatible +docker build --network=host -t sideband-dmake . +docker run \ + --rm \ + --tty \ + --network=host \ + --tmpfs /tmp:rw,exec \ + -e P4A_RELEASE_KEYALIAS=$P4A_RELEASE_KEYALIAS \ + -e P4A_RELEASE_KEYSTORE_PASSWD=$P4A_RELEASE_KEYSTORE_PASSWD \ + -e P4A_RELEASE_KEYSTORE="/keystore.jks" \ + -e P4A_RELEASE_KEYALIAS_PASSWD=$P4A_RELEASE_KEYALIAS_PASSWD \ + -v "$(realpath $(dirname "$0")/..):/repositories:rw" \ + -v "$(realpath ./.buildozer-container):/root/.buildozer:rw" \ + -v "$(realpath ./sbapp/.buildozer-container):/repositories/Sideband/sbapp/.buildozer:rw" \ + -v "$(realpath ~/.cache):/root/.cache:rw" \ + -v "$P4A_RELEASE_KEYSTORE:/keystore.jks:ro" \ + -v "$(realpath ~/.android):/root/.android:rw" \ + -v "$(realpath ~/.gradle):/root/.gradle:rw" \ + sideband-dmake \ + /bin/bash \ + -c \ + "python3 -m venv --system-site-packages /tmp/venv \ + && source /tmp/venv/bin/activate \ + && cd /repositories/Sideband \ + && pip install -e . \"Cython<3.0\" \ + && make -C sbapp $@" diff --git a/recipes/codec2/__init__.py b/recipes/codec2/__init__.py index 81aa527..fd63c0a 100644 --- a/recipes/codec2/__init__.py +++ b/recipes/codec2/__init__.py @@ -1,13 +1,19 @@ from os.path import join +from tempfile import TemporaryDirectory from pythonforandroid.recipe import Recipe from pythonforandroid.toolchain import current_directory, shprint +import os import sh # For debugging, clean with # buildozer android p4a -- clean_recipe_build codec2 --local-recipes ~/Information/Source/Sideband/recipes class Codec2Recipe(Recipe): + # recipe for building codec2 from https://github.com/markqvist/codec2 + url = "https://github.com/markqvist/codec2/archive/00e01c9d72d3b1607e165c71c4c9c942d277dfac.tar.gz" + sha512sum = "2f8db660592e19b7f853c146793ccbde90f1d505663084f055172c8e5088a9fc2ddb588cc014ed8dec46a678ec73aaf654bbe77ff29f21caa7c45fb121f2281f" + built_libraries = {'libcodec2.so': 'build_android/src'} def include_flags(self, arch): @@ -41,10 +47,18 @@ class Codec2Recipe(Recipe): # cd = sh.cd("build_android") os.chdir("build_android") cmake = sh.Command('cmake') + gcc = sh.Command("gcc") shprint(cmake, *flags, _env=env) - shprint(sh.make, _env=env) - sh.cp("../src/codec2.h", "./codec2/") + + # before running the make, we need to compile `generate_codebook` from the codec2 repository for the architecture we are on + # allowing it to be compiled with the rest of the + with TemporaryDirectory() as tmp: + shprint(gcc, "../src/generate_codebook.c", "-o" f"{tmp}{os.sep}generate_codebook", "-lm") + + env_tmp = env | {"PATH": f"{env['PATH']}{os.pathsep}{tmp}"} + shprint(sh.make, _env=env_tmp) + sh.cp("../src/codec2.h", "./codec2/") recipe = Codec2Recipe() diff --git a/recipes/codec2/generate_codebook b/recipes/codec2/generate_codebook deleted file mode 100755 index b4ed668330bf279fc2490b543091b7bcb68ce516..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16456 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 ZjLUlMQhV+@lm0(mXG>gOp-{oH{{r8OXJh~X diff --git a/recipes/opusfile/__init__.py b/recipes/opusfile/__init__.py index 27d0f29..472e12d 100644 --- a/recipes/opusfile/__init__.py +++ b/recipes/opusfile/__init__.py @@ -34,8 +34,6 @@ class OpusFileRecipe(Recipe): # env['LDFLAGS'] += openssl_recipe.link_dirs_flags(arch) # env['LIBS'] = openssl_recipe.link_libs_flags() - from rich.pretty import pprint - pprint(env) time.sleep(5) configure = sh.Command('./configure') diff --git a/sbapp/Makefile b/sbapp/Makefile index d0f9028..49114eb 100644 --- a/sbapp/Makefile +++ b/sbapp/Makefile @@ -15,7 +15,7 @@ cleanlibs: cleanall: clean cleanlibs -pacthfiles: patchsdl injectxml patchpycodec2 +patchfiles: patchsdl injectxml patchpycodec2 patchsdl: # Pach USB HID behaviour @@ -35,10 +35,7 @@ patchpycodec2: injectxml: # mkdir /home/markqvist/.local/lib/python3.11/site-packages/pythonforandroid/bootstraps/sdl2/build/src/main/xml # Inject XML on arm64-v8a - mkdir -p .buildozer/android/platform/build-arm64-v8a_armeabi-v7a/dists/sideband/src/main/res/xml mkdir -p .buildozer/android/platform/build-arm64-v8a_armeabi-v7a/dists/sideband/templates - cp patches/device_filter.xml .buildozer/android/platform/build-arm64-v8a_armeabi-v7a/dists/sideband/src/main/res/xml/ - cp patches/file_paths.xml .buildozer/android/platform/build-arm64-v8a_armeabi-v7a/dists/sideband/src/main/res/xml/ cp patches/AndroidManifest.tmpl.xml .buildozer/android/platform/build-arm64-v8a_armeabi-v7a/dists/sideband/templates/ cp patches/p4a_build.py .buildozer/android/platform/build-arm64-v8a_armeabi-v7a/dists/sideband/build.py @@ -51,26 +48,95 @@ ifneq (,$(wildcard .buildozer/android/platform/build-arm64-v8a_armeabi-v7a/dists else @(echo Prebaking build before patching files...) @(sleep 2) - -(buildozer android release) + (buildozer android release) # this mustn't be ignored, or else the release will indubitably fail @(echo Prebake finished, applying patches and rebuilding...) @(sleep 2) endif +createshare: + # NOTICE: if the git refs of each repository here are not pinned, the build will NOT be deterministic! + mkdir -p ../../dist_archive + rm -vrf ../../dist_archive/* + # mirrors + # reticulum.network + cp -fv ../../reticulum_website/docs/manual/Reticulum\ Manual.pdf ../../dist_archive + cp -fv ../../reticulum_website/docs/manual/Reticulum\ Manual.epub ../../dist_archive + -(rm -rf ../../dist_archive/reticulum.network) + cp -frv ../../reticulum_website/docs ../../dist_archive/reticulum.network + # unsigned.io (mirror from https://git.liberatedsystems.co.uk/jacob.eva/openCom-Companion/src/branch/master/Dockerfile) + $(eval cwd := $(shell pwd)) + cd ../../dist_archive && \ + rm -rf ./unsigned.io && \ + wget -q https://liberatedsystems.co.uk/unsigned_io_archive.zip && \ + unzip -q unsigned_io_archive.zip && \ + rm unsigned_io_archive.zip && \ + cd $(cwd) + # build wheels + # rns, rnspure, lxmf, lxst, nomadnet, rnsh + $(eval cwd := $(shell pwd)) + cd ../../Reticulum && \ + rm -rf ./dist && \ + python3 ./setup.py bdist_wheel && \ + cp -fv ./dist/* ../dist_archive && \ + cd $(cwd) + + $(eval cwd := $(shell pwd)) + cd ../../Reticulum && \ + rm -rf ./dist && \ + python3 ./setup.py bdist_wheel --pure && \ + cp -fv ./dist/* ../dist_archive && \ + cd $(cwd) + + $(eval cwd := $(shell pwd)) + cd ../../LXMF && \ + rm -rf ./dist && \ + python3 ./setup.py bdist_wheel && \ + cp -fv ./dist/* ../dist_archive && \ + cd $(cwd) + + $(eval cwd := $(shell pwd)) + cd ../../LXST && \ + rm -rf ./dist && \ + python3 ./setup.py bdist_wheel && \ + cp -fv ./dist/* ../dist_archive && \ + cd $(cwd) + + $(eval cwd := $(shell pwd)) + cd ../../nomadnet && \ + rm -rf ./dist && \ + python3 ./setup.py bdist_wheel && \ + cp -fv ./dist/* ../dist_archive && \ + cd $(cwd) + + $(eval cwd := $(shell pwd)) + cd ../../rnsh && \ + rm -rf ./dist && \ + poetry build && \ + cp -fv ./dist/* ../dist_archive && \ + cd $(cwd) + # rnode firmware source zip + cd ../../dist_archive && \ + curl -L https://github.com/markqvist/RNode_Firmware/archive/refs/heads/master.zip --clobber -o RNode_Firmware-master.zip && \ + cd $(cwd) + fetchshare: + mkdir -p ./share/pkg -(rm ./share/pkg/*) + mkdir -p ./share/mirrors -(rm ./share/mirrors/* -r) - cp ../../dist_archive/rns-*-py3-none-any.whl ./share/pkg/ - cp ../../dist_archive/rnspure-*-py3-none-any.whl ./share/pkg/ - cp ../../dist_archive/lxmf-*-py3-none-any.whl ./share/pkg/ - cp ../../dist_archive/nomadnet-*-py3-none-any.whl ./share/pkg/ - cp ../../dist_archive/rnsh-*-py3-none-any.whl ./share/pkg/ - cp ../../dist_archive/RNode_Firmware_*_Source.zip ./share/pkg/ + cp -fv ../../dist_archive/rns-*-py3-none-any.whl ./share/pkg/ + cp -fv ../../dist_archive/rnspure-*-py3-none-any.whl ./share/pkg/ + cp -fv ../../dist_archive/lxmf-*-py3-none-any.whl ./share/pkg/ + cp -fv ../../dist_archive/lxst-*-py3-none-any.whl ./share/pkg/ + cp -fv ../../dist_archive/nomadnet-*-py3-none-any.whl ./share/pkg/ + cp -fv ../../dist_archive/rnsh-*-py3-none-any.whl ./share/pkg/ + cp -fv ../../dist_archive/RNode_Firmware-*.zip ./share/pkg/ zip --junk-paths ./share/pkg/example_plugins.zip ../docs/example_plugins/*.py - cp -r ../../dist_archive/reticulum.network ./share/mirrors/ - cp -r ../../dist_archive/unsigned.io ./share/mirrors/ - cp ../../dist_archive/Reticulum\ Manual.pdf ./share/mirrors/Reticulum_Manual.pdf - cp ../../dist_archive/Reticulum\ Manual.epub ./share/mirrors/Reticulum_Manual.epub - cp -r ../../rnode-flasher ./share/mirrors/ + cp -rfv ../../dist_archive/reticulum.network ./share/mirrors/ + cp -rfv ../../dist_archive/unsigned.io ./share/mirrors/ + cp -fv ../../dist_archive/Reticulum\ Manual.pdf ./share/mirrors/Reticulum_Manual.pdf + cp -fv ../../dist_archive/Reticulum\ Manual.epub ./share/mirrors/Reticulum_Manual.epub + cp -rfv ../../rnode-flasher ./share/mirrors/ -(rm ./share/mirrors/rnode-flasher/.git -rf) release: @@ -79,25 +145,37 @@ release: postbuild: $(MAKE) cleanrns -apk: prepare prebake pacthfiles fetchshare release postbuild +apk: clean prepare prebake patchfiles createshare fetchshare release postbuild -devapk: prepare prebake pacthfiles fetchshare debug postbuild +devapk: clean prepare prebake patchfiles debug postbuild version: @(echo $$(python ./gv.py)) install: - adb install bin/sideband-$$(python ./gv.py)-arm64-v8a_armeabi-v7a-release.apk + adb install -r bin/sideband-$$(python ./gv.py)-arm64-v8a_armeabi-v7a_x86_x86_64-release.apk + +devinstall: + adb install -r bin/sideband-$$(python ./gv.py)-arm64-v8a_armeabi-v7a_x86_x86_64-debug.apk + +install-multi: + adb devices | tail -n +2 | cut -sf 1 | xargs -iX adb -s X install -r ./bin/sideband-$$(python ./gv.py)-arm64-v8a_armeabi-v7a_x86_x86_64-release.apk + +devinstall-multi: + adb devices | tail -n +2 | cut -sf 1 | xargs -iX adb -s X install -r ./bin/sideband-$$(python ./gv.py)-arm64-v8a_armeabi-v7a_x86_x86_64-debug.apk console: (adb logcat | grep "python\|sidebandservice") getrns: - (cp -rv ../../Reticulum/RNS ./;rm ./RNS/Utilities/RNS) + (cp -rv ../../Reticulum/RNS ./) + -(rm ./RNS/Utilities/RNS) # created by the create_symlinks target in Reticulum -(rm ./RNS/__pycache__ -r) - (cp -rv ../../LXMF/LXMF ./;rm ./LXMF/Utilities/LXMF) + (cp -rv ../../LXMF/LXMF ./) + -(rm ./LXMF/Utilities/LXMF) # ditto -(rm ./LXMF/__pycache__ -r) - (cp -rv ../../LXST/LXST ./;rm ./LXST/Utilities/LXST) + (cp -rv ../../LXST/LXST ./) + -(rm ./LXST/Utilities/LXST) -(rm ./LXST/__pycache__ -r) -(rm ./LXST/Utilities/__pycache__ -r) diff --git a/sbapp/buildozer.spec b/sbapp/buildozer.spec index b6b8594..9ab9926 100644 --- a/sbapp/buildozer.spec +++ b/sbapp/buildozer.spec @@ -12,7 +12,7 @@ version.regex = __version__ = ['"](.*)['"] version.filename = %(source.dir)s/main.py android.numeric_version = 20250220 -requirements = kivy==2.3.0,libbz2,pillow==10.2.0,qrcode==7.3.1,usb4a,usbserial4a,able_recipe,libwebp,libogg,libopus,opusfile,numpy,cryptography,ffpyplayer,codec2,pycodec2,sh,pynacl,typing-extensions,mistune>=3.0.2,beautifulsoup4 +requirements = kivy==2.3.1,libbz2,pillow==10.3.0,freetype-py==2.2.0,qrcode==7.3.1,usb4a,usbserial4a,able_recipe,libwebp,libogg,libopus,opusfile,numpy,cryptography,ffpyplayer,codec2,pycodec2,sh,pynacl,typing-extensions,mistune>=3.0.2,beautifulsoup4,filetype android.gradle_dependencies = com.android.support:support-compat:28.0.0 #android.enable_androidx = True @@ -37,11 +37,13 @@ android.ndk = 25b android.skip_update = False android.accept_sdk_license = True android.release_artifact = apk -android.archs = arm64-v8a,armeabi-v7a +android.archs = arm64-v8a,armeabi-v7a,x86,x86_64 #android.logcat_filters = *:S python:D services = sidebandservice:services/sidebandservice.py:foreground android.whitelist = lib-dynload/termios.so +android.add_src = src/main/java +android.res_xml = src/main/res/xml/device_filter.xml,src/main/res/xml/file_paths.xml android.manifest.intent_filters = patches/intent-filter.xml # android.add_libs_armeabi_v7a = ../libs/armeabi/*.so* diff --git a/sbapp/main.py b/sbapp/main.py index c157d92..1b834a3 100644 --- a/sbapp/main.py +++ b/sbapp/main.py @@ -23,11 +23,30 @@ import re import pathlib import base64 import threading +import traceback import RNS.vendor.umsgpack as msgpack WINDOW_DEFAULT_WIDTH = 494 WINDOW_DEFAULT_HEIGHT = 800 +# not all exceptions caught by sys.excepthook are sent to logcat: this is a small shim that ensures that always happens +original_excepthook = sys.excepthook + +# Custom exception handler that writes to Android log +def custom_excepthook(exc_type, exc_value, exc_traceback): + # First call the original excepthook to maintain default behavior + original_excepthook(exc_type, exc_value, exc_traceback) + + # Format the exception and traceback as a string + exception_str = ''.join(traceback.format_exception(exc_type, exc_value, exc_traceback)) + + # add extra handling to make sure any Python errors are exposed to logcat + if RNS.vendor.platformutils.is_android(): + RNS.log(f"PYTHON EXCEPTION: {exception_str}") + +# Replace the default exception handler +sys.excepthook = custom_excepthook + app_ui_scaling_path = None def apply_ui_scale(): global app_ui_scaling_path diff --git a/sbapp/src/main/java/io/unsigned/sideband/.gitkeep b/sbapp/src/main/java/io/unsigned/sideband/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/sbapp/patches/device_filter.xml b/sbapp/src/main/res/xml/device_filter.xml similarity index 100% rename from sbapp/patches/device_filter.xml rename to sbapp/src/main/res/xml/device_filter.xml diff --git a/sbapp/patches/file_paths.xml b/sbapp/src/main/res/xml/file_paths.xml similarity index 100% rename from sbapp/patches/file_paths.xml rename to sbapp/src/main/res/xml/file_paths.xml From b88f4db391d18d8c267855b874308ba61ea33784 Mon Sep 17 00:00:00 2001 From: regulad Date: Thu, 13 Mar 2025 21:58:20 -0400 Subject: [PATCH 2/2] Update patches to use directory including x86 and x86_64 --- sbapp/Makefile | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/sbapp/Makefile b/sbapp/Makefile index 49114eb..2094bae 100644 --- a/sbapp/Makefile +++ b/sbapp/Makefile @@ -19,31 +19,31 @@ patchfiles: patchsdl injectxml patchpycodec2 patchsdl: # Pach USB HID behaviour - cp patches/HIDDeviceUSB.java .buildozer/android/platform/build-arm64-v8a_armeabi-v7a/build/bootstrap_builds/sdl2/jni/SDL/android-project/app/src/main/java/org/libsdl/app/HIDDeviceUSB.java - cp patches/HIDDeviceUSB.java .buildozer/android/platform/build-arm64-v8a_armeabi-v7a/dists/sideband/src/main/java/org/libsdl/app/HIDDeviceUSB.java - cp patches/HIDDeviceUSB.java .buildozer/android/platform/build-arm64-v8a_armeabi-v7a/dists/sideband/jni/SDL/android-project/app/src/main/java/org/libsdl/app/HIDDeviceUSB.java + cp patches/HIDDeviceUSB.java .buildozer/android/platform/build-arm64-v8a_armeabi-v7a_x86_x86_64/build/bootstrap_builds/sdl2/jni/SDL/android-project/app/src/main/java/org/libsdl/app/HIDDeviceUSB.java + cp patches/HIDDeviceUSB.java .buildozer/android/platform/build-arm64-v8a_armeabi-v7a_x86_x86_64/dists/sideband/src/main/java/org/libsdl/app/HIDDeviceUSB.java + cp patches/HIDDeviceUSB.java .buildozer/android/platform/build-arm64-v8a_armeabi-v7a_x86_x86_64/dists/sideband/jni/SDL/android-project/app/src/main/java/org/libsdl/app/HIDDeviceUSB.java # Pach service loader cp patches/PythonService.java .buildozer/android/platform/python-for-android/pythonforandroid/bootstraps/common/build/src/main/java/org/kivy/android/PythonService.java - cp patches/PythonService.java .buildozer/android/platform/build-arm64-v8a_armeabi-v7a/build/bootstrap_builds/sdl2/src/main/java/org/kivy/android/PythonService.java - cp patches/PythonService.java .buildozer/android/platform/build-arm64-v8a_armeabi-v7a/dists/sideband/src/main/java/org/kivy/android/PythonService.java + cp patches/PythonService.java .buildozer/android/platform/build-arm64-v8a_armeabi-v7a_x86_x86_64/build/bootstrap_builds/sdl2/src/main/java/org/kivy/android/PythonService.java + cp patches/PythonService.java .buildozer/android/platform/build-arm64-v8a_armeabi-v7a_x86_x86_64/dists/sideband/src/main/java/org/kivy/android/PythonService.java patchpycodec2: - patchelf --replace-needed libcodec2.so.1.2 libcodec2.so .buildozer/android/platform/build-arm64-v8a_armeabi-v7a/dists/sideband/_python_bundle__arm64-v8a/_python_bundle/site-packages/pycodec2/pycodec2.so - patchelf --replace-needed libcodec2.so.1.2 libcodec2.so .buildozer/android/platform/build-arm64-v8a_armeabi-v7a/dists/sideband/_python_bundle__armeabi-v7a/_python_bundle/site-packages/pycodec2/pycodec2.so + patchelf --replace-needed libcodec2.so.1.2 libcodec2.so .buildozer/android/platform/build-arm64-v8a_armeabi-v7a_x86_x86_64/dists/sideband/_python_bundle__arm64-v8a/_python_bundle/site-packages/pycodec2/pycodec2.so + patchelf --replace-needed libcodec2.so.1.2 libcodec2.so .buildozer/android/platform/build-arm64-v8a_armeabi-v7a_x86_x86_64/dists/sideband/_python_bundle__armeabi-v7a/_python_bundle/site-packages/pycodec2/pycodec2.so injectxml: # mkdir /home/markqvist/.local/lib/python3.11/site-packages/pythonforandroid/bootstraps/sdl2/build/src/main/xml # Inject XML on arm64-v8a - mkdir -p .buildozer/android/platform/build-arm64-v8a_armeabi-v7a/dists/sideband/templates - cp patches/AndroidManifest.tmpl.xml .buildozer/android/platform/build-arm64-v8a_armeabi-v7a/dists/sideband/templates/ - cp patches/p4a_build.py .buildozer/android/platform/build-arm64-v8a_armeabi-v7a/dists/sideband/build.py + mkdir -p .buildozer/android/platform/build-arm64-v8a_armeabi-v7a_x86_x86_64/dists/sideband/templates + cp patches/AndroidManifest.tmpl.xml .buildozer/android/platform/build-arm64-v8a_armeabi-v7a_x86_x86_64/dists/sideband/templates/ + cp patches/p4a_build.py .buildozer/android/platform/build-arm64-v8a_armeabi-v7a_x86_x86_64/dists/sideband/build.py debug: buildozer android debug prebake: -ifneq (,$(wildcard .buildozer/android/platform/build-arm64-v8a_armeabi-v7a/dists/sideband/src/main/res/xml/device_filter.xml)) +ifneq (,$(wildcard .buildozer/android/platform/build-arm64-v8a_armeabi-v7a_x86_x86_64/dists/sideband/src/main/res/xml/device_filter.xml)) @echo Device filter XML exists, skipping prebake else @(echo Prebaking build before patching files...)