Skip to content

Latest commit

 

History

History
368 lines (350 loc) · 21.7 KB

File metadata and controls

368 lines (350 loc) · 21.7 KB

Status

Last updated: 2026-10-01 (APK rebranded to New Moon — package org.palemoon.community, label "New Moon", newmoon-52.6.0 APK — installs and launches on an Android 34 emulator; XRE_mainRun reaches steady state with the Fennec XUL chrome parsed and XBL-cached; content page loads are not yet confirmed to execute — see below).

Verified

  • Historical source recovered. vendor/uxp-android/ was extracted from UXP @ 63295d0087eb58a6eb34cad324c4c53d1b220491 — confirmed to contain the full pm4a surface: mobile/android (incl. geckoview/, branding official/unofficial), widget/android, mozglue/android, gradle/, build/mobile, build/annotationProcessors, hal/android, dom/system/android, dom/gamepad/android, dom/media/platforms/android, dom/plugins/base/android, dom/xbl/builtin/android, image/decoders/icon/android, media/libyuv/util/android, media/webrtc/trunk/build/android.
  • Android triples canonicalize. build/autoconf/config.sub now maps aarch64-linux-android, arm-linux-androideabi, etc. (patch 0002).
  • NSPR cross-builds. With patches/0001-nspr-modern-android-ndk.patch applied and Android NDK r27, nsprpub configures and compiles for aarch64-linux-android (API 21). Output: libnspr4.so, libplc4.so, libplds4.so — ELF 64-bit ARM aarch64 shared objects. Reproduce: scripts/build-nspr-android.sh.
  • Full-tree ./mach configure completes for --enable-application=mobile/android --target=aarch64-linux-android with --enable-noncomm-build --enable-default-toolkit=cairo-android, NDK r27.2 (unified LLVM toolchain, API 21), Android SDK 34 (build-tools 34.0.0: aapt/aapt2/d8/aidl/zipalign/apksigner), JDK 17. Reproduce: cp mozconfig/mozconfig.android-aarch64 upstream/uxp/mozconfig, export ANDROID_HOME=<sdk> ANDROID_NDK=<sdk>/ndk/27.2.12479018, then cd upstream/uxp && ./mach configure. 917 moz.build files read, 6206 descriptors, RecursiveMake + FasterMake backends generated.
  • ./mach build completes end-to-end. All C++ (incl. libxul.so, ~19 MB), libmozglue.so (shared, with BionicGlue.cpp), and all Java jars (gecko-browser, gecko-util, geckoview, sync/etc. restored from mozilla/gecko-dev esr52, stumbler, bouncer, constants, thirdparty) compile for aarch64-android. Fennec JNI wrappers were regenerated via make -C obj-android-aarch64/mobile/android/base FennecJNIWrappers.cpp then make update-fennec-wrappers.
  • ./mach package produces a signed, installable APK: upstream/obj-android-aarch64/dist/newmoon-52.6.0.linux-android-aarch64.apk (~33 MB, 1536 entries). Verified by inspection:
    • lib/arm64-v8a/: libmozglue.so, libplugin-container.so (Fennec layout: only the custom-linker loader libs live under lib/).
    • assets/arm64-v8a/: libxul.so + all NSS/NSPR/sqlite/etc. — extracted and loaded at runtime by mozglue's custom linker.
    • classes.dex (~7.5 MB, produced by d8), assets/omni.ja (~6.4 MB, includes chrome/chrome/content/browser.xul + 38 XUL/XBL files — the full Fennec XUL frontend), 1183 res/ drawables.
    • apksigner verify --verbose --print-certs: Verifies with v1+v2+v3 schemes (CN=Android Debug cert from ~/.android/debug.keystore).
    • aapt badging: package org.palemoon.community, versionName 52.6.0, minSdk 15, targetSdk 23; application-label "New Moon".

What patch 0003 changes

  • Restores build/autoconf/android.m4 (modernized): MOZ_ANDROID_NDK, MOZ_ANDROID_CPU_ARCH, MOZ_ANDROID_SDK rewritten for unified LLVM NDK
    • modern SDK layout (d8/aapt2, emulator/ dir); legacy support-AAR checks are gated off (those deps will come from androidx/Gradle later).
  • Restores ~20 Android hunks in old-configure.in (toolchain flags, MOZ_LINKER, hash-style sysv, ANDROID_PACKAGE_NAME, gamepad, mozglue, TK_CFLAGS for android widget toolkit, MOZ_ANDROID_SDK(34) for mobile/android).
  • Restores moz.build Android frontend machinery: ANDROID_RES_DIRS, ANDROID_EXTRA_RES_DIRS, ANDROID_ASSETS_DIRS, ANDROID_EXTRA_PACKAGES, ANDROID_GENERATED_RESFILES, ANDROID_APK_NAME, ANDROID_APK_PACKAGE, ANDROID_INSTRUMENTATION_MANIFESTS in context.py/data.py/ emitter.py/recursivemake.py.
  • constants.py: Android added to OS enum (required for --enable-default-toolkit=cairo-android).
  • java.configure: javah optional (removed in JDK 10+); javac_version decoded as text.
  • icu.m4: accepts clang as the ICU assembler (unified NDK has no GNU as and no yasm target flags on aarch64).
  • config/external/moz.build: modules/xz-embedded builds when MOZ_LINKER (mozglue/linker needs it for szip APK decompression).
  • dom/base/moz.build, toolkit/modules/moz.build: Android provides its own SiteSpecificUserAgent.js / LightweightThemeConsumer.jsm — gated like 2019's MOZ_FENNEC guards.
  • mobile/android: GCM default off (no Play Services yet); MOZ_NATIVE_DEVICES unset; dead imply_options removed; dead mozilla.dtd locale entries removed.
  • New file build/autoconf/android.m4 and gradlew shim live under vendor/uxp-android/ (applied by overlay).

What patch 0004 changes (build + packaging bring-up)

  • mozglue/build/moz.build: builds libmozglue.so as a shared library on Android (was WINNT/Darwin only) and adds BionicGlue.cpp.
  • upload-files.mk: MOZ_PKG_FORMAT = APK for the android widget toolkit; upload-files-APK.mk restored to vendor — drives mozbuild.action.package_fennec_apk.
  • old-configure.in: OMNIJAR_NAME = assets/omni.ja when MOZ_BUILD_APP=mobile/android (required by the APK packager).
  • config/makefiles/java-build.mk + mobile/android/base/Makefile.in (vendor): dexing switched from dx to d8 (build-tools 34 has no dx; d8 needs an existing output dir and jar/class-file inputs).
  • config/android-common.mk (vendor): RELEASE_SIGN_ANDROID_APK now does zipalign then apksigner sign with the standard debug keystore (v1+v2+v3); the old jarsigner path produced APKs that fail apksigner verify on API 15–20.
  • mobile/android proguard cfgs (vendor): -dontwarn com.google.android.gms.** (play-services-ads 8.4.0 references WebSettings AppCache APIs removed in API 28).
  • python/mozbuild/mozpack/files.py, recursivemake.py, emitter.py, generate_browsersearch.py: py3 str/bytes fixes for the packaging path.
  • config/config.mk: -static-libstdc++ for OS_TARGET=Android — the custom linker loads packaged .so files itself, so nothing may need libc++_shared.so (same approach as the 2019 port).
  • mobile/android/installer/package-manifest.in (vendor): libhunspell.so added to assets/ — it is a NEEDED dep of libxul and its absence aborted the libxul load.
  • mozglue/linker/XZStream.cpp: ParseUncompressedSize() now sums all index records instead of reading only the first. Modern xz -T writes multi-block streams (4 blocks for libxul); only the first block's size was used, producing a 25 MB cache file for an 80 MB libxul → SIGBUS on segment mapping. Fixed file now decompresses fully (verified in logcat: XZStream decoded 80352792).
  • mozglue/linker/Elfxx.h: aarch64 R_AARCH64_ABS64/GLOB_DAT/JUMP_SLOT/ RELATIVE constants for the custom linker.
  • Remaining C++ interface fixes across dom/plugins/ipc, ipc/chromium, hal, widget, gfx, netwerk, security, toolkit, xpcom, memory/jemalloc, mozglue/linker to reconcile the 2019 Android code with current UXP.
  • API-34 javac collisions renamed in vendor: RemotePresentationService.getDeviceId() → getPresentationDeviceId() (clashes with ContextWrapper.getDeviceId():int), and BouncerService.getDataDir() → getAppDataDir() (clashes with Context.getDataDir():File).

Environment dependencies (build machine)

  • Android SDK 34 + NDK 27.2.12479018, JDK 17.
  • ProGuard is no longer in the SDK. A 6.2.0 proguard.jar must be at $ANDROID_HOME/tools/proguard/lib/proguard.jar (obtained here from the Ubuntu libproguard-java deb).
  • ~/.android/debug.keystore (alias androiddebugkey, pass android) is created automatically by the signing rule if absent.
  • Vendored AARs under $ANDROID_HOME/extras/{android,google}/m2repository/ (incl. play-services-*-8.4.0) — see scripts/ for install steps.

Runtime status (verified on emulator, Android 34 / x86_64 + ndk_translation)

AVD nocturne-emu (google_apis x86_64, abi list includes arm64-v8a via ndk_translation). No /dev/kvm → TCG software CPU, cold boot ~8 min.

  • adb install -r dist/newmoon-52.6.0.linux-android-aarch64.apk: succeeds (adb install itself is flaky on this emulator; adb push to /data/local/tmp/ + pm install -r is reliable).
  • am start -n org.palemoon.community/.App: the app launches. Java frontend verified working end-to-end: LauncherActivity → BrowserApp, profile migration, preferences, network listener, search engine manager, and the home screen UI renders (GLES/EGL).
  • mozglue's custom linker on aarch64 works: decompresses every xz'd library (incl. 80 MB libxul), resolves all relocations (ABS64/GLOB_DAT/JUMP_SLOT/RELATIVE), loads NSS/NSPR/sqlite/hunspell/etc., and begins running libxul's C++ static initializers.
  • MOZ_LINKER_ONDEMAND=0 (eager page mapping) is required on this emulator — without it the run dies earlier with SEGV_ACCERR on the main thread; the fault-handler-based lazy-page path is untested on real arm64 hardware.
  • The app reaches steady state. XRE_mainRun completes end to end: omni.ja component/xpt registration, directory-provider startup, chrome manifest registration, profile prefs, profile-after-change, chrome window creation via nsWindowWatcher::OpenWindow (browser.xul loads — nsWebShellWindow::JustCreateWebShell → docshell → CreateAboutBlankContentViewer → XPConnect globals wrapped → loadURI rv=0), hidden window, final-ui-startup, appstartup-run, and the Gecko event loop then idles in epoll_wait. Verified on cold (pm clear) and warm launches; the warm launch renders Top Sites with real bookmark data (profile DB works). Screenshot-verified, not just logcat.
  • The earlier SIGSEGV@0 in libxul static-init was actually two packaging/config bugs, both now fixed (see below); the stagefright frame turned out to be a red herring (first .init_array entry to trip the pref service, not the culprit).
  • Remaining emulator issue (environmental): system_server and the app both ANR under ndk_translation load during startup ("Timed out while trying to bind" / broadcast timeouts on MY_PACKAGE_REPLACED). The ANR dialogs block input dispatch, so interactive verification (typing a URL, clicking links) is not possible on this emulator. system_server keeps making progress (not deadlocked); a real arm64 device is unlikely to exhibit this.
  • XUL pipeline verified on-device. The profile's startupCache contains xulcache/…/chrome/content/browser.xul (the chrome XUL was parsed and its prototype cached) plus xblcache/ entries for toolkit bindings — XUL parsing, the prototype cache, and the XBL binding engine all execute correctly.
  • Real web page loads verified end-to-end (2026-10-01). After fixing the libxul logging blackout (see root causes), the earlier "navigations never start" conclusion proved to be an observability artifact, not a functional failure. Verified via am start -a VIEW:
    • http://neverssl.com — full navigation lifecycle: START → TITLE → LOCATION_CHANGE → SECURITY_CHANGE → PAGE_SHOW → STOP → FAVICON → THUMBNAIL, including a followed HTTP redirect chain (neverssl.com → fineolduniquesong.neverssl.com/online).
    • https://example.com — same full cycle including SECURITY_CHANGE (NSS/PSM path works; TLS handshake + cert verification complete, ~48 s wall-clock under ndk_translation). The first-ever HTTPS attempt appeared to stall at START for several minutes — first-use NSS/certdb initialization under translation is extremely slow; a subsequent run completed normally.
  • All observed chrome JS errors resolved. After browser.xul loads, the GeckoConsole bridge showed a cascade of JS errors — every one root-caused and fixed (see root causes): unpreprocessed browser.js, missing Services.androidBridge/Services.telemetry getters, UITelemetry module absent, parental-controls NOT_AVAILABLE, missing tracking-protection prefs, stale storage-mozStorage.js contract+manifest entries, unpackaged blocklist.manifest, and unguarded imports of modules (ExtensionContent, PresentationDeviceInfoManager, SimpleServiceDiscovery) that UXP no longer ships. Remaining console noise is cosmetic: GMPInstallManager.jsm lazy import (MOZ_GMP unset), ua-update.json profile-path lookup, a dead snippets.mozilla.net endpoint, and Cu.import failure lines logged (but caught) by the guarded stubs.
  • Emulation caveat: everything above runs under ndk_translation (arm64→x86_64). lldb-server/gdbserver cannot run inside it, so native debugging is limited to logcat instrumentation.

Runtime root causes found and fixed (this bring-up)

  1. Omnijar never initialized on Android — XRE_InitCommandLine in toolkit/xre/nsAppRunner.cpp only calls mozilla::Omnijar::Init when UXP_CUSTOM_OMNI is set; esr52 processed -greomni unconditionally. Without it the gre omni.ja's chrome.manifest/components.manifest/xpt never register → every XPConnect wrap fails → the first content window cannot be created. Fixed with a MOZ_WIDGET_ANDROID conditional (patch 0004).
  2. goanna.js missing from packaged omni.ja — mobile/android/installer/package-manifest.in still listed esr52's @BINPATH@/greprefs.js; UXP renamed it to goanna.js. The packager only warns about missing manifest entries, so this was silent in the log. Missing goanna.js → pref_ReadPrefFromJar fails → Preferences::Init fails → gCacheData/gObserverTable never allocated → SIGSEGV@0 in AddBoolVarCache during nsIOService::Init. Fixed by renaming the manifest entry (in vendor/uxp-android/mobile/android/installer/package-manifest.in).
  3. All libxul logging was dead — the largest single debugging root cause of this port. libxul exports its own __android_log_print/__android_log_write/__android_log_vprint/ __android_log_assert (T, @@xul6-versioned) from the bundled stagefright liblog (media/libstagefright/system/core/liblog/ logd_write.c, FAKE_LOG_DEVICE=True in moz.build). That stub writes to /dev/log/* (removed since Android L) and falls back to stderr — which is /dev/null in the app — so every libxul-side __android_log_print, MOZ_LOG, and MOZ_ASSERT message was silently discarded while Java-side logging looked fine. This is why "nothing Gecko-side happened after runGecko" looked real. mozglue/linker/ElfLoader.cpp:30 explicitly warns about bundled stub __android_log_* implementations. Fixed by dlopening the real liblog.so inside the stub on __ANDROID__ and forwarding __android_log_buf_write/__android_log_bwrite (dlopen inside libxul routes through __wrap_dlopen → SystemElf → real dlopen). Verified: PM* instrumentation, GeckoConsole, MOZ_LOG module output (e.g. nsScreenManagerAndroid) now all reach logcat.
  4. browser.js shipped unpreprocessed — vendored jar.mn lacked the * marker, so literal #ifdef MOZ_SAFE_BROWSING lines shipped in the chrome → SyntaxError → BrowserApp undefined → startup dead after window creation. Fixed by marking browser.js preprocessed in mobile/android/chrome/jar.mn.
  5. Missing XPConnect glue / services that esr52-era chrome expects: Services.androidBridge (added to Services.jsm initTable under MOZ_WIDGET_ANDROID; nsAndroidBridge factory was already registered in widget/android/nsWidgetFactory.cpp), Services. telemetry (no-op getter — no nsITelemetry exists in UXP, but SessionStore.js calls getHistogramById), UITelemetry.jsm (new module implementing nsIUITelemetryObserver — start/stop/ addEvent; the Java→native widget::Telemetry observer path routes back into it), nsIParentalControlsService::IsAllowed returning NS_ERROR_NOT_AVAILABLE on Android (aborted BrowserApp.startup mid-way; now returns allowed under ANDROID — no Android restriction provider exists), missing privacy.trackingprotection.{enabled,pbmode.enabled} default prefs (getTrackingMode threw; added to mobile.js), and packaging drift: storage-json.js/blocklist.manifest absent from package-manifest.in (login storage + addon-manager startup failed), plus unguarded imports of modules UXP deleted (ExtensionContent — killed the entire content.js frame script, PresentationDeviceInfoManager, SimpleServiceDiscovery — replaced with a lazy stub so casting code no-ops cleanly).

Unverified / partial (honest caveats)

  • No user interaction verified. The app reaches steady state, renders, and completes real HTTP/HTTPS navigations driven by VIEW intents, but taps/typing are untested because the emulator's system_server ANR dialogs (and the recurring "built for an older version of Android" notice for targetSdk=23) block input dispatch. Driving the UI interactively needs a real arm64 device or a KVM host.
  • Compositor depth is partially verified. nsWindow, nsAppShell, the docshell/viewer path, and full tab lifecycle events (incl. THUMBNAIL captures of loaded pages) all execute; screenshots confirm the chrome UI but loaded content pages have not been screenshot-verified past the persistent system dialog overlay.
  • Tab content does not present on emulator (2026-10-02). The compositor produces real frames — tabs-tray thumbnails show rendered pages — but the live LayerView SurfaceView stays white for every tab (about:addons, about:config, example.com alike). This is the presentation-layer failure behind the reported blank about:addons; see docs/ABOUT-ADDONS-BLANK.md for the full evidence chain and the chrome.manifest instrumentation recipe.
  • Rebranded to unofficial "New Moon" identity (2026-10-01): MOZ_APP_BASENAME=NewMoon, MOZ_APP_VENDOR=Moonchild, ANDROID_PACKAGE_NAME=org.palemoon.community, display name "New Moon" — per Pale Moon's TRADEMARK notice, official "Pale Moon" branding requires Moonchild permission and this is a community port. MOZ_APP_ID now uses Pale Moon's real GUID {8de7fcbb-c55c-4fbe-bfc5-fc555c87dbc4} + UXP_APPCOMPAT_GUID=1 so Pale Moon-targeted extensions/themes install without compat hacks; MOZ_APP_UA_NAME=Palemoon. New branding dir vendor/uxp-android/mobile/android/branding/newmoon/ with generated crescent-moon launcher/favicon/about assets. Verified in the built APK: aapt badging org.palemoon.community / label "New Moon", brand.properties in omni.ja. Gotcha: after changing confvars.sh, mobile/android/base generated sources regenerate but classes.dex can stay stale — javac constant-folds AppConstants.ANDROID_PACKAGE_NAME into content:// URIs, and a stale fold produced content://org.mozilla.fennec_ubuntu.db.browser SecurityExceptions on first launch (provider permission denials, fatal GeckoBackgroundThread crash). Fix: delete objdir/mobile/android/base/{generated,*classes*,*.jar,classes.dex} and rebuild + repackage. Verified: 0 fennec_ubuntu literals in the new dex, clean launch under pid of the new package.
  • Signed with the auto-generated debug key only.
  • The UI is the Fennec-derived pm4a mobile frontend (XUL/XBL chrome: browser.xul + bindings inside omni.ja) on the full Goanna/UXP platform — not the desktop Pale Moon browser chrome. XUL does map to Android here: the XUL/XBL frontend ships, its window instantiates at runtime, and the chrome JS runs — the gap to "full Pale Moon UI" is the chrome content itself (mobile chrome vs browser/ desktop chrome), not the XUL platform.
  • Support-library AAR extra_jars that resolve to None are still filtered in the backend; androidx/Gradle frontend rework not done.
  • ANDROID_TOOLS maps to the SDK emulator/ dir (no tools/ dir in modern SDKs).
  • Two benign packaging warnings remain: "nothing matches overlay file sync_avatar_default.png/sync_promo.png" — the drawables still land in the APK.
  • Crash-path diagnostics remain in the tree (Android-gated): mozglue/linker/ElfLoader.cpp (moz_pmlog export), mfbt/Assertions.cpp (assert → logcat), memory/mozalloc abort → logcat. They log only on crashes/fatals and are worth keeping until first interactive use is stable; all temporary instrumentation has been removed.

Known missing pieces (next work)

  1. Interactive verification on a real arm64 device (or a faster emulator host): page loads via intent are verified (HTTP + HTTPS with full tab lifecycle); remaining is interactive use — typing URLs, tapping links — blocked on this emulator by ANR dialogs and the targetSdk=23 notice; watch for ndk_translation-specific behavior that won't reproduce on hardware.
  2. Pale Moon branding/product pass — done (unofficial "New Moon" branding + Pale Moon app GUID/UA); official "Pale Moon" branding needs Moonchild's permission and remains available via MOZ_OFFICIAL_BRANDING_DIRECTORY.
  3. Java frontend SDK modernization (targetSdk, Gradle 8, API 34) — replace make-driven javac/aapt + support libs with androidx + Gradle.
  4. Desktop Pale Moon browser chrome (browser/ XUL) on Android, if the mobile Fennec chrome is deemed insufficient for the "full Pale Moon UI" goal — large effort; the Fennec chrome is already XUL/XBL and fully executing.
  5. Release signing path + l10n/crashreporter overrides audit.