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

Commit 6caa0a64 authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Fix OOM of metro clock" into udc-qpr-dev am: d756cad8 am: 9958d631

parents c109edfe 9958d631
Loading
Loading
Loading
Loading
+51 −18
Original line number Original line Diff line number Diff line
@@ -26,6 +26,7 @@ import android.util.TypedValue
import android.view.View
import android.view.View
import android.view.View.OnAttachStateChangeListener
import android.view.View.OnAttachStateChangeListener
import android.view.ViewTreeObserver
import android.view.ViewTreeObserver
import android.view.ViewTreeObserver.OnGlobalLayoutListener
import android.widget.FrameLayout
import android.widget.FrameLayout
import androidx.annotation.VisibleForTesting
import androidx.annotation.VisibleForTesting
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.Lifecycle
@@ -88,6 +89,15 @@ constructor(
) {
) {
    var clock: ClockController? = null
    var clock: ClockController? = null
        set(value) {
        set(value) {
            smallClockOnAttachStateChangeListener?.let {
                field?.smallClock?.view?.removeOnAttachStateChangeListener(it)
                smallClockFrame?.viewTreeObserver
                        ?.removeOnGlobalLayoutListener(onGlobalLayoutListener)
            }
            largeClockOnAttachStateChangeListener?.let {
                field?.largeClock?.view?.removeOnAttachStateChangeListener(it)
            }

            field = value
            field = value
            if (value != null) {
            if (value != null) {
                smallLogBuffer?.log(TAG, DEBUG, {}, { "New Clock" })
                smallLogBuffer?.log(TAG, DEBUG, {}, { "New Clock" })
@@ -130,44 +140,62 @@ constructor(
                    }
                    }
                    value.events.onWeatherDataChanged(it)
                    value.events.onWeatherDataChanged(it)
                }
                }
                value.smallClock.view.addOnAttachStateChangeListener(

                smallClockOnAttachStateChangeListener =
                    object : OnAttachStateChangeListener {
                    object : OnAttachStateChangeListener {
                        var pastVisibility: Int? = null
                        var pastVisibility: Int? = null
                        override fun onViewAttachedToWindow(view: View?) {
                        override fun onViewAttachedToWindow(view: View?) {
                            value.events.onTimeFormatChanged(DateFormat.is24HourFormat(context))
                            value.events.onTimeFormatChanged(DateFormat.is24HourFormat(context))
                            if (view != null) {
                            if (view != null) {
                                val smallClockFrame = view.parent as FrameLayout
                                smallClockFrame = view.parent as FrameLayout
                                pastVisibility = smallClockFrame.visibility
                                smallClockFrame?.let {frame ->
                                smallClockFrame.viewTreeObserver.addOnGlobalLayoutListener(
                                    pastVisibility = frame.visibility
                                        ViewTreeObserver.OnGlobalLayoutListener {
                                    onGlobalLayoutListener = OnGlobalLayoutListener {
                                    val currentVisibility = smallClockFrame.visibility
                                        val currentVisibility = frame.visibility
                                        if (pastVisibility != currentVisibility) {
                                        if (pastVisibility != currentVisibility) {
                                            pastVisibility = currentVisibility
                                            pastVisibility = currentVisibility
                                        // when small clock  visible, recalculate bounds and sample
                                            // when small clock  visible,
                                            // recalculate bounds and sample
                                            if (currentVisibility == View.VISIBLE) {
                                            if (currentVisibility == View.VISIBLE) {
                                                smallRegionSampler?.stopRegionSampler()
                                                smallRegionSampler?.stopRegionSampler()
                                                smallRegionSampler?.startRegionSampler()
                                                smallRegionSampler?.startRegionSampler()
                                            }
                                            }
                                        }
                                        }
                                })
                                    }
                                    frame.viewTreeObserver
                                            .addOnGlobalLayoutListener(onGlobalLayoutListener)
                                }
                            }
                            }
                        }
                        }


                        override fun onViewDetachedFromWindow(p0: View?) {
                        override fun onViewDetachedFromWindow(p0: View?) {
                            smallClockFrame?.viewTreeObserver
                                    ?.removeOnGlobalLayoutListener(onGlobalLayoutListener)
                        }
                }
                }
                })
                value.smallClock.view
                value.largeClock.view.addOnAttachStateChangeListener(
                        .addOnAttachStateChangeListener(smallClockOnAttachStateChangeListener)

                largeClockOnAttachStateChangeListener =
                    object : OnAttachStateChangeListener {
                    object : OnAttachStateChangeListener {
                        override fun onViewAttachedToWindow(p0: View?) {
                        override fun onViewAttachedToWindow(p0: View?) {
                            value.events.onTimeFormatChanged(DateFormat.is24HourFormat(context))
                            value.events.onTimeFormatChanged(DateFormat.is24HourFormat(context))
                        }
                        }

                        override fun onViewDetachedFromWindow(p0: View?) {
                        override fun onViewDetachedFromWindow(p0: View?) {
                        }
                        }
                })
                }
                value.largeClock.view
                        .addOnAttachStateChangeListener(largeClockOnAttachStateChangeListener)
            }
            }
        }
        }


    @VisibleForTesting
    var smallClockOnAttachStateChangeListener: OnAttachStateChangeListener? = null
    @VisibleForTesting
    var largeClockOnAttachStateChangeListener: OnAttachStateChangeListener? = null
    private var smallClockFrame: FrameLayout? = null
    private var onGlobalLayoutListener: OnGlobalLayoutListener? = null

    private var isDozing = false
    private var isDozing = false
        private set
        private set


@@ -307,7 +335,6 @@ constructor(
            return
            return
        }
        }
        isRegistered = true
        isRegistered = true

        broadcastDispatcher.registerReceiver(
        broadcastDispatcher.registerReceiver(
            localeBroadcastReceiver,
            localeBroadcastReceiver,
            IntentFilter(Intent.ACTION_LOCALE_CHANGED)
            IntentFilter(Intent.ACTION_LOCALE_CHANGED)
@@ -346,6 +373,12 @@ constructor(
        largeRegionSampler?.stopRegionSampler()
        largeRegionSampler?.stopRegionSampler()
        smallTimeListener?.stop()
        smallTimeListener?.stop()
        largeTimeListener?.stop()
        largeTimeListener?.stop()
        clock?.smallClock?.view
                ?.removeOnAttachStateChangeListener(smallClockOnAttachStateChangeListener)
        smallClockFrame?.viewTreeObserver
                ?.removeOnGlobalLayoutListener(onGlobalLayoutListener)
        clock?.largeClock?.view
                ?.removeOnAttachStateChangeListener(largeClockOnAttachStateChangeListener)
    }
    }


    private fun updateTimeListeners() {
    private fun updateTimeListeners() {
+44 −3
Original line number Original line Diff line number Diff line
@@ -18,7 +18,8 @@ package com.android.keyguard
import android.content.BroadcastReceiver
import android.content.BroadcastReceiver
import android.testing.AndroidTestingRunner
import android.testing.AndroidTestingRunner
import android.view.View
import android.view.View
import android.widget.TextView
import android.view.ViewTreeObserver
import android.widget.FrameLayout
import androidx.test.filters.SmallTest
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.SysuiTestCase
import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository
@@ -83,7 +84,13 @@ class ClockEventControllerTest : SysuiTestCase() {
    @Mock private lateinit var bgExecutor: Executor
    @Mock private lateinit var bgExecutor: Executor
    @Mock private lateinit var featureFlags: FeatureFlags
    @Mock private lateinit var featureFlags: FeatureFlags
    @Mock private lateinit var smallClockController: ClockFaceController
    @Mock private lateinit var smallClockController: ClockFaceController
    @Mock private lateinit var smallClockView: View
    @Mock private lateinit var smallClockViewTreeObserver: ViewTreeObserver
    @Mock private lateinit var smallClockFrame: FrameLayout
    @Mock private lateinit var smallClockFrameViewTreeObserver: ViewTreeObserver
    @Mock private lateinit var largeClockController: ClockFaceController
    @Mock private lateinit var largeClockController: ClockFaceController
    @Mock private lateinit var largeClockView: View
    @Mock private lateinit var largeClockViewTreeObserver: ViewTreeObserver
    @Mock private lateinit var smallClockEvents: ClockFaceEvents
    @Mock private lateinit var smallClockEvents: ClockFaceEvents
    @Mock private lateinit var largeClockEvents: ClockFaceEvents
    @Mock private lateinit var largeClockEvents: ClockFaceEvents
    @Mock private lateinit var parentView: View
    @Mock private lateinit var parentView: View
@@ -99,8 +106,12 @@ class ClockEventControllerTest : SysuiTestCase() {
    fun setUp() {
    fun setUp() {
        whenever(clock.smallClock).thenReturn(smallClockController)
        whenever(clock.smallClock).thenReturn(smallClockController)
        whenever(clock.largeClock).thenReturn(largeClockController)
        whenever(clock.largeClock).thenReturn(largeClockController)
        whenever(smallClockController.view).thenReturn(TextView(context))
        whenever(smallClockController.view).thenReturn(smallClockView)
        whenever(largeClockController.view).thenReturn(TextView(context))
        whenever(smallClockView.parent).thenReturn(smallClockFrame)
        whenever(smallClockView.viewTreeObserver).thenReturn(smallClockViewTreeObserver)
        whenever(smallClockFrame.viewTreeObserver).thenReturn(smallClockFrameViewTreeObserver)
        whenever(largeClockController.view).thenReturn(largeClockView)
        whenever(largeClockView.viewTreeObserver).thenReturn(largeClockViewTreeObserver)
        whenever(smallClockController.events).thenReturn(smallClockEvents)
        whenever(smallClockController.events).thenReturn(smallClockEvents)
        whenever(largeClockController.events).thenReturn(largeClockEvents)
        whenever(largeClockController.events).thenReturn(largeClockEvents)
        whenever(clock.events).thenReturn(events)
        whenever(clock.events).thenReturn(events)
@@ -302,6 +313,36 @@ class ClockEventControllerTest : SysuiTestCase() {
        verify(configurationController).removeCallback(any())
        verify(configurationController).removeCallback(any())
        verify(batteryController).removeCallback(any())
        verify(batteryController).removeCallback(any())
        verify(keyguardUpdateMonitor).removeCallback(any())
        verify(keyguardUpdateMonitor).removeCallback(any())
        verify(smallClockController.view)
                .removeOnAttachStateChangeListener(underTest.smallClockOnAttachStateChangeListener)
        verify(largeClockController.view)
                .removeOnAttachStateChangeListener(underTest.largeClockOnAttachStateChangeListener)
    }

    @Test
    fun registerOnAttachStateChangeListener_validate() = runBlocking(IMMEDIATE) {
        verify(smallClockController.view)
            .addOnAttachStateChangeListener(underTest.smallClockOnAttachStateChangeListener)
        verify(largeClockController.view)
            .addOnAttachStateChangeListener(underTest.largeClockOnAttachStateChangeListener)
    }

    @Test
    fun registerAndRemoveOnGlobalLayoutListener_correctly() = runBlocking(IMMEDIATE) {
        underTest.smallClockOnAttachStateChangeListener!!.onViewAttachedToWindow(smallClockView)
        verify(smallClockFrame.viewTreeObserver).addOnGlobalLayoutListener(any())
        underTest.smallClockOnAttachStateChangeListener!!.onViewDetachedFromWindow(smallClockView)
        verify(smallClockFrame.viewTreeObserver).removeOnGlobalLayoutListener(any())
    }

    @Test
    fun registerOnGlobalLayoutListener_RemoveOnAttachStateChangeListener_correctly() =
        runBlocking(IMMEDIATE) {
            underTest.smallClockOnAttachStateChangeListener!!
                .onViewAttachedToWindow(smallClockView)
            verify(smallClockFrame.viewTreeObserver).addOnGlobalLayoutListener(any())
            underTest.unregisterListeners()
            verify(smallClockFrame.viewTreeObserver).removeOnGlobalLayoutListener(any())
        }
        }


    companion object {
    companion object {