TeamAmaze / TeamAmaze/AmazeFileManager

Potential main-thread database cursor access in Amaze editable file initialization flow

Open
#4,647 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Issue-Maybe-Bug
Dominant language
Kotlin
Stars
6.4k
Forks
1.7k
Avg merge
3d 9h
Merged PRs (30d)
1

Description

Hi Amaze File Manager Team,

I’m a PhD student researching Android performance issues. My research group recently ran a static analysis scan for thread-affinity and main-thread blocking bugs in real-world Android apps, and our prototype flagged a potential issue in Amaze File Manager.

This report is source-confirmed against the current GitHub source snapshot referenced below. I did not dynamically reproduce an ANR/crash, so this should be treated as a source-confirmed main-thread blocking risk rather than a reproduced runtime failure.

Checked target

  • Repository: TeamAmaze/AmazeFileManager
  • Source-level caller: com.amaze.filemanager.filesystem.EditableFileAbstraction#<init>
  • Detected API / pattern: android.database.sqlite.SQLiteDatabase#rawQuery and Cursor#moveToFirst
  • Underlying platform APIs: SQLiteDatabase#rawQuery(...), Cursor#moveToFirst()
  • Observed context: file abstraction construction reachable from UI-side file operations
  • Expected context: worker/background thread before blocking I/O, database, media preparation, bitmap compression, or slow system-service work

What I found

The current source still contains a path where com.amaze.filemanager.filesystem.EditableFileAbstraction#<init> reaches android.database.sqlite.SQLiteDatabase#rawQuery and Cursor#moveToFirst synchronously. The concern is that this operation can block on local storage, a content provider, database work, media preparation, bitmap encoding, or a system service. When this path is executed from the main thread, the UI thread may be delayed.

Verified bug trace

UI/file operation builds EditableFileAbstraction
  -> EditableFileAbstraction constructor
  -> SQLiteDatabase#rawQuery(...)
  -> Cursor#moveToFirst()
  -> main thread waits for database result

Why this matters

This path is likely user-visible because it can run while the app is opening a screen, loading UI data, importing user-selected content, resolving provider metadata, or handling a user action. Android’s ANR guidance lists slow I/O, long calculations, and synchronous Binder calls on the main thread as common ANR patterns. In this case the risky operation is synchronous database lookup while constructing file metadata; possible jank or ANR when many files are inspected.

Possible fix

Avoid synchronous database access in the constructor; preload metadata on a worker thread and pass resolved metadata to UI objects.

A typical structure is:

lifecycleScope.launch {
    val result = withContext(Dispatchers.IO) {
        // perform database/content-provider/file/media work here
    }

    // update UI here on the main thread
}

For non-UI classes, use a dedicated executor, repository-level coroutine scope, or existing background worker. The important point is to avoid performing the blocking operation synchronously on the main thread.

Reference

Android ANR guidance:

https://developer.android.com/topic/performance/vitals/anr

API-specific reference:

https://developer.android.com/topic/performance/vitals/anr

Source references

Current source snapshot:

https://github.com/TeamAmaze/AmazeFileManager/blob/840eef133906a9b85de08d41b562569b4082d318/app/src/main/java/com/amaze/filemanager/filesystem/EditableFileAbstraction.java#L68

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with app/src/main/java/com/amaze/filemanager/filesystem/EditableFileAbstraction.java at the constructor and inspect the UI-side callers that build it. Trace the rawQuery and Cursor.moveToFirst path to determine whether it can run on the main thread. Done means the database lookup is no longer performed synchronously there and the affected file-operation flow still receives the required metadata.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, java, kotlin
Domain
database, mobile
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.