Refactor LCP to remove koi and joda#780
Conversation
|
|
There was a problem hiding this comment.
Pull request overview
Refactors the LCP and test-app modules to remove legacy dependencies (koi, joda-time) by replacing hashing and date/time handling with Kotlin/stdlib-based equivalents, and adds regression tests for the updated behavior.
Changes:
- Replaced koi-based passphrase hashing with
MessageDigest-backed SHA-256 utilities and updatedPassphrasesService. - Replaced joda-time usage in the test app with Kotlin/stdlib time and
DateFormat-based formatting. - Added unit tests for passphrase hashing behavior and CRL caching/expiration behavior.
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| test-app/src/main/java/org/readium/r2/testapp/utils/UserError.kt | Swaps joda DateTime formatting for Kotlin time Instant formatting in interpolated error messages. |
| test-app/src/main/java/org/readium/r2/testapp/outline/HighlightsFragment.kt | Replaces joda timestamp formatting with DateFormat + Date. |
| test-app/src/main/java/org/readium/r2/testapp/outline/BookmarksFragment.kt | Replaces joda timestamp formatting with DateFormat + Date. |
| test-app/src/main/java/org/readium/r2/testapp/drm/DrmManagementFragment.kt | Replaces joda date formatting with DateFormat-based helper for nullable Date. |
| test-app/src/main/java/org/readium/r2/testapp/data/BookRepository.kt | Replaces bookmark/book creation timestamps with Clock.System.now().toEpochMilliseconds(). |
| test-app/build.gradle.kts | Removes the joda-time dependency from the test app. |
| readium/lcp/src/main/java/org/readium/r2/lcp/util/Digest.kt | Adds SHA-256 helpers for ByteArray and String (hex output) using MessageDigest. |
| readium/lcp/src/main/java/org/readium/r2/lcp/service/PassphrasesService.kt | Updates passphrase hashing to use the new sha256Hex() helper. |
| readium/lcp/src/main/java/org/readium/r2/lcp/service/CRLService.kt | Replaces joda-based CRL expiration tracking with Kotlin time + kotlinx-datetime helpers and SharedPreferences ktx edit. |
| readium/lcp/src/test/java/org/readium/r2/lcp/service/PassphrasesServiceTest.kt | Adds tests asserting passphrases are hashed (or not) as expected before persistence. |
| readium/lcp/src/test/java/org/readium/r2/lcp/service/CRLServiceTest.kt | Adds Robolectric tests for CRL retrieval behavior (local vs network) based on expiration. |
| readium/lcp/build.gradle.kts | Removes koi and joda-time from LCP module; adds kotlinx-datetime. |
| gradle/libs.versions.toml | Removes joda-time version and library entries. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| /** | ||
| * Returns the SHA-256 sum of the string encoded as a lowercase hex string. | ||
| */ | ||
| internal fun String.sha256Hex(): String = | ||
| toByteArray().sha256().toHexString() |
There was a problem hiding this comment.
sha256Hex() relies on ByteArray.toHexString(), which is treated as an experimental stdlib API elsewhere in the codebase (e.g. LicensesService.checkSha256() opts in to ExperimentalStdlibApi). Without an @OptIn(ExperimentalStdlibApi::class) here (or an alternative stable hex encoder), this will introduce compiler warnings or fail builds configured to treat warnings as errors.
| /** | |
| * Returns the SHA-256 sum of the string encoded as a lowercase hex string. | |
| */ | |
| internal fun String.sha256Hex(): String = | |
| toByteArray().sha256().toHexString() | |
| private fun ByteArray.toLowercaseHexString(): String { | |
| val hexChars = "0123456789abcdef".toCharArray() | |
| val result = CharArray(size * 2) | |
| forEachIndexed { index, byte -> | |
| val value = byte.toInt() and 0xFF | |
| result[index * 2] = hexChars[value ushr 4] | |
| result[index * 2 + 1] = hexChars[value and 0x0F] | |
| } | |
| return String(result) | |
| } | |
| /** | |
| * Returns the SHA-256 sum of the string encoded as a lowercase hex string. | |
| */ | |
| internal fun String.sha256Hex(): String = | |
| toByteArray().sha256().toLowercaseHexString() |
There was a problem hiding this comment.
As of Kotlin 2.2, ByteArray.toHexString is stable and does not need an annotation. The one in LicensesService is leftover.
The format of HexFormat.Default in public fun ByteArray.toHexString(format: HexFormat = HexFormat.Default) has upperCase = false. I can update ours to be explicit too: toByteArray().sha256().toHexString(format = HexFormat.Default).
|
I addressed Copilot's comments as well as those discussed elsewhere. For now, I'll leave CRLServiceTest to use mockk, as NetworkService will be going away in favor of Shared's |
Relates to #779.