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

Commit 58bd27d6 authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Verify that TaskOrganizer gets transferred launch cookie

If task A launches task B before A is drawn, the launch cookie
will be transferred from A to B. So onTaskAppeared should only
get the launch cookie from B.

Also clean up duplicated usages of ITaskOrganizer in unit tests.

Bug: 129067201
Test: atest WmTests:ActivityOptionsTest#testTransferLaunchCookie
Change-Id: I63bc8cd339642d3131c6a666cfffe37ad1a4c611
parent aa36363f
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -66,6 +66,18 @@
        <activity android:name="com.android.server.wm.TaskStackChangedListenerTest$ResumeWhilePausingActivity"
                  android:resumeWhilePausing="true"/>
        <activity android:name="com.android.server.wm.ActivityLeakTests$DetectLeakActivity" />
        <!--
            Simulate the common trampoline task that uses floating/translucent theme to avoid double
            starting windows and animations of task open.
        -->
        <activity android:name="com.android.server.wm.ActivityOptionsTest$TrampolineActivity"
                  android:taskAffinity="com.android.frameworks.wmtests.trampoline"
                  android:theme="@android:style/Theme.Translucent.NoTitleBar"
                  android:turnScreenOn="true"
                  android:showWhenLocked="true" />
        <activity android:name="com.android.server.wm.ActivityOptionsTest$MainActivity"
                  android:turnScreenOn="true"
                  android:showWhenLocked="true" />
    </application>

    <instrumentation
+93 −0
Original line number Diff line number Diff line
@@ -20,17 +20,36 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_ROTATE;

import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import android.app.Activity;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.ActivityOptions;
import android.app.Instrumentation;
import android.app.Instrumentation.ActivityMonitor;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.platform.test.annotations.Presubmit;
import android.view.SurfaceControl;
import android.window.TaskOrganizer;

import androidx.test.filters.MediumTest;

import org.junit.Test;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * Build/Install/Run:
 *  atest WmTests:ActivityOptionsTest
@@ -70,4 +89,78 @@ public class ActivityOptionsTest {
        assertTrue(restoredOpts.getTaskOverlay());
        assertTrue(restoredOpts.canTaskOverlayResume());
    }

    @Test
    public void testTransferLaunchCookie() {
        final Binder cookie = new Binder();
        final ActivityOptions options = ActivityOptions.makeBasic();
        options.setLaunchCookie(cookie);
        final Instrumentation instrumentation = getInstrumentation();
        final Context context = instrumentation.getContext();
        final ComponentName trampoline = new ComponentName(context, TrampolineActivity.class);
        final ComponentName main = new ComponentName(context, MainActivity.class);
        final Intent intent = new Intent().setComponent(trampoline)
                .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        final ActivityMonitor monitor = new ActivityMonitor(main.getClassName(),
                null /* result */, false /* block */);
        instrumentation.addMonitor(monitor);
        final CountDownLatch mainLatch = new CountDownLatch(1);
        final IBinder[] appearedCookies = new IBinder[2];
        final TaskOrganizer organizer = new TaskOrganizer() {
            @Override
            public void onTaskAppeared(RunningTaskInfo taskInfo, SurfaceControl leash) {
                try (SurfaceControl.Transaction t = new SurfaceControl.Transaction()) {
                    t.setVisibility(leash, true /* visible */).apply();
                }
                int cookieIndex = -1;
                if (trampoline.equals(taskInfo.baseActivity)) {
                    cookieIndex = 0;
                } else if (main.equals(taskInfo.baseActivity)) {
                    cookieIndex = 1;
                    mainLatch.countDown();
                }
                if (cookieIndex >= 0) {
                    appearedCookies[cookieIndex] = taskInfo.launchCookies.isEmpty()
                            ? null : taskInfo.launchCookies.get(0);
                }
            }
        };
        Activity mainActivity = null;
        try {
            organizer.registerOrganizer();
            context.startActivity(intent, options.toBundle());
            try {
                mainLatch.await(10, TimeUnit.SECONDS);
            } catch (InterruptedException ignored) {
            }
            mainActivity = monitor.getLastActivity();

            assertNotNull(mainActivity);
            assertNotEquals(TrampolineActivity.sTaskId, mainActivity.getTaskId());
            assertNull("Trampoline task must not have cookie", appearedCookies[0]);
            assertEquals("Main task must get the same cookie", cookie, appearedCookies[1]);
        } finally {
            organizer.unregisterOrganizer();
            instrumentation.removeMonitor(monitor);
            if (mainActivity != null) {
                mainActivity.finish();
            }
        }
    }

    public static class TrampolineActivity extends Activity {
        static int sTaskId;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            sTaskId = getTaskId();
            startActivity(new Intent(this, MainActivity.class)
                    .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
            finish();
        }
    }

    public static class MainActivity extends Activity {
    }
}
+5 −70
Original line number Diff line number Diff line
@@ -543,33 +543,7 @@ public class WindowOrganizerTests extends WindowTestsBase {

    @Test
    public void testTileAddRemoveChild() {
        ITaskOrganizer listener = new ITaskOrganizer.Stub() {
            @Override
            public void addStartingWindow(StartingWindowInfo info, IBinder appToken) {

            }

            @Override
            public void removeStartingWindow(int taskId, SurfaceControl leash, Rect frame,
                    boolean playRevealAnimation) { }

            @Override
            public void copySplashScreenView(int taskId) { }

            @Override
            public void onTaskAppeared(RunningTaskInfo taskInfo, SurfaceControl leash) { }

            @Override
            public void onTaskVanished(RunningTaskInfo container) { }

            @Override
            public void onTaskInfoChanged(RunningTaskInfo info) throws RemoteException {
            }

            @Override
            public void onBackPressedOnTaskRoot(RunningTaskInfo taskInfo) {
            }
        };
        final StubOrganizer listener = new StubOrganizer();
        mWm.mAtmService.mTaskOrganizerController.registerTaskOrganizer(listener);
        Task task = mWm.mAtmService.mTaskOrganizerController.createRootTask(
                mDisplayContent, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, null);
@@ -612,31 +586,12 @@ public class WindowOrganizerTests extends WindowTestsBase {
    public void testTaskInfoCallback() {
        final ArrayList<RunningTaskInfo> lastReportedTiles = new ArrayList<>();
        final boolean[] called = {false};
        ITaskOrganizer listener = new ITaskOrganizer.Stub() {
            @Override
            public void addStartingWindow(StartingWindowInfo info, IBinder appToken) {

            }
            @Override
            public void removeStartingWindow(int taskId, SurfaceControl leash, Rect frame,
                    boolean playRevealAnimation) { }
        final StubOrganizer listener = new StubOrganizer() {
            @Override
            public void copySplashScreenView(int taskId) { }
            @Override
            public void onTaskAppeared(RunningTaskInfo taskInfo, SurfaceControl leash) { }

            @Override
            public void onTaskVanished(RunningTaskInfo container) { }

            @Override
            public void onTaskInfoChanged(RunningTaskInfo info) throws RemoteException {
            public void onTaskInfoChanged(RunningTaskInfo info) {
                lastReportedTiles.add(info);
                called[0] = true;
            }

            @Override
            public void onBackPressedOnTaskRoot(RunningTaskInfo taskInfo) {
            }
        };
        mWm.mAtmService.mTaskOrganizerController.registerTaskOrganizer(listener);
        Task task = mWm.mAtmService.mTaskOrganizerController.createRootTask(
@@ -689,31 +644,11 @@ public class WindowOrganizerTests extends WindowTestsBase {
    @Test
    public void testHierarchyTransaction() {
        final ArrayMap<IBinder, RunningTaskInfo> lastReportedTiles = new ArrayMap<>();
        ITaskOrganizer listener = new ITaskOrganizer.Stub() {
            @Override
            public void addStartingWindow(StartingWindowInfo info, IBinder appToken) {

            }

            @Override
            public void removeStartingWindow(int taskId, SurfaceControl leash, Rect frame,
                    boolean playRevealAnimation) { }
            @Override
            public void copySplashScreenView(int taskId) { }
            @Override
            public void onTaskAppeared(RunningTaskInfo taskInfo, SurfaceControl leash) { }

            @Override
            public void onTaskVanished(RunningTaskInfo container) { }

        final StubOrganizer listener = new StubOrganizer() {
            @Override
            public void onTaskInfoChanged(RunningTaskInfo info) {
                lastReportedTiles.put(info.token.asBinder(), info);
            }

            @Override
            public void onBackPressedOnTaskRoot(RunningTaskInfo taskInfo) {
            }
        };
        mWm.mAtmService.mTaskOrganizerController.registerTaskOrganizer(listener);

@@ -838,7 +773,7 @@ public class WindowOrganizerTests extends WindowTestsBase {
        verify(transactionListener).onTransactionReady(anyInt(), any());
    }

    class StubOrganizer extends ITaskOrganizer.Stub {
    static class StubOrganizer extends ITaskOrganizer.Stub {
        RunningTaskInfo mInfo;

        @Override
+3 −37
Original line number Diff line number Diff line
@@ -92,7 +92,6 @@ import android.view.SurfaceControl.Transaction;
import android.view.View;
import android.view.WindowManager;
import android.view.WindowManager.DisplayImePolicy;
import android.window.ITaskOrganizer;
import android.window.ITransitionPlayer;
import android.window.StartingWindowInfo;
import android.window.TransitionInfo;
@@ -1216,7 +1215,7 @@ class WindowTestsBase extends SystemServiceTestsBase {
        }
    }

    static class TestStartingWindowOrganizer extends ITaskOrganizer.Stub {
    static class TestStartingWindowOrganizer extends WindowOrganizerTests.StubOrganizer {
        private final ActivityTaskManagerService mAtm;
        private final WindowManagerService mWMService;
        private final WindowState.PowerManagerWrapper mPowerManagerWrapper;
@@ -1281,24 +1280,9 @@ class WindowTestsBase extends SystemServiceTestsBase {
                }
            }
        }
        @Override
        public void copySplashScreenView(int taskId) {
        }
        @Override
        public void onTaskAppeared(ActivityManager.RunningTaskInfo info, SurfaceControl leash) {
        }
        @Override
        public void onTaskVanished(ActivityManager.RunningTaskInfo info) {
        }
        @Override
        public void onTaskInfoChanged(ActivityManager.RunningTaskInfo info) {
        }
        @Override
        public void onBackPressedOnTaskRoot(ActivityManager.RunningTaskInfo taskInfo) {
        }
    }

    static class TestSplitOrganizer extends ITaskOrganizer.Stub {
    static class TestSplitOrganizer extends WindowOrganizerTests.StubOrganizer {
        final ActivityTaskManagerService mService;
        Task mPrimary;
        Task mSecondary;
@@ -1332,22 +1316,7 @@ class WindowTestsBase extends SystemServiceTestsBase {
        public void setMoveToSecondaryOnEnter(boolean move) {
            mMoveToSecondaryOnEnter = move;
        }
        @Override
        public void addStartingWindow(StartingWindowInfo info, IBinder appToken) {
        }
        @Override
        public void removeStartingWindow(int taskId, SurfaceControl leash, Rect frame,
                boolean playRevealAnimation) {
        }
        @Override
        public void copySplashScreenView(int taskId) {
        }
        @Override
        public void onTaskAppeared(ActivityManager.RunningTaskInfo info, SurfaceControl leash) {
        }
        @Override
        public void onTaskVanished(ActivityManager.RunningTaskInfo info) {
        }

        @Override
        public void onTaskInfoChanged(ActivityManager.RunningTaskInfo info) {
            if (mInSplit) {
@@ -1374,9 +1343,6 @@ class WindowTestsBase extends SystemServiceTestsBase {
                }
            });
        }
        @Override
        public void onBackPressedOnTaskRoot(ActivityManager.RunningTaskInfo taskInfo) {
        }
    }

    static TestWindowToken createTestWindowToken(int type, DisplayContent dc) {