Skip to content

fix: run Android on Linux emulator VMs - #2

Closed
tiensonqin wants to merge 4 commits into
mainfrom
logseq/android-emulator-verify-2232
Closed

tiensonqin wants to merge 4 commits into
mainfrom
logseq/android-emulator-verify-2232

Conversation

@tiensonqin

@tiensonqin tiensonqin commented Sep 3, 2026 •

Copy link
Copy Markdown
Contributor

Pulls latest main and unblocks building/running the Skip Android app on a Linux KVM emulator.

Why

The Android native core only built arm64-v8a by default, Gradle always invoked Skip’s Xcode xcrun prebuild, and OSLog was imported on every non-Android platform. Together those prevent Skipstone + Gradle from producing an x86_64 emulator APK on a Linux VM.

Startup also treated a missing Cognito session as a visible error. Skip does not honor LocalizedError, so the sign-in screen showed the Kotlin case name LogseqAuthenticationError$NotSignedInCase.

Changes

  • Gate OSLog to Apple OS’s so Linux Skipstone transpile can compile LogseqChatModel / app logging
  • Compile LogseqChatModel networking on Linux (FoundationNetworking, no URLSession.bytes)
  • Let Gradle build one or more JNI ABIs via LOGSEQ_CHAT_ANDROID_ABI / LOGSEQ_CHAT_ANDROID_ABIS (x86_64 for emulator, arm64-v8a for devices)
  • Fall back to skip plugin --no-prebuild when xcrun is missing, then consume existing skipstone output
  • Bump the Android Gradle wrapper to 9.4.1 for Skip 1.9.8 / AGP 9.2
  • Do not surface expected unsigned-in state as an error on the sign-in screen
  • Tighten the Android native wiring script test (grep -F --) so --no-prebuild is matched correctly

Test plan

  • scripts/test-android-native-script.sh
  • LOGSEQ_CHAT_ANDROID_ABI=x86_64 scripts/build-android-native.sh
  • Skipstone transpile + Gradle assembleDebug against an x86_64 API 34 emulator
  • Install and launch com.logseq.chat on the KVM AVD
  • Confirm the sign-in screen does not show a Kotlin case name

Emulator results

KVM AVD logseq_chat_api34 (API 34, x86_64). APK includes lib/x86_64/liblogseq_chat_core.so. Launch reaches com.logseq.chat/logseq.chat.MainActivity. Sign-in no longer shows the Kotlin case name; tapping Sign in starts the hosted browser flow (Chrome first-run on a fresh AVD).

Sign-in screen before fix, showing Kotlin error name
Sign-in screen after fix, no Kotlin error
android_emulator_signin.mp4

To show artifacts inline, enable in settings.

Open in Web Open in Cursor 

cursoragent and others added 4 commits September 3, 2026 03:23
Gate OSLog to Apple platforms so Skipstone can transpile on Linux, teach Gradle to build x86_64 JNI for the emulator ABI, and skip Xcode prebuild when xcrun is missing.

Co-authored-by: Tienson Qin <tiensonqin@gmail.com>
Import FoundationNetworking where needed and keep Apple-only URLSession.bytes/download APIs off the Linux host compile so Skipstone can transpile for the emulator.

Co-authored-by: Tienson Qin <tiensonqin@gmail.com>
AGP 9.2 from Skip 1.9.8 requires Gradle 9.4.1, so the wrapper matches the plugin version used to assemble the emulator APK.

Co-authored-by: Tienson Qin <tiensonqin@gmail.com>
Skip does not honor LocalizedError, so a missing access token was shown as
the Kotlin case name. Treat not-signed-in as a normal signed-out path and
prefer errorDescription for real failures.

Co-authored-by: Tienson Qin <tiensonqin@gmail.com>
@tiensonqin
tiensonqin marked this pull request as ready for review September 3, 2026 03:58
Copilot AI lite review requested due to automatic review settings September 3, 2026 03:58

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

There are small but user-visible and test-quality issues (error-message masking heuristic and test failure assertions) that should be tightened before merge.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR updates the Skip/Swift + Android build pipeline and a few cross-platform runtime behaviors to unblock building and running the Android app (x86_64 emulator APK) on Linux KVM emulator VMs, while also improving sign-in error presentation.

Changes:

  • Make Swift model/UI logging and networking compile on non-Apple platforms (Linux Skipstone) by gating OSLog imports and adding FoundationNetworking where needed.
  • Update Android Gradle integration to support selectable JNI ABIs and avoid requiring Xcode (xcrun) by falling back to skip plugin --no-prebuild.
  • Avoid surfacing the expected “not signed in” state as a visible error message and add a regression test.
File summaries
File Description
Tests/LogseqChatModelTests/AuthenticationTests.swift Adds a regression test to ensure missing token doesn’t show a raw error on the sign-in screen.
Sources/LogseqChatModel/ViewModel.swift Gates OSLog to Apple OSes; adds Linux networking import; disables SSE on unsupported platforms with an explicit error.
Sources/LogseqChatModel/PendingSyncTransport.swift Imports FoundationNetworking on non-Skip (Linux) builds.
Sources/LogseqChatModel/GraphSyncHTTP.swift Adds Linux-compatible snapshot download path (no URLSession.download(for:)).
Sources/LogseqChatModel/Authentication.swift Normalizes displayed authentication errors and suppresses “not signed in” as a visible message.
Sources/LogseqChat/LogseqChatApp.swift Gates OSLog usage to Apple OSes to avoid non-Apple build failures.
scripts/test-android-native-script.sh Makes grep checks robust for patterns starting with -- and adds assertions for ABI + Gradle wrapper changes.
Android/settings.gradle.kts Uses --no-prebuild when xcrun is unavailable (Linux hosts).
Android/gradle/wrapper/gradle-wrapper.properties Bumps Gradle wrapper to 9.4.1.
Android/app/build.gradle.kts Adds multi-ABI native core build task fan-out via LOGSEQ_CHAT_ANDROID_ABI(S).
Review details
  • Files reviewed: 10/10 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +128 to +132
let description = error.localizedDescription
if description.contains("$") || description.contains("Case") {
return "Something went wrong. Try signing in again."
}
return description
Comment on lines +113 to +121
do {
_ = try await auth.accessToken()
#expect(1 == 0, "Expected a missing access token to throw")
} catch is LogseqAuthenticationError {
#expect(auth.state == .signedOut)
#expect(auth.errorMessage == nil)
} catch {
#expect(1 == 0, "Expected LogseqAuthenticationError.notSignedIn")
}
@tiensonqin tiensonqin closed this Sep 21, 2026
@tiensonqin
tiensonqin deleted the logseq/android-emulator-verify-2232 branch September 21, 2026 15:26
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.

3 participants