Fix crash when widget config deserialization fails

This commit is contained in:
MM20 2023-04-14 00:33:00 +02:00
parent e6751541dd
commit fb87ab20f9
No known key found for this signature in database
GPG Key ID: 0B61A8F2DEAFA389
3 changed files with 29 additions and 7 deletions

View File

@ -42,6 +42,7 @@ dependencies {
implementation(libs.androidx.appcompat) implementation(libs.androidx.appcompat)
implementation(libs.bundles.androidx.lifecycle) implementation(libs.bundles.androidx.lifecycle)
implementation(libs.commons.text) implementation(libs.commons.text)
implementation(libs.kotlinx.serialization.json)
testImplementation(libs.bundles.tests) testImplementation(libs.bundles.tests)

View File

@ -0,0 +1,14 @@
package de.mm20.launcher2.ktx
import kotlinx.serialization.SerializationException
import kotlinx.serialization.json.Json
import kotlinx.serialization.decodeFromString
inline fun <reified T>Json.decodeFromStringOrNull(json: String?): T? {
if (json == null) return null
return try {
decodeFromString(json)
} catch (e: SerializationException) {
null
}
}

View File

@ -6,10 +6,10 @@ import android.appwidget.AppWidgetManager
import android.content.ComponentName import android.content.ComponentName
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import de.mm20.launcher2.database.entities.WidgetEntity
import de.mm20.launcher2.database.entities.PartialWidgetEntity import de.mm20.launcher2.database.entities.PartialWidgetEntity
import de.mm20.launcher2.database.entities.WidgetEntity
import de.mm20.launcher2.ktx.decodeFromStringOrNull
import de.mm20.launcher2.ktx.tryStartActivity import de.mm20.launcher2.ktx.tryStartActivity
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import java.util.UUID import java.util.UUID
@ -28,6 +28,7 @@ sealed class Widget {
) )
} }
} }
abstract fun toDatabaseEntity(): PartialWidgetEntity abstract fun toDatabaseEntity(): PartialWidgetEntity
open val isConfigurable: Boolean = false open val isConfigurable: Boolean = false
@ -37,17 +38,25 @@ sealed class Widget {
fun fromDatabaseEntity(context: Context, entity: WidgetEntity): Widget? { fun fromDatabaseEntity(context: Context, entity: WidgetEntity): Widget? {
return when (entity.type) { return when (entity.type) {
WeatherWidget.Type -> { WeatherWidget.Type -> {
val config: WeatherWidgetConfig = Json.decodeFromString(entity.config ?: "{}") val config: WeatherWidgetConfig =
Json.decodeFromStringOrNull(entity.config?.takeIf { it.isNotBlank() })
?: WeatherWidgetConfig()
WeatherWidget(entity.id, config) WeatherWidget(entity.id, config)
} }
MusicWidget.Type -> MusicWidget(entity.id) MusicWidget.Type -> MusicWidget(entity.id)
CalendarWidget.Type -> { CalendarWidget.Type -> {
val config: CalendarWidgetConfig = Json.decodeFromString(entity.config ?: "{}") val config: CalendarWidgetConfig =
Json.decodeFromStringOrNull(entity.config?.takeIf { it.isNotBlank() })
?: CalendarWidgetConfig()
CalendarWidget(entity.id, config) CalendarWidget(entity.id, config)
} }
FavoritesWidget.Type -> FavoritesWidget(entity.id) FavoritesWidget.Type -> FavoritesWidget(entity.id)
AppWidget.Type -> { AppWidget.Type -> {
val config: AppWidgetConfig = Json.decodeFromString(entity.config ?: "{}") val config: AppWidgetConfig =
Json.decodeFromStringOrNull(entity.config?.takeIf { it.isNotBlank() })
?: return null
AppWidget( AppWidget(
entity.id, entity.id,
config, config,
@ -99,8 +108,6 @@ data class MusicWidget(
} }
data class FavoritesWidget( data class FavoritesWidget(
override val id: UUID, override val id: UUID,
) : Widget() { ) : Widget() {