Skip to content

Commit

Permalink
Merge branch 'feature/lcp-streaming'
Browse files Browse the repository at this point in the history
  • Loading branch information
io7m committed Oct 25, 2024
2 parents 3a533ae + 31d4968 commit c37443e
Show file tree
Hide file tree
Showing 99 changed files with 2,446 additions and 2,667 deletions.
2 changes: 1 addition & 1 deletion org.thepalaceproject.android.platform
37 changes: 7 additions & 30 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,13 @@ dependencyResolutionManagement {
val credentialsPath =
propertyOptional("org.thepalaceproject.app.credentials.palace")

if (lcpDRMEnabled && !s3RepositoryEnabled) {
throw GradleException(
"If the org.thepalaceproject.lcp.enabled property is set to true, " +
"the org.thepalaceproject.s3.depend property must also be set to true."
)
}

/*
* The set of repositories used to resolve library dependencies. The order is significant!
*/
Expand Down Expand Up @@ -184,36 +191,6 @@ dependencyResolutionManagement {
}
}

/*
* Enable access to various credentials-gated elements.
*/

if (lcpDRMEnabled) {
val filePath: String =
when (val lcpProfile = property("org.thepalaceproject.lcp.profile")) {
"prod", "test" -> {
"${credentialsPath}/LCP/Android/build_lcp_${lcpProfile}.properties"
}
else -> {
throw GradleException("Unrecognized LCP profile: $lcpProfile")
}
}

val lcpProperties = Properties()
lcpProperties.load(File(filePath).inputStream())

ivy {
name = "LCP"
url = uri(lcpProperties.getProperty("org.thepalaceproject.lcp.repositoryURI"))
patternLayout {
artifact(lcpProperties.getProperty("org.thepalaceproject.lcp.repositoryLayout"))
}
metadataSources {
artifact()
}
}
}

/*
* Obsolete dependencies.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ class AccountProviderRegistry private constructor(
@Volatile
private var statusRef: AccountProviderRegistryStatus = Idle

private val descriptions = Collections.synchronizedMap(LinkedHashMap<URI, AccountProviderDescription>())
private val descriptions =
Collections.synchronizedMap(LinkedHashMap<URI, AccountProviderDescription>())
private val descriptionsReadOnly = Collections.unmodifiableMap(this.descriptions)
private val resolved = ConcurrentHashMap<URI, AccountProviderType>()
private val resolvedReadOnly = Collections.unmodifiableMap(this.resolved)
Expand Down Expand Up @@ -87,6 +88,7 @@ class AccountProviderRegistry private constructor(
this.updateDescription(newDescriptions[key]!!)
}
}

is AccountProviderSourceType.SourceResult.SourceFailed -> {
this.eventsActual.onNext(SourceFailed(source.javaClass, result.exception))
}
Expand Down Expand Up @@ -118,6 +120,7 @@ class AccountProviderRegistry private constructor(
this.updateDescription(newDescriptions[key]!!)
}
}

is AccountProviderSourceType.SourceResult.SourceFailed -> {
this.eventsActual.onNext(SourceFailed(source.javaClass, result.exception))
}
Expand Down Expand Up @@ -202,20 +205,27 @@ class AccountProviderRegistry private constructor(
this.updateDescription(result.result.toDescription())
taskRecorder.finishSuccess(result.result)
}

is TaskResult.Failure -> taskRecorder.finishFailure()
}
}
}

taskRecorder.currentStepFailed(
"No sources can resolve the given description.",
"noApplicableSource ${description.id} ${description.title}"
message = "No sources can resolve the given description.",
errorCode = "noApplicableSource ${description.id} ${description.title}",
extraMessages = listOf()
)
return taskRecorder.finishFailure()
} catch (e: Exception) {
this.logger.debug("resolution exception: ", e)
val message = e.message ?: e.javaClass.canonicalName ?: "unknown"
taskRecorder.currentStepFailedAppending(message, "unexpectedException", e)
taskRecorder.currentStepFailedAppending(
message = message,
errorCode = "unexpectedException",
exception = e,
extraMessages = listOf()
)
return taskRecorder.finishFailure()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@ class AccountProviderResolution(
taskRecorder.currentStepFailedAppending(
message = this.stringResources.resolvingUnexpectedException,
errorCode = unexpectedException(this.description),
exception = e
exception = e,
extraMessages = listOf()
)
taskRecorder.finishFailure()
}
Expand Down Expand Up @@ -201,7 +202,11 @@ class AccountProviderResolution(
}

val message = this.stringResources.resolvingAuthDocumentNoStartURI
taskRecorder.currentStepFailed(message, authDocumentUnusable(this.description))
taskRecorder.currentStepFailed(
message = message,
errorCode = authDocumentUnusable(this.description),
extraMessages = listOf()
)
onProgress.invoke(this.description.id, message)
throw IOException()
}
Expand Down Expand Up @@ -252,6 +257,7 @@ class AccountProviderResolution(
this.extractAuthenticationDescriptionSAML20(taskRecorder, authObject)
)
}

BASIC_TOKEN_TYPE -> {
authObjects.add(
extractAuthenticationDescriptionBasicToken(taskRecorder, authObject)
Expand Down Expand Up @@ -279,7 +285,11 @@ class AccountProviderResolution(
}

val message = this.stringResources.resolvingAuthDocumentNoUsableAuthenticationTypes
taskRecorder.currentStepFailed(message, authDocumentUnusable(this.description))
taskRecorder.currentStepFailed(
message = message,
errorCode = authDocumentUnusable(this.description),
extraMessages = listOf()
)
throw IOException(message)
}

Expand All @@ -295,7 +305,11 @@ class AccountProviderResolution(
val authenticateURI = authenticate?.hrefURI
if (authenticateURI == null) {
val message = this.stringResources.resolvingAuthDocumentSAML20Malformed
taskRecorder.currentStepFailed(message, authDocumentUnusable(this.description))
taskRecorder.currentStepFailed(
message = message,
errorCode = authDocumentUnusable(this.description),
extraMessages = listOf()
)
throw IOException(message)
}

Expand All @@ -318,7 +332,11 @@ class AccountProviderResolution(
val authenticateURI = authenticate?.hrefURI
if (authenticateURI == null) {
val message = this.stringResources.resolvingAuthDocumentOAuthMalformed
taskRecorder.currentStepFailed(message, authDocumentUnusable(this.description))
taskRecorder.currentStepFailed(
message = message,
errorCode = authDocumentUnusable(this.description),
extraMessages = listOf()
)
throw IOException(message)
}

Expand Down Expand Up @@ -361,7 +379,11 @@ class AccountProviderResolution(
val authenticateURI = authenticate?.hrefURI
if (authenticateURI == null) {
val message = this.stringResources.resolvingAuthDocumentBasicTokenMalformed
taskRecorder.currentStepFailed(message, authDocumentUnusable(this.description))
taskRecorder.currentStepFailed(
message = message,
errorCode = authDocumentUnusable(this.description),
extraMessages = listOf()
)
throw IOException(message)
}

Expand Down Expand Up @@ -420,7 +442,11 @@ class AccountProviderResolution(
)
} else {
val message = this.stringResources.resolvingAuthDocumentCOPPAAgeGateMalformed
taskRecorder.currentStepFailed(message, authDocumentUnusable(this.description))
taskRecorder.currentStepFailed(
message = message,
errorCode = authDocumentUnusable(this.description),
extraMessages = listOf()
)
throw IOException(message)
}
}
Expand Down Expand Up @@ -472,12 +498,13 @@ class AccountProviderResolution(
} else {
val message = this.stringResources.resolvingAuthDocumentRetrievalFailed
taskRecorder.currentStepFailed(
message,
httpRequestFailed(
message = message,
errorCode = httpRequestFailed(
targetLink.hrefURI,
status.properties.originalStatus,
status.properties.message
)
),
extraMessages = listOf()
)
throw IOException(message)
}
Expand All @@ -491,7 +518,11 @@ class AccountProviderResolution(

is Link.LinkTemplated -> {
val message = this.stringResources.resolvingAuthDocumentUnusableLink
taskRecorder.currentStepFailed(message, authDocumentUnusableLink(this.description))
taskRecorder.currentStepFailed(
message = message,
errorCode = authDocumentUnusableLink(this.description),
extraMessages = listOf()
)
throw IOException(message)
}
}
Expand All @@ -516,7 +547,11 @@ class AccountProviderResolution(
parseResult.warnings.forEach { warning -> this.logger.warn("{}", warning.message) }
parseResult.errors.forEach { error -> this.logger.error("{}", error.message) }
val message = this.stringResources.resolvingAuthDocumentParseFailed
taskRecorder.currentStepFailed(message, authDocumentParseFailed(this.description))
taskRecorder.currentStepFailed(
message = message,
errorCode = authDocumentParseFailed(this.description),
extraMessages = listOf()
)
throw IOException(message)
}
}
Expand Down
23 changes: 4 additions & 19 deletions simplified-app-palace/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ dependencies {
*/

if (lcpDRM) {
implementation(libs.readium.lcp) {
implementation(libs.palace.liblcp) {
artifact {
type = "aar"
}
Expand Down Expand Up @@ -523,10 +523,10 @@ dependencies {
implementation(libs.google.gson)
implementation(libs.google.guava)
implementation(libs.google.material)
implementation(libs.io7m.jfunctional)
implementation(libs.io7m.jnull)
implementation(libs.io7m.jattribute.core)
implementation(libs.io7m.jfunctional)
implementation(libs.io7m.jmulticlose)
implementation(libs.io7m.jnull)
implementation(libs.irradia.fieldrush.api)
implementation(libs.irradia.fieldrush.vanilla)
implementation(libs.irradia.mime.api)
Expand Down Expand Up @@ -564,6 +564,7 @@ dependencies {
implementation(libs.palace.audiobook.http)
implementation(libs.palace.audiobook.json.canon)
implementation(libs.palace.audiobook.json.web.token)
implementation(libs.palace.audiobook.lcp.downloads)
implementation(libs.palace.audiobook.lcp.license.status)
implementation(libs.palace.audiobook.license.check.api)
implementation(libs.palace.audiobook.license.check.spi)
Expand Down Expand Up @@ -616,25 +617,9 @@ dependencies {
implementation(libs.rxjava)
implementation(libs.rxjava2)
implementation(libs.rxjava2.extensions)
implementation(libs.service.wight.annotation)
implementation(libs.service.wight.core)
implementation(libs.slf4j)
implementation(libs.timber)
implementation(libs.transport.api)
implementation(libs.transport.backend.cct)
implementation(libs.transport.runtime)
implementation(libs.truecommons.cio)
implementation(libs.truecommons.io)
implementation(libs.truecommons.key.disable)
implementation(libs.truecommons.key.spec)
implementation(libs.truecommons.logging)
implementation(libs.truecommons.services)
implementation(libs.truecommons.shed)
implementation(libs.truevfs.access)
implementation(libs.truevfs.comp.zip)
implementation(libs.truevfs.comp.zipdriver)
implementation(libs.truevfs.driver.file)
implementation(libs.truevfs.driver.zip)
implementation(libs.truevfs.kernel.impl)
implementation(libs.truevfs.kernel.spec)
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,15 @@ sealed class BookDRMInformation : Serializable {
* The hashed LCP passphrase for the book.
*/

val hashedPassphrase: String?
val hashedPassphrase: String?,

/**
* The bytes of the LCP license.
*/

val licenseBytes: ByteArray?
) : BookDRMInformation() {

override fun playerCredentials(): PlayerBookCredentialsType {
return if (this.hashedPassphrase != null) {
PlayerBookCredentialsLCP(this.hashedPassphrase)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ sealed class BookFormat {
* The URI that can be used to fetch a more recent copy of the manifest.
*/

val manifestURI: URI,
val manifestURI: URI?,

/**
* The most recent copy of the audio book manifest, if any has been fetched.
Expand Down Expand Up @@ -112,6 +112,7 @@ sealed class BookFormat {
* only the manifest is downloaded, this will always be null.
*/

@Deprecated("Packaged audiobooks are no longer handled by the application directly.")
val file: File?,

/**
Expand Down
6 changes: 6 additions & 0 deletions simplified-books-audio/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
dependencies {
implementation(project(":simplified-accounts-api"))
implementation(project(":simplified-books-database-api"))
implementation(project(":simplified-presentableerror-api"))
implementation(project(":simplified-services-api"))
implementation(project(":simplified-taskrecorder-api"))

implementation(libs.androidx.constraintlayout)
implementation(libs.androidx.constraintlayout.core)
implementation(libs.google.guava)
implementation(libs.io7m.junreachable)
implementation(libs.irradia.mime.api)
Expand All @@ -13,6 +16,7 @@ dependencies {
implementation(libs.palace.audiobook.api)
implementation(libs.palace.audiobook.downloads)
implementation(libs.palace.audiobook.feedbooks)
implementation(libs.palace.audiobook.lcp.downloads)
implementation(libs.palace.audiobook.license.check.api)
implementation(libs.palace.audiobook.license.check.spi)
implementation(libs.palace.audiobook.manifest.api)
Expand All @@ -25,6 +29,8 @@ dependencies {
implementation(libs.palace.audiobook.manifest.parser.webpub)
implementation(libs.palace.audiobook.parser.api)
implementation(libs.palace.http.api)
implementation(libs.palace.http.downloads)
implementation(libs.r2.lcp)
implementation(libs.r2.shared)
implementation(libs.rxjava2)
implementation(libs.slf4j)
Expand Down
Loading

0 comments on commit c37443e

Please sign in to comment.