feat(android): add Pixel 10 optimized build profile
Pixel 10 APK / build (push) Failing after 7m26s

This commit is contained in:
Codex
2026-08-09 17:19:52 +02:00
parent 7b942e9bc3
commit 05e8639b67
6 changed files with 273 additions and 0 deletions
+99
View File
@@ -0,0 +1,99 @@
name: Pixel 10 APK
on:
workflow_dispatch:
push:
branches:
- pixel10
jobs:
build:
runs-on: ubuntu-latest
env:
KEY_JKS: ${{ secrets.PIXEL10_KEY_JKS }}
KEY_PATH: ${{ github.workspace }}/apps/weblibre/pixel10-release.jks
KEY_PASSWORD: ${{ secrets.PIXEL10_KEY_PASSWORD }}
KEY_ALIAS: ${{ secrets.PIXEL10_KEY_ALIAS }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: "17"
- uses: actions/setup-go@v5
with:
go-version: 1.25.x
- uses: actions/setup-node@v4
with:
node-version: "20"
- uses: subosito/flutter-action@v2
with:
channel: stable
flutter-version: 3.44.5
cache: true
- name: Install Android NDK
shell: bash
run: |
set -euo pipefail
ndk_version="$(sed -n 's/^weblibre\.ndkVersion[[:space:]]*=[[:space:]]*//p' apps/weblibre/android/gradle.properties)"
test -n "$ndk_version"
yes | "$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" --install "ndk;$ndk_version" || test "${PIPESTATUS[1]}" -eq 0
{
echo "ANDROID_NDK_HOME=$ANDROID_HOME/ndk/$ndk_version"
echo "ANDROID_NDK_ROOT=$ANDROID_HOME/ndk/$ndk_version"
echo "NDK_HOME=$ANDROID_HOME/ndk/$ndk_version"
} >> "$GITHUB_ENV"
- name: Install workspace dependencies
run: |
dart pub global activate melos 7.8.1
melos bootstrap
- name: Generate bundled assets
run: |
melos run update-assets --no-select
melos run build-components --no-select
- name: Checkout pinned native sources
shell: bash
run: |
set -euo pipefail
source native/go_mobile_runtime/pins.env
git clone https://github.com/SagerNet/sing-box.git "$RUNNER_TEMP/sing-box"
git -C "$RUNNER_TEMP/sing-box" checkout "$SING_BOX_TAG"
test "$(git -C "$RUNNER_TEMP/sing-box" rev-parse HEAD)" = "$SING_BOX_COMMIT"
git clone https://github.com/tladesignz/IPtProxy.git "$RUNNER_TEMP/IPtProxy"
git -C "$RUNNER_TEMP/IPtProxy" checkout "$IPTPROXY_TAG"
test "$(git -C "$RUNNER_TEMP/IPtProxy" rev-parse HEAD)" = "$IPTPROXY_COMMIT"
git -C "$RUNNER_TEMP/IPtProxy" submodule update --init dnstt
- name: Build native runtime
env:
SING_BOX_SOURCE: ${{ runner.temp }}/sing-box
IPTPROXY_SOURCE: ${{ runner.temp }}/IPtProxy
run: melos run build-go-runtime --no-select
- name: Create release key
shell: bash
run: |
set -euo pipefail
test -n "$KEY_JKS"
printf '%s' "$KEY_JKS" | base64 -d > "$KEY_PATH"
chmod 600 "$KEY_PATH"
- name: Build and verify Pixel 10 APK
run: melos run build-browser-pixel10 --no-select
- uses: actions/upload-artifact@v4
with:
name: mrbweblibre-pixel10
path: apps/weblibre/build/app/outputs/flutter-apk/app-pixel10-release.apk
- name: Remove release key
if: always()
run: rm -f "$KEY_PATH"
+57
View File
@@ -0,0 +1,57 @@
# MrbWebLibre for Google Pixel 10
This fork keeps WebLibre's upstream behavior and adds a focused build profile
for the Google Pixel 10 family.
## What is optimized
- **ARM64 only:** Pixel 10 uses a 64-bit Tensor G5 platform. The `pixel10`
flavor excludes unused 32-bit native libraries, reducing the APK size and
eliminating accidental 32-bit packaging.
- **Impeller enabled:** the Flutter renderer remains enabled for smooth GPU
rendering on the 60120 Hz Pixel display.
- **High refresh rate by default:** WebLibre's existing `RefreshRateMode.high`
default is retained. It can still be changed under General settings when
battery life matters more than maximum smoothness.
- **16 KB page-size gate:** every native ARM64 library in the final APK is
checked for 16 KB-compatible ELF LOAD-segment alignment. This catches an
incompatible Gecko, Flutter, Tor, or proxy binary before the APK is shipped.
- **Separate app identity:** `cc.mrblake.mrbweblibre` installs alongside the
upstream `eu.weblibre.gecko` app and cannot overwrite an upstream-signed APK.
The fork deliberately does not spoof the device model or change Gecko web
preferences only for Pixels. Those changes would increase fingerprinting and
make upstream security updates harder to merge.
## Build
Use the Flutter and Android versions pinned by the upstream CI workflow, build
the generated assets and native runtime, then run:
```bash
melos run build-browser-pixel10 --no-select
```
The command produces:
```text
apps/weblibre/build/app/outputs/flutter-apk/app-pixel10-release.apk
```
Release builds require the same signing environment variables as upstream:
`KEY_PATH`, `KEY_ALIAS`, and `KEY_PASSWORD`.
## Verify an existing APK
```bash
scripts/verify-pixel10-apk.sh path/to/app-pixel10-release.apk
```
The verifier requires `unzip` and GNU `readelf` (usually supplied by the
`binutils` package).
## Keeping the fork current
The upstream remote should point at `https://github.com/FaFre/WebLibre.git`.
Rebase the `pixel10` branch on upstream `main`, run the full test suite, build
the APK, and do a real-device smoke test before publishing an update.
+6
View File
@@ -4,6 +4,12 @@
# WebLibre
> [!NOTE]
> This repository contains **MrbWebLibre**, a Google Pixel 10-focused fork of
> WebLibre. See [the Pixel 10 build profile](PIXEL_10.md) for the ARM64-only
> flavor, 16 KB native-library verification, build instructions, and the
> differences from upstream.
<p align="center"><strong>A privacy-focused Android browser with powerful browsing separation, local-first tools, and deep customization.</strong></p>
<p align="center">
+13
View File
@@ -73,6 +73,19 @@ android {
versionNameSuffix "-alpha"
manifestPlaceholders = [appName: "WebLibre Alpha (Legacy)", enableImpeller: "false"]
}
// Pixel 10 devices are 64-bit only and ship a 120 Hz display. Keep a
// separate, side-by-side installable identity for the optimized fork,
// retain Impeller, and prevent transitive dependencies from packaging
// unused 32-bit native libraries.
pixel10 {
dimension "track"
applicationId "cc.mrblake.mrbweblibre"
versionNameSuffix "-pixel10"
manifestPlaceholders = [appName: "MrbWebLibre", enableImpeller: "true"]
ndk {
abiFilters "arm64-v8a"
}
}
}
sourceSets {
+7
View File
@@ -106,3 +106,10 @@ melos:
set -e
cd apps/weblibre
flutter build apk --release --flavor alphaLegacy --target-platform android-arm,android-arm64 --split-per-abi --no-tree-shake-icons
build-browser-pixel10:
description: Build and verify the ARM64-only MrbWebLibre release for Google Pixel 10
run: |
set -e
cd apps/weblibre
flutter build apk --release --flavor pixel10 --target-platform android-arm64 --no-tree-shake-icons
../../scripts/verify-pixel10-apk.sh build/app/outputs/flutter-apk/app-pixel10-release.apk
+91
View File
@@ -0,0 +1,91 @@
#!/usr/bin/env bash
set -euo pipefail
readonly REQUIRED_PAGE_SIZE=$((16 * 1024))
usage() {
echo "Usage: $0 path/to/app-pixel10-release.apk" >&2
}
if [[ $# -ne 1 ]]; then
usage
exit 2
fi
apk="$1"
if [[ ! -f "$apk" ]]; then
echo "APK not found: $apk" >&2
exit 1
fi
for command_name in unzip readelf; do
if ! command -v "$command_name" >/dev/null 2>&1; then
echo "Required command not found: $command_name" >&2
exit 1
fi
done
native_entries="$(unzip -Z1 "$apk" | sed -n '/^lib\/.*\.so$/p')"
if [[ -z "$native_entries" ]]; then
echo "No native libraries found in $apk" >&2
exit 1
fi
unexpected_abis=()
while IFS= read -r entry; do
if [[ "$entry" != lib/arm64-v8a/* ]]; then
unexpected_abis+=("$entry")
fi
done <<< "$native_entries"
if [[ ${#unexpected_abis[@]} -gt 0 ]]; then
echo "Pixel 10 APK contains non-ARM64 native libraries:" >&2
printf ' %s\n' "${unexpected_abis[@]}" >&2
exit 1
fi
temporary_root="${TMPDIR:-/tmp}"
if [[ ! -d "$temporary_root" || ! -w "$temporary_root" ]]; then
temporary_root="$PWD"
fi
temporary_directory="$(mktemp -d "$temporary_root/mrbweblibre-verify.XXXXXX")"
trap 'rm -rf -- "$temporary_directory"' EXIT
unzip -qq "$apk" 'lib/arm64-v8a/*.so' -d "$temporary_directory"
failures=0
checked=0
native_library_list="$temporary_directory/native-libraries.list"
find "$temporary_directory/lib/arm64-v8a" -type f -name '*.so' -print0 > "$native_library_list"
while IFS= read -r -d '' library; do
checked=$((checked + 1))
machine="$(readelf -hW "$library" | sed -n 's/^[[:space:]]*Machine:[[:space:]]*//p')"
if [[ "$machine" != "AArch64" ]]; then
echo "Architecture failure: ${library#"$temporary_directory"/} is $machine, expected AArch64" >&2
failures=$((failures + 1))
continue
fi
load_alignments="$(readelf -lW "$library" | awk '$1 == "LOAD" { print $NF }')"
if [[ -z "$load_alignments" ]]; then
echo "No ELF LOAD segments found: ${library#"$temporary_directory"/}" >&2
failures=$((failures + 1))
continue
fi
while IFS= read -r alignment; do
if (( alignment < REQUIRED_PAGE_SIZE )); then
echo "16 KB alignment failure: ${library#"$temporary_directory"/} has LOAD alignment $alignment" >&2
failures=$((failures + 1))
break
fi
done <<< "$load_alignments"
done < "$native_library_list"
if (( failures > 0 )); then
echo "Pixel 10 compatibility verification failed ($failures issue(s))." >&2
exit 1
fi
echo "Pixel 10 APK verified: ARM64-only; $checked native libraries use 16 KB-compatible ELF alignment."