Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 20a47541 authored by Chris Li's avatar Chris Li
Browse files

Immediately dispatch for LaunchActivityItem

Before bundleClientTransaction, RemoteException during startActivity
will restart the process to relaunch.
After bundleClientTransaction, the RemoteExcepetion will not restart the
process but just let it finished by the server.

As a result, we need to handle LaunchActivityItem differently so that
the existing restart process handling can still take effect.

There is no immediate action needed for other transaction item, because
the process will be killed with/without bundleCleintTransaction on
RemoteException.

Fix: 322171786
Bug: 260873529
Test: atest WmTests:ClientLifecycleManagerTests
Change-Id: Iffb4ad09d2e5db7f6af068da89376bebdeb88633
parent 6df10854
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -943,7 +943,10 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {

                // Schedule transaction.
                mService.getLifecycleManager().scheduleTransactionAndLifecycleItems(
                        proc.getThread(), launchActivityItem, lifecycleItem);
                        proc.getThread(), launchActivityItem, lifecycleItem,
                        // Immediately dispatch the transaction, so that if it fails, the server can
                        // restart the process and retry now.
                        true /* shouldDispatchImmediately */);

                if (procConfig.seq > mRootWindowContainer.getConfiguration().seq) {
                    // If the seq is increased, there should be something changed (e.g. registered
+24 −5
Original line number Diff line number Diff line
@@ -110,7 +110,8 @@ class ClientLifecycleManager {
            final ClientTransaction clientTransaction = getOrCreatePendingTransaction(client);
            clientTransaction.addTransactionItem(transactionItem);

            onClientTransactionItemScheduled(clientTransaction);
            onClientTransactionItemScheduled(clientTransaction,
                    false /* shouldDispatchImmediately */);
        } else {
            // TODO(b/260873529): cleanup after launch.
            final ClientTransaction clientTransaction = ClientTransaction.obtain(client);
@@ -123,14 +124,30 @@ class ClientLifecycleManager {
        }
    }

    void scheduleTransactionAndLifecycleItems(@NonNull IApplicationThread client,
            @NonNull ClientTransactionItem transactionItem,
            @NonNull ActivityLifecycleItem lifecycleItem) throws RemoteException {
        scheduleTransactionAndLifecycleItems(client, transactionItem, lifecycleItem,
                false /* shouldDispatchImmediately */);
    }

    /**
     * Schedules a single transaction item with a lifecycle request, delivery to client application.
     *
     * @param shouldDispatchImmediately whether or not to dispatch the transaction immediately. This
     *                                  should only be {@code true} when it is important to know the
     *                                  result of dispatching immediately. For example, when cold
     *                                  launches an app, the server needs to know if the transaction
     *                                  is dispatched successfully, and may restart the process if
     *                                  not.
     *
     * @throws RemoteException
     * @see ClientTransactionItem
     */
    void scheduleTransactionAndLifecycleItems(@NonNull IApplicationThread client,
            @NonNull ClientTransactionItem transactionItem,
            @NonNull ActivityLifecycleItem lifecycleItem) throws RemoteException {
            @NonNull ActivityLifecycleItem lifecycleItem,
            boolean shouldDispatchImmediately) throws RemoteException {
        // The behavior is different depending on the flag.
        // When flag is on, we wait until RootWindowContainer#performSurfacePlacementNoTrace to
        // dispatch all pending transactions at once.
@@ -139,7 +156,7 @@ class ClientLifecycleManager {
            clientTransaction.addTransactionItem(transactionItem);
            clientTransaction.addTransactionItem(lifecycleItem);

            onClientTransactionItemScheduled(clientTransaction);
            onClientTransactionItemScheduled(clientTransaction, shouldDispatchImmediately);
        } else {
            // TODO(b/260873529): cleanup after launch.
            final ClientTransaction clientTransaction = ClientTransaction.obtain(client);
@@ -162,6 +179,7 @@ class ClientLifecycleManager {
                scheduleTransaction(transaction);
            } catch (RemoteException e) {
                Slog.e(TAG, "Failed to deliver pending transaction", e);
                // TODO(b/323801078): apply cleanup for individual transaction item if needed.
            }
        }
        mPendingTransactions.clear();
@@ -198,8 +216,9 @@ class ClientLifecycleManager {

    /** Must only be called with WM lock. */
    private void onClientTransactionItemScheduled(
            @NonNull ClientTransaction clientTransaction) throws RemoteException {
        if (shouldDispatchPendingTransactionsImmediately()) {
            @NonNull ClientTransaction clientTransaction,
            boolean shouldDispatchImmediately) throws RemoteException {
        if (shouldDispatchImmediately || shouldDispatchPendingTransactionsImmediately()) {
            // Dispatch the pending transaction immediately.
            mPendingTransactions.remove(clientTransaction.getClient().asBinder());
            scheduleTransaction(clientTransaction);
+15 −0
Original line number Diff line number Diff line
@@ -207,6 +207,21 @@ public class ClientLifecycleManagerTests extends SystemServiceTestsBase {
        verify(mLifecycleManager, never()).scheduleTransaction(any());
    }

    @Test
    public void testScheduleTransactionAndLifecycleItems_shouldDispatchImmediately()
            throws RemoteException {
        mSetFlagsRule.enableFlags(FLAG_BUNDLE_CLIENT_TRANSACTION_FLAG);
        spyOn(mWms.mWindowPlacerLocked);
        doReturn(true).when(mWms.mWindowPlacerLocked).isTraversalScheduled();

        // Use non binder client to get non-recycled ClientTransaction.
        mLifecycleManager.scheduleTransactionAndLifecycleItems(mNonBinderClient, mTransactionItem,
                mLifecycleItem, true /* shouldDispatchImmediately */);

        verify(mLifecycleManager).scheduleTransaction(any());
        assertTrue(mLifecycleManager.mPendingTransactions.isEmpty());
    }

    @Test
    public void testDispatchPendingTransactions() throws RemoteException {
        mSetFlagsRule.enableFlags(FLAG_BUNDLE_CLIENT_TRANSACTION_FLAG);