Remove decoration layers from hierarchy on release

Bug: 244586478
Bug: 243977698
Test: Decor layers aren't in the hierarchy after release.
Test: Old task backgrounds don't remain.
Change-Id: I28b31409069fd482bbf235ed39a16681e5b7c250
This commit is contained in:
Garfield Tan
2022-09-01 11:45:08 -07:00
parent 8055d0e9df
commit c6a2b7e299
2 changed files with 51 additions and 22 deletions

View File

@@ -66,6 +66,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
final DisplayController mDisplayController;
final ShellTaskOrganizer mTaskOrganizer;
final Supplier<SurfaceControl.Builder> mSurfaceControlBuilderSupplier;
final Supplier<SurfaceControl.Transaction> mSurfaceControlTransactionSupplier;
final Supplier<WindowContainerTransaction> mWindowContainerTransactionSupplier;
final SurfaceControlViewHostFactory mSurfaceControlViewHostFactory;
private final DisplayController.OnDisplaysChangedListener mOnDisplaysChangedListener =
@@ -104,8 +105,8 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
RunningTaskInfo taskInfo,
SurfaceControl taskSurface) {
this(context, displayController, taskOrganizer, taskInfo, taskSurface,
SurfaceControl.Builder::new, WindowContainerTransaction::new,
new SurfaceControlViewHostFactory() {});
SurfaceControl.Builder::new, SurfaceControl.Transaction::new,
WindowContainerTransaction::new, new SurfaceControlViewHostFactory() {});
}
WindowDecoration(
@@ -115,6 +116,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
RunningTaskInfo taskInfo,
SurfaceControl taskSurface,
Supplier<SurfaceControl.Builder> surfaceControlBuilderSupplier,
Supplier<SurfaceControl.Transaction> surfaceControlTransactionSupplier,
Supplier<WindowContainerTransaction> windowContainerTransactionSupplier,
SurfaceControlViewHostFactory surfaceControlViewHostFactory) {
mContext = context;
@@ -123,6 +125,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
mTaskInfo = taskInfo;
mTaskSurface = taskSurface;
mSurfaceControlBuilderSupplier = surfaceControlBuilderSupplier;
mSurfaceControlTransactionSupplier = surfaceControlTransactionSupplier;
mWindowContainerTransactionSupplier = windowContainerTransactionSupplier;
mSurfaceControlViewHostFactory = surfaceControlViewHostFactory;
@@ -320,19 +323,28 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
mCaptionWindowManager = null;
final SurfaceControl.Transaction t = mSurfaceControlTransactionSupplier.get();
boolean released = false;
if (mCaptionContainerSurface != null) {
mCaptionContainerSurface.release();
t.remove(mCaptionContainerSurface);
mCaptionContainerSurface = null;
released = true;
}
if (mDecorationContainerSurface != null) {
mDecorationContainerSurface.release();
t.remove(mDecorationContainerSurface);
mDecorationContainerSurface = null;
released = true;
}
if (mTaskBackgroundSurface != null) {
mTaskBackgroundSurface.release();
t.remove(mTaskBackgroundSurface);
mTaskBackgroundSurface = null;
released = true;
}
if (released) {
t.apply();
}
final WindowContainerTransaction wct = mWindowContainerTransactionSupplier.get();

View File

@@ -27,6 +27,7 @@ import static org.mockito.Mockito.any;
import static org.mockito.Mockito.argThat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.same;
@@ -59,6 +60,7 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InOrder;
import org.mockito.Mock;
import java.util.ArrayList;
@@ -96,6 +98,8 @@ public class WindowDecorationTests extends ShellTestCase {
@Mock
private WindowContainerTransaction mMockWindowContainerTransaction;
private final List<SurfaceControl.Transaction> mMockSurfaceControlTransactions =
new ArrayList<>();
private final List<SurfaceControl.Builder> mMockSurfaceControlBuilders = new ArrayList<>();
private SurfaceControl.Transaction mMockSurfaceControlStartT;
private SurfaceControl.Transaction mMockSurfaceControlFinishT;
@@ -265,6 +269,9 @@ public class WindowDecorationTests extends ShellTestCase {
createMockSurfaceControlBuilder(captionContainerSurface);
mMockSurfaceControlBuilders.add(captionContainerSurfaceBuilder);
final SurfaceControl.Transaction t = mock(SurfaceControl.Transaction.class);
mMockSurfaceControlTransactions.add(t);
final ActivityManager.TaskDescription.Builder taskDescriptionBuilder =
new ActivityManager.TaskDescription.Builder()
.setBackgroundColor(Color.YELLOW);
@@ -287,19 +294,19 @@ public class WindowDecorationTests extends ShellTestCase {
windowDecor.relayout(taskInfo);
verify(mMockSurfaceControlViewHost, never()).release();
verify(decorContainerSurface, never()).release();
verify(taskBackgroundSurface, never()).release();
verify(captionContainerSurface, never()).release();
verify(t, never()).apply();
verify(mMockWindowContainerTransaction, never())
.removeInsetsProvider(eq(taskInfo.token), any());
taskInfo.isVisible = false;
windowDecor.relayout(taskInfo);
verify(mMockSurfaceControlViewHost).release();
verify(decorContainerSurface).release();
verify(taskBackgroundSurface).release();
verify(captionContainerSurface).release();
final InOrder releaseOrder = inOrder(t, mMockSurfaceControlViewHost);
releaseOrder.verify(mMockSurfaceControlViewHost).release();
releaseOrder.verify(t).remove(captionContainerSurface);
releaseOrder.verify(t).remove(decorContainerSurface);
releaseOrder.verify(t).remove(taskBackgroundSurface);
releaseOrder.verify(t).apply();
verify(mMockWindowContainerTransaction).removeInsetsProvider(eq(taskInfo.token), any());
}
@@ -351,21 +358,30 @@ public class WindowDecorationTests extends ShellTestCase {
private TestWindowDecoration createWindowDecoration(
ActivityManager.RunningTaskInfo taskInfo, SurfaceControl testSurface) {
return new TestWindowDecoration(mContext, mMockDisplayController, mMockShellTaskOrganizer,
taskInfo, testSurface, new MockSurfaceControlBuilderSupplier(),
taskInfo, testSurface,
new MockObjectSupplier<>(mMockSurfaceControlBuilders,
() -> createMockSurfaceControlBuilder(mock(SurfaceControl.class))),
new MockObjectSupplier<>(mMockSurfaceControlTransactions,
() -> mock(SurfaceControl.Transaction.class)),
() -> mMockWindowContainerTransaction, mMockSurfaceControlViewHostFactory);
}
private class MockSurfaceControlBuilderSupplier implements Supplier<SurfaceControl.Builder> {
private class MockObjectSupplier<T> implements Supplier<T> {
private final List<T> mObjects;
private final Supplier<T> mDefaultSupplier;
private int mNumOfCalls = 0;
private MockObjectSupplier(List<T> objects, Supplier<T> defaultSupplier) {
mObjects = objects;
mDefaultSupplier = defaultSupplier;
}
@Override
public SurfaceControl.Builder get() {
final SurfaceControl.Builder builder =
mNumOfCalls < mMockSurfaceControlBuilders.size()
? mMockSurfaceControlBuilders.get(mNumOfCalls)
: createMockSurfaceControlBuilder(mock(SurfaceControl.class));
public T get() {
final T mock = mNumOfCalls < mObjects.size()
? mObjects.get(mNumOfCalls) : mDefaultSupplier.get();
++mNumOfCalls;
return builder;
return mock;
}
}
@@ -383,11 +399,12 @@ public class WindowDecorationTests extends ShellTestCase {
ShellTaskOrganizer taskOrganizer, ActivityManager.RunningTaskInfo taskInfo,
SurfaceControl taskSurface,
Supplier<SurfaceControl.Builder> surfaceControlBuilderSupplier,
Supplier<SurfaceControl.Transaction> surfaceControlTransactionSupplier,
Supplier<WindowContainerTransaction> windowContainerTransactionSupplier,
SurfaceControlViewHostFactory surfaceControlViewHostFactory) {
super(context, displayController, taskOrganizer, taskInfo, taskSurface,
surfaceControlBuilderSupplier, windowContainerTransactionSupplier,
surfaceControlViewHostFactory);
surfaceControlBuilderSupplier, surfaceControlTransactionSupplier,
windowContainerTransactionSupplier, surfaceControlViewHostFactory);
}
@Override