Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c0dab5c0 authored by Austin Wang's avatar Austin Wang
Browse files

Fix TimeTicker not registered when unregistering

Unregistering the `TimeTicker` could happen multiple times, and it's
happening during onDestroy. It might potentially assign ticker
without unregistering, or unregister the same ticker multiple times as well.

To fix these:
1. The unregister is happened when `onDestroy`, changed to `onPause`.
2. Prevent multiple calls to register/unregister by explicit
   registering/unregistering.

Fixes: 269196790
Test: tapping the settings entry fast
Change-Id: Ie162a095ba81ba02d24ee7225576bffc554bf27c
parent fa7c7360
Loading
Loading
Loading
Loading
+13 −6
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.core.view.isVisible
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
@@ -89,13 +90,19 @@ object ClockCarouselViewBinder {
            }
        }

        lifecycleOwner.lifecycleScope.launch {
            lifecycleOwner.repeatOnLifecycle(Lifecycle.State.RESUMED) {
                clockViewFactory.registerTimeTicker()
        lifecycleOwner.lifecycle.addObserver(
            LifecycleEventObserver { source, event ->
                when (event) {
                    Lifecycle.Event.ON_RESUME -> {
                        clockViewFactory.registerTimeTicker(source)
                    }
                    Lifecycle.Event.ON_PAUSE -> {
                        clockViewFactory.unregisterTimeTicker(source)
                    }
            // When paused
            clockViewFactory.unregisterTimeTicker()
                    else -> {}
                }
            }
        )

        return object : Binding {
            override fun show() {
+13 −6
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.widget.SeekBar
import androidx.core.view.isInvisible
import androidx.core.view.isVisible
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
@@ -170,12 +171,18 @@ object ClockSettingsBinder {
            }
        }

        lifecycleOwner.lifecycleScope.launch {
            lifecycleOwner.repeatOnLifecycle(Lifecycle.State.RESUMED) {
                clockViewFactory.registerTimeTicker()
        lifecycleOwner.lifecycle.addObserver(
            LifecycleEventObserver { source, event ->
                when (event) {
                    Lifecycle.Event.ON_RESUME -> {
                        clockViewFactory.registerTimeTicker(source)
                    }
                    Lifecycle.Event.ON_PAUSE -> {
                        clockViewFactory.unregisterTimeTicker(source)
                    }
            // When paused
            clockViewFactory.unregisterTimeTicker()
                    else -> {}
                }
            }
        )
    }
}
+15 −5
Original line number Diff line number Diff line
@@ -18,18 +18,20 @@ package com.android.customization.picker.clock.ui.view
import android.app.Activity
import android.view.View
import androidx.annotation.ColorInt
import androidx.lifecycle.LifecycleOwner
import com.android.systemui.plugins.ClockController
import com.android.systemui.shared.clocks.ClockRegistry
import com.android.wallpaper.R
import com.android.wallpaper.util.ScreenSizeCalculator
import com.android.wallpaper.util.TimeUtils.TimeTicker
import java.util.concurrent.ConcurrentHashMap

class ClockViewFactory(
    private val activity: Activity,
    private val registry: ClockRegistry,
) {
    private val timeTickListeners: ConcurrentHashMap<Int, TimeTicker> = ConcurrentHashMap()
    private val clockControllers: HashMap<String, ClockController> = HashMap()
    private var ticker: TimeTicker? = null

    fun getView(clockId: String): View {
        return (clockControllers[clockId] ?: initClockController(clockId)).largeClock.view
@@ -45,15 +47,23 @@ class ClockViewFactory(
            .onSeedColorChanged(seedColor)
    }

    fun registerTimeTicker() {
        ticker =
    fun registerTimeTicker(owner: LifecycleOwner) {
        val hashCode = owner.hashCode()
        if (timeTickListeners.keys.contains(hashCode)) {
            return
        }
        timeTickListeners[hashCode] =
            TimeTicker.registerNewReceiver(activity.applicationContext) {
                clockControllers.values.forEach { it.largeClock.events.onTimeTick() }
            }
    }

    fun unregisterTimeTicker() {
        activity.applicationContext.unregisterReceiver(ticker)
    fun unregisterTimeTicker(owner: LifecycleOwner) {
        val hashCode = owner.hashCode()
        timeTickListeners[hashCode]?.let {
            activity.applicationContext.unregisterReceiver(it)
            timeTickListeners.remove(hashCode)
        }
    }

    private fun initClockController(clockId: String): ClockController {