diff --git a/packages/SystemUI/src/com/android/systemui/communal/service/CommunalSurfaceViewController.java b/packages/SystemUI/src/com/android/systemui/communal/service/CommunalSurfaceViewController.java index 15cd7071d8d2a..07ba830bb3053 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/service/CommunalSurfaceViewController.java +++ b/packages/SystemUI/src/com/android/systemui/communal/service/CommunalSurfaceViewController.java @@ -51,6 +51,9 @@ public class CommunalSurfaceViewController extends ViewController { private int mCurrentState; + // The current in-flight request for a surface package. + private ListenableFuture mCurrentSurfaceFuture; + private final SurfaceHolder.Callback mSurfaceHolderCallback = new SurfaceHolder.Callback() { @Override public void surfaceCreated(@NonNull SurfaceHolder holder) { @@ -99,20 +102,30 @@ public class CommunalSurfaceViewController extends ViewController { mCurrentState = newState; - if (newState == STATE_CAN_SHOW_SURFACE) { - showSurface(); - } + showSurface(newState == STATE_CAN_SHOW_SURFACE); } - private void showSurface() { + private void showSurface(boolean show) { mView.setWillNotDraw(false); - final ListenableFuture surfaceFuture = - mSource.requestCommunalSurface(mView.getHostToken(), + if (!show) { + // If the surface is no longer showing, cancel any in-flight requests. + if (mCurrentSurfaceFuture != null) { + mCurrentSurfaceFuture.cancel(true); + mCurrentSurfaceFuture = null; + } + + mView.setWillNotDraw(true); + return; + } + + // Since this method is only called when the state has changed, mCurrentSurfaceFuture should + // be null here. + mCurrentSurfaceFuture = mSource.requestCommunalSurface(mView.getHostToken(), mView.getDisplay().getDisplayId(), mView.getMeasuredWidth(), mView.getMeasuredHeight()); - surfaceFuture.addListener(new Runnable() { + mCurrentSurfaceFuture.addListener(new Runnable() { @Override public void run() { try { @@ -121,7 +134,9 @@ public class CommunalSurfaceViewController extends ViewController { return; } - SurfaceControlViewHost.SurfacePackage surfacePackage = surfaceFuture.get(); + SurfaceControlViewHost.SurfacePackage surfacePackage = + mCurrentSurfaceFuture.get(); + mCurrentSurfaceFuture = null; if (DEBUG) { Log.d(TAG, "Received surface package:" + surfacePackage); diff --git a/packages/SystemUI/tests/src/com/android/systemui/communal/service/CommunalSurfaceViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/communal/service/CommunalSurfaceViewControllerTest.java index 8a2f7361eb1ee..a9e85cc005580 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/communal/service/CommunalSurfaceViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/communal/service/CommunalSurfaceViewControllerTest.java @@ -16,8 +16,10 @@ package com.android.systemui.communal.service; +import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -109,6 +111,8 @@ public class CommunalSurfaceViewControllerTest extends SysuiTestCase { verify(mCommunalSource, times(0)) .requestCommunalSurface(any(), anyInt(), anyInt(), anyInt()); + clearInvocations(mSurfaceView); + // Request surface view once all conditions are met. mCallback.surfaceCreated(mSurfaceHolder); verify(mCommunalSource) @@ -126,4 +130,45 @@ public class CommunalSurfaceViewControllerTest extends SysuiTestCase { verify(mSurfaceView).setZOrderOnTop(true); verify(mSurfaceView).setWillNotDraw(false); } + + // Invoked to setup surface view package. + private void givenSurfacePresent() { + mController.onViewAttached(); + mCallback.surfaceCreated(mSurfaceHolder); + when(mSurfaceView.isAttachedToWindow()).thenReturn(true); + mPackageFuture.set(mSurfacePackage); + mFakeExecutor.runAllReady(); + clearInvocations(mSurfaceView); + } + + @Test + public void testClearOnDetach() { + givenSurfacePresent(); + when(mSurfaceView.isAttachedToWindow()).thenReturn(false); + mController.onViewDetached(); + verify(mSurfaceView).setWillNotDraw(true); + } + + @Test + public void testClearOnSurfaceDestroyed() { + givenSurfacePresent(); + mCallback.surfaceDestroyed(mSurfaceHolder); + verify(mSurfaceView).setWillNotDraw(true); + } + + @Test + public void testCancelRequest() { + mController.onViewAttached(); + mCallback.surfaceCreated(mSurfaceHolder); + when(mSurfaceView.isAttachedToWindow()).thenReturn(true); + mFakeExecutor.runAllReady(); + clearInvocations(mSurfaceView); + + verify(mCommunalSource, times(1)) + .requestCommunalSurface(mHostToken, DISPLAY_ID, MEASURED_WIDTH, MEASURED_HEIGHT); + + mController.onViewDetached(); + assertTrue(mPackageFuture.isCancelled()); + verify(mSurfaceView).setWillNotDraw(true); + } }