summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java4
-rw-r--r--services/core/java/com/android/server/wm/ClientLifecycleManager.java53
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java12
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ClientLifecycleManagerTests.java32
4 files changed, 84 insertions, 17 deletions
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 869bcc0f9b8f..dd29995cb156 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -4762,6 +4762,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();
}
/**
diff --git a/services/core/java/com/android/server/wm/ClientLifecycleManager.java b/services/core/java/com/android/server/wm/ClientLifecycleManager.java
index 6b6388b10ce7..2e476772f85b 100644
--- a/services/core/java/com/android/server/wm/ClientLifecycleManager.java
+++ b/services/core/java/com/android/server/wm/ClientLifecycleManager.java
@@ -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);
}
+ }
- // 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();
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
index d2c731c3f8ad..ed99108e0da3 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
@@ -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();
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ClientLifecycleManagerTests.java b/services/tests/wmtests/src/com/android/server/wm/ClientLifecycleManagerTests.java
index 7fdc5fc2cff6..c757457a55ec 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ClientLifecycleManagerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ClientLifecycleManagerTests.java
@@ -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());
+ }
}