Merge "BLASTSyncEngine: Child Window Support" into rvc-dev

This commit is contained in:
Rob Carr
2020-03-15 20:42:33 +00:00
committed by Android (Google) Code Review
3 changed files with 74 additions and 11 deletions

View File

@@ -2461,6 +2461,19 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
mWaitingSyncId = -1;
}
/**
* Returns true if any of the children elected to participate in the Sync
*/
boolean addChildrenToSyncSet(int localId) {
boolean willSync = false;
for (int i = 0; i < mChildren.size(); i++) {
final WindowContainer child = mChildren.get(i);
willSync |= mBLASTSyncEngine.addToSyncSet(localId, child);
}
return willSync;
}
boolean prepareForSync(BLASTSyncEngine.TransactionReadyListener waitingListener,
int waitingId) {
boolean willSync = false;
@@ -2469,16 +2482,12 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
}
mUsingBLASTSyncTransaction = true;
int localId = mBLASTSyncEngine.startSyncSet(this);
for (int i = 0; i < mChildren.size(); i++) {
final WindowContainer child = mChildren.get(i);
willSync = mBLASTSyncEngine.addToSyncSet(localId, child) | willSync;
}
// Make sure to set these before we call setReady in case the sync was a no-op
mWaitingSyncId = waitingId;
mWaitingListener = waitingListener;
int localId = mBLASTSyncEngine.startSyncSet(this);
willSync |= addChildrenToSyncSet(localId);
mBLASTSyncEngine.setReady(localId);
return willSync;

View File

@@ -679,6 +679,15 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
*/
int mFrameRateSelectionPriority = RefreshRatePolicy.LAYER_PRIORITY_UNSET;
/**
* BLASTSyncEngine ID corresponding to a sync-set for all
* our children. We add our children to this set in Sync,
* but we save it and don't mark it as ready until finishDrawing
* this way we have a two way latch between all our children finishing
* and drawing ourselves.
*/
private int mLocalSyncId = -1;
static final int BLAST_TIMEOUT_DURATION = 5000; /* milliseconds */
/**
@@ -5684,11 +5693,13 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
@Override
boolean prepareForSync(BLASTSyncEngine.TransactionReadyListener waitingListener,
int waitingId) {
// TODO(b/148871522): Support child window
mWaitingListener = waitingListener;
mWaitingSyncId = waitingId;
mUsingBLASTSyncTransaction = true;
mLocalSyncId = mBLASTSyncEngine.startSyncSet(this);
addChildrenToSyncSet(mLocalSyncId);
mWmService.mH.removeMessages(WINDOW_STATE_BLAST_SYNC_TIMEOUT, this);
mWmService.mH.sendNewMessageDelayed(WINDOW_STATE_BLAST_SYNC_TIMEOUT, this,
BLAST_TIMEOUT_DURATION);
@@ -5702,11 +5713,21 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
mWmService.mH.removeMessages(WINDOW_STATE_BLAST_SYNC_TIMEOUT, this);
if (postDrawTransaction == null) {
postDrawTransaction = new SurfaceControl.Transaction();
if (postDrawTransaction != null) {
mBLASTSyncTransaction.merge(postDrawTransaction);
}
postDrawTransaction.merge(mBLASTSyncTransaction);
mWaitingListener.transactionReady(mWaitingSyncId, postDrawTransaction);
// If localSyncId is >0 then we are syncing with children and will
// invoke transaction ready from our own #transactionReady callback
// we just need to signal our side of the sync (setReady). But if we
// have no sync operation at this level transactionReady will never
// be invoked and we need to invoke it ourself.
if (mLocalSyncId >= 0) {
mBLASTSyncEngine.setReady(mLocalSyncId);
} else {
mWaitingListener.transactionReady(mWaitingSyncId, mBLASTSyncTransaction);
}
mUsingBLASTSyncTransaction = false;
mWaitingSyncId = 0;

View File

@@ -32,6 +32,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.reset;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
@@ -567,6 +568,38 @@ public class TaskOrganizerTests extends WindowTestsBase {
.transactionReady(anyInt(), any());
}
@Test
public void testBLASTCallbackWithChildWindow() {
final ActivityStack stackController1 = createTaskStackOnDisplay(mDisplayContent);
final Task task = createTaskInStack(stackController1, 0 /* userId */);
final ITaskOrganizer organizer = registerMockOrganizer();
final WindowState w = createAppWindow(task, TYPE_APPLICATION, "Enlightened Window");
final WindowState child = createWindow(w, TYPE_APPLICATION, "Other Window");
w.mActivityRecord.setVisible(true);
makeWindowVisible(w, child);
BLASTSyncEngine bse = new BLASTSyncEngine();
BLASTSyncEngine.TransactionReadyListener transactionListener =
mock(BLASTSyncEngine.TransactionReadyListener.class);
int id = bse.startSyncSet(transactionListener);
assertEquals(true, bse.addToSyncSet(id, task));
bse.setReady(id);
w.finishDrawing(null);
// Since we have a child window we still shouldn't be done.
verify(transactionListener, never())
.transactionReady(anyInt(), any());
reset(transactionListener);
child.finishDrawing(null);
// Ah finally! Done
verify(transactionListener)
.transactionReady(anyInt(), any());
}
class StubOrganizer extends ITaskOrganizer.Stub {
RunningTaskInfo mInfo;