This commit is contained in:
@@ -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
@@ -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 60–120 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.
|
||||
@@ -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">
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
Executable
+91
@@ -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."
|
||||
Reference in New Issue
Block a user