Synchronize window config updates (13/n)
Queueing ClientTransactions when deferWindowLayout. This should cover most system transition, like WindowOrganizerController#applyTransaction. Bug: 260873529 Test: atest WmTests:ClientLifecycleManagerTests Change-Id: I98a17e11ad77f4f93eb9fc4a580fceaa3dea8e1e
This commit is contained in:
parent
cc024fb28d
commit
a19b571c36
@ -4762,6 +4762,10 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
|||||||
if (DEBUG_ALL && !mWindowManager.mWindowPlacerLocked.isLayoutDeferred()) {
|
if (DEBUG_ALL && !mWindowManager.mWindowPlacerLocked.isLayoutDeferred()) {
|
||||||
Slog.i(TAG, "continueWindowLayout reason=" + mLayoutReasons);
|
Slog.i(TAG, "continueWindowLayout reason=" + mLayoutReasons);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ClientTransactions is queued during #deferWindowLayout() for performance.
|
||||||
|
// Notify to continue.
|
||||||
|
mLifecycleManager.onLayoutContinued();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -105,7 +105,7 @@ class ClientLifecycleManager {
|
|||||||
final ClientTransaction clientTransaction = getOrCreatePendingTransaction(client);
|
final ClientTransaction clientTransaction = getOrCreatePendingTransaction(client);
|
||||||
clientTransaction.addTransactionItem(transactionItem);
|
clientTransaction.addTransactionItem(transactionItem);
|
||||||
|
|
||||||
onClientTransactionItemScheduledLocked(clientTransaction);
|
onClientTransactionItemScheduled(clientTransaction);
|
||||||
} else {
|
} else {
|
||||||
// TODO(b/260873529): cleanup after launch.
|
// TODO(b/260873529): cleanup after launch.
|
||||||
final ClientTransaction clientTransaction = ClientTransaction.obtain(client);
|
final ClientTransaction clientTransaction = ClientTransaction.obtain(client);
|
||||||
@ -134,7 +134,7 @@ class ClientLifecycleManager {
|
|||||||
clientTransaction.addTransactionItem(transactionItem);
|
clientTransaction.addTransactionItem(transactionItem);
|
||||||
clientTransaction.addTransactionItem(lifecycleItem);
|
clientTransaction.addTransactionItem(lifecycleItem);
|
||||||
|
|
||||||
onClientTransactionItemScheduledLocked(clientTransaction);
|
onClientTransactionItemScheduled(clientTransaction);
|
||||||
} else {
|
} else {
|
||||||
// TODO(b/260873529): cleanup after launch.
|
// TODO(b/260873529): cleanup after launch.
|
||||||
final ClientTransaction clientTransaction = ClientTransaction.obtain(client);
|
final ClientTransaction clientTransaction = ClientTransaction.obtain(client);
|
||||||
@ -146,6 +146,9 @@ class ClientLifecycleManager {
|
|||||||
|
|
||||||
/** Executes all the pending transactions. */
|
/** Executes all the pending transactions. */
|
||||||
void dispatchPendingTransactions() {
|
void dispatchPendingTransactions() {
|
||||||
|
if (!Flags.bundleClientTransactionFlag()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
final int size = mPendingTransactions.size();
|
final int size = mPendingTransactions.size();
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
final ClientTransaction transaction = mPendingTransactions.valueAt(i);
|
final ClientTransaction transaction = mPendingTransactions.valueAt(i);
|
||||||
@ -158,6 +161,20 @@ class ClientLifecycleManager {
|
|||||||
mPendingTransactions.clear();
|
mPendingTransactions.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called to when {@link WindowSurfacePlacer#continueLayout}.
|
||||||
|
* Dispatches all pending transactions unless there is an ongoing/scheduled layout, in which
|
||||||
|
* case the pending transactions will be dispatched in
|
||||||
|
* {@link RootWindowContainer#performSurfacePlacementNoTrace}.
|
||||||
|
*/
|
||||||
|
void onLayoutContinued() {
|
||||||
|
if (shouldDispatchPendingTransactionsImmediately()) {
|
||||||
|
// Dispatch the pending transactions immediately if there is no ongoing/scheduled layout
|
||||||
|
dispatchPendingTransactions();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Must only be called with WM lock. */
|
||||||
@NonNull
|
@NonNull
|
||||||
private ClientTransaction getOrCreatePendingTransaction(@NonNull IApplicationThread client) {
|
private ClientTransaction getOrCreatePendingTransaction(@NonNull IApplicationThread client) {
|
||||||
final IBinder clientBinder = client.asBinder();
|
final IBinder clientBinder = client.asBinder();
|
||||||
@ -173,20 +190,28 @@ class ClientLifecycleManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Must only be called with WM lock. */
|
/** Must only be called with WM lock. */
|
||||||
private void onClientTransactionItemScheduledLocked(
|
private void onClientTransactionItemScheduled(
|
||||||
@NonNull ClientTransaction clientTransaction) throws RemoteException {
|
@NonNull ClientTransaction clientTransaction) throws RemoteException {
|
||||||
// TODO(b/260873529): make sure WindowSurfacePlacer#requestTraversal is called before
|
if (shouldDispatchPendingTransactionsImmediately()) {
|
||||||
// ClientTransaction scheduled when needed.
|
// Dispatch the pending transaction immediately.
|
||||||
|
mPendingTransactions.remove(clientTransaction.getClient().asBinder());
|
||||||
if (mWms != null && (mWms.mWindowPlacerLocked.isInLayout()
|
scheduleTransaction(clientTransaction);
|
||||||
|| mWms.mWindowPlacerLocked.isTraversalScheduled())) {
|
|
||||||
// The pending transactions will be dispatched when
|
|
||||||
// RootWindowContainer#performSurfacePlacementNoTrace.
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Dispatch the pending transaction immediately.
|
/** Must only be called with WM lock. */
|
||||||
mPendingTransactions.remove(clientTransaction.getClient().asBinder());
|
private boolean shouldDispatchPendingTransactionsImmediately() {
|
||||||
scheduleTransaction(clientTransaction);
|
if (mWms == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// Do not dispatch when
|
||||||
|
// 1. Layout deferred.
|
||||||
|
// 2. Layout requested.
|
||||||
|
// 3. Layout in process.
|
||||||
|
// The pending transactions will be dispatched during layout in
|
||||||
|
// RootWindowContainer#performSurfacePlacementNoTrace.
|
||||||
|
return !mWms.mWindowPlacerLocked.isLayoutDeferred()
|
||||||
|
&& !mWms.mWindowPlacerLocked.isTraversalScheduled()
|
||||||
|
&& !mWms.mWindowPlacerLocked.isInLayout();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1087,4 +1087,16 @@ public class ActivityTaskManagerServiceTests extends WindowTestsBase {
|
|||||||
assertTrue(homeActivity.getTask().isFocused());
|
assertTrue(homeActivity.getTask().isFocused());
|
||||||
assertFalse(pinnedTask.isFocused());
|
assertFalse(pinnedTask.isFocused());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testContinueWindowLayout_notifyClientLifecycleManager() {
|
||||||
|
clearInvocations(mClientLifecycleManager);
|
||||||
|
mAtm.deferWindowLayout();
|
||||||
|
|
||||||
|
verify(mClientLifecycleManager, never()).onLayoutContinued();
|
||||||
|
|
||||||
|
mAtm.continueWindowLayout();
|
||||||
|
|
||||||
|
verify(mClientLifecycleManager).onLayoutContinued();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package com.android.server.wm;
|
package com.android.server.wm;
|
||||||
|
|
||||||
|
import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT;
|
||||||
|
|
||||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
|
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
|
||||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
|
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
|
||||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
|
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
|
||||||
@ -52,14 +54,12 @@ import org.mockito.MockitoAnnotations;
|
|||||||
* Build/Install/Run:
|
* Build/Install/Run:
|
||||||
* atest WmTests:ClientLifecycleManagerTests
|
* atest WmTests:ClientLifecycleManagerTests
|
||||||
*/
|
*/
|
||||||
// Suppress GuardedBy warning on unit tests
|
|
||||||
@SuppressWarnings("GuardedBy")
|
|
||||||
@SmallTest
|
@SmallTest
|
||||||
@Presubmit
|
@Presubmit
|
||||||
public class ClientLifecycleManagerTests {
|
public class ClientLifecycleManagerTests {
|
||||||
|
|
||||||
@Rule(order = 0)
|
@Rule(order = 0)
|
||||||
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
|
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT);
|
||||||
|
|
||||||
@Rule(order = 1)
|
@Rule(order = 1)
|
||||||
public final SystemServicesTestRule mSystemServices = new SystemServicesTestRule();
|
public final SystemServicesTestRule mSystemServices = new SystemServicesTestRule();
|
||||||
@ -225,4 +225,30 @@ public class ClientLifecycleManagerTests {
|
|||||||
verify(mTransaction).schedule();
|
verify(mTransaction).schedule();
|
||||||
verify(mTransaction).recycle();
|
verify(mTransaction).recycle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLayoutDeferred() throws RemoteException {
|
||||||
|
mSetFlagsRule.enableFlags(FLAG_BUNDLE_CLIENT_TRANSACTION_FLAG);
|
||||||
|
spyOn(mWms.mWindowPlacerLocked);
|
||||||
|
doReturn(false).when(mWms.mWindowPlacerLocked).isInLayout();
|
||||||
|
doReturn(false).when(mWms.mWindowPlacerLocked).isTraversalScheduled();
|
||||||
|
doReturn(true).when(mWms.mWindowPlacerLocked).isLayoutDeferred();
|
||||||
|
|
||||||
|
// Queue transactions during layout deferred.
|
||||||
|
mLifecycleManager.scheduleTransactionItem(mNonBinderClient, mLifecycleItem);
|
||||||
|
|
||||||
|
verify(mLifecycleManager, never()).scheduleTransaction(any());
|
||||||
|
|
||||||
|
// Continue queueing when there are multi-level defer.
|
||||||
|
mLifecycleManager.onLayoutContinued();
|
||||||
|
|
||||||
|
verify(mLifecycleManager, never()).scheduleTransaction(any());
|
||||||
|
|
||||||
|
// Immediately dispatch when layout continue without ongoing/scheduled layout.
|
||||||
|
doReturn(false).when(mWms.mWindowPlacerLocked).isLayoutDeferred();
|
||||||
|
|
||||||
|
mLifecycleManager.onLayoutContinued();
|
||||||
|
|
||||||
|
verify(mLifecycleManager).scheduleTransaction(any());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user