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
|
# 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"><strong>A privacy-focused Android browser with powerful browsing separation, local-first tools, and deep customization.</strong></p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
|
|||||||
@@ -73,6 +73,19 @@ android {
|
|||||||
versionNameSuffix "-alpha"
|
versionNameSuffix "-alpha"
|
||||||
manifestPlaceholders = [appName: "WebLibre Alpha (Legacy)", enableImpeller: "false"]
|
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 {
|
sourceSets {
|
||||||
|
|||||||
@@ -106,3 +106,10 @@ melos:
|
|||||||
set -e
|
set -e
|
||||||
cd apps/weblibre
|
cd apps/weblibre
|
||||||
flutter build apk --release --flavor alphaLegacy --target-platform android-arm,android-arm64 --split-per-abi --no-tree-shake-icons
|
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