Generate SSD PDF loading from typed Jerboa

ober

f156f8c1c93f7c0e4b8b3adf4004b278395540e9

diff --git a/templates/ssd-review.ss b/templates/ssd-review.ss
index aceda99..a6a376e 100644
--- a/templates/ssd-review.ss
+++ b/templates/ssd-review.ss
@@ -4701,6 +4701,7 @@
                       (java lang Thread)
                       (android app AlertDialog)
                       (android app AlertDialog Builder)
+                      (android content ContentResolver)
                       (android content Context)
                       (android content DialogInterface)
                       (android graphics Bitmap)
@@ -4830,6 +4831,7 @@
                 mainActivityMergeRemoteTruthAsync
                 mainActivityRenderCurrentPageAsync
                 mainActivitySyncSelectedTreeAsync
+                mainActivityLoadPdfAsync
                 mainActivityInstallApproveAreaDialogButton
                 mainActivityInstallAppendDialogButton
                 mainActivityInstallEditDialogButtons
@@ -4917,6 +4919,7 @@
         (type AutoCompleteTextView)
         (type Button)
         (type CharSequence)
+        (type ContentResolver)
         (type Context)
         (type DialogInterface)
         (type Editable)
@@ -4956,6 +4959,14 @@
           (kotlin-member-get isFile))
         (extern (documentFileDelete (file : DocumentFile)) : Bool
           (kotlin-member-call delete))
+        (extern (contentResolverOpenInputStreamRaw
+                  (resolver : ContentResolver)
+                  (uri : Uri)) : (Nullable InputStream)
+          (kotlin-member-call openInputStream))
+        (extern (sha1HexRaw (input : InputStream)) : String
+          (kotlin-call sha1Hex))
+        (extern (uiInputStreamCloseRaw (input : InputStream)) : Unit
+          (kotlin-member-call close))
         (extern (windowSetSoftInputMode (window : Window) (mode : Int32)) : Unit
           (kotlin-member-call setSoftInputMode))
         (extern (alertDialogIsShowing (dialog : AlertDialog)) : Bool
@@ -5338,6 +5349,12 @@
         (extern (mainActivityPdfUriRaw
                   (activity : MainActivity)) : (Nullable Uri)
           (kotlin-member-get pdfUri))
+        (extern (mainActivityPdfNameRaw
+                  (activity : MainActivity)) : String
+          (kotlin-member-get pdfName))
+        (extern (mainActivityContentResolverRaw
+                  (activity : MainActivity)) : ContentResolver
+          (kotlin-member-get contentResolver))
         (extern (mainActivityLoadGenerationRaw
                   (activity : MainActivity)) : Int32
           (kotlin-member-get loadGeneration))
@@ -5363,6 +5380,14 @@
                   (expectedPdfSha1 : String)
                   (expectedPageCount : Int32)) : Unit
           (kotlin-member-call detectCurrent))
+        (extern (mainActivityPdfPageCountRaw
+                  (activity : MainActivity)
+                  (uri : Uri)) : Int32
+          (kotlin-member-call pdfPageCount))
+        (extern (mainActivityPersistCurrentPdfStateRaw
+                  (activity : MainActivity)
+                  (includeViewport : Bool)) : Unit
+          (kotlin-member-call persistCurrentPdfState))
         (extern (mainActivityCurrentSessionRaw
                   (activity : MainActivity)) : (Nullable SsdSession)
           (kotlin-member-get currentSession))
@@ -7035,6 +7060,62 @@
                           activity
                           (folderSyncFailedStatus
                             (exceptionMessageRaw error)))))))))))
+        (def (sha1HexOrEmptyAndClose
+               (input : (Nullable InputStream))) : String
+          (if (nullable-null? input)
+            ""
+            (let ((stream (nullable-get input)))
+              (let ((hash (sha1HexRaw stream)))
+                (begin
+                  (uiInputStreamCloseRaw stream)
+                  hash)))))
+        (def (mainActivityLoadPdfAsync
+               (activity : MainActivity)
+               (uri : Uri)
+               (initialPageIndex : Int32)
+               (restoring : Bool)) : Unit
+          (begin
+            (mainActivitySetStatusRaw
+              activity
+              (hashingPdfStatus (mainActivityPdfNameRaw activity)))
+            (runBackground
+              (lambda ()
+                (try
+                  (let ((hash
+                          (sha1HexOrEmptyAndClose
+                            (contentResolverOpenInputStreamRaw
+                              (mainActivityContentResolverRaw activity)
+                              uri))))
+                    (let ((count (mainActivityPdfPageCountRaw activity uri)))
+                      (mainActivityRunOnUiThreadRaw
+                        activity
+                        (lambda ()
+                          (begin
+                            (mainActivitySetLoadedPdfState
+                              activity
+                              hash
+                              count
+                              initialPageIndex)
+                            (if (shouldPersistLoadedPdfState restoring)
+                              (mainActivityPersistCurrentPdfStateRaw
+                                activity
+                                #f)
+                              (begin))
+                            (mainActivitySetStatusRaw
+                              activity
+                              (loadedPdfStatus
+                                (mainActivityPdfNameRaw activity)
+                                count))
+                            (mainActivityRenderCurrentPageRaw
+                              activity))))))
+                  (catch (error : Exception)
+                    (mainActivityRunOnUiThreadRaw
+                      activity
+                      (lambda ()
+                        (mainActivitySetStatusRaw
+                          activity
+                          (openFailedStatus
+                            (exceptionMessageRaw error)))))))))))
         (def (mainActivityInstallApproveAreaDialogButton
                (activity : MainActivity)
                (dialog : AlertDialog)
@@ -9603,22 +9684,7 @@
        "            .edit()"
        "            .putString(PREF_LAST_PDF_URI, uri.toString())"
        "            .apply()"
-       "        setStatus(hashingPdfStatus(pdfName))"
-       "        thread {"
-       "            try {"
-       "                val pdfInput = contentResolver.openInputStream(uri)"
-       "                val hash = if (inputStreamPresent(pdfInput)) checkNotNull(pdfInput).use { sha1Hex(it) } else \"\""
-       "                val count = pdfPageCount(uri)"
-       "                runOnUiThread {"
-       "                    mainActivitySetLoadedPdfState(this, hash, count, initialPageIndex)"
-       "                    if (shouldPersistLoadedPdfState(restoring)) persistCurrentPdfState(includeViewport = false)"
-       "                    setStatus(loadedPdfStatus(pdfName, pageCount))"
-       "                    renderCurrentPage()"
-       "                }"
-       "            } catch (error: Exception) {"
-       "                runOnUiThread { setStatus(openFailedStatus(error.message)) }"
-       "            }"
-       "        }"
+       "        mainActivityLoadPdfAsync(this, uri, initialPageIndex, restoring)"
        "    }"
        ""
        "    private fun restoreLastPdf(): Boolean {"
@@ -9634,7 +9700,7 @@
        "        }"
        "    }"
        ""
-       "    private fun persistCurrentPdfState(includeViewport: Boolean) {"
+       "    internal fun persistCurrentPdfState(includeViewport: Boolean) {"
        "        if (!pdfUriLoaded(pdfUri)) return"
        "        val uri = uriOrEmpty(pdfUri)"
        "        val edit = getPreferences(MODE_PRIVATE).edit()"
@@ -9678,7 +9744,7 @@
        "        )"
        "    }"
        ""
-       "    private fun pdfPageCount(uri: Uri): Int {"
+       "    internal fun pdfPageCount(uri: Uri): Int {"
        "        openPdfRenderer(uri).use { renderer -> return renderer.pageCount }"
        "    }"
        ""