Skip to content

fix(app-preferences): anr - #17968

Merged
alperozturk96 merged 2 commits into
masterfrom
fix/arbitrary-dao-provider-impl-anr
Nov 11, 2026
Merged

alperozturk96 merged 2 commits into
masterfrom
fix/arbitrary-dao-provider-impl-anr

Conversation

@alperozturk96

@alperozturk96 alperozturk96 commented Nov 5, 2026 •

Copy link
Copy Markdown
Collaborator

Issue

AppPreferencesImpl do writes on main thread.

at jdk.internal.misc.Unsafe.park (Native method)
  at java.util.concurrent.locks.LockSupport.parkNanos (LockSupport.java:276)
  at android.database.sqlite.SQLiteConnectionPool.waitForConnection (SQLiteConnectionPool.java:797)
  at android.database.sqlite.SQLiteConnectionPool.acquireConnection (SQLiteConnectionPool.java:403)
This function call is performing I/O operations, which have unpredictable timing. [Learn more](https://developer.android.com/topic/performance/anrs/find-unresponsive-thread#blocking-io)
  at android.database.sqlite.SQLiteSession.acquireConnection (SQLiteSession.java:931)
  at android.database.sqlite.SQLiteSession.beginTransactionUnchecked (SQLiteSession.java:332)
  at android.database.sqlite.SQLiteSession.beginTransaction (SQLiteSession.java:311)
  at android.database.sqlite.SQLiteDatabase.beginTransaction (SQLiteDatabase.java:841)
  at android.database.sqlite.SQLiteDatabase.beginTransaction (SQLiteDatabase.java:824)
  at android.database.sqlite.SQLiteDatabase.beginTransactionNonExclusive (SQLiteDatabase.java:701)
  at androidx.sqlite.db.framework.FrameworkSQLiteDatabase.beginTransactionNonExclusive (FrameworkSQLiteDatabase.android.kt:56)
  at androidx.sqlite.driver.SupportSQLiteStatement$TransactionSQLiteStatement.step (SupportSQLiteStatement.android.kt:261)
  at androidx.sqlite.SQLite.execSQL (SQLite.kt:56)
  at androidx.room.coroutines.PassthroughConnection.transaction (PassthroughConnectionPool.kt:117)
  at androidx.room.coroutines.PassthroughConnection.access$transaction (PassthroughConnectionPool.kt:77)
  at androidx.room.coroutines.PassthroughConnection$withTransaction$2.invokeSuspend (PassthroughConnectionPool.kt:103)
  at androidx.room.coroutines.PassthroughConnection$withTransaction$2.invoke (unavailable:8)
  at androidx.room.coroutines.PassthroughConnection$withTransaction$2.invoke (unavailable:2)
  at androidx.room.RoomDatabaseKt__RoomDatabase_androidKt.compatTransactionCoroutineExecute (RoomDatabase.android.kt:2187)
  at androidx.room.RoomDatabaseKt.compatTransactionCoroutineExecute (unavailable:1)
  at androidx.room.RoomDatabase$createConnectionManager$3.invoke (RoomDatabase.android.kt:338)
  at androidx.room.RoomDatabase$createConnectionManager$3.invoke (RoomDatabase.android.kt:338)
  at androidx.room.coroutines.PassthroughConnection.withTransaction (PassthroughConnectionPool.kt:103)
  at androidx.room.util.DBUtil__DBUtil_androidKt$performBlocking$1$1$invokeSuspend$$inlined$internalPerform$1.invokeSuspend (DBUtil.kt:59)
  at androidx.room.util.DBUtil__DBUtil_androidKt$performBlocking$1$1$invokeSuspend$$inlined$internalPerform$1.invoke (unavailable:8)
  at androidx.room.util.DBUtil__DBUtil_androidKt$performBlocking$1$1$invokeSuspend$$inlined$internalPerform$1.invoke (unavailable:4)
  at androidx.room.coroutines.PassthroughConnectionPool$useConnection$2.invokeSuspend (PassthroughConnectionPool.kt:59)
  at androidx.room.coroutines.PassthroughConnectionPool$useConnection$2.invoke (unavailable:8)
  at androidx.room.coroutines.PassthroughConnectionPool$useConnection$2.invoke (unavailable:4)
  at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatched (Undispatched.kt:66)
  at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn (Undispatched.kt:43)
  at kotlinx.coroutines.BuildersKt__Builders_commonKt.withContext (Builders.common.kt:497)
  at kotlinx.coroutines.BuildersKt.withContext (unavailable:1)
  at androidx.room.coroutines.PassthroughConnectionPool.useConnection (PassthroughConnectionPool.kt:59)
  at androidx.room.RoomConnectionManager.useConnection (RoomConnectionManager.android.kt:138)
  at androidx.room.RoomDatabase.useConnection (RoomDatabase.android.kt:619)
  at androidx.room.util.DBUtil__DBUtil_androidKt$performBlocking$1$1.invokeSuspend (DBUtil.android.kt:260)
  at androidx.room.util.DBUtil__DBUtil_androidKt$performBlocking$1$1.invoke (unavailable:8)
  at androidx.room.util.DBUtil__DBUtil_androidKt$performBlocking$1$1.invoke (unavailable:4)
  at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatched (Undispatched.kt:66)
  at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn (Undispatched.kt:43)
  at kotlinx.coroutines.BuildersKt__Builders_commonKt.withContext (Builders.common.kt:489)
  at kotlinx.coroutines.BuildersKt.withContext (unavailable:1)
  at androidx.room.util.DBUtil__DBUtil_androidKt$performBlocking$1.invokeSuspend (DBUtil.android.kt:72)
  at androidx.room.util.DBUtil__DBUtil_androidKt$performBlocking$1.invoke (unavailable:8)
  at androidx.room.util.DBUtil__DBUtil_androidKt$performBlocking$1.invoke (unavailable:4)
  at androidx.room.coroutines.RunBlockingUninterruptible_androidKt$runBlockingUninterruptible$1$1.invokeSuspend (RunBlockingUninterruptible.android.kt:52)
  at androidx.room.coroutines.RunBlockingUninterruptible_androidKt$runBlockingUninterruptible$1$1.invoke (unavailable:8)
  at androidx.room.coroutines.RunBlockingUninterruptible_androidKt$runBlockingUninterruptible$1$1.invoke (unavailable:4)
  at kotlinx.coroutines.intrinsics.UndispatchedKt.startCoroutineUndispatched (Undispatched.kt:20)
  at kotlinx.coroutines.CoroutineStart.invoke (CoroutineStart.kt:360)
  at kotlinx.coroutines.AbstractCoroutine.start (AbstractCoroutine.kt:134)
  at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch (Builders.common.kt:209)
  at kotlinx.coroutines.BuildersKt.launch (unavailable:1)
  at androidx.room.coroutines.RunBlockingUninterruptible_androidKt$runBlockingUninterruptible$1.invokeSuspend (RunBlockingUninterruptible.android.kt:51)
  at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith (ContinuationImpl.kt:34)
  at kotlinx.coroutines.DispatchedTask.run (DispatchedTask.kt:100)
  at kotlinx.coroutines.EventLoopImplBase.processNextEvent (EventLoop.common.kt:256)
  at kotlinx.coroutines.BlockingCoroutine.joinBlocking (Builders.kt:54)
  at kotlinx.coroutines.BuildersKt__BuildersKt.runBlockingImpl (Builders.kt:30)
  at kotlinx.coroutines.BuildersKt.runBlockingImpl (unavailable:1)
  at kotlinx.coroutines.BuildersKt__Builders_concurrentKt.runBlockingK (Builders.concurrent.kt:172)
  at kotlinx.coroutines.BuildersKt.runBlockingK (unavailable:1)
  at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking (Builders.kt:22)
  at kotlinx.coroutines.BuildersKt.runBlocking (unavailable:1)
  at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default (Builders.kt:20)
  at kotlinx.coroutines.BuildersKt.runBlocking$default (unavailable:1)
  at androidx.room.coroutines.RunBlockingUninterruptible_androidKt.runBlockingUninterruptible (RunBlockingUninterruptible.android.kt:45)
  at androidx.room.util.DBUtil__DBUtil_androidKt.performBlocking (DBUtil.android.kt:71)
  at androidx.room.util.DBUtil.performBlocking (unavailable:1)
  at com.nextcloud.client.database.dao.ArbitraryDataDao_Impl.insertValue (ArbitraryDataDao_Impl.kt:81)
  at com.owncloud.android.datamodel.ArbitraryDataProviderImpl.storeOrUpdateKeyValue (ArbitraryDataProviderImpl.java:79)
  at com.nextcloud.client.preferences.AppPreferencesImpl.setFolderPreference (AppPreferencesImpl.java:731)
  at com.nextcloud.client.preferences.AppPreferencesImpl.setSortOrder (AppPreferencesImpl.java:385)
  at com.owncloud.android.ui.adapter.OCFileListAdapter.setSortOrder (OCFileListAdapter.java:933)
  at com.owncloud.android.ui.fragment.FileListLayoutManager.sortFiles (FileListLayoutManager.kt:26)
  at com.owncloud.android.ui.activity.FileDisplayActivity.onSortingOrderChosen (FileDisplayActivity.kt:1547)
  at com.owncloud.android.ui.dialog.SortingOrderDialogFragment$OnSortOrderClickListener.onClick (SortingOrderDialogFragment.kt:107)
  at android.view.View.performClick (View.java:8220)
  at com.google.android.material.button.MaterialButton.performClick (MaterialButton.java:1786)
  at android.view.View.performClickInternal (View.java:8197)
  at android.view.View.-$$Nest$mperformClickInternal (unavailable)
  at android.view.View$PerformClick.run (View.java:32040)
  at android.os.Handler.handleCallback (Handler.java:1082)
  at android.os.Handler.dispatchMessageImpl (Handler.java:135)
  at android.os.Handler.dispatchMessage (Handler.java:126)
  at android.os.Looper.loopOnce (Looper.java:295)
  at android.os.Looper.loop (Looper.java:398)
  at android.app.ActivityThread.main (ActivityThread.java:9569)
  at java.lang.reflect.Method.invoke (Native method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:575)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:918)

Changes

  • Writes now in IO thread.
  • De-duplicates ArbitraryDataProvider construction.

How to test?

  • On master change file listing sorting (a to z, z to a, old to new, etc...) and file listing mode (grid, list)
  • Upgrade this branch everything must stay as same
  • Change values again, changes must be applied correctly

@github-actions

github-actions Bot commented Nov 5, 2026 •

Copy link
Copy Markdown

📱 QA build

Download app-qa-debug.apk
QR code Open the QR code for this download
Commit 4611b31
Version 17968
Available until 7 days after this build

The QA build installs alongside a released Nextcloud app, so you can keep
using your existing install while testing.

Downloading the file requires a GitHub account, so open this link on the
device you want to test on, or transfer the APK to it.

@github-actions

github-actions Bot commented Nov 5, 2026

Copy link
Copy Markdown

SpotBugs

CategoryBaseNew
Bad practice2424
Correctness4848
Dodgy code132132
Experimental11
Malicious code vulnerability11
Multithreaded correctness1313
Performance2828
Security1515
Total262262

Signed-off-by: alperozturk96 <alper_ozturk@proton.me>

# Conflicts:
#	app/src/main/java/com/owncloud/android/MainApp.java
Signed-off-by: alperozturk96 <alper_ozturk@proton.me>
@alperozturk96
alperozturk96 force-pushed the fix/arbitrary-dao-provider-impl-anr branch from 6fbb004 to 4611b31 Compare November 11, 2026 09:50
@codecov

codecov Bot commented Nov 11, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 45.00000% with 11 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...xtcloud/client/preferences/AppPreferencesImpl.java 44.44% 10 Missing ⚠️
app/src/main/java/com/owncloud/android/MainApp.kt 0.00% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@alperozturk96
alperozturk96 merged commit 10e53d4 into master Nov 11, 2026
25 of 27 checks passed
@alperozturk96
alperozturk96 deleted the fix/arbitrary-dao-provider-impl-anr branch November 11, 2026 11:39
@alperozturk96

Copy link
Copy Markdown
Collaborator Author

/backport to stable-35.1.x

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