From bd7df4f6a04d92240a4e40c3c807cc6c9c10d70d Mon Sep 17 00:00:00 2001 From: Josia Pietsch Date: Sat, 17 May 2025 12:12:03 +0200 Subject: [PATCH] (try to) fix #172 --- .../launcher/preferences/Preferences.kt | 12 ++++-- .../launcher/preferences/legacy/Version100.kt | 39 +++++++++++++++++++ .../launcher/preferences/legacy/Version4.kt | 5 ++- .../widgets/manage/ManageWidgetsActivity.kt | 4 -- .../ui/widgets/manage/SelectWidgetActivity.kt | 12 +++--- .../android/launcher/widgets/ClockWidget.kt | 2 +- .../launcher/widgets/DebugInfoWidget.kt | 2 +- .../jrpie/android/launcher/widgets/Widget.kt | 4 +- .../jrpie/android/launcher/widgets/Widgets.kt | 17 +++++--- 9 files changed, 72 insertions(+), 25 deletions(-) create mode 100644 app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version100.kt diff --git a/app/src/main/java/de/jrpie/android/launcher/preferences/Preferences.kt b/app/src/main/java/de/jrpie/android/launcher/preferences/Preferences.kt index 8936675..e5877f5 100644 --- a/app/src/main/java/de/jrpie/android/launcher/preferences/Preferences.kt +++ b/app/src/main/java/de/jrpie/android/launcher/preferences/Preferences.kt @@ -10,6 +10,7 @@ import de.jrpie.android.launcher.apps.AbstractAppInfo.Companion.INVALID_USER import de.jrpie.android.launcher.apps.AppInfo import de.jrpie.android.launcher.apps.DetailedAppInfo import de.jrpie.android.launcher.preferences.legacy.migratePreferencesFromVersion1 +import de.jrpie.android.launcher.preferences.legacy.migratePreferencesFromVersion100 import de.jrpie.android.launcher.preferences.legacy.migratePreferencesFromVersion2 import de.jrpie.android.launcher.preferences.legacy.migratePreferencesFromVersion3 import de.jrpie.android.launcher.preferences.legacy.migratePreferencesFromVersion4 @@ -21,12 +22,13 @@ import de.jrpie.android.launcher.widgets.DebugInfoWidget import de.jrpie.android.launcher.widgets.WidgetPanel import de.jrpie.android.launcher.widgets.WidgetPosition import de.jrpie.android.launcher.widgets.deleteAllWidgets +import de.jrpie.android.launcher.widgets.generateInternalId /* Current version of the structure of preferences. * Increase when breaking changes are introduced and write an appropriate case in * `migratePreferencesToNewVersion` */ -const val PREFERENCE_VERSION = 100 +const val PREFERENCE_VERSION = 101 const val UNKNOWN_PREFERENCE_VERSION = -1 private const val TAG = "Launcher - Preferences" @@ -65,6 +67,10 @@ fun migratePreferencesToNewVersion(context: Context) { migratePreferencesFromVersion4(context) Log.i(TAG, "migration of preferences complete (4 -> ${PREFERENCE_VERSION}).") } + 100 -> { + migratePreferencesFromVersion100(context) + Log.i(TAG, "migration of preferences complete (100 -> ${PREFERENCE_VERSION}).") + } else -> { Log.w( @@ -91,7 +97,7 @@ fun resetPreferences(context: Context) { LauncherPreferences.widgets().widgets( setOf( ClockWidget( - (context.applicationContext as Application).appWidgetHost.allocateAppWidgetId(), + generateInternalId(), WidgetPosition(1, 3, 10, 4), WidgetPanel.HOME.id ) @@ -103,7 +109,7 @@ fun resetPreferences(context: Context) { LauncherPreferences.widgets().widgets().also { it.add( DebugInfoWidget( - (context.applicationContext as Application).appWidgetHost.allocateAppWidgetId(), + generateInternalId(), WidgetPosition(1, 1, 10, 4), WidgetPanel.HOME.id ) diff --git a/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version100.kt b/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version100.kt new file mode 100644 index 0000000..43e4bc7 --- /dev/null +++ b/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version100.kt @@ -0,0 +1,39 @@ +package de.jrpie.android.launcher.preferences.legacy + +import android.content.Context +import de.jrpie.android.launcher.Application +import de.jrpie.android.launcher.preferences.LauncherPreferences +import de.jrpie.android.launcher.preferences.PREFERENCE_VERSION +import de.jrpie.android.launcher.widgets.ClockWidget +import de.jrpie.android.launcher.widgets.DebugInfoWidget +import de.jrpie.android.launcher.widgets.generateInternalId +import de.jrpie.android.launcher.widgets.updateWidget + +fun migratePreferencesFromVersion100(context: Context) { + assert(PREFERENCE_VERSION == 101) + assert(LauncherPreferences.internal().versionCode() == 100) + + val widgets = LauncherPreferences.widgets().widgets() ?: setOf() + widgets.forEach { widget -> + when (widget) { + is ClockWidget -> { + val id = widget.id + val newId = generateInternalId() + (context.applicationContext as Application).appWidgetHost.deleteAppWidgetId(id) + widget.delete(context) + widget.id = newId + updateWidget(widget) + } + is DebugInfoWidget -> { + val id = widget.id + val newId = generateInternalId() + (context.applicationContext as Application).appWidgetHost.deleteAppWidgetId(id) + widget.delete(context) + widget.id = newId + updateWidget(widget) + } + else -> {} + } + } + LauncherPreferences.internal().versionCode(101) +} \ No newline at end of file diff --git a/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version4.kt b/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version4.kt index a9ab3a1..b13978b 100644 --- a/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version4.kt +++ b/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version4.kt @@ -7,19 +7,20 @@ import de.jrpie.android.launcher.preferences.PREFERENCE_VERSION import de.jrpie.android.launcher.widgets.ClockWidget import de.jrpie.android.launcher.widgets.WidgetPanel import de.jrpie.android.launcher.widgets.WidgetPosition +import de.jrpie.android.launcher.widgets.generateInternalId fun migratePreferencesFromVersion4(context: Context) { - assert(PREFERENCE_VERSION == 100) assert(LauncherPreferences.internal().versionCode() < 100) LauncherPreferences.widgets().widgets( setOf( ClockWidget( - (context.applicationContext as Application).appWidgetHost.allocateAppWidgetId(), + generateInternalId(), WidgetPosition(1, 3, 10, 4), WidgetPanel.HOME.id ) ) ) LauncherPreferences.internal().versionCode(100) + migratePreferencesFromVersion100(context) } \ No newline at end of file diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/widgets/manage/ManageWidgetsActivity.kt b/app/src/main/java/de/jrpie/android/launcher/ui/widgets/manage/ManageWidgetsActivity.kt index 984df85..953fc28 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/widgets/manage/ManageWidgetsActivity.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/widgets/manage/ManageWidgetsActivity.kt @@ -135,10 +135,6 @@ class ManageWidgetsActivity : UIObject, Activity() { val appWidgetHost = (application as Application).appWidgetHost startActivityForResult( Intent(this, SelectWidgetActivity::class.java).also { - it.putExtra( - AppWidgetManager.EXTRA_APPWIDGET_ID, - appWidgetHost.allocateAppWidgetId() - ) it.putExtra( EXTRA_PANEL_ID, panelId diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/widgets/manage/SelectWidgetActivity.kt b/app/src/main/java/de/jrpie/android/launcher/ui/widgets/manage/SelectWidgetActivity.kt index 0efdb43..eeb98df 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/widgets/manage/SelectWidgetActivity.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/widgets/manage/SelectWidgetActivity.kt @@ -14,6 +14,7 @@ import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView +import de.jrpie.android.launcher.Application import de.jrpie.android.launcher.R import de.jrpie.android.launcher.databinding.ActivitySelectWidgetBinding import de.jrpie.android.launcher.ui.UIObject @@ -24,7 +25,7 @@ import de.jrpie.android.launcher.widgets.LauncherWidgetProvider import de.jrpie.android.launcher.widgets.WidgetPanel import de.jrpie.android.launcher.widgets.WidgetPosition import de.jrpie.android.launcher.widgets.bindAppWidgetOrRequestPermission -import de.jrpie.android.launcher.widgets.getAppWidgetHost +import de.jrpie.android.launcher.widgets.generateInternalId import de.jrpie.android.launcher.widgets.getAppWidgetProviders import de.jrpie.android.launcher.widgets.updateWidget @@ -38,12 +39,13 @@ private const val REQUEST_WIDGET_PERMISSION = 29 */ class SelectWidgetActivity : AppCompatActivity(), UIObject { lateinit var binding: ActivitySelectWidgetBinding - var widgetId: Int = -1 var widgetPanelId: Int = WidgetPanel.HOME.id private fun tryBindWidget(info: LauncherWidgetProvider) { when (info) { is LauncherAppWidgetProvider -> { + val widgetId = + (applicationContext as Application).appWidgetHost.allocateAppWidgetId() if (bindAppWidgetOrRequestPermission( this, info.info, @@ -62,7 +64,7 @@ class SelectWidgetActivity : AppCompatActivity(), UIObject { } } is LauncherClockWidgetProvider -> { - updateWidget(ClockWidget(widgetId, WidgetPosition(0, 4, 12, 3), widgetPanelId)) + updateWidget(ClockWidget(generateInternalId(), WidgetPosition(0, 4, 12, 3), widgetPanelId)) finish() } } @@ -81,11 +83,7 @@ class SelectWidgetActivity : AppCompatActivity(), UIObject { setContentView(binding.root) - widgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1) widgetPanelId = intent.getIntExtra(EXTRA_PANEL_ID, WidgetPanel.HOME.id) - if (widgetId == -1) { - widgetId = getAppWidgetHost().allocateAppWidgetId() - } val viewManager = LinearLayoutManager(this) val viewAdapter = SelectWidgetRecyclerAdapter() diff --git a/app/src/main/java/de/jrpie/android/launcher/widgets/ClockWidget.kt b/app/src/main/java/de/jrpie/android/launcher/widgets/ClockWidget.kt index d0d1c0e..f864ee8 100644 --- a/app/src/main/java/de/jrpie/android/launcher/widgets/ClockWidget.kt +++ b/app/src/main/java/de/jrpie/android/launcher/widgets/ClockWidget.kt @@ -12,7 +12,7 @@ import kotlinx.serialization.Serializable @Serializable @SerialName("widget:clock") class ClockWidget( - override val id: Int, + override var id: Int, override var position: WidgetPosition, override val panelId: Int, override var allowInteraction: Boolean = true diff --git a/app/src/main/java/de/jrpie/android/launcher/widgets/DebugInfoWidget.kt b/app/src/main/java/de/jrpie/android/launcher/widgets/DebugInfoWidget.kt index 01ecddc..75ae6d0 100644 --- a/app/src/main/java/de/jrpie/android/launcher/widgets/DebugInfoWidget.kt +++ b/app/src/main/java/de/jrpie/android/launcher/widgets/DebugInfoWidget.kt @@ -12,7 +12,7 @@ import kotlinx.serialization.Serializable @Serializable @SerialName("widget:debuginfo") class DebugInfoWidget( - override val id: Int, + override var id: Int, override var position: WidgetPosition, override val panelId: Int, override var allowInteraction: Boolean = true diff --git a/app/src/main/java/de/jrpie/android/launcher/widgets/Widget.kt b/app/src/main/java/de/jrpie/android/launcher/widgets/Widget.kt index 28539a2..fd96f14 100644 --- a/app/src/main/java/de/jrpie/android/launcher/widgets/Widget.kt +++ b/app/src/main/java/de/jrpie/android/launcher/widgets/Widget.kt @@ -27,7 +27,9 @@ sealed class Widget { abstract fun configure(activity: Activity, requestCode: Int) fun delete(context: Context) { - context.getAppWidgetHost().deleteAppWidgetId(id) + if (id >= 0) { + context.getAppWidgetHost().deleteAppWidgetId(id) + } LauncherPreferences.widgets().widgets( LauncherPreferences.widgets().widgets()?.also { diff --git a/app/src/main/java/de/jrpie/android/launcher/widgets/Widgets.kt b/app/src/main/java/de/jrpie/android/launcher/widgets/Widgets.kt index cded50c..593f3b3 100644 --- a/app/src/main/java/de/jrpie/android/launcher/widgets/Widgets.kt +++ b/app/src/main/java/de/jrpie/android/launcher/widgets/Widgets.kt @@ -13,6 +13,7 @@ import android.os.UserManager import android.util.Log import de.jrpie.android.launcher.Application import de.jrpie.android.launcher.preferences.LauncherPreferences +import kotlin.math.min fun deleteAllWidgets(context: Context) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { @@ -29,12 +30,9 @@ fun deleteAllWidgets(context: Context) { * * @return true iff the app widget was bound successfully. */ -fun bindAppWidgetOrRequestPermission(activity: Activity, providerInfo: AppWidgetProviderInfo, id: Int, requestCode: Int? = null): Boolean { - val appWidgetId = if(id == -1) { - activity.getAppWidgetHost().allocateAppWidgetId() - } else { id } +fun bindAppWidgetOrRequestPermission(activity: Activity, providerInfo: AppWidgetProviderInfo, appWidgetId: Int, requestCode: Int? = null): Boolean { - Log.i("Launcher", "Binding new widget ${appWidgetId}") + Log.i("Launcher", "Binding new widget $appWidgetId") if (!activity.getAppWidgetManager().bindAppWidgetIdIfAllowed( appWidgetId, providerInfo.provider @@ -79,6 +77,13 @@ fun updateWidget(widget: Widget) { ) } + +// TODO: this needs to be improved +fun generateInternalId(): Int { + val minId = min(-5,(LauncherPreferences.widgets().widgets() ?: setOf()).minOfOrNull { it.id } ?: 0) + return minId -1 +} + fun updateWidgetPanel(widgetPanel: WidgetPanel) { LauncherPreferences.widgets().customPanels( (LauncherPreferences.widgets().customPanels() ?: setOf()) @@ -92,4 +97,4 @@ fun Context.getAppWidgetHost(): AppWidgetHost { } fun Context.getAppWidgetManager(): AppWidgetManager { return (this.applicationContext as Application).appWidgetManager -} +} \ No newline at end of file