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

Commit ed607673 authored by Chris Li's avatar Chris Li Committed by Android (Google) Code Review
Browse files

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

parents 0302afaa f1f091ad
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -208,9 +208,11 @@ import android.view.contentcapture.IContentCaptureOptionsCallback;
import android.view.translation.TranslationSpec;
import android.view.translation.UiTranslationSpec;
import android.webkit.WebView;
import android.window.ITaskFragmentOrganizer;
import android.window.SizeConfigurationBuckets;
import android.window.SplashScreen;
import android.window.SplashScreenView;
import android.window.TaskFragmentTransaction;
import android.window.WindowContextInfo;
import android.window.WindowProviderService;
import android.window.WindowTokenClientController;
@@ -2046,6 +2048,14 @@ public final class ActivityThread extends ClientTransactionHandler
            ActivityThread.this.scheduleTransaction(transaction);
        }

        @Override
        public void scheduleTaskFragmentTransaction(@NonNull ITaskFragmentOrganizer organizer,
                @NonNull TaskFragmentTransaction transaction) throws RemoteException {
            // TODO(b/260873529): ITaskFragmentOrganizer can be cleanup to be a IBinder token
            // after flag removal.
            organizer.onTransactionReady(transaction);
        }

        @Override
        public void requestDirectActions(@NonNull IBinder activityToken,
                @NonNull IVoiceInteractor interactor, @Nullable RemoteCallback cancellationCallback,
+4 −0
Original line number Diff line number Diff line
@@ -48,6 +48,8 @@ import android.os.SharedMemory;
import android.view.autofill.AutofillId;
import android.view.translation.TranslationSpec;
import android.view.translation.UiTranslationSpec;
import android.window.ITaskFragmentOrganizer;
import android.window.TaskFragmentTransaction;

import com.android.internal.app.IVoiceInteractor;
import com.android.internal.content.ReferrerIntent;
@@ -157,6 +159,8 @@ oneway interface IApplicationThread {
    void scheduleApplicationInfoChanged(in ApplicationInfo ai);
    void setNetworkBlockSeq(long procStateSeq);
    void scheduleTransaction(in ClientTransaction transaction);
    void scheduleTaskFragmentTransaction(in ITaskFragmentOrganizer organizer,
            in TaskFragmentTransaction transaction);
    void requestDirectActions(IBinder activityToken, IVoiceInteractor intractor,
            in RemoteCallback cancellationCallback, in RemoteCallback callback);
    void performDirectAction(IBinder activityToken, String actionId,
+28 −1
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import static java.util.Objects.requireNonNull;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.IApplicationThread;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Binder;
@@ -106,6 +107,7 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
     */
    private class TaskFragmentOrganizerState implements IBinder.DeathRecipient {
        private final ArrayList<TaskFragment> mOrganizedTaskFragments = new ArrayList<>();
        private final IApplicationThread mAppThread;
        private final ITaskFragmentOrganizer mOrganizer;
        private final int mOrganizerPid;
        private final int mOrganizerUid;
@@ -169,6 +171,11 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr

        TaskFragmentOrganizerState(@NonNull ITaskFragmentOrganizer organizer, int pid, int uid,
                boolean isSystemOrganizer) {
            if (Flags.bundleClientTransactionFlag()) {
                mAppThread = getAppThread(pid, uid);
            } else {
                mAppThread = null;
            }
            mOrganizer = organizer;
            mOrganizerPid = pid;
            mOrganizerUid = uid;
@@ -407,7 +414,13 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
                return;
            }
            try {
                if (Flags.bundleClientTransactionFlag()) {
                    // Dispatch through IApplicationThread to ensure the binder call is in order
                    // with ClientTransaction.
                    mAppThread.scheduleTaskFragmentTransaction(mOrganizer, transaction);
                } else {
                    mOrganizer.onTransactionReady(transaction);
                }
            } catch (RemoteException e) {
                Slog.d(TAG, "Exception sending TaskFragmentTransaction", e);
                return;
@@ -1198,6 +1211,20 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
        }
    }

    @VisibleForTesting
    @NonNull
    IApplicationThread getAppThread(int pid, int uid) {
        final WindowProcessController wpc = mAtmService.mProcessMap.getProcess(pid);
        final IApplicationThread appThread = wpc != null && wpc.mUid == uid
                ? wpc.getThread()
                : null;
        if (appThread == null) {
            throw new IllegalArgumentException("Cannot find process for pid=" + pid
                    + " uid=" + uid);
        }
        return appThread;
    }

    /**
     * Trims the given Intent to only those that are needed to for embedding rules. This helps to
     * make it safer for cross-uid embedding even if we only send the Intent for trusted embedding.
+50 −2
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.wm;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_CLOSE;
@@ -74,6 +75,7 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;

import android.annotation.NonNull;
import android.app.IApplicationThread;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ActivityInfo;
@@ -86,6 +88,7 @@ import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
import android.platform.test.flag.junit.SetFlagsRule;
import android.view.RemoteAnimationDefinition;
import android.view.SurfaceControl;
import android.window.IRemoteTransition;
@@ -104,7 +107,10 @@ import android.window.WindowContainerTransaction;

import androidx.test.filters.SmallTest;

import com.android.window.flags.Flags;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -123,7 +129,9 @@ import java.util.List;
@Presubmit
@RunWith(WindowTestRunner.class)
public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
    private static final int TASK_ID = 10;

    @Rule
    public SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT);

    private TaskFragmentOrganizerController mController;
    private WindowOrganizerController mWindowOrganizerController;
@@ -143,6 +151,8 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
    private TaskFragmentInfo mTaskFragmentInfo;
    @Mock
    private Task mTask;
    @Mock
    private IApplicationThread mAppThread;
    @Captor
    private ArgumentCaptor<TaskFragmentTransaction> mTransactionCaptor;

@@ -178,6 +188,15 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
        doReturn(new SurfaceControl()).when(mTaskFragment).getSurfaceControl();
        doReturn(mFragmentToken).when(mTaskFragment).getFragmentToken();
        doReturn(new Configuration()).when(mTaskFragmentInfo).getConfiguration();
        doReturn(mAppThread).when(mController).getAppThread(anyInt(), anyInt());
        doAnswer(invocation -> {
            final ITaskFragmentOrganizer organizer =
                    (ITaskFragmentOrganizer) invocation.getArguments()[0];
            final TaskFragmentTransaction taskFragmentTransaction =
                    (TaskFragmentTransaction) invocation.getArguments()[1];
            organizer.onTransactionReady(taskFragmentTransaction);
            return null;
        }).when(mAppThread).scheduleTaskFragmentTransaction(any(), any());

        // To prevent it from calling the real server.
        doNothing().when(mOrganizer).applyTransaction(any(), anyInt(), anyBoolean());
@@ -204,12 +223,40 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
    }

    @Test
    public void testOnTaskFragmentAppeared() {
    public void testOnTaskFragmentAppeared_throughTaskFragmentOrganizer() throws RemoteException {
        mSetFlagsRule.disableFlags(Flags.FLAG_BUNDLE_CLIENT_TRANSACTION_FLAG);

        // No-op when the TaskFragment is not attached.
        mController.onTaskFragmentAppeared(mTaskFragment.getTaskFragmentOrganizer(), mTaskFragment);
        mController.dispatchPendingEvents();

        verify(mOrganizer, never()).onTransactionReady(any());
        verify(mAppThread, never()).scheduleTaskFragmentTransaction(any(), any());

        // Send callback when the TaskFragment is attached.
        setupMockParent(mTaskFragment, mTask);

        mController.onTaskFragmentAppeared(mTaskFragment.getTaskFragmentOrganizer(), mTaskFragment);
        mController.dispatchPendingEvents();

        assertTaskFragmentParentInfoChangedTransaction(mTask);
        assertTaskFragmentAppearedTransaction(false /* hasSurfaceControl */);
        verify(mAppThread, never()).scheduleTaskFragmentTransaction(any(), any());
    }

    @Test
    public void testOnTaskFragmentAppeared_throughApplicationThread() throws RemoteException  {
        mSetFlagsRule.enableFlags(Flags.FLAG_BUNDLE_CLIENT_TRANSACTION_FLAG);
        // Re-register the organizer in case the flag was disabled during setup.
        mController.unregisterOrganizer(mIOrganizer);
        mController.registerOrganizer(mIOrganizer);

        // No-op when the TaskFragment is not attached.
        mController.onTaskFragmentAppeared(mTaskFragment.getTaskFragmentOrganizer(), mTaskFragment);
        mController.dispatchPendingEvents();

        verify(mOrganizer, never()).onTransactionReady(any());
        verify(mAppThread, never()).scheduleTaskFragmentTransaction(any(), any());

        // Send callback when the TaskFragment is attached.
        setupMockParent(mTaskFragment, mTask);
@@ -217,6 +264,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
        mController.onTaskFragmentAppeared(mTaskFragment.getTaskFragmentOrganizer(), mTaskFragment);
        mController.dispatchPendingEvents();

        verify(mAppThread).scheduleTaskFragmentTransaction(eq(mIOrganizer), any());
        assertTaskFragmentParentInfoChangedTransaction(mTask);
        assertTaskFragmentAppearedTransaction(false /* hasSurfaceControl */);
    }
+4 −1
Original line number Diff line number Diff line
@@ -40,11 +40,11 @@ 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;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
import static com.android.server.wm.testing.Assert.assertThrows;
import static com.android.server.wm.ActivityRecord.State.RESUMED;
import static com.android.server.wm.WindowContainer.POSITION_TOP;
import static com.android.server.wm.WindowContainer.SYNC_STATE_READY;
import static com.android.server.wm.WindowState.BLAST_TIMEOUT_DURATION;
import static com.android.server.wm.testing.Assert.assertThrows;

import static com.google.common.truth.Truth.assertThat;

@@ -154,6 +154,9 @@ public class WindowOrganizerTests extends WindowTestsBase {

    @Before
    public void setUp() {
        mSystemServicesTestRule.addProcess("pkgName", "procName",
                WindowManagerService.MY_PID, WindowManagerService.MY_UID);

        // We defer callbacks since we need to adjust task surface visibility, but for these tests,
        // just run the callbacks synchronously
        mWm.mAtmService.mTaskOrganizerController.setDeferTaskOrgCallbacksConsumer((r) -> r.run());