Skip to content

Resurrect HelloAndroid and HelloAndroidCamera2 - #9295

Open
alexreinking wants to merge 4 commits into
alexreinking/apps-wasmfrom
alexreinking/apps-android
Open

Resurrect HelloAndroid and HelloAndroidCamera2#9295
alexreinking wants to merge 4 commits into
alexreinking/apps-wasmfrom
alexreinking/apps-android

Conversation

@alexreinking

@alexreinking alexreinking commented Aug 6, 2026

Copy link
Copy Markdown
Member

apps/HelloAndroid had no working build: build.gradle pinned Gradle 2.2 / AGP 1.2.2 and resolved from jcenter(), which shut down in 2021; jni/Application.mk's APP_STL := gnustl_static is a hard error on current NDKs; and the src/res/AndroidManifest.xml-at-the-root layout predates Android Studio.

Replace it with the standard app/src/main/{java,res,cpp} module layout, current Gradle/AGP, and a single app/src/main/cpp/CMakeLists.txt that Gradle's externalNativeBuild drives directly. The CMakeLists.txt configures itself twice: once as a host build (to compile the Halide generator, via execute_process() before find_package() needs it) and once as this Android target build. This is admittedly a hack to work around Gradle's lack of a host-target externalNativeBuild variant. Targets arm64-v8a and x86_64, dropping 32-bit Android targets that are obsolete.

Also fixes two runtime bugs: CameraActivity never requested the CAMERA permission at runtime (added the standard ContextCompat/ActivityCompat check-then-request flow), and hello_wrapper.cpp built its halide_buffer_t structs without setting .dimensions, so every pipeline call failed a dimension-count check and the app eventually crashed.

HelloAndroidCamera2 got the same modernization and also fixed three runtime issues: CameraActivity never requested the CAMERA permission at runtime (added the standard ContextCompat/ActivityCompat check-then-request flow); Camera2BasicFragment.java's switch (view.getId()) { case R.id.toggle: } doesn't compile under AGP's non-final resource IDs default, rewritten as an if; and YuvBufferT's "packed planar" chroma case built a Buffer for just the U (or V) plane and then called crop(1, 0, height * 2) to try to extend it to cover both planes -- Buffer::crop() only ever narrows within a buffer's existing declared bounds, so this crashed (SIGABRT) the moment the camera produced a frame in this layout. Fixed by constructing packedPlanarChromaView_ directly from the pointer with the full doubled-height shape, the same way the sibling "interleaved" branch already does.

Testing

Add an android-apps job (testing-linux.yml) that builds both apps via ./gradlew assembleDebug and then smoke-tests them (apps/support/android_smoke_test.sh) against a real booted emulator, rather than only checking that they build: (1) fresh install, launch, confirm the OS shows a runtime permission prompt -- catches an app relying on its manifest declaration alone; (2) grant the permission, relaunch, and confirm the process survives with none of a set of known-bad logcat signatures (fatal crash signals, plus each app's own previously-fixed bug's exact error string). Deliberately does not require seeing a "pipeline completed" log line: whether the camera preview surface negotiates a size the pipeline actually runs on is sensitive to the emulator's screen/camera configuration, which varies by
environment.

Uses reactivecircus/android-emulator-runner with an x86_64 (not arm64-v8a) system image so the emulator gets KVM hardware acceleration on these x86_64 GitHub-hosted runners, and an emulated back/front camera so no physical camera is needed.

Fixes #8727
Fixes #8728

Breaking changes

None.

Checklist

  • Tests added or updated (not required for docs, CI config, or typo fixes)
  • Documentation updated (if public API changed)
  • Commits include AI attribution where applicable (see Code of Conduct)

Stack created with GitHub Stacks CLIGive Feedback 💬

@alexreinking alexreinking changed the title alexreinking/apps android Resurrect HelloAndroid and HelloAndroidCamera2 Aug 6, 2026
@alexreinking
alexreinking marked this pull request as ready for review August 6, 2026 20:40
@alexreinking
alexreinking force-pushed the alexreinking/apps-android branch from f71bb9e to 09fcae0 Compare August 7, 2026 07:45
@codecov

codecov Bot commented Aug 7, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (alexreinking/apps-wasm@9eb5a6f). Learn more about missing BASE report.

Additional details and impacted files
@@                    Coverage Diff                    @@
##             alexreinking/apps-wasm    #9295   +/-   ##
=========================================================
  Coverage                          ?   70.09%           
=========================================================
  Files                             ?      258           
  Lines                             ?    79160           
  Branches                          ?    18997           
=========================================================
  Hits                              ?    55489           
  Misses                            ?    17831           
  Partials                          ?     5840           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@alexreinking
alexreinking force-pushed the alexreinking/apps-android branch from 3e78ba2 to a783a13 Compare August 7, 2026 12:27

@abadams abadams left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I recommend just deleting HelloAndroid and renaming HelloAndroidCamera2 to HelloAndroid

alexreinking and others added 4 commits August 7, 2026 22:05
apps/HelloAndroid had no working build: build.gradle pinned Gradle 2.2 /
AGP 1.2.2 and resolved from jcenter(), which shut down in 2021;
jni/Application.mk's `APP_STL := gnustl_static` is a hard error on
current NDKs; and the src/res/AndroidManifest.xml-at-the-root layout
predates Android Studio.

Replace it with the standard app/src/main/{java,res,cpp} module layout,
current Gradle/AGP, and a single app/src/main/cpp/CMakeLists.txt that
Gradle's externalNativeBuild drives directly. Following the "Use
add_halide_generator" pattern in doc/HalideCMakePackage.md, the
CMakeLists.txt configures itself twice: once as a host build (to compile
the Halide generator, via execute_process() before find_package() needs
it) and once as this Android target build. No manual per-ABI
TARGETS/loop is needed: add_halide_library without TARGETS resolves the
Halide "cmake" meta-target from the ambient CMAKE_SYSTEM_NAME/
CMAKE_SYSTEM_PROCESSOR the NDK toolchain sets per ABI. Targets arm64-v8a
and x86_64.

Also fixes two runtime bugs: CameraActivity never requested the CAMERA
permission at runtime (added the standard ContextCompat/ActivityCompat
check-then-request flow), and hello_wrapper.cpp built its
halide_buffer_t structs without setting `.dimensions`, so every pipeline
call failed a dimension-count check and the app eventually crashed.

Fixes #8727

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Same build-system rot as HelloAndroid: an unbuildable Gradle 2.2/AGP
1.2.2 setup resolving from the dead jcenter(), and a src/res layout
predating Android Studio. Replace it with the standard
app/src/main/{java,res,cpp} module layout and a single
app/src/main/cpp/CMakeLists.txt driven by Gradle's externalNativeBuild,
adapted for this app's two generators (deinterleave, edge_detect) and
four JNI wrapper sources. Targets arm64-v8a and x86_64.

Also fixes three runtime issues: CameraActivity never requested the
CAMERA permission at runtime (added the standard
ContextCompat/ActivityCompat check-then-request flow);
Camera2BasicFragment.java's `switch (view.getId()) { case R.id.toggle:
}` doesn't compile under AGP's non-final resource IDs default, rewritten
as an if; and YuvBufferT's "packed planar" chroma case built a Buffer
for just the U (or V) plane and then called crop(1, 0, height * 2) to
try to extend it to cover both planes -- Buffer::crop() only ever
narrows within a buffer's existing declared bounds, so this crashed
(SIGABRT) the moment the camera produced a frame in this layout. Fixed
by constructing packedPlanarChromaView_ directly from the pointer with
the full doubled-height shape, the same way the sibling "interleaved"
branch already does.

Fixes #8728

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Add an android-apps job (testing-linux.yml) that builds both apps via
`./gradlew assembleDebug` and then smoke-tests them
(apps/support/android_smoke_test.sh) against a real booted emulator,
rather than only checking that they build: (1) fresh install, launch,
confirm the OS shows a runtime permission prompt -- catches an app
relying on its manifest declaration alone; (2) grant the permission,
relaunch, and confirm the process survives with none of a set of
known-bad logcat signatures (fatal crash signals, plus each app's own
previously-fixed bug's exact error string). Deliberately does not
require seeing a "pipeline completed" log line: whether the camera
preview surface negotiates a size the pipeline actually runs on is
sensitive to the emulator's screen/camera configuration, which varies by
environment.

Uses reactivecircus/android-emulator-runner with an x86_64 (not
arm64-v8a) system image so the emulator gets KVM hardware acceleration on
these x86_64 GitHub-hosted runners, and an emulated back/front camera so
no physical camera is needed.

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
reactivecircus/android-emulator-runner's `script` input splits on
newlines and runs each line as an independent `sh -c` command; it does
not honor `\` line-continuation, so the wrapped invocations were
running android_smoke_test.sh with zero arguments.
@alexreinking
alexreinking force-pushed the alexreinking/apps-android branch from a783a13 to 12ea58c Compare August 8, 2026 02:05
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.

Add testing for HelloAndroidCamera2 Add testing for HelloAndroid

2 participants