Generate SSD URI permission helpers from typed Jerboa

ober

2e2d74bd55a22cd1396f46244b537a2134def458

diff --git a/templates/ssd-review.ss b/templates/ssd-review.ss
index f507d0c..20b202f 100644
--- a/templates/ssd-review.ss
+++ b/templates/ssd-review.ss
@@ -4769,6 +4769,7 @@
                       (android content ContentResolver)
                       (android content Context)
                       (android content SharedPreferences)
+                      (android content SharedPreferences Editor)
                       (android content res Resources)
                       (android content DialogInterface)
                       (android graphics Bitmap)
@@ -4924,6 +4925,8 @@
                 mainActivityInitialPickerUri mainActivityOpenPdf
                 mainActivityOpenAnyPdf mainActivityChooseSsdPdfFolder
                 mainActivityRequestDownloadAccess
+                mainActivityRememberAndBrowseSsdFolder
+                mainActivitySyncSelectedTree
                 mainActivitySetPositiveChooseSsdPdfFolder
                 mainActivitySetNeutralChooseSsdPdfFolder
                 mainActivitySetPositiveOpenAnyPdf
@@ -5049,6 +5052,7 @@
         (type DialogInterface)
         (type DocumentsContract)
         (type Editable)
+        (type Editor)
         (type EditText)
         (type File)
         (type FileTreeWalk)
@@ -7912,11 +7916,27 @@
                   (activity : MainActivity)
                   (mode : Int32)) : SharedPreferences
           (kotlin-member-call getPreferences))
+        (extern (sharedPreferencesEditRaw
+                  (preferences : SharedPreferences)) : Editor
+          (kotlin-member-call edit))
+        (extern (sharedPreferencesEditorPutStringRaw
+                  (editor : Editor)
+                  (key : String)
+                  (value : String)) : Editor
+          (kotlin-member-call putString))
+        (extern (sharedPreferencesEditorApplyRaw
+                  (editor : Editor)) : Unit
+          (kotlin-member-call apply))
         (extern (sharedPreferencesGetStringRaw
                   (preferences : SharedPreferences)
                   (key : String)
                   (defaultValue : (Nullable String))) : (Nullable String)
           (kotlin-member-call getString))
+        (extern (contentResolverTakePersistableUriPermissionRaw
+                  (resolver : ContentResolver)
+                  (uri : Uri)
+                  (flags : Int32)) : Unit
+          (kotlin-member-call takePersistableUriPermission))
         (extern (contextModePrivate) : Int32
           (kotlin-value Context MODE_PRIVATE))
         (extern (mainActivityDpiValue) : Int32
@@ -8436,6 +8456,68 @@
             (mainActivityGetPreferencesRaw activity (contextModePrivate))
             key
             (nullable-none String)))
+        (def (persistableReadWriteUriPermissionFlags (flags : Int32)) : Int32
+          (bitwise-and
+            flags
+            (bitwise-ior
+              (intentFlagGrantReadUriPermission)
+              (intentFlagGrantWriteUriPermission))))
+        (def (takePersistableUriPermissionIgnoringError
+               (resolver : ContentResolver)
+               (uri : Uri)
+               (flags : Int32)) : Unit
+          (try
+            (contentResolverTakePersistableUriPermissionRaw
+              resolver
+              uri
+              flags)
+            (catch (error : Exception)
+              (begin))))
+        (def (mainActivityStorePreferenceString
+               (activity : MainActivity)
+               (key : String)
+               (value : String)) : Unit
+          (sharedPreferencesEditorApplyRaw
+            (sharedPreferencesEditorPutStringRaw
+              (sharedPreferencesEditRaw
+                (mainActivityGetPreferencesRaw activity (contextModePrivate)))
+              key
+              value)))
+        (def (mainActivityRememberAndBrowseSsdFolder
+               (activity : MainActivity)
+               (uri : Uri)
+               (flags : Int32)
+               (treePreferenceKey : String)
+               (lastPdfPreferenceKey : String)
+               (requestOpenPdfCode : Int32)
+               (requestOpenTreeCode : Int32)) : Unit
+          (begin
+            (takePersistableUriPermissionIgnoringError
+              (mainActivityContentResolverRaw activity)
+              uri
+              (persistableReadWriteUriPermissionFlags flags))
+            (mainActivityStorePreferenceString
+              activity
+              treePreferenceKey
+              (uriToStringRaw uri))
+            (mainActivityShowSsdPdfBrowserAsync
+              activity
+              uri
+              requestOpenPdfCode
+              requestOpenTreeCode
+              treePreferenceKey
+              lastPdfPreferenceKey)))
+        (def (mainActivitySyncSelectedTree
+               (activity : MainActivity)
+               (store : TruthStore)
+               (uri : Uri)
+               (flags : Int32)) : Unit
+          (begin
+            (takePersistableUriPermissionIgnoringError
+              (mainActivityContentResolverRaw activity)
+              uri
+              (persistableReadWriteUriPermissionFlags flags))
+            (mainActivitySyncSelectedTreeAsync activity store uri)))
         (def (mainActivitySdkAtLeast (sdk : Int32) (api : Int32)) : Bool
           (>= sdk api))
         (def (mainActivityInitialPickerUri
@@ -11676,7 +11758,7 @@
        "        if (requestIsOpenPdf(requestCode, REQ_OPEN_PDF)) {"
        "            loadPdf(uri, flags)"
        "        } else if (requestIsOpenSsdPdfTree(requestCode, REQ_OPEN_SSD_PDF_TREE)) {"
-       "            rememberAndBrowseSsdFolder(uri, flags)"
+       "            mainActivityRememberAndBrowseSsdFolder(this, uri, flags, PREF_SSD_PDF_TREE_URI, PREF_LAST_PDF_URI, REQ_OPEN_PDF, REQ_OPEN_SSD_PDF_TREE)"
        "        } else if (requestIsExportZip(requestCode, REQ_EXPORT_ZIP)) {"
        "            val output = contentResolver.openOutputStream(uri)"
        "            if (outputStreamPresent(output)) {"
@@ -11694,7 +11776,7 @@
        "                }"
        "            }"
        "        } else if (requestIsSyncTree(requestCode, REQ_SYNC_TREE)) {"
-       "            syncSelectedTree(uri, flags)"
+       "            mainActivitySyncSelectedTree(this, truthStore, uri, flags)"
        "        }"
        "    }"
        ""
@@ -11710,21 +11792,6 @@
        "        }"
        "    }"
        ""
-       "    private fun rememberAndBrowseSsdFolder(uri: Uri, flags: Int) {"
-       "        try {"
-       "            contentResolver.takePersistableUriPermission("
-       "                uri,"
-       "                flags and (Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)"
-       "            )"
-       "        } catch (_: Exception) {"
-       "        }"
-       "        getPreferences(MODE_PRIVATE)"
-       "            .edit()"
-       "            .putString(PREF_SSD_PDF_TREE_URI, uri.toString())"
-       "            .apply()"
-       "        mainActivityShowSsdPdfBrowserAsync(this, uri, REQ_OPEN_PDF, REQ_OPEN_SSD_PDF_TREE, PREF_SSD_PDF_TREE_URI, PREF_LAST_PDF_URI)"
-       "    }"
-       ""
        "    internal fun findSsdPdfsFromTree(treeUri: Uri): List<SsdPdfChoice> {"
        "        val maybeRoot = DocumentFile.fromTreeUri(this, treeUri)"
        "        if (!documentFilePresent(maybeRoot)) return emptyList()"
@@ -11837,17 +11904,6 @@
        "        }"
        "    }"
        ""
-       "    private fun syncSelectedTree(uri: Uri, flags: Int) {"
-       "        try {"
-       "            contentResolver.takePersistableUriPermission("
-       "                uri,"
-       "                flags and (Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)"
-       "            )"
-       "        } catch (_: Exception) {"
-       "        }"
-       "        mainActivitySyncSelectedTreeAsync(this, truthStore, uri)"
-       "    }"
-       ""
        "    internal fun loadPdf(uri: Uri, flags: Int, initialPageIndex: Int = 0, restoring: Boolean = false) {"
        "        try {"
        "            contentResolver.takePersistableUriPermission(uri, flags and Intent.FLAG_GRANT_READ_URI_PERMISSION)"