Skip to content

fix(android): persist prefs/logs under app filesDir - #877

Merged
H-Chris233 merged 2 commits into
Open-Less:betafrom
HKLHaoBin:fix/android-persistence-files-dir
Aug 2, 2026
Merged

fix(android): persist prefs/logs under app filesDir#877
H-Chris233 merged 2 commits into
Open-Less:betafrom
HKLHaoBin:fix/android-persistence-files-dir

Conversation

@HKLHaoBin

@HKLHaoBinHKLHaoBin commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

User description

Summary

Fixes Honor / Huawei devices where Settings → Services provider switches and preference saves fail with generic「操作失败」.

Root cause: On Android, Coordinator::new() ran before JNI Context was ready. data_dir() fell back to std::env::temp_dir() (/data/local/tmp), which the app sandbox cannot write. PreferencesStore then degraded to openless_prefs_fallback.json under /data/local/tmp, so every updatePrefs / set_settings write failed.

This PR also includes SAF content:// log export (dialog save URI) and multi-path lookup for openless.log once file logging is created under files/logs/.

Related to #865 — this PR fixes preferences / shared data_dir persistence and log export only. It does not change CredentialsVault / Android Keystore / set_credential. If「只保存 API Key」still fails after this lands, that needs a separate follow-up.

Error UX: Settings toasts remain generic「操作失败」; we intentionally do not surface Rust error strings in ProvidersSection. Use Advanced → Debug tools → Export log for details.

Changes

  • Add persistence/android_storage.rs: resolve filesDir via JNI + OnceLock; never use /data/local/tmp for persistence
  • mobile_runtime: init_android_storage_rootsinit_file_loggerCoordinator::newapp.manage inside setup()
  • Android store fallbacks use memory-only empty paths instead of temp files
  • StylePack: refuse persisting icons when asset_root is empty (memory-only fallback)
  • Coordinator degrade logs: Android-only suffix for /data/local/tmp note
  • log_dir_path(){filesDir}/logs; export via ContentResolver for SAF URIs
  • Kotlin: prefer filesDir/OpenLess for overlay prefs reads

Not included: ADB specialist debug kit, CI workflow changes, specialist-only UI, or credential storage changes.

Test plan

  • CI: Android APK succeeded on this branch
  • Honor device: adb install -r (no pm clear)
  • Settings → Services: switch ASR/LLM →「已保存」; logcat has no openless_prefs_fallback
  • run-as com.openless.app ls files/OpenLess files/logs shows preferences.json and openless.log
  • Advanced → Debug → Export error log via SAF succeeds

PR Type

Bug fix, Tests


Description

  • Fix Honor settings saves by using app filesDir.

  • Initialize storage roots before Coordinator in setup.

  • Add SAF content:// log export via ContentResolver.

  • Make Android fallback stores memory-only with empty paths.


Diagram Walkthrough

flowchart LR
A["Android setup()"] --> B["init_android_storage_roots (JNI filesDir)"]
B --> C["file logger + Coordinator"]
C --> D["persistence stores under filesDir/OpenLess"]
D --> E["settings saves work"]
F["export_error_log"] --> G["content:// URI"]
G --> H["OpenLessContentWriter.writeBytes"]
Loading

File Walkthrough

Relevant files
Enhancement
2 files
jni.rs
Add JNI write_content_uri SAF helper
+32/-0
OpenLessContentWriter.kt
Add Kotlin ContentResolver SAF writer
+37/-0
Bug fix
13 files
misc.rs
Route log export via content URI on Android
+44/-6
lib.rs
Use Android filesDir logs and improve logger init
+27/-7
mobile_runtime.rs
Initialize Coordinator after Android storage roots
+16/-6
android_storage.rs
Add Android storage roots resolver and unit tests
+198/-0
correction.rs
Use memory-only fallback path on Android
+2/-2
dictionary.rs
Use memory-only fallback path on Android
+2/-2
history.rs
Use memory-only fallback path on Android
+3/-4
mod.rs
Add empty path guard and Android data_dir
+35/-5
preferences.rs
Use memory-only fallback path on Android
+3/-2
style_pack.rs
Use memory-only fallback path on Android
+7/-4
style_pack_archive.rs
Guard empty asset root and add test
+35/-0
utils.ts
Omit dialog filters on Android for save export
+13/-4
OpenLessAndroidPreferences.kt
Prefer filesDir when reading Android preferences
+3/-1
Logging
1 files
coordinator.rs
Add Android degrade log suffix
+20/-5
Error handling
1 files
DebugToolsSection.tsx
Show export error message in debug tools
+2/-1
Dependencies
2 files
package.json
Bump plugin-dialog dependency to 2.7.2
+1/-1
Cargo.toml
Bump tauri-plugin-dialog to 2.7.2
+1/-1
Configuration changes
1 files
copy-android-scaffolding.mjs
Include OpenLessContentWriter in Kotlin scaffolding
+1/-0

Honor devices reject writes under /data/local/tmp, which caused PreferencesStore to fall back to openless_prefs_fallback.json and settings saves to fail. Initialize JNI storage roots before Coordinator and file logging, route logs to files/logs/openless.log, and export via ContentResolver for SAF content:// URIs.
@github-actions

github-actionsBot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

PR Reviewer Guide 🔍

(Review updated until commit 10b3c02)

Here are some key observations to aid the review process:

🎫 Ticket compliance analysis 🔶

865 - Partially compliant

Compliant requirements:

  • Preference and shared data persistence now use app-private filesDir (never /data/local/tmp).
  • Coordinator creation moved into Tauri setup() after Android storage roots are initialized, avoiding JNI-context-not-ready failures.
  • Log export supports SAF content:// URIs and searches multiple openless.log candidate paths.
  • Added diagnostics for store/logger init failures and Android-specific degrade notes.
  • Unit tests added for Android storage path resolution and empty asset root behavior.

Non-compliant requirements:

  • Provider credential save via Android Keystore (set_credential / CredentialsVault) is not changed, so API key saving may still fail where the Keystore is the problem.
  • Settings toasts remain generic "操作失败"; Rust error strings are not surfaced in ProvidersSection, so failure details are not shown to the user at the point of failure.
  • No WebView/UA detection or minimum-Chromium guard was added.

Requires further human verification:

  • On-device testing on Honor/Huawei (Magic UI 4.0) to confirm provider switches and preference saves persist across restarts.
  • On-device verification of API key / endpoint / model saving; if still failing, Keystore follow-up is required.
  • Manual verification of exported log contents and the DebugTools error message rendering on Android.
⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 PR contains tests
🔒 No security concerns identified
⚡ No major issues detected

@HKLHaoBinHKLHaoBin changed the title fix(android): persist prefs/logs under app filesDir (fixes #865)fix(android): persist prefs/logs under app filesDirAug 1, 2026
… logs
Reject persisting style pack icons when asset_root is empty to avoid writing under cwd; no-op cleanup on empty root. Limit Coordinator persistence degrade log suffix to Android only. Add unit test.
Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions

Copy link
Copy Markdown
Contributor

Persistent review updated to latest commit 10b3c02

@HKLHaoBinHKLHaoBin left a comment

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

旧结论已不适用于新内容。

@H-Chris233
H-Chris233 merged commit 7ad24d3 into Open-Less:betaAug 2, 2026
5 checks passed
H-Chris233 added a commit that referenced this pull request Aug 3, 2026
* feat(android): expose advanced debug tools on mobile
Show Advanced debug tools on Android with mobile-friendly layout. Backend SAF log export already landed in #877.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(settings): 调试工具保留条数说明仅移动端展示,导出成功消息可换行并显示完整路径
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Chris233 <h-chris233@outlook.com>
@HKLHaoBin
HKLHaoBin deleted the fix/android-persistence-files-dir branch August 26, 2026 15:10
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@HKLHaoBin@H-Chris233