Skip to content

Commit 6941ee9

Browse files
authored
Additional copy preventions for protected publications (#424)
1 parent 3ce38c6 commit 6941ee9

File tree

5 files changed

+61
-25
lines changed

5 files changed

+61
-25
lines changed

readium/adapters/pspdfkit/navigator/src/main/java/org/readium/adapter/pspdfkit/navigator/PsPdfKitDocumentFragment.kt

+10-5
Original file line numberDiff line numberDiff line change
@@ -283,11 +283,16 @@ public class PsPdfKitDocumentFragment internal constructor(
283283
return listener?.onTap(pagePosition) ?: false
284284
}
285285

286-
private val allowedTextSelectionItems = listOf(
287-
com.pspdfkit.R.id.pspdf__text_selection_toolbar_item_share,
288-
com.pspdfkit.R.id.pspdf__text_selection_toolbar_item_copy,
289-
com.pspdfkit.R.id.pspdf__text_selection_toolbar_item_speak
290-
)
286+
private val allowedTextSelectionItems: List<Int> by lazy {
287+
buildList {
288+
add(com.pspdfkit.R.id.pspdf__text_selection_toolbar_item_speak)
289+
290+
if (!publication.isProtected) {
291+
add(com.pspdfkit.R.id.pspdf__text_selection_toolbar_item_share)
292+
add(com.pspdfkit.R.id.pspdf__text_selection_toolbar_item_copy)
293+
}
294+
}
295+
}
291296

292297
override fun onPrepareTextSelectionPopupToolbar(toolbar: PdfTextSelectionPopupToolbar) {
293298
// Makes sure only the menu items in `allowedTextSelectionItems` will be visible.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright 2023 Readium Foundation. All rights reserved.
3+
* Use of this source code is governed by the BSD-style license
4+
* available in the top-level LICENSE file of the project.
5+
*/
6+
7+
package org.readium.r2.navigator
8+
9+
import android.os.Bundle
10+
import android.view.WindowManager
11+
import androidx.fragment.app.Fragment
12+
import org.readium.r2.shared.publication.Publication
13+
import org.readium.r2.shared.publication.services.isProtected
14+
import org.readium.r2.shared.publication.services.isRestricted
15+
16+
public abstract class NavigatorFragment internal constructor(
17+
override val publication: Publication
18+
) : Fragment(), Navigator {
19+
20+
override fun onCreate(savedInstanceState: Bundle?) {
21+
require(!publication.isRestricted) { "The provided publication is restricted. Check that any DRM was properly unlocked using a Content Protection." }
22+
23+
super.onCreate(savedInstanceState)
24+
}
25+
26+
override fun onResume() {
27+
super.onResume()
28+
29+
// Prevent screenshots and text selection from the task switcher for protected publications.
30+
if (publication.isProtected) {
31+
activity?.window?.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
32+
}
33+
}
34+
35+
override fun onStop() {
36+
super.onStop()
37+
38+
if (publication.isProtected) {
39+
activity?.window?.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
40+
}
41+
}
42+
}

readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFragment.kt

+3-7
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ import org.readium.r2.navigator.Decoration
4747
import org.readium.r2.navigator.DecorationId
4848
import org.readium.r2.navigator.ExperimentalDecorator
4949
import org.readium.r2.navigator.HyperlinkNavigator
50+
import org.readium.r2.navigator.NavigatorFragment
5051
import org.readium.r2.navigator.OverflowNavigator
5152
import org.readium.r2.navigator.R
5253
import org.readium.r2.navigator.R2BasicWebView
@@ -85,7 +86,6 @@ import org.readium.r2.shared.publication.Publication
8586
import org.readium.r2.shared.publication.ReadingProgression as PublicationReadingProgression
8687
import org.readium.r2.shared.publication.epub.EpubLayout
8788
import org.readium.r2.shared.publication.presentation.presentation
88-
import org.readium.r2.shared.publication.services.isRestricted
8989
import org.readium.r2.shared.publication.services.positionsByReadingOrder
9090
import org.readium.r2.shared.util.Url
9191
import org.readium.r2.shared.util.mediatype.MediaType
@@ -106,7 +106,7 @@ public typealias JavascriptInterfaceFactory = (resource: Link) -> Any?
106106
*/
107107
@OptIn(ExperimentalDecorator::class, ExperimentalReadiumApi::class, DelicateReadiumApi::class)
108108
public class EpubNavigatorFragment internal constructor(
109-
override val publication: Publication,
109+
publication: Publication,
110110
private val initialLocator: Locator?,
111111
readingOrder: List<Link>?,
112112
private val initialPreferences: EpubPreferences,
@@ -115,7 +115,7 @@ public class EpubNavigatorFragment internal constructor(
115115
epubLayout: EpubLayout,
116116
private val defaults: EpubDefaults,
117117
configuration: Configuration
118-
) : Fragment(),
118+
) : NavigatorFragment(publication),
119119
OverflowNavigator,
120120
SelectableNavigator,
121121
DecorableNavigator,
@@ -261,10 +261,6 @@ public class EpubNavigatorFragment internal constructor(
261261

262262
public interface Listener : OverflowNavigator.Listener, HyperlinkNavigator.Listener
263263

264-
init {
265-
require(!publication.isRestricted) { "The provided publication is restricted. Check that any DRM was properly unlocked using a Content Protection." }
266-
}
267-
268264
// Configurable
269265

270266
override val settings: StateFlow<EpubSettings> get() = viewModel.settings

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

+3-8
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@ import android.os.Bundle
1313
import android.view.LayoutInflater
1414
import android.view.View
1515
import android.view.ViewGroup
16-
import androidx.fragment.app.Fragment
1716
import androidx.fragment.app.FragmentActivity
1817
import androidx.fragment.app.FragmentFactory
1918
import androidx.viewpager.widget.ViewPager
2019
import kotlinx.coroutines.flow.MutableStateFlow
2120
import kotlinx.coroutines.flow.StateFlow
2221
import kotlinx.coroutines.flow.asStateFlow
2322
import kotlinx.coroutines.runBlocking
23+
import org.readium.r2.navigator.NavigatorFragment
2424
import org.readium.r2.navigator.OverflowNavigator
2525
import org.readium.r2.navigator.SimplePresentation
2626
import org.readium.r2.navigator.VisualNavigator
@@ -44,25 +44,20 @@ import org.readium.r2.shared.publication.Locator
4444
import org.readium.r2.shared.publication.Publication
4545
import org.readium.r2.shared.publication.ReadingProgression as PublicationReadingProgression
4646
import org.readium.r2.shared.publication.indexOfFirstWithHref
47-
import org.readium.r2.shared.publication.services.isRestricted
4847
import org.readium.r2.shared.publication.services.positions
4948

5049
/**
5150
* Navigator for bitmap-based publications, such as CBZ.
5251
*/
5352
@OptIn(ExperimentalReadiumApi::class, DelicateReadiumApi::class)
5453
public class ImageNavigatorFragment private constructor(
55-
override val publication: Publication,
54+
publication: Publication,
5655
private val initialLocator: Locator? = null,
5756
internal val listener: Listener? = null
58-
) : Fragment(), OverflowNavigator {
57+
) : NavigatorFragment(publication), OverflowNavigator {
5958

6059
public interface Listener : VisualNavigator.Listener
6160

62-
init {
63-
require(!publication.isRestricted) { "The provided publication is restricted. Check that any DRM was properly unlocked using a Content Protection." }
64-
}
65-
6661
internal lateinit var positions: List<Locator>
6762
internal lateinit var resourcePager: R2ViewPager
6863

readium/navigator/src/main/java/org/readium/r2/navigator/pdf/PdfNavigatorFragment.kt

+3-5
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import kotlinx.coroutines.flow.StateFlow
2222
import kotlinx.coroutines.flow.launchIn
2323
import kotlinx.coroutines.flow.onEach
2424
import kotlinx.coroutines.launch
25+
import org.readium.r2.navigator.NavigatorFragment
2526
import org.readium.r2.navigator.OverflowNavigator
2627
import org.readium.r2.navigator.R
2728
import org.readium.r2.navigator.VisualNavigator
@@ -40,7 +41,6 @@ import org.readium.r2.shared.publication.Link
4041
import org.readium.r2.shared.publication.Locator
4142
import org.readium.r2.shared.publication.Publication
4243
import org.readium.r2.shared.publication.ReadingProgression as PublicationReadingProgression
43-
import org.readium.r2.shared.publication.services.isRestricted
4444
import org.readium.r2.shared.util.mediatype.MediaType
4545

4646
/**
@@ -54,12 +54,12 @@ import org.readium.r2.shared.util.mediatype.MediaType
5454
@ExperimentalReadiumApi
5555
@OptIn(DelicateReadiumApi::class)
5656
public class PdfNavigatorFragment<S : Configurable.Settings, P : Configurable.Preferences<P>> internal constructor(
57-
override val publication: Publication,
57+
publication: Publication,
5858
private val initialLocator: Locator? = null,
5959
private val initialPreferences: P,
6060
private val listener: Listener?,
6161
private val pdfEngineProvider: PdfEngineProvider<S, P, *>
62-
) : Fragment(), VisualNavigator, OverflowNavigator, Configurable<S, P> {
62+
) : NavigatorFragment(publication), VisualNavigator, OverflowNavigator, Configurable<S, P> {
6363

6464
public interface Listener : VisualNavigator.Listener
6565

@@ -94,8 +94,6 @@ public class PdfNavigatorFragment<S : Configurable.Settings, P : Configurable.Pr
9494
}
9595

9696
init {
97-
require(!publication.isRestricted) { "The provided publication is restricted. Check that any DRM was properly unlocked using a Content Protection." }
98-
9997
require(
10098
publication.readingOrder.count() == 1 &&
10199
publication.readingOrder.first().mediaType?.matches(MediaType.PDF) == true

0 commit comments

Comments
 (0)