android(test app): MainActivity wrapper requests CAMERA at onCreate#359
Open
leaiss wants to merge 1 commit into
Open
android(test app): MainActivity wrapper requests CAMERA at onCreate#359leaiss wants to merge 1 commit into
leaiss wants to merge 1 commit into
Conversation
Thin Kotlin NativeActivity subclass whose only job is to surface the runtime CAMERA permission dialog. CNSDK's face tracker opens the front camera during xrCreateSession; without a runtime grant on Android 6+ the open silently fails and head tracking permanently uses the default centered eye position. The wrapper hands off to NativeActivity via super.onCreate immediately, so native init / xrCreateInstance run in parallel with the permission request — by the time the face tracker needs the camera, the user has already decided. Eliminates the `adb pm grant` step from the bring-up checklist's Step 0 for interactive day-1 use; pre-grant via adb remains documented for non-interactive bring-up (CI, scripted soak tests). Validated on the Android-36 emulator: GrantPermissionsActivity launched at start, full chain xrCreateInstance / xrCreateVulkanInstance / xrCreateVulkanDevice -> XR_SUCCESS unchanged, same expected emulator- Vulkan wall at VK device-extension check. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
35bc5c3 to
fa1b139
Compare
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.
Summary
Pick-up of the deferred follow-up from #350. Adds a thin Kotlin
MainActivitysubclass ofNativeActivitywhose only job is to callrequestPermissions(CAMERA)fromonCreate. Stacked on top of #350 (the manifest declarations the wrapper depends on).Why this matters
CNSDK's face tracker (
libleiaSDK-faceTrackingInApp.so, loaded into the app's process by the DisplayXR runtime broker) opens the front camera duringxrCreateSession. On Android 6+ a manifest<uses-permission>declaration is not sufficient for "dangerous" perms — the user must explicitly grant at runtime. Without the grant: cameraopen()silently fails, CNSDK never reports a face, allxrLocateViewscalls return the default centered eye position. No crash, no log error — just permanently no head tracking, which on Lume Pad is the entire point of the platform.Pre-this-PR the only workaround was
adb shell pm grant ...documented in Step 0 of the bring-up checklist (#350). That works for emulator + developer-mode device but is not a real day-1 path for hardware.How it works
super.onCreate(...)runs the fullNativeActivityglue (spawns theandroid_mainthread, sets up theANativeActivitycallbacks, attaches the window) before we kick offrequestPermissions. The native init /xrCreateInstancechain runs in parallel with the user-facing dialog. By the time CNSDK reaches itsleia_core_enable_face_trackingcall at session start, the user has already decided.Trade-offs
onRequestPermissionsResultoverride: we don't need one. The native code never asks Java about the permission; it just calls into CNSDK which calls into the system camera. If the permission flips state mid-session, CNSDK'sleia_core_enable_face_trackingeither succeeds or no-ops — both are valid states.Verification (Android-36 emulator)
Same full sentinel chain as pre-wrapper. No regression in
NativeActivityglue (android_main,APP_CMD_INIT_WINDOW,xrInitializeLoaderKHRall reached). The permission dialog launches as theGrantPermissionsActivityintent.Files
test_apps/cube_handle_vk_android/build.gradle— Kotlin Android plugin,kotlin-stdlibdep,kotlinOptions { jvmTarget = 17 }.test_apps/cube_handle_vk_android/src/main/java/.../MainActivity.kt— the wrapper (~10 lines of actual code, rest is the file's why-this-exists block comment).test_apps/cube_handle_vk_android/src/main/AndroidManifest.xml— dropandroid:hasCode="false", swapandroid.app.NativeActivity→.MainActivity.android.app.lib_namemeta-data preserved (the wrapper inherits the native lib load path).docs/getting-started/android-bringup-checklist.md— Step 0 rewritten: dialog is now the default day-1 path;adb pm grantbecomes opt-in for non-interactive bring-up.Test plan
dumpsys package ... | grep CAMERAshowinggranted=true.🤖 Generated with Claude Code