Skip to content

Commit

Permalink
fix: API crashes with UnsatisfiedLinkError
Browse files Browse the repository at this point in the history
We needed a call to `System.loadLibrary("rsdroid")`

```
java.lang.UnsatisfiedLinkError: No implementation found for byte[][] net.ankiweb.rsdroid.NativeMethods.openBackend(byte[]) (tried Java_net_ankiweb_rsdroid_NativeMethods_openBackend and Java_net_ankiweb_rsdroid_NativeMethods_openBackend___3B) - is the library loaded, e.g. System.loadLibrary?
    at net.ankiweb.rsdroid.NativeMethods.openBackend(Native Method)
```

Fixes 14621
Fixes 14829
  • Loading branch information
david-allison authored and mikehardy committed Nov 29, 2023
1 parent a98992f commit 63b5b52
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 6 deletions.
25 changes: 19 additions & 6 deletions AnkiDroid/src/main/java/com/ichi2/anki/AnkiDroidApp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import com.ichi2.anki.preferences.sharedPrefs
import com.ichi2.anki.services.BootService
import com.ichi2.anki.services.NotificationService
import com.ichi2.anki.ui.dialogs.ActivityAgnosticDialogs
import com.ichi2.annotations.NeedsTest
import com.ichi2.compat.CompatHelper
import com.ichi2.utils.*
import kotlinx.coroutines.CoroutineScope
Expand Down Expand Up @@ -156,12 +157,7 @@ open class AnkiDroidApp : Application() {
)
CompatHelper.compat.setupNotificationChannel(applicationContext)

if (Build.FINGERPRINT != "robolectric") {
// Prevent sqlite throwing error 6410 due to the lack of /tmp on Android
Os.setenv("TMPDIR", cacheDir.path, false)
// Load backend library
System.loadLibrary("rsdroid")
}
makeBackendUsable(this)

// Configure WebView to allow file scheme pages to access cookies.
if (!acceptFileSchemeCookies()) {
Expand Down Expand Up @@ -415,6 +411,23 @@ open class AnkiDroidApp : Application() {
}
}

/** Load the libraries to allow access to Anki-Android-Backend */
@NeedsTest("Not calling this in the ContentProvider should have failed a test")
fun makeBackendUsable(context: Context) {
// Robolectric uses RustBackendLoader.ensureSetup()
if (Build.FINGERPRINT == "robolectric") return

try {
// Prevent sqlite throwing error 6410 due to the lack of /tmp on Android
Os.setenv("TMPDIR", context.cacheDir.path, false)
// Load backend library
System.loadLibrary("rsdroid")
} catch (e: Error) {
// this routine /may/ be called more than once: we'll know if/when it occurs
Timber.e("Failed to open usable backend", e)
}
}

val appResources: Resources
get() = instance.resources
val isSdCardMounted: Boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ class CardContentProvider : ContentProvider() {
override fun onCreate(): Boolean {
// Initialize content provider on startup.
Timber.d("CardContentProvider: onCreate")
AnkiDroidApp.makeBackendUsable(context!!)
return true
}

Expand Down

0 comments on commit 63b5b52

Please sign in to comment.