fix: run Android on Linux emulator VMs - #2
Closed
tiensonqin wants to merge 4 commits into
Closed
tiensonqin wants to merge 4 commits into
tiensonqin wants to merge 4 commits into
Conversation
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>
There was a problem hiding this comment.
🟡 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
OSLogimports and addingFoundationNetworkingwhere needed. - Update Android Gradle integration to support selectable JNI ABIs and avoid requiring Xcode (
xcrun) by falling back toskip 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") | ||
| } |
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.
Pulls latest
mainand unblocks building/running the Skip Android app on a Linux KVM emulator.Why
The Android native core only built
arm64-v8aby default, Gradle always invoked Skip’s Xcodexcrunprebuild, andOSLogwas 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 nameLogseqAuthenticationError$NotSignedInCase.Changes
OSLogto Apple OS’s so Linux Skipstone transpile can compileLogseqChatModel/ app loggingLogseqChatModelnetworking on Linux (FoundationNetworking, noURLSession.bytes)LOGSEQ_CHAT_ANDROID_ABI/LOGSEQ_CHAT_ANDROID_ABIS(x86_64for emulator,arm64-v8afor devices)skip plugin --no-prebuildwhenxcrunis missing, then consume existing skipstone outputgrep -F --) so--no-prebuildis matched correctlyTest plan
scripts/test-android-native-script.shLOGSEQ_CHAT_ANDROID_ABI=x86_64 scripts/build-android-native.shassembleDebugagainst an x86_64 API 34 emulatorcom.logseq.chaton the KVM AVDEmulator results
KVM AVD
logseq_chat_api34(API 34, x86_64). APK includeslib/x86_64/liblogseq_chat_core.so. Launch reachescom.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.