11package org.nypl.simplified.books.api
22
33import android.app.Application
4+ import org.nypl.drm.core.BoundlessServiceType
45import org.nypl.drm.core.ContentProtectionProvider
56import org.nypl.simplified.lcp.LCPContentProtectionProvider
67import org.readium.r2.shared.publication.protection.ContentProtection
78import org.slf4j.LoggerFactory
9+ import java.time.OffsetDateTime
810
911object BookContentProtections {
1012
@@ -13,40 +15,79 @@ object BookContentProtections {
1315
1416 /*
1517 * Instantiate any content protections that might be needed for DRM...
18+ *
19+ * XXX: This interface needs to be replaced with something else. It's messy and is trying to
20+ * squash multiple different interfaces into a single method.
1621 */
1722
1823 fun create (
1924 context : Application ,
2025 contentProtectionProviders : List <ContentProtectionProvider >,
26+ boundless : BoundlessServiceType ? ,
27+ format : BookFormat ,
2128 drmInfo : BookDRMInformation ,
2229 isManualPassphraseEnabled : Boolean = false,
2330 onLCPDialogDismissed : () -> Unit = {}
2431 ): List <ContentProtection > {
25- return contentProtectionProviders.mapNotNull { provider ->
26- this .logger.debug(" instantiating content protection provider {}" , provider.javaClass.canonicalName)
27-
28- /*
29- * XXX: It's unpleasant to have to special-case like this, but we don't control the
30- * org.nypl.drm.core.ContentProtectionProvider interface. When LCP is implemented upstream,
31- * all of those interfaces can be upgraded to properly support passing in credentials.
32- */
33-
34- if (provider is LCPContentProtectionProvider ) {
35- when (drmInfo) {
36- is BookDRMInformation .LCP -> {
37- provider.passphrase = drmInfo.hashedPassphrase
38- provider.isManualPassphraseEnabled = isManualPassphraseEnabled
39- provider.onLcpDialogDismissed = onLCPDialogDismissed
32+ return try {
33+ when (drmInfo) {
34+ /*
35+ * ACS doesn't require any special handling. Just instantiate the one provider if it exists.
36+ */
37+
38+ is BookDRMInformation .ACS -> {
39+ contentProtectionProviders.mapNotNull { provider -> provider.create(context) }
40+ }
41+
42+ /*
43+ * Boundless only works for EPUB files, and requires a bit of information up-front.
44+ */
45+ is BookDRMInformation .Boundless -> {
46+ if (boundless != null ) {
47+ if (format is BookFormat .BookFormatEPUB ) {
48+ listOf (
49+ boundless.createContentProtection(
50+ epubFile = format.file!! ,
51+ licenseFile = drmInfo.license!! ,
52+ tempDirectory = context.cacheDir,
53+ inMemorySizeThreshold = 10_000_000UL ,
54+ currentTime = OffsetDateTime .now()
55+ )
56+ )
57+ } else {
58+ listOf ()
59+ }
60+ } else {
61+ listOf ()
4062 }
63+ }
4164
42- is BookDRMInformation .ACS ,
43- is BookDRMInformation .AXIS ,
44- BookDRMInformation .None -> {
45- // do nothing
65+ /*
66+ * LCP requires data up front.
67+ */
68+ is BookDRMInformation .LCP -> {
69+ val lcpProvider =
70+ contentProtectionProviders.filter { provider -> provider is LCPContentProtectionProvider }
71+ .map { provider -> provider as LCPContentProtectionProvider }
72+ .firstOrNull()
73+
74+ if (lcpProvider != null ) {
75+ lcpProvider.passphrase = drmInfo.hashedPassphrase
76+ lcpProvider.isManualPassphraseEnabled = isManualPassphraseEnabled
77+ lcpProvider.onLcpDialogDismissed = onLCPDialogDismissed
78+ listOfNotNull(lcpProvider.create(context))
79+ } else {
80+ listOf ()
4681 }
4782 }
83+
84+ BookDRMInformation .None -> {
85+ listOf ()
86+ }
4887 }
49- provider.create(context)
88+ } catch (e: Throwable ) {
89+ this .logger.error(" Failed to handle DRM providers: " , e)
90+ listOf ()
5091 }
5192 }
5293}
0 commit comments