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

Commit 6a2f4e2a authored by Selim Cinek's avatar Selim Cinek Committed by Android (Google) Code Review
Browse files

Merge "Fix RegionSamplingHelper race condition" into tm-qpr-dev

parents 55d90e49 524ae21e
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -217,12 +217,16 @@ public class RegionSamplingHelper implements View.OnAttachStateChangeListener,
                unregisterSamplingListener();
                mSamplingListenerRegistered = true;
                SurfaceControl wrappedStopLayer = wrap(stopLayerControl);

                // pass this to background thread to avoid empty Rect race condition
                final Rect boundsCopy = new Rect(mSamplingRequestBounds);

                mBackgroundExecutor.execute(() -> {
                    if (wrappedStopLayer != null && !wrappedStopLayer.isValid()) {
                        return;
                    }
                    mCompositionSamplingListener.register(mSamplingListener, DEFAULT_DISPLAY,
                            wrappedStopLayer, mSamplingRequestBounds);
                            wrappedStopLayer, boundsCopy);
                });
                mRegisteredSamplingBounds.set(mSamplingRequestBounds);
                mRegisteredStopLayer = stopLayerControl;
+47 −3
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
 */

package com.android.systemui.shared.navigationbar

import android.graphics.Rect
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
@@ -24,15 +25,23 @@ import android.view.ViewRootImpl
import androidx.concurrent.futures.DirectExecutor
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.argumentCaptor
import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.ArgumentMatchers.eq
import org.mockito.Mock
import org.mockito.Mockito.*
import org.mockito.junit.MockitoJUnit
import org.mockito.Mockito.mock
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when` as whenever
import org.mockito.junit.MockitoJUnit

@RunWith(AndroidTestingRunner::class)
@SmallTest
@@ -99,4 +108,39 @@ class RegionSamplingHelperTest : SysuiTestCase() {
        regionSamplingHelper.stopAndDestroy()
        verify(compositionListener).unregister(any())
    }

    @Test
    fun testCompositionSamplingListener_has_nonEmptyRect() {
        // simulate race condition
        val fakeExecutor = FakeExecutor(FakeSystemClock()) // pass in as backgroundExecutor
        val fakeSamplingCallback = mock(RegionSamplingHelper.SamplingCallback::class.java)

        whenever(fakeSamplingCallback.isSamplingEnabled).thenReturn(true)
        whenever(wrappedSurfaceControl.isValid).thenReturn(true)

        regionSamplingHelper = object : RegionSamplingHelper(sampledView, fakeSamplingCallback,
                DirectExecutor.INSTANCE, fakeExecutor, compositionListener) {
            override fun wrap(stopLayerControl: SurfaceControl?): SurfaceControl {
                return wrappedSurfaceControl
            }
        }
        regionSamplingHelper.setWindowVisible(true)
        regionSamplingHelper.start(Rect(0, 0, 100, 100))

        // make sure background task is enqueued
        assertThat(fakeExecutor.numPending()).isEqualTo(1)

        // make sure regionSamplingHelper will have empty Rect
        whenever(fakeSamplingCallback.getSampledRegion(any())).thenReturn(Rect(0, 0, 0, 0))
        regionSamplingHelper.onLayoutChange(sampledView, 0, 0, 0, 0, 0, 0, 0, 0)

        // resume running of background thread
        fakeExecutor.runAllReady()

        // grab Rect passed into compositionSamplingListener and make sure it's not empty
        val argumentGrabber = argumentCaptor<Rect>()
        verify(compositionListener).register(any(), anyInt(), eq(wrappedSurfaceControl),
                argumentGrabber.capture())
        assertThat(argumentGrabber.value.isEmpty).isFalse()
    }
}