Skip to content

Commit 27d64b1

Browse files
mickael-menuqnga
andauthored
Fix a bunch of thread violations (readium#490)
Co-authored-by: qnga <32197639+qnga@users.noreply.github.com>
1 parent 9d18784 commit 27d64b1

File tree

15 files changed

+66
-63
lines changed

15 files changed

+66
-63
lines changed

.idea/.gitignore

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

gradle/libs.versions.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ junit = "4.13.2"
5555

5656
kotlinx-coroutines = "1.7.3"
5757
kotlinx-coroutines-test = "1.7.3"
58+
kotlinx-datetime = "0.6.0-RC.2"
5859
kotlinx-serialization-json = "1.6.2"
5960

6061
# Make sure to align with the Kotlin version.
@@ -139,6 +140,7 @@ kotlin-stdlib = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib", versio
139140

140141
kotlinx-coroutines-android = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-android", version.ref = "kotlinx-coroutines" }
141142
kotlinx-coroutines-test = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-test", version.ref = "kotlinx-coroutines-test" }
143+
kotlinx-datetime = { group = "org.jetbrains.kotlinx", name = "kotlinx-datetime", version.ref = "kotlinx-datetime" }
142144
kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlinx-serialization-json" }
143145

144146
pdfium = { group = "com.github.barteksc", name = "pdfium-android", version.ref="pdfium" }

readium/adapters/pdfium/document/src/main/java/org/readium/adapter/pdfium/document/PdfiumDocument.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import kotlinx.coroutines.Dispatchers
1717
import kotlinx.coroutines.withContext
1818
import org.readium.r2.shared.InternalReadiumApi
1919
import org.readium.r2.shared.extensions.md5
20+
import org.readium.r2.shared.extensions.tryOrLog
2021
import org.readium.r2.shared.extensions.tryOrNull
2122
import org.readium.r2.shared.util.Try
2223
import org.readium.r2.shared.util.data.ReadError
@@ -69,7 +70,11 @@ public class PdfiumDocument(
6970
core.getTableOfContents(document).map { it.toOutlineNode() }
7071
}
7172

72-
override suspend fun close() {}
73+
override suspend fun close() {
74+
tryOrLog {
75+
core.closeDocument(document)
76+
}
77+
}
7378

7479
public companion object
7580
}

readium/navigator/src/main/java/org/readium/r2/navigator/R2BasicWebView.kt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
package org.readium.r2.navigator
88

99
import android.content.Context
10-
import android.content.SharedPreferences
1110
import android.graphics.PointF
1211
import android.graphics.Rect
1312
import android.graphics.RectF
@@ -112,7 +111,6 @@ internal open class R2BasicWebView(context: Context, attrs: AttributeSet) : WebV
112111
}
113112

114113
var listener: Listener? = null
115-
internal var preferences: SharedPreferences? = null
116114

117115
var resourceUrl: AbsoluteUrl? = null
118116

readium/navigator/src/main/java/org/readium/r2/navigator/image/ImageNavigatorFragment.kt

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66

77
package org.readium.r2.navigator.image
88

9-
import android.content.Context
10-
import android.content.SharedPreferences
119
import android.graphics.PointF
1210
import android.os.Bundle
1311
import android.view.LayoutInflater
@@ -65,8 +63,6 @@ public class ImageNavigatorFragment private constructor(
6563
internal lateinit var positions: List<Locator>
6664
internal lateinit var resourcePager: R2ViewPager
6765

68-
internal lateinit var preferences: SharedPreferences
69-
7066
internal lateinit var adapter: R2PagerAdapter
7167
private lateinit var currentActivity: FragmentActivity
7268

@@ -102,10 +98,6 @@ public class ImageNavigatorFragment private constructor(
10298
_binding = ReadiumNavigatorViewpagerBinding.inflate(inflater, container, false)
10399
val view = binding.root
104100

105-
preferences = requireContext().getSharedPreferences(
106-
"org.readium.r2.settings",
107-
Context.MODE_PRIVATE
108-
)
109101
resourcePager = binding.resourcePager
110102
resourcePager.publicationType = R2ViewPager.PublicationType.CBZ
111103

readium/navigator/src/main/java/org/readium/r2/navigator/pager/R2EpubPageFragment.kt

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
package org.readium.r2.navigator.pager
1111

1212
import android.annotation.SuppressLint
13-
import android.content.Context
14-
import android.content.SharedPreferences
1513
import android.graphics.PointF
1614
import android.os.Bundle
1715
import android.util.DisplayMetrics
@@ -63,7 +61,6 @@ internal class R2EpubPageFragment : Fragment() {
6361
private set
6462

6563
private lateinit var containerView: View
66-
private lateinit var preferences: SharedPreferences
6764
private val viewModel: EpubNavigatorViewModel by viewModels(
6865
ownerProducer = { requireParentFragment() }
6966
)
@@ -137,10 +134,6 @@ internal class R2EpubPageFragment : Fragment() {
137134
): View {
138135
_binding = ReadiumNavigatorViewpagerFragmentEpubBinding.inflate(inflater, container, false)
139136
containerView = binding.root
140-
preferences = activity?.getSharedPreferences(
141-
"org.readium.r2.settings",
142-
Context.MODE_PRIVATE
143-
)!!
144137

145138
val webView = binding.webView
146139
this.webView = webView
@@ -158,7 +151,6 @@ internal class R2EpubPageFragment : Fragment() {
158151
}
159152
}
160153
}
161-
webView.preferences = preferences
162154

163155
webView.settings.javaScriptEnabled = true
164156
webView.isVerticalScrollBarEnabled = false

readium/shared/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ dependencies {
1717
implementation(libs.androidx.appcompat)
1818
implementation(libs.androidx.browser)
1919
implementation(libs.timber)
20-
implementation(libs.joda.time)
2120
implementation(libs.kotlin.reflect)
2221
implementation(libs.kotlinx.coroutines.android)
22+
implementation(libs.kotlinx.datetime)
2323
implementation(libs.kotlinx.serialization.json)
2424
implementation(libs.jsoup)
2525

readium/shared/src/main/java/org/readium/r2/shared/extensions/Date.kt

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@
99

1010
package org.readium.r2.shared.extensions
1111

12-
import java.util.*
13-
import org.joda.time.DateTime
14-
import org.joda.time.DateTimeZone
12+
import java.util.Date
13+
import kotlinx.datetime.Instant
14+
import kotlinx.datetime.format
15+
import kotlinx.datetime.format.DateTimeComponents
1516
import org.readium.r2.shared.InternalReadiumApi
1617

1718
@InternalReadiumApi
18-
public fun Date.toIso8601String(timeZone: TimeZone = TimeZone.getTimeZone("UTC")): String =
19-
DateTime(this, DateTimeZone.forTimeZone(timeZone)).toString()
19+
public fun Date.toIso8601String(): String =
20+
Instant.fromEpochMilliseconds(time).format(DateTimeComponents.Formats.ISO_DATE_TIME_OFFSET)

readium/shared/src/main/java/org/readium/r2/shared/extensions/String.kt

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,30 +12,26 @@ package org.readium.r2.shared.extensions
1212
import android.net.Uri
1313
import java.net.URL
1414
import java.security.MessageDigest
15-
import java.util.*
16-
import org.joda.time.DateTime
17-
import org.joda.time.DateTimeZone
15+
import java.util.Date
16+
import kotlinx.datetime.Instant
17+
import kotlinx.datetime.LocalDate
18+
import kotlinx.datetime.LocalDateTime
19+
import kotlinx.datetime.TimeZone
20+
import kotlinx.datetime.atStartOfDayIn
21+
import kotlinx.datetime.toInstant
1822
import org.json.JSONException
1923
import org.json.JSONObject
2024
import org.readium.r2.shared.InternalReadiumApi
2125

2226
@InternalReadiumApi
23-
public fun String.iso8601ToDate(): Date? =
24-
try {
25-
// We assume that a date without a time zone component is in UTC. To handle this properly,
26-
// we need to set the default time zone of Joda to UTC, since by default it uses the local
27-
// time zone. This ensures that apps see exactly the same dates (e.g. published) no matter
28-
// where they are located.
29-
// For the same reason, the output Date will be in UTC. Apps should convert it to the local
30-
// time zone for display purposes, or keep it as UTC for storage.
31-
val defaultTZ = DateTimeZone.getDefault()
32-
DateTimeZone.setDefault(DateTimeZone.UTC)
33-
val date = DateTime(this).toDateTime(DateTimeZone.UTC).toDate()
34-
DateTimeZone.setDefault(defaultTZ)
35-
date
36-
} catch (e: Exception) {
37-
null
38-
}
27+
public fun String.iso8601ToDate(): Date? {
28+
val instant = tryOrNull { Instant.parse(this) }
29+
?: tryOrNull { LocalDateTime.parse(this).toInstant(TimeZone.UTC) }
30+
?: tryOrNull { LocalDate.parse(this).atStartOfDayIn(TimeZone.UTC) }
31+
?: return null
32+
33+
return Date(instant.toEpochMilliseconds())
34+
}
3935

4036
/**
4137
* If this string starts with the given [prefix], returns this string.

readium/shared/src/main/java/org/readium/r2/shared/util/file/FileResource.kt

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -99,21 +99,24 @@ public class FileResource(
9999
}
100100

101101
override suspend fun length(): Try<Long, ReadError> =
102-
metadataLength?.let { Try.success(it) }
103-
?: Try.failure(
104-
ReadError.UnsupportedOperation(
105-
DebugError("Length not available for file at ${file.path}.")
102+
withContext(Dispatchers.IO) {
103+
metadataLength?.let { Try.success(it) }
104+
?: Try.failure(
105+
ReadError.UnsupportedOperation(
106+
DebugError("Length not available for file at ${file.path}.")
107+
)
106108
)
107-
)
109+
}
108110

109-
private val metadataLength: Long? =
111+
private val metadataLength: Long? by lazy {
110112
tryOrNull {
111113
if (file.isFile) {
112114
file.length()
113115
} else {
114116
null
115117
}
116118
}
119+
}
117120

118121
private inline fun <T> Try.Companion.catching(closure: () -> T): Try<T, ReadError> =
119122
try {

0 commit comments

Comments
 (0)