Skip to content

Harden Android Blockly runtime and test isolation - #9

Merged
yyods merged 4 commits into
mainfrom
agent/android-blockly-hardening
Aug 7, 2026
Merged

Harden Android Blockly runtime and test isolation#9
yyods merged 4 commits into
mainfrom
agent/android-blockly-hardening

Conversation

@yyods

@yyods yyods commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Summary

  • make the Android manifest explicit about BLE hardware, Android 12+ permissions, legacy permission caps, and the temporary Lenovo/MediaTek Impeller fallback
  • preserve the GPIO chooser's text-input identity across keyboard insets and make Blockly generation an explicit Preview/Create/Replace action
  • bind Blockly bridge traffic to a per-page host epoch, serialize native WebView setup, retry failed readiness safely, and ignore stale reload traffic
  • recognize Blockly's canonical {} serialization as an empty workspace
  • isolate Android integration tests under dev.pyble.pyble.integrationtest while compiling and auditing the normal production package separately in CI
  • freeze the behavior in the app specifications and add unit, widget, integration, asset, and CI-contract coverage

Why

Android validation exposed several independent failure modes:

  • Flutter 3.44 Impeller/Vulkan rendered a blank foreground frame on the Lenovo TB-J616X / MediaTek Android 12 device.
  • The GPIO chooser could replace its effective input client during keyboard-driven responsive rebuilds, while per-keystroke WebView generation added avoidable native-platform churn.
  • Blockly readiness and later messages were not tied to the document generation that emitted them, so reloads and delayed traffic could affect the current host.
  • Device-test installation and cleanup reused the normal launcher application ID.
  • Blockly serializes a truly empty workspace as {}, which the native empty-state check did not recognize.

Impact

The normal Android launcher remains dev.pyble.pyble. Device tests now use the disposable integration flavor, so they cannot replace or uninstall a user's PyBLE installation. GPIO edits stay native and focused until the user requests generation, and reload traffic is generation-scoped.

The production-flavor APK is still signed with Gradle's debug configuration. It is a local development artifact, not a public beta or release.

Validation

  • flutter test --exclude-tags golden: 649 passed
  • focused Android/Blockly regression set: 106 passed
  • flutter analyze: clean
  • Blockly Node asset smoke: passed
  • publication CI contract: 8/8 passed
  • no-leak, SPDX, import-boundary, locale-parity, formatting, DCO, and diff checks: passed
  • production APK built as dev.pyble.pyble; isolated test APK built as dev.pyble.pyble.integrationtest
  • production APK contains no integration-test payload and verifies with the expected Android Debug certificate
  • manual Lenovo TB-J616X / Android 12 validation connected to a classic ESP32 and ran Blink an LED on GPIO 2 to Finished with a physical blink; the same Android implementation also connected to an ESP32-S3 module and ran Blink a NeoPixel on its onboard GPIO 48 pixel

Scope

This PR is based on the current public main lineage. The local CNX correspondence draft, legacy announcement kit/assets, datasheet, and unrelated MicroPython submodule work are intentionally excluded.

yyods added 4 commits August 7, 2026 16:19
Signed-off-by: Viwat Vchirawongkwin <viwat.v@chula.ac.th>
Signed-off-by: Viwat Vchirawongkwin <viwat.v@chula.ac.th>
Signed-off-by: Viwat Vchirawongkwin <viwat.v@chula.ac.th>
Signed-off-by: Viwat Vchirawongkwin <viwat.v@chula.ac.th>
@yyods
yyods marked this pull request as ready for review August 7, 2026 09:58
@yyods
yyods merged commit 189d3f9 into main Aug 7, 2026
32 checks passed
@yyods
yyods deleted the agent/android-blockly-hardening branch August 7, 2026 09:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant