88 lines
3.5 KiB
Kotlin
88 lines
3.5 KiB
Kotlin
// Android DocumentsProvider (Storage Access Framework) scaffold for UltiDrive.
|
|
//
|
|
// Exposes the user's Ulti drive inside the system Files app and any app that
|
|
// uses the SAF picker. Backed by the backend at /api/v1/drive. Add this class +
|
|
// the <provider> snippet (see ../AndroidManifest.snippets.xml) to the UltiDrive
|
|
// app's gen/android project after `pnpm tauri android init`.
|
|
//
|
|
// Auth: read the OIDC access token from the shared session store written by
|
|
// ulti-core (see SharedSecretProvider / EncryptedSharedPreferences). NETWORK
|
|
// CALLS BELOW ARE STUBBED — wire to your HTTP client + backend DTOs.
|
|
|
|
package space.ulti.drive.drive
|
|
|
|
import android.database.Cursor
|
|
import android.database.MatrixCursor
|
|
import android.os.CancellationSignal
|
|
import android.os.ParcelFileDescriptor
|
|
import android.provider.DocumentsContract.Document
|
|
import android.provider.DocumentsContract.Root
|
|
import android.provider.DocumentsProvider
|
|
|
|
class UltiDriveDocumentsProvider : DocumentsProvider() {
|
|
|
|
private val defaultRootProjection = arrayOf(
|
|
Root.COLUMN_ROOT_ID, Root.COLUMN_FLAGS, Root.COLUMN_TITLE,
|
|
Root.COLUMN_DOCUMENT_ID, Root.COLUMN_ICON,
|
|
)
|
|
private val defaultDocProjection = arrayOf(
|
|
Document.COLUMN_DOCUMENT_ID, Document.COLUMN_DISPLAY_NAME,
|
|
Document.COLUMN_MIME_TYPE, Document.COLUMN_FLAGS,
|
|
Document.COLUMN_SIZE, Document.COLUMN_LAST_MODIFIED,
|
|
)
|
|
|
|
override fun onCreate(): Boolean = true
|
|
|
|
override fun queryRoots(projection: Array<out String>?): Cursor {
|
|
val cursor = MatrixCursor(projection ?: defaultRootProjection)
|
|
cursor.newRow().apply {
|
|
add(Root.COLUMN_ROOT_ID, "ulti-drive")
|
|
add(Root.COLUMN_DOCUMENT_ID, "root")
|
|
add(Root.COLUMN_TITLE, "Ulti Drive")
|
|
add(Root.COLUMN_FLAGS, Root.FLAG_SUPPORTS_CREATE or Root.FLAG_SUPPORTS_IS_CHILD)
|
|
add(Root.COLUMN_ICON, applicationInfo().icon)
|
|
}
|
|
return cursor
|
|
}
|
|
|
|
override fun queryDocument(documentId: String?, projection: Array<out String>?): Cursor {
|
|
val cursor = MatrixCursor(projection ?: defaultDocProjection)
|
|
// TODO GET /api/v1/drive/items/{documentId} -> fill row.
|
|
includeStubDir(cursor, documentId ?: "root", "Ulti Drive")
|
|
return cursor
|
|
}
|
|
|
|
override fun queryChildDocuments(
|
|
parentDocumentId: String?,
|
|
projection: Array<out String>?,
|
|
sortOrder: String?,
|
|
): Cursor {
|
|
val cursor = MatrixCursor(projection ?: defaultDocProjection)
|
|
// TODO GET /api/v1/drive/items?parent={parentDocumentId} -> one row each.
|
|
return cursor
|
|
}
|
|
|
|
override fun openDocument(
|
|
documentId: String?,
|
|
mode: String?,
|
|
signal: CancellationSignal?,
|
|
): ParcelFileDescriptor {
|
|
// TODO Download GET /api/v1/drive/items/{documentId}/content into a
|
|
// local cache file (or use a pipe for streaming) and return its FD.
|
|
throw UnsupportedOperationException("openDocument not yet wired")
|
|
}
|
|
|
|
private fun includeStubDir(cursor: MatrixCursor, id: String, name: String) {
|
|
cursor.newRow().apply {
|
|
add(Document.COLUMN_DOCUMENT_ID, id)
|
|
add(Document.COLUMN_DISPLAY_NAME, name)
|
|
add(Document.COLUMN_MIME_TYPE, Document.MIME_TYPE_DIR)
|
|
add(Document.COLUMN_FLAGS, Document.FLAG_DIR_SUPPORTS_CREATE)
|
|
add(Document.COLUMN_SIZE, null)
|
|
add(Document.COLUMN_LAST_MODIFIED, System.currentTimeMillis())
|
|
}
|
|
}
|
|
|
|
private fun applicationInfo() = context!!.applicationInfo
|
|
}
|