feat(blackberry): add the Classic native QNX and Android Runtime hosts - #298
Merged
Merged
Conversation
HalfSweet
force-pushed
the
feat/blackberry-classic
branch
from
August 18, 2026 16:07
d2d0c6a to
cb1eb85
Compare
HalfSweet
force-pushed
the
feat/blackberry-classic
branch
from
August 18, 2026 16:32
cb1eb85 to
2612f3b
Compare
HalfSweet
marked this pull request as ready for review
August 18, 2026 16:36
This was referenced Aug 19, 2026
HalfSweet
force-pushed
the
feat/blackberry-classic
branch
from
August 19, 2026 09:31
accad19 to
546c815
Compare
Add the BlackBerry Classic (SQC100, BlackBerry 10.3) as a private target
family with two hosts over one shared contract:
- hosts/blackberry-qnx: BB10 Core Native host (libscreen + BPS +
EGL/GLES2), unsigned development BAR built and packaged in the
digest-pinned BBNDK image, installed with blackberry-deploy on a rooted
Classic. First device run recorded (SQC100-4, 10.3.3.3216).
- hosts/blackberry-android: Android Runtime (API 18) host, v1-signed APK
with a JNI armeabi-v7a library over the same QuickJS bridge and Rust
core, sideloaded on a stock Classic.
- tools/blackberry-classic-profile.ts registers blackberry-qnx-dev and
blackberry-android-dev (720x720 physical, 360x360 logical at density 2,
host ABI 9); apps/blackberry-classic-demo is the Hero wrapper both hosts
build; tools/native-host-build.ts holds the pinned QuickJS checkout,
guest bundle, and package-identity steps native host tools share.
- The resolved plan carries app.version next to id and title, and
HostBuildInputs exposes app {id, title, version}: the Android manifest,
strings, and BAR descriptor are templates rendered from that identity
(id with `-` -> `_`, version verbatim, versionCode/buildId from the
version), so no host holds a second copy of the package identity.
- hosts/iphone2g/pocket_spec.h is generated from contracts/spec/spec.ts
(gen-c.ts, drift-guarded by tests/contract.ts); both hosts take the
portable button mask from it.
- hosts/iphone2g/pocket_input.{c,h}: the input state machine both hosts
feed (key edges, relative-axis pulses, primary button, one tracked touch
contact whose latch fires only on down), unit-tested with the host
compiler in tests/pocket-input.test.ts.
- hosts/iphone2g/pocket_runtime.c gains pocket_runtime_tick (one guest turn
+ one core tick, the frame contract new hosts call) and
pocket_runtime_gl_reset; the N-tick form stays internal behind the legacy
iPhone/Windows CE entry points.
- Both native hosts take the logical viewport, target id, host ABI, and
raster density from the resolved plan.
- tools/blackberry-android.ts unpacks the pinned SDK archives per host OS
(Platform 18, Build-Tools 35.0.0, NDK r23c; published SHA-1s), pulls the
pinned JDK image, and picks the NDK prebuilt by platform; tools/
blackberry-qnx.ts builds offline in the container and deploys over the
device address.
- tests/blackberry-classic.test.ts, docs/BLACKBERRY_CLASSIC.md, and the
package/test registrations.
HalfSweet
force-pushed
the
feat/blackberry-classic
branch
from
August 19, 2026 09:37
546c815 to
5d292a3
Compare
doodlewind
approved these changes
Aug 20, 2026
Collaborator
|
Thanks for the feat! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds BlackBerry Classic (SQC100, BlackBerry 10.3) as a private PocketJS target family with two hosts over one shared contract.
hosts/blackberry-qnxhosts/blackberry-androidGLSurfaceViewActivity over one JNIarmeabi-v7alibrarybun blackberry-qnx setup|doctor|build|install|device-statusbun blackberry-android setup|doctor|buildShared by both hosts:
tools/blackberry-classic-profile.ts— private targetsblackberry-qnx-devandblackberry-android-dev: 720×720 physical, 360×360 logical at raster density 2, host ABI 9,input.buttons+input.touch+text.glyphs.baked.apps/blackberry-classic-demois the Hero wrapper both build.ResolvedBuildPlan.appnow carriesversionnext toid/title;HostBuildInputsexposesapp {id, title, version}(andPOCKETJS_APP_ID/TITLE/VERSIONin the host environment).packageIdentity(tools/native-host-build.ts) maps it onto the platform — id with-→_(dev.pocket_stack.blackberry_classic_demo), version verbatim,versionCode/buildId=major·1e6 + minor·1e3 + patch(0.1.1 → 1001).AndroidManifest.xml,strings.xml, andbar-descriptor.xmlare@POCKET_…@templates rendered at build time; the toolchain JSONs no longer carry package/version fields; both tools verify the produced APK badging / BAR manifest against the derived identity. Plan fixtures regenerated.hosts/iphone2g/pocket_spec.h— generated fromcontracts/spec/spec.tsbycontracts/spec/gen-c.ts(POCKET_BTN_*,POCKET_ANALOG_CENTER), byte-compared intests/contract.ts; both hosts and the bridge use it instead of hand-written masks.hosts/iphone2g/pocket_input.{c,h}— the input state machine both hosts feed: key down = one press edge (auto-repeat does not re-press) + held; relative motion pulses a d-pad direction once per threshold crossing and resets the axis (QNX: integer joystick displacement, threshold 1; Android: scroll/trackball deltas, threshold 0.35); the primary button is CIRCLE with its own held state; one tracked touch contact, latch set only on down, release reported at the next sample, second finger ignored. Unit-tested with the host compiler (tests/pocket-input.test.ts→tests/fixtures/pocket-input-test.c).pocket_runtime_tick(const PocketRuntimeInput *)inhosts/iphone2g/pocket_runtime.c— exactly one guest turn + one core tick; both hosts call it. The N-tick form is internal;pocket_runtime_frame/pocket_runtime_frame_ticksremain for the iPhone 2G/4S and Windows CE hosts. Alsopocket_runtime_gl_reset(GL resources dropped for re-initialization after context loss),POCKET_ANALOG_CENTERfrom the generated header, and one sharedrust_eh_personality.cshim.engine/symbianno-std core with the GLES2 DrawList backend (bare-platform): QNX through the checked-inarmv7-qnx-eabi.jsontarget withbuild-std, Android througharmv7-linux-androideabi.POCKET_LOGICAL_WIDTH/HEIGHT, target id, host ABI, and raster density from the resolved plan.Native QNX host:
hosts/blackberry-qnx/main.c(BPS event loop, libscreen keyboard / multi-touch /SCREEN_EVENT_JOYSTICKtrackpad, navigator system keys,data/pocketjs-qnx.statusreceipt),bar-descriptor.xmltemplate,tools/blackberry-qnx.ts(digest-pinnedaccupara/bbndkimage, offline compile + BAR packaging,blackberry-deployinstall/status),tools/blackberry-qnx/build.sh,quickjs-qnx.patch(no<stdatomic.h>, nomalloc_usable_sizeon QNX).Android Runtime host:
hosts/blackberry-android/app(PocketActivity.java+jni/runtime.c, callbacks into the shared state machine under one mutex, one guest tick peronDrawFrame),tools/blackberry-android.ts(SDK archives unpacked from Google's repository per host OS with published SHA-1s — Platform 18, Build-Tools 35.0.0, NDK r23c; JDK 17 via the digest-pinnedeclipse-temurinimage; v1-only APK signing; NDK prebuilt chosen by host platform).Registration:
package.jsonfiles/scripts,tests/npm-package.test.ts,tests/platform-contracts.test.ts,tests/test-suite.test.ts,tools/test.ts;tests/blackberry-classic.test.ts(profile resolution for both targets incl.viewport.policy/companions, negative admission, plan-derived identity mapping, demo type-check, toolchain-pin cross-checks);docs/BLACKBERRY_CLASSIC.md.Verified:
bun tools/test.ts --stage=unit(the one failure,iphone2g-toolchain.test.ts, is a local GPG fixture-commit issue),bun tests/contract.ts; on macOS (Apple silicon) —bun blackberry-qnx setup && bun blackberry-qnx build(unsigned BAR, ARM ELF againstlibbps/libscreen/libEGL/libGLESv2,Package-Name: dev.pocket_stack.blackberry_classic_demo,Package-Version: 0.1.1.1001) andbun blackberry-android setup && bun blackberry-android build(v1-signed APK,package: name='dev.pocket_stack.blackberry_classic_demo' versionCode='1001' versionName='0.1.1') both complete.Not in this PR (next PRs): moving the shared C bridge out of
hosts/iphone2g/and renamingengine/symbian; the new shared files (pocket_spec.h,pocket_input.{c,h},rust_eh_personality.c) sit next to the bridge so that move carries them in onegit mv; lifting the generic parts oftools/native-host-build.tsinto the Meizu tool.