Add deferred plugin storage strategy
This commit is contained in:
parent
ef1d6c70e8
commit
2efc159741
@ -21,5 +21,13 @@ enum class StorageStrategy {
|
|||||||
* Use this strategy if your plugin needs to perform network requests to retrieve search
|
* Use this strategy if your plugin needs to perform network requests to retrieve search
|
||||||
* results and if you don't want to implement a cache for search results.
|
* results and if you don't want to implement a cache for search results.
|
||||||
*/
|
*/
|
||||||
StoreCopy;
|
StoreCopy,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The launcher stores all relevant information in its own internal database, like [StoreCopy].
|
||||||
|
* A fresh copy is fetched from the plugin provider when the user opens the search result's
|
||||||
|
* detail view. This allows the plugin provider to update the search result at a later point in
|
||||||
|
* time, without the time constraints of [StoreReference].
|
||||||
|
*/
|
||||||
|
Deferred,
|
||||||
}
|
}
|
||||||
@ -5,6 +5,7 @@ import android.net.Uri
|
|||||||
import android.provider.MediaStore
|
import android.provider.MediaStore
|
||||||
import androidx.core.database.getStringOrNull
|
import androidx.core.database.getStringOrNull
|
||||||
import de.mm20.launcher2.crashreporter.CrashReporter
|
import de.mm20.launcher2.crashreporter.CrashReporter
|
||||||
|
import de.mm20.launcher2.files.providers.DeferredFile
|
||||||
import de.mm20.launcher2.files.providers.GDriveFile
|
import de.mm20.launcher2.files.providers.GDriveFile
|
||||||
import de.mm20.launcher2.files.providers.LocalFile
|
import de.mm20.launcher2.files.providers.LocalFile
|
||||||
import de.mm20.launcher2.files.providers.NextcloudFile
|
import de.mm20.launcher2.files.providers.NextcloudFile
|
||||||
@ -22,6 +23,7 @@ import de.mm20.launcher2.search.FileMetaType
|
|||||||
import de.mm20.launcher2.search.SavableSearchable
|
import de.mm20.launcher2.search.SavableSearchable
|
||||||
import de.mm20.launcher2.search.SearchableDeserializer
|
import de.mm20.launcher2.search.SearchableDeserializer
|
||||||
import de.mm20.launcher2.search.SearchableSerializer
|
import de.mm20.launcher2.search.SearchableSerializer
|
||||||
|
import de.mm20.launcher2.search.UpdateResult
|
||||||
import kotlinx.collections.immutable.persistentMapOf
|
import kotlinx.collections.immutable.persistentMapOf
|
||||||
import kotlinx.collections.immutable.toImmutableMap
|
import kotlinx.collections.immutable.toImmutableMap
|
||||||
import kotlinx.coroutines.flow.firstOrNull
|
import kotlinx.coroutines.flow.firstOrNull
|
||||||
@ -331,7 +333,7 @@ internal class PluginFileSerializer(
|
|||||||
"thumbnailUri" to searchable.thumbnailUri?.toString(),
|
"thumbnailUri" to searchable.thumbnailUri?.toString(),
|
||||||
"isDirectory" to searchable.isDirectory,
|
"isDirectory" to searchable.isDirectory,
|
||||||
"authority" to searchable.authority,
|
"authority" to searchable.authority,
|
||||||
"strategy" to "copy",
|
"strategy" to if (searchable.storageStrategy == StorageStrategy.StoreCopy) "copy" else "deferred",
|
||||||
).toString()
|
).toString()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -344,14 +346,22 @@ internal class PluginFileSerializer(
|
|||||||
internal class PluginFileDeserializer(
|
internal class PluginFileDeserializer(
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
private val pluginRepository: PluginRepository,
|
private val pluginRepository: PluginRepository,
|
||||||
): SearchableDeserializer {
|
) : SearchableDeserializer {
|
||||||
override suspend fun deserialize(serialized: String): SavableSearchable? {
|
override suspend fun deserialize(serialized: String): SavableSearchable? {
|
||||||
val jsonObject = JSONObject(serialized)
|
val jsonObject = JSONObject(serialized)
|
||||||
|
|
||||||
return if (jsonObject.optString("strategy", "ref") == "ref") {
|
return when (jsonObject.optString("strategy", "copy")) {
|
||||||
getByRef(jsonObject)
|
"ref" -> {
|
||||||
} else {
|
getByRef(jsonObject)
|
||||||
getByCopy(jsonObject)
|
}
|
||||||
|
|
||||||
|
"deferred" -> {
|
||||||
|
getDeferred(jsonObject)
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
getByCopy(jsonObject)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -368,6 +378,33 @@ internal class PluginFileDeserializer(
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getDeferred(obj: JSONObject): File? {
|
||||||
|
val cached = getByCopy(obj) ?: return null
|
||||||
|
val timestamp = obj.optLong("timestamp", 0L)
|
||||||
|
return DeferredFile(
|
||||||
|
cachedFile = cached as PluginFile,
|
||||||
|
timestamp = timestamp,
|
||||||
|
updatedSelf = {
|
||||||
|
val plugin = pluginRepository.get(cached.authority).firstOrNull()
|
||||||
|
?: return@DeferredFile UpdateResult.PermanentlyUnavailable()
|
||||||
|
if (!plugin.enabled) return@DeferredFile UpdateResult.PermanentlyUnavailable()
|
||||||
|
val provider = PluginFileProvider(context, cached.authority)
|
||||||
|
try {
|
||||||
|
val file = provider.getFile(cached.id)
|
||||||
|
if (file == null) {
|
||||||
|
UpdateResult.PermanentlyUnavailable()
|
||||||
|
} else {
|
||||||
|
UpdateResult.Success(file)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
CrashReporter.logException(e)
|
||||||
|
UpdateResult.TemporarilyUnavailable(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun getByCopy(obj: JSONObject): File? {
|
private fun getByCopy(obj: JSONObject): File? {
|
||||||
try {
|
try {
|
||||||
val uri = obj.getString("uri")
|
val uri = obj.getString("uri")
|
||||||
|
|||||||
@ -0,0 +1,11 @@
|
|||||||
|
package de.mm20.launcher2.files.providers
|
||||||
|
|
||||||
|
import de.mm20.launcher2.search.File
|
||||||
|
import de.mm20.launcher2.search.UpdatableSearchable
|
||||||
|
import de.mm20.launcher2.search.UpdateResult
|
||||||
|
|
||||||
|
class DeferredFile(
|
||||||
|
cachedFile: File,
|
||||||
|
override val timestamp: Long,
|
||||||
|
override var updatedSelf: (suspend () -> UpdateResult<File>)? = null,
|
||||||
|
) : File by cachedFile, UpdatableSearchable<File>
|
||||||
Loading…
x
Reference in New Issue
Block a user