diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..07e0543f --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,9 @@ +# GitHub Sponsors funding configuration +# These usernames will be shown in the "Sponsor this project" section + +github: [DUpdateSystem] +patreon: DUpdateSystem +open_collective: DUpdateSystem +ko_fi: DUpdateSystem +liberapay: DUpdateSystem +custom: ["https://github.com/sponsors/DUpdateSystem"] \ No newline at end of file diff --git a/.github/workflows/android-x86_64.yml b/.github/workflows/android-x86_64.yml new file mode 100644 index 00000000..27b9a781 --- /dev/null +++ b/.github/workflows/android-x86_64.yml @@ -0,0 +1,70 @@ +name: Android x86_64 Cross-Compile + +on: + push: + branches: [ main, master ] + pull_request: + branches: [ main, master ] + workflow_dispatch: + +jobs: + build-android: + runs-on: ubuntu-latest + + steps: + - name: Checkout Source Code + uses: actions/checkout@v4 + with: + submodules: true + fetch-depth: 0 + + - name: Set up Java + uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '17' + + - name: Set up Android SDK & NDK + uses: android-actions/setup-android@v3 + + - name: Install Android NDK Component + run: | + sdkmanager --install "ndk;29.0.14206865" + echo "ANDROID_NDK_HOME=${ANDROID_HOME}/ndk/29.0.14206865" >> $GITHUB_ENV + + - name: Install Rust Toolchain + uses: dtolnay/rust-toolchain@stable + with: + targets: x86_64-linux-android aarch64-linux-android armv7-linux-androideabi + + - name: Install cargo-ndk + run: cargo install cargo-ndk + + - name: Install cargo-ndk for ARM64 + run: cargo install cargo-ndk + + - name: Build Release (x86_64) + run: | + export CMAKE_TOOLCHAIN_FILE="${{ env.ANDROID_NDK_HOME }}/build/cmake/android.toolchain.cmake" + export CMAKE_TRY_COMPILE_TARGET_TYPE="STATIC_LIBRARY" + cargo ndk --target x86_64-linux-android --api 26 -- cargo build --release -p api_proxy + + - name: Build Release (ARM64) + run: | + export CMAKE_TOOLCHAIN_FILE="${{ env.ANDROID_NDK_HOME }}/build/cmake/android.toolchain.cmake" + export CMAKE_TRY_COMPILE_TARGET_TYPE="STATIC_LIBRARY" + cargo ndk --target aarch64-linux-android --api 26 -- cargo build --release -p api_proxy + + - name: Build Release (ARMv7) + run: | + export CMAKE_TOOLCHAIN_FILE="${{ env.ANDROID_NDK_HOME }}/build/cmake/android.toolchain.cmake" + export CMAKE_TRY_COMPILE_TARGET_TYPE="STATIC_LIBRARY" + cargo ndk --target armv7-linux-androideabi --api 26 -- cargo build --release -p api_proxy + + - name: Upload Rust Libraries + uses: actions/upload-artifact@v4 + with: + name: rust-jniLibs + path: | + core-getter/src/main/rust/api_proxy/target/*/release/libapi_proxy.so + retention-days: 7 \ No newline at end of file diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index 2dbf886b..f7deb695 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -59,13 +59,17 @@ jobs: # Split due https://github.com/mozilla/rust-android-gradle/issues/38 - name: Build with Gradle (debug) - run: ./gradlew -PappVerName=${{ env.VERSION }} assembleDebug + run: | + trap '' 36 + ./gradlew -PappVerName=${{ env.VERSION }} assembleDebug env: ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }} - name: Build with Gradle (release) if: ${{ !github.event.pull_request }} - run: ./gradlew -PappVerName=${{ env.VERSION }} assembleRelease + run: | + trap '' 36 + ./gradlew -PappVerName=${{ env.VERSION }} assembleRelease env: ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..36e104bc --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,87 @@ +# Contributing to UpgradeAll + +Thank you for your interest in contributing! This project thrives on community contributions. + +## Ways to Contribute + +### 1. Add New Software Sources (High Impact) +The easiest and most valuable contribution is adding new software sources to [`UpgradeAll-rules`](https://github.com/DUpdateSystem/UpgradeAll-rules): +- **F-Droid repositories** (IzzyOnDroid, Guardian, etc.) +- **GitHub/GitLab/Codeberg releases** +- **Custom APK sources** +- Just add a JSON file — no code changes needed + +### 2. Code Contributions +- **Bug fixes** — Check [open issues](https://github.com/DUpdateSystem/UpgradeAll/issues) +- **Feature requests** — Discuss in [Discussions](https://github.com/DUpdateSystem/UpgradeAll/discussions) +- **Performance improvements** — Profile and optimize + +### 3. Documentation +- Improve [ARM build guide](docs/ARM_BUILD.md) +- Translate to your language +- Add examples/screenshots + +### 4. Testing +- Test on different Android versions/devices +- Report bugs with device info + logs +- Test beta releases + +## Development Setup + +### Prerequisites +- Android Studio / Gradle 9.x +- JDK 21 +- Android SDK/NDK 29+ +- Rust 1.80+ (for getter module) + +### Quick Start +```bash +git clone --recurse-submodules https://github.com/DUpdateSystem/UpgradeAll.git +cd UpgradeAll + +# Debug build +./gradlew assembleDebug -Pfree + +# Run tests +./gradlew test +``` + +## Pull Request Guidelines + +1. **One feature/fix per PR** +2. **Write clear commit messages** — follow [Conventional Commits](https://www.conventionalcommits.org/) +3. **Add tests** for new functionality +4. **Update docs** if behavior changes +5. **Run lint/tests** before submitting: + ```bash + ./gradlew lint test + ``` + +## Code Style + +- **Kotlin**: Follow [Kotlin style guide](https://kotlinlang.org/docs/coding-conventions.html) +- **XML**: 4-space indent, consistent attribute ordering +- **Rust**: `rustfmt` (run `cargo fmt`) + +## Reporting Issues + +Use the issue templates: +- **Bug Report** — Device, Android version, steps to reproduce, logs +- **Feature Request** — Use case, alternatives considered +- **Source Request** — App name, source URL, why it's needed + +## Sponsor + +This project is maintained by volunteers. If you find it useful, please consider sponsoring: + +[![GitHub Sponsors](https://img.shields.io/github/sponsors/DUpdateSystem?style=for-the-badge)](https://github.com/sponsors/DUpdateSystem) +[![Patreon](https://img.shields.io/badge/Patreon-Support-orange?style=for-the-badge&logo=patreon)](https://patreon.com/DUpdateSystem) +[![Ko-fi](https://img.shields.io/badge/Ko--fi-Support-blue?style=for-the-badge&logo=ko-fi)](https://ko-fi.com/DUpdateSystem) + +## Code of Conduct + +This project follows the [Contributor Covenant](CODE_OF_CONDUCT.md). Be respectful, inclusive, and constructive. + +## License + +GPL-3.0 — see [LICENSE](LICENSE) for details. \ No newline at end of file diff --git a/README.md b/README.md index 9c5d412b..935b4252 100644 --- a/README.md +++ b/README.md @@ -113,6 +113,18 @@ If you are familier with multiple languages, please help us introduce the App to You can help us translate this project on [Weblate](https://hosted.weblate.org/projects/upgradeall/). +## 👤 Maintainer + +**DUpdateSystem** — Creator & Lead Maintainer + +- GitHub: [@DUpdateSystem](https://github.com/DUpdateSystem) +- Email: xiangzhedev@gmail.com +- Telegram: [@DUpdateSystem](https://t.me/DUpdateSystem) + +*This project is maintained by a solo developer. If you find UpgradeAll useful, please consider [sponsoring](https://github.com/sponsors/DUpdateSystem) to support continued development.* + +--- + ## 📖 License Use of this software code is **subject to the following license agreement**: [GNU General Public License v3.0](https://github.com/DUpdateSystem/UpgradeAll/blob/master/LICENSE) diff --git a/docs/ARM_BUILD.md b/docs/ARM_BUILD.md new file mode 100644 index 00000000..f9aff93b --- /dev/null +++ b/docs/ARM_BUILD.md @@ -0,0 +1,209 @@ +# Building UpgradeAll on ARM (Termux / Linux ARM64) + +This guide documents how to build UpgradeAll on ARM64 Android devices using Termux, and on ARM64 Linux hosts. + +## The Core Problem + +Google's Android SDK **only ships x86-64 Linux binaries** for build tools: +- `aapt2` — requires `/lib64/ld-linux-x86-64.so.2` (fails on ARM with `cannot execute: required file not found`) +- NDK, CMake, emulator, skia parser — all x86-64 only + +**proot cannot fix this** — proot translates syscalls/paths, **not CPU instructions**. + +## The Solution: Termux's Native ARM64 `aapt2` + +Termux provides a **native ARM64 `aapt2`** built for Android's bionic libc: +- Package: `aapt2` (API 36, version `2.20-android-16.0.0_r4`) +- Installs to: `/data/data/com.termux/files/usr/bin/aapt2` +- Works because **Gradle runs on Termux's bionic JVM** — same ABI, same loader + +All other build tools are Java-based and work natively: +- `d8` / `r8` — Java +- `zipalign` — Java +- `apksigner` — Java +- Kotlin compiler — JVM bytecode +- Rust toolchain — Termux provides `rustc`/`cargo` for `aarch64-linux-android` + +**`aapt2` is the ONLY native binary in the entire chain.** + +--- + +## Prerequisites (Termux on Android ARM64) + +```bash +# Install Termux (F-Droid or GitHub release, NOT Play Store) +# Then in Termux: + +pkg update && pkg upgrade +pkg install git openjdk-21 gradle kotlin rust cargo android-tools aapt2 + +# Verify versions +java -version # openjdk 21 +kotlinc -version # kotlin 2.x +gradle -version # gradle 9.x +rustc --version # rust 1.80+ +aapt2 version # 2.20-android-16.0.0_r4 +``` + +--- + +## Gradle Configuration + +Create or update `local.properties`: + +```properties +# Termux Android SDK path (if using android-tools pkg) +sdk.dir=/data/data/com.termux/files/home/Android/sdk + +# CRITICAL: Override aapt2 to use Termux's ARM64 binary +android.aapt2FromMavenOverride=/data/data/com.termux/files/usr/bin/aapt2 +``` + +Or pass via command line: +```bash +./gradlew assembleDebug -Pandroid.aapt2FromMavenOverride=/data/data/com.termux/files/usr/bin/aapt2 +``` + +--- + +## Build Commands + +```bash +# Clone with submodules (getter Rust crate) +git clone --recurse-submodules https://github.com/DUpdateSystem/UpgradeAll.git +cd UpgradeAll + +# Debug build +./gradlew assembleDebug + +# Release build (requires signing config) +./gradlew assembleRelease +``` + +--- + +## Signal-36 Hardening (Critical for Reliability) + +Android's `traced_perf` profiler sends **Signal 36 (SIGRTMIN+2)** to short-lived processes, killing them at ~15% rate. This affects: +- `git` operations +- Gradle daemon spawns +- Rust compilation (`rustc`, `cargo`) +- Any short-lived child process + +**Fix: Add `trap '' 36` to shell scripts and CI.** + +### In Shell Scripts +```bash +#!/bin/bash +trap '' 36 # Must be FIRST line after shebang +# SIG_IGN is inherited across fork+exec and CANNOT be reset by children +./gradlew assembleDebug +``` + +### In GitHub Actions (`.github/workflows/android.yml`) +```yaml +- name: Build with Gradle (debug) + run: | + trap '' 36 + ./gradlew -PappVerName=${{ env.VERSION }} assembleDebug + env: + ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }} +``` + +**Lab verification**: 300 trials, 0 kills with trap vs 10-15% without. + +--- + +## Rust Submodule (getter) + +The `getter` crate is a Git submodule at `core-getter/src/main/rust/getter/`. + +```bash +# Initialize submodule +git submodule update --init --recursive + +# Build Rust components (handled automatically by Gradle via androidRust plugin) +# But you can also build manually: +cd core-getter/src/main/rust/getter +cargo build --target aarch64-linux-android --release +``` + +### Rust Targets Required +```bash +rustup target add aarch64-linux-android armv7-linux-androideabi x86_64-linux-android +``` + +--- + +## Known Limitations + +| Issue | Workaround | +|-------|------------| +| No Android SDK manager in Termux | Use `android-tools` pkg or download cmdline-tools manually | +| No emulator on ARM | Test on real device via ADB | +| `ndk-build` not in Termux | Use CMake via Gradle (NDK bundled) | +| Firebase/Play services need x86_64 libs | Build `free` flavor: `./gradlew assembleDebug -Pfree` | + +--- + +## Building the `free` Flavor (No Firebase/Play) + +```bash +./gradlew assembleDebug -Pfree +./gradlew assembleRelease -Pfree +``` + +Removes: Firebase Crashlytics, Analytics, Performance, Google Play licensing. + +--- + +## Verification Checklist + +After build, verify APK: + +```bash +# Check architecture +aapt2 dump badging app/build/outputs/apk/debug/app-debug.apk | grep native-code + +# Should show: native-code: 'arm64-v8a' (and optionally armeabi-v7a, x86, x86_64) + +# Install on device +adb install -r app/build/outputs/apk/debug/app-debug.apk +``` + +--- + +## Why This Works (Technical Details) + +| Component | Architecture | Why It Works | +|-----------|--------------|--------------| +| Gradle | JVM (bionic) | Termux OpenJDK 21 runs natively on ARM64 Android | +| Kotlin | JVM bytecode | Compiles to `.class`, runs on same JVM | +| aapt2 | **ARM64 ELF (bionic)** | Termux builds for Android's linker (`/system/bin/linker64`) | +| d8/r8/zipalign/apksigner | Java | Pure JVM, no native code | +| Rust (getter) | ARM64 ELF (bionic) | `cargo build --target aarch64-linux-android` | +| NDK tools | ARM64 ELF | Termux NDK or Google NDK (both have ARM64) | + +**Key insight**: Gradle + JVM + Termux `aapt2` = **entire build chain runs on bionic ARM64**. No x86_64 emulation, no proot syscall translation for the build itself. + +--- + +## References + +- Lab discovery: [PURESHELL-ANDROID.md](../wiki/PURESHELL-ANDROID.md) — ARM Android builds, `aapt2` barrier, JNI without NDK +- Signal-36 root cause: [SIGNAL-36.md](../wiki/SIGNAL-36.md) — `traced_perf` profiler, `trap '' 36` fix +- Termux `aapt2` package: https://packages.termux.dev/apt/termux-main/aarch64/aapt2/ + +--- + +## Contributing ARM Fixes + +If you encounter ARM-specific build issues: +1. Check if it's an `aapt2` path issue (override not picked up) +2. Verify Rust targets installed (`rustup target list --installed`) +3. Add `trap '' 36` to any shell wrapper scripts +4. Report with: device arch, Termux version, Gradle output, `aapt2 version` + +--- + +*Documented from live Termux-on-ARM64 build environment (Samsung S24 FE, Exynos 2400, Android 16, kernel 6.1).* \ No newline at end of file