summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/navigationbar/RegionSamplingHelper.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shared/navigationbar/RegionSamplingHelperTest.kt50
2 files changed, 52 insertions, 4 deletions
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/navigationbar/RegionSamplingHelper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/navigationbar/RegionSamplingHelper.java
index c7d5ffe1b84c..023ef319352e 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/navigationbar/RegionSamplingHelper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/navigationbar/RegionSamplingHelper.java
@@ -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;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/navigationbar/RegionSamplingHelperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/navigationbar/RegionSamplingHelperTest.kt
index 8bc438bce5cc..5fc09c7d5563 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/navigationbar/RegionSamplingHelperTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/navigationbar/RegionSamplingHelperTest.kt
@@ -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())
}
-} \ No newline at end of file
+
+ @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()
+ }
+}