Skip to content

Commit

Permalink
Fix websocket stays subscribed after widget edit due to multiple inst…
Browse files Browse the repository at this point in the history
…ances (#2753)

* Fix websocket stays subscribed after widget edit due to multiple instances

 - When a widget is edited, the system will send a broadcast to _a new instance_ of the widget class. Because there is a websocket connection to keep widgets updated, the new instance of the class should also receive events to unsubscribe.

* Use companion object to prevent unnecessary updates

 - Only actually start listening for updates in one of the instances in order to prevent unnecessary duplicate widget updates
  • Loading branch information
jpelgrom committed Aug 3, 2022
1 parent c543aff commit 7953f81
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import android.appwidget.AppWidgetProvider
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Bundle
import android.util.Log
import android.widget.RemoteViews
Expand Down Expand Up @@ -70,14 +71,20 @@ abstract class BaseWidgetProvider : AppWidgetProvider() {

fun onScreenOn(context: Context) {
mainScope = CoroutineScope(Dispatchers.Main + Job())
if (entityUpdates == null) {
if (!isSubscribed()) {
mainScope.launch {
if (!integrationUseCase.isRegistered()) {
return@launch
}
updateAllWidgets(context)
if (getAllWidgetIds(context).isNotEmpty()) {
context.applicationContext.registerReceiver(
this@BaseWidgetProvider,
IntentFilter(Intent.ACTION_SCREEN_OFF)
)

entityUpdates = integrationUseCase.getEntityUpdates()
setSubscribed(entityUpdates != null)
entityUpdates?.collect {
onEntityStateChanged(context, it)
}
Expand All @@ -89,6 +96,7 @@ abstract class BaseWidgetProvider : AppWidgetProvider() {
private fun onScreenOff() {
mainScope.cancel()
entityUpdates = null
setSubscribed(false)
}

private suspend fun updateAllWidgets(
Expand Down Expand Up @@ -125,6 +133,8 @@ abstract class BaseWidgetProvider : AppWidgetProvider() {
}
}

abstract fun isSubscribed(): Boolean
abstract fun setSubscribed(subscribed: Boolean)
abstract fun getWidgetProvider(context: Context): ComponentName
abstract suspend fun getWidgetRemoteViews(context: Context, appWidgetId: Int, suggestedEntity: Entity<Map<String, Any>>? = null): RemoteViews
abstract suspend fun getAllWidgetIds(context: Context): List<Int>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,19 @@ class EntityWidget : BaseWidgetProvider() {
internal const val EXTRA_TEXT_COLOR = "EXTRA_TEXT_COLOR"

private data class ResolvedText(val text: CharSequence?, val exception: Boolean = false)

private var isSubscribed = false
}

@Inject
lateinit var staticWidgetDao: StaticWidgetDao

override fun isSubscribed(): Boolean = isSubscribed

override fun setSubscribed(subscribed: Boolean) {
isSubscribed = subscribed
}

override fun getWidgetProvider(context: Context): ComponentName =
ComponentName(context, EntityWidget::class.java)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ class MediaPlayerControlsWidget : BaseWidgetProvider() {
internal const val EXTRA_SHOW_SKIP = "EXTRA_INCLUDE_SKIP"
internal const val EXTRA_SHOW_SEEK = "EXTRA_INCLUDE_SEEK"
internal const val EXTRA_BACKGROUND_TYPE = "EXTRA_BACKGROUND_TYPE"

private var isSubscribed = false
}

@Inject
Expand All @@ -72,6 +74,12 @@ class MediaPlayerControlsWidget : BaseWidgetProvider() {
@Inject
lateinit var mediaPlayCtrlWidgetDao: MediaPlayerControlsWidgetDao

override fun isSubscribed(): Boolean = isSubscribed

override fun setSubscribed(subscribed: Boolean) {
isSubscribed = subscribed
}

override fun getWidgetProvider(context: Context): ComponentName =
ComponentName(context, MediaPlayerControlsWidget::class.java)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ class TemplateWidget : BaseWidgetProvider() {
internal const val EXTRA_TEXT_SIZE = "EXTRA_TEXT_SIZE"
internal const val EXTRA_BACKGROUND_TYPE = "EXTRA_BACKGROUND_TYPE"
internal const val EXTRA_TEXT_COLOR = "EXTRA_TEXT_COLOR"

private var isSubscribed = false
}

@Inject
Expand All @@ -47,6 +49,12 @@ class TemplateWidget : BaseWidgetProvider() {
}
}

override fun isSubscribed(): Boolean = isSubscribed

override fun setSubscribed(subscribed: Boolean) {
isSubscribed = subscribed
}

override fun getWidgetProvider(context: Context): ComponentName =
ComponentName(context, TemplateWidget::class.java)

Expand Down

0 comments on commit 7953f81

Please sign in to comment.