From fb87ab20f96c5dd979e57d5e4b2c811d4e7cf863 Mon Sep 17 00:00:00 2001 From: MM20 <15646950+MM2-0@users.noreply.github.com> Date: Fri, 14 Apr 2023 00:33:00 +0200 Subject: [PATCH] Fix crash when widget config deserialization fails --- core/ktx/build.gradle.kts | 1 + .../main/java/de/mm20/launcher2/ktx/Json.kt | 14 +++++++++++++ .../java/de/mm20/launcher2/widgets/Widget.kt | 21 ++++++++++++------- 3 files changed, 29 insertions(+), 7 deletions(-) create mode 100644 core/ktx/src/main/java/de/mm20/launcher2/ktx/Json.kt diff --git a/core/ktx/build.gradle.kts b/core/ktx/build.gradle.kts index 945545a5..c2285719 100644 --- a/core/ktx/build.gradle.kts +++ b/core/ktx/build.gradle.kts @@ -42,6 +42,7 @@ dependencies { implementation(libs.androidx.appcompat) implementation(libs.bundles.androidx.lifecycle) implementation(libs.commons.text) + implementation(libs.kotlinx.serialization.json) testImplementation(libs.bundles.tests) diff --git a/core/ktx/src/main/java/de/mm20/launcher2/ktx/Json.kt b/core/ktx/src/main/java/de/mm20/launcher2/ktx/Json.kt new file mode 100644 index 00000000..f28ed514 --- /dev/null +++ b/core/ktx/src/main/java/de/mm20/launcher2/ktx/Json.kt @@ -0,0 +1,14 @@ +package de.mm20.launcher2.ktx + +import kotlinx.serialization.SerializationException +import kotlinx.serialization.json.Json +import kotlinx.serialization.decodeFromString + +inline fun Json.decodeFromStringOrNull(json: String?): T? { + if (json == null) return null + return try { + decodeFromString(json) + } catch (e: SerializationException) { + null + } +} \ No newline at end of file diff --git a/data/widgets/src/main/java/de/mm20/launcher2/widgets/Widget.kt b/data/widgets/src/main/java/de/mm20/launcher2/widgets/Widget.kt index f579759f..d915c9f9 100644 --- a/data/widgets/src/main/java/de/mm20/launcher2/widgets/Widget.kt +++ b/data/widgets/src/main/java/de/mm20/launcher2/widgets/Widget.kt @@ -6,10 +6,10 @@ import android.appwidget.AppWidgetManager import android.content.ComponentName import android.content.Context import android.content.Intent -import de.mm20.launcher2.database.entities.WidgetEntity 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 kotlinx.serialization.decodeFromString import kotlinx.serialization.json.Json import java.util.UUID @@ -28,6 +28,7 @@ sealed class Widget { ) } } + abstract fun toDatabaseEntity(): PartialWidgetEntity open val isConfigurable: Boolean = false @@ -37,17 +38,25 @@ sealed class Widget { fun fromDatabaseEntity(context: Context, entity: WidgetEntity): Widget? { return when (entity.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) } + MusicWidget.Type -> MusicWidget(entity.id) CalendarWidget.Type -> { - val config: CalendarWidgetConfig = Json.decodeFromString(entity.config ?: "{}") + val config: CalendarWidgetConfig = + Json.decodeFromStringOrNull(entity.config?.takeIf { it.isNotBlank() }) + ?: CalendarWidgetConfig() CalendarWidget(entity.id, config) } + FavoritesWidget.Type -> FavoritesWidget(entity.id) AppWidget.Type -> { - val config: AppWidgetConfig = Json.decodeFromString(entity.config ?: "{}") + val config: AppWidgetConfig = + Json.decodeFromStringOrNull(entity.config?.takeIf { it.isNotBlank() }) + ?: return null AppWidget( entity.id, config, @@ -99,8 +108,6 @@ data class MusicWidget( } - - data class FavoritesWidget( override val id: UUID, ) : Widget() {