Merge "Synchronize window config updates (13/n)" into main

This commit is contained in:
Chris Li 2023-12-18 01:10:17 +00:00 committed by Android (Google) Code Review
commit 6e72846153
4 changed files with 84 additions and 17 deletions

View File

@ -4777,6 +4777,10 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
if (DEBUG_ALL && !mWindowManager.mWindowPlacerLocked.isLayoutDeferred()) {
Slog.i(TAG, "continueWindowLayout reason=" + mLayoutReasons);
}
// ClientTransactions is queued during #deferWindowLayout() for performance.
// Notify to continue.
mLifecycleManager.onLayoutContinued();
}
/**

View File

@ -105,7 +105,7 @@ class ClientLifecycleManager {
final ClientTransaction clientTransaction = getOrCreatePendingTransaction(client);
clientTransaction.addTransactionItem(transactionItem);
onClientTransactionItemScheduledLocked(clientTransaction);
onClientTransactionItemScheduled(clientTransaction);
} else {
// TODO(b/260873529): cleanup after launch.
final ClientTransaction clientTransaction = ClientTransaction.obtain(client);
@ -134,7 +134,7 @@ class ClientLifecycleManager {
clientTransaction.addTransactionItem(transactionItem);
clientTransaction.addTransactionItem(lifecycleItem);
onClientTransactionItemScheduledLocked(clientTransaction);
onClientTransactionItemScheduled(clientTransaction);
} else {
// TODO(b/260873529): cleanup after launch.
final ClientTransaction clientTransaction = ClientTransaction.obtain(client);
@ -146,6 +146,9 @@ class ClientLifecycleManager {
/** Executes all the pending transactions. */
void dispatchPendingTransactions() {
if (!Flags.bundleClientTransactionFlag()) {
return;
}
final int size = mPendingTransactions.size();
for (int i = 0; i < size; i++) {
final ClientTransaction transaction = mPendingTransactions.valueAt(i);
@ -158,6 +161,20 @@ class ClientLifecycleManager {
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
private ClientTransaction getOrCreatePendingTransaction(@NonNull IApplicationThread client) {
final IBinder clientBinder = client.asBinder();
@ -173,20 +190,28 @@ class ClientLifecycleManager {
}
/** Must only be called with WM lock. */
private void onClientTransactionItemScheduledLocked(
private void onClientTransactionItemScheduled(
@NonNull ClientTransaction clientTransaction) throws RemoteException {
// TODO(b/260873529): make sure WindowSurfacePlacer#requestTraversal is called before
// ClientTransaction scheduled when needed.
if (mWms != null && (mWms.mWindowPlacerLocked.isInLayout()
|| mWms.mWindowPlacerLocked.isTraversalScheduled())) {
// The pending transactions will be dispatched when
// RootWindowContainer#performSurfacePlacementNoTrace.
return;
}
if (shouldDispatchPendingTransactionsImmediately()) {
// Dispatch the pending transaction immediately.
mPendingTransactions.remove(clientTransaction.getClient().asBinder());
scheduleTransaction(clientTransaction);
}
}
/** Must only be called with WM lock. */
private boolean shouldDispatchPendingTransactionsImmediately() {
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();
}
}

View File

@ -1087,4 +1087,16 @@ public class ActivityTaskManagerServiceTests extends WindowTestsBase {
assertTrue(homeActivity.getTask().isFocused());
assertFalse(pinnedTask.isFocused());
}
@Test
public void testContinueWindowLayout_notifyClientLifecycleManager() {
clearInvocations(mClientLifecycleManager);
mAtm.deferWindowLayout();
verify(mClientLifecycleManager, never()).onLayoutContinued();
mAtm.continueWindowLayout();
verify(mClientLifecycleManager).onLayoutContinued();
}
}

View File

@ -16,6 +16,8 @@
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.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
@ -52,14 +54,12 @@ import org.mockito.MockitoAnnotations;
* Build/Install/Run:
* atest WmTests:ClientLifecycleManagerTests
*/
// Suppress GuardedBy warning on unit tests
@SuppressWarnings("GuardedBy")
@SmallTest
@Presubmit
public class ClientLifecycleManagerTests {
@Rule(order = 0)
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT);
@Rule(order = 1)
public final SystemServicesTestRule mSystemServices = new SystemServicesTestRule();
@ -225,4 +225,30 @@ public class ClientLifecycleManagerTests {
verify(mTransaction).schedule();
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());
}
}