Skip to content

fix(settings): resolve transient URI permission revocation and file picker crash on custom ROMs#42

Merged
sohilsayed merged 2 commits into
sohilsayed:mainfrom
Jolimunium:main
Jul 4, 2026
Merged

fix(settings): resolve transient URI permission revocation and file picker crash on custom ROMs#42
sohilsayed merged 2 commits into
sohilsayed:mainfrom
Jolimunium:main

Conversation

@Jolimunium

@Jolimunium Jolimunium commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Overview

This PR fixes a bug where users could not import Yomichan/Yomitan dictionaries on certain devices (specifically custom Android ROMs like Xiaomi HyperOS/MIUI devices) due to transient URI permission revocations and system-level SecurityException crashes.

Problem Description

  1. Transient URI Permission Revocation: When using rememberLauncherForActivityResult with OpenMultipleDocuments, the returned URIs are granted transient read permissions. Deferring the stream opening (openInputStream) entirely inside a background thread coroutine (scope.launch) causes the callback thread to exit immediately, prompting Android to revoke the read permission before the background thread can open the file.
  2. System Provider Permission Denial: On some customized ROMs, opening streams from picked files throws SecurityException: Permission Denial: com.android.externalstorage has no access to content://media/ because of system-level provider bugs, rendering standard ContentResolver.openInputStream unusable.

Solution Implemented

  1. Synchronous Stream Open: In importLauncher, we now synchronously call openStreamWithFallback on the main thread during the activity result callback to grab and secure the file descriptor immediately before Android can revoke the transient permissions.
  2. Direct File Path Fallback: Added a path resolver (getPathFromUri) that parses com.android.externalstorage.documents and com.android.providers.downloads.documents URIs to their absolute storage paths (e.g., /storage/emulated/0/...). When the system openInputStream fails, it falls back to direct file reading using FileInputStream under the existing MANAGE_EXTERNAL_STORAGE permission.
  3. Aggregated Results UI & Clean Error Reporting: Replaced the truncated Toast error notification with a styled Compose AlertDialog. The new dialog compiles a clean, user-friendly import report for single/multiple file selections, mapping success states with checkmarks () and failure states with cross marks (). It filters out raw developer diagnostics (such as long URIs, absolute file paths, and internal variables) to prevent UI clutter. Furthermore, it dynamically displays a "Grant Permission" button if a storage permission failure is detected, allowing users to navigate directly to settings to grant the required access.
  4. Native Error Propagation: Modified the JNI bridge (hoshidicts_jni.cpp) to pass raw C++ exception messages (such as empty dictionary or JSON parsing failures) in the title field of the ImportResult on failure, allowing the UI to display the exact root cause.

Screenshots

Screenshot_2026-07-02-01-55-11-479_app chimahon dev Screenshot_2026-07-02-01-55-50-809_app chimahon dev

…ostics UX

- Fix transient URI permission revocation when launching background import coroutines by opening input streams synchronously on the main thread during the activity callback.
- Implement `openStreamWithFallback` and `getPathFromUri` to resolve local documents and media provider URIs directly to file system paths, allowing direct file reading via `FileInputStream` under the `MANAGE_EXTERNAL_STORAGE` permission (bypasses buggy system-level `ExternalStorageProvider` SecurityExceptions on custom Android ROMs).
- Upgrade import UI to collect success/failure status by file name and display an aggregated `AlertDialog` report containing formatted checkmark/cross lists.
- Update JNI bridge (`hoshidicts_jni.cpp`) to pass the raw C++ error message in the `title` field on JNI import failure so Kotlin can display detailed native errors.
@sohilsayed

Copy link
Copy Markdown
Owner

lgtm

@sohilsayed sohilsayed merged commit 7031cdb into sohilsayed:main Jul 4, 2026
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.

2 participants