@@ -3,6 +3,7 @@ package app.grapheneos.pdfviewer.viewModel
33import android.app.Application
44import android.content.ContentResolver
55import android.content.Intent
6+ import android.content.UriPermission
67import android.net.Uri
78import android.util.Log
89import androidx.core.net.toUri
@@ -119,7 +120,7 @@ class PdfViewModel(application: Application) : AndroidViewModel(application) {
119120 /* *
120121 * Load initial PDF state if preference is enabled
121122 */
122- fun maybeLoadPdfBlocking (): PdfPreferencesRepository .PdfState ? {
123+ fun maybeLoadPdfStateBlocking (): PdfPreferencesRepository .PdfState ? {
123124 return runBlocking {
124125 if (PreferenceHelper .isResumeLastDocumentEnabled(getApplication())) {
125126 repository.pdfStateFlow.first()
@@ -170,19 +171,7 @@ class PdfViewModel(application: Application) : AndroidViewModel(application) {
170171 */
171172 fun savePdfState (uriString : String , page : Int , includeHashMapping : Boolean ) {
172173 viewModelScope.launch {
173- val oldState = repository.pdfStateFlow.first()
174- val oldUri = oldState.lastOpenedUri
175-
176- repository.saveLastOpened(uriString, page)
177-
178- // Release old permission if it's different from new URI
179- if (oldUri != null && oldUri != uriString) {
180- releaseUriPermissionIfHeld(oldUri.toUri())
181- }
182-
183- if (includeHashMapping && currentFileHash != null ) {
184- repository.updatePagePosition(currentFileHash!! , page)
185- }
174+ savePdfStateCommon(uriString, page, includeHashMapping)
186175 }
187176 }
188177
@@ -196,19 +185,23 @@ class PdfViewModel(application: Application) : AndroidViewModel(application) {
196185 */
197186 fun savePdfStateBlocking (uriString : String , page : Int , includeHashMapping : Boolean ) {
198187 runBlocking {
199- val oldState = repository.pdfStateFlow.first()
200- val oldUri = oldState.lastOpenedUri
188+ savePdfStateCommon(uriString, page, includeHashMapping)
189+ }
190+ }
201191
202- repository.saveLastOpened(uriString, page)
192+ private suspend fun savePdfStateCommon (uriString : String , page : Int , includeHashMapping : Boolean ) {
193+ val oldState = repository.pdfStateFlow.first()
194+ val oldUri = oldState.lastOpenedUri
203195
204- // Release old permission if it's different from new URI
205- if (oldUri != null && oldUri != uriString) {
206- releaseUriPermissionIfHeld(oldUri.toUri())
207- }
196+ repository.saveLastOpened(uriString, page)
208197
209- if (includeHashMapping && currentFileHash != null ) {
210- repository.updatePagePosition(currentFileHash!! , page)
211- }
198+ // Release old permission if it's different from new URI
199+ if (oldUri != null && oldUri != uriString) {
200+ releaseUriPermissionIfHeld(oldUri.toUri())
201+ }
202+
203+ if (includeHashMapping && currentFileHash != null ) {
204+ repository.updatePagePosition(currentFileHash!! , page)
212205 }
213206 }
214207
@@ -225,6 +218,13 @@ class PdfViewModel(application: Application) : AndroidViewModel(application) {
225218 }
226219 }
227220
221+ fun prepareNewPdf (uri : Uri , page : Int ) {
222+ if (takePersistableUriPermission(uri)) {
223+ savePdfState(uri.toString(), page, false )
224+ }
225+ calculateHash(uri)
226+ }
227+
228228 private fun releaseUriPermissionIfHeld (uri : Uri ) {
229229 try {
230230 // Find if we have persisted permission for this URI
@@ -251,4 +251,22 @@ class PdfViewModel(application: Application) : AndroidViewModel(application) {
251251 Log .w(TAG , " Permission release failed" , e)
252252 }
253253 }
254+
255+ private fun takePersistableUriPermission (uri : Uri ): Boolean {
256+ try {
257+ contentResolver.takePersistableUriPermission(
258+ uri,
259+ Intent .FLAG_GRANT_READ_URI_PERMISSION
260+ )
261+ return true
262+ } catch (_: SecurityException ) {
263+ return false
264+ }
265+ }
266+
267+ fun hasUriPermission (uri : Uri ? ): Boolean {
268+ return contentResolver.persistedUriPermissions
269+ .stream()
270+ .anyMatch { permission: UriPermission ? -> permission!! .uri == uri && permission.isReadPermission }
271+ }
254272}
0 commit comments