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

@HKLHaoBin HKLHaoBin 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-actions Bot 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

@HKLHaoBin HKLHaoBin changed the title fix(android): persist prefs/logs under app filesDir (fixes #865) fix(android): persist prefs/logs under app filesDir Aug 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

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Persistent review updated to latest commit 10b3c02

@HKLHaoBin HKLHaoBin left a comment

Copy link
Copy Markdown
Contributor Author

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:beta Aug 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>
Sign up for free to 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