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

Commit ba10eadc authored by Chris Li's avatar Chris Li
Browse files

Mark TaskFragment transition ready after apply the transaction

Before, we would wait activity resume/pause to trigger setReady, which
can be timeout. Now, we call setAllReady after apply the transaction.

Fix: 267401674
Test: atest FlickerTests:OpenSecondaryToSplitTest
Change-Id: Icdf4ed8fda957b694644eed80dfc93b1314245e4
parent ce9816e8
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -431,6 +431,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
                applyTransaction(wct, -1 /* syncId */, transition, caller);
                mTransitionController.requestStartTransition(transition, null /* startTask */,
                        null /* remoteTransition */, null /* displayChange */);
                transition.setAllReady();
                return;
            }

@@ -469,6 +470,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
                            mTransitionController.requestStartTransition(nextTransition,
                                    null /* startTask */, null /* remoteTransition */,
                                    null /* displayChange */);
                            nextTransition.setAllReady();
                        } else {
                            nextTransition.abort();
                        }
+40 −63
Original line number Diff line number Diff line
@@ -33,13 +33,13 @@ import org.junit.runners.Parameterized
 * Test opening an activity that will launch another activity as ActivityEmbedding placeholder in
 * split.
 *
 * To run this test: `atest FlickerTests:OpenActivityEmbeddingPlaceholderSplit`
 * To run this test: `atest FlickerTests:OpenActivityEmbeddingPlaceholderSplitTest`
 */
@RequiresDevice
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
class OpenActivityEmbeddingPlaceholderSplit(flicker: FlickerTest) :
class OpenActivityEmbeddingPlaceholderSplitTest(flicker: FlickerTest) :
    ActivityEmbeddingTestBase(flicker) {

    /** {@inheritDoc} */
@@ -55,9 +55,21 @@ class OpenActivityEmbeddingPlaceholderSplit(flicker: FlickerTest) :
        }
    }

    /** Main activity should become invisible after launching the placeholder primary activity. */
    @Presubmit
    @Test
    fun mainActivityBecomesInvisible() {
    fun mainActivityWindowBecomesInvisible() {
        flicker.assertWm {
            isAppWindowVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
                .then()
                .isAppWindowInvisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
        }
    }

    /** Main activity should become invisible after launching the placeholder primary activity. */
    @Presubmit
    @Test
    fun mainActivityLayerBecomesInvisible() {
        flicker.assertLayers {
            isVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
                .then()
@@ -65,76 +77,41 @@ class OpenActivityEmbeddingPlaceholderSplit(flicker: FlickerTest) :
        }
    }

    /**
     * Placeholder primary and secondary should become visible after launch. The windows are not
     * necessarily to become visible at the same time.
     */
    @Presubmit
    @Test
    fun placeholderSplitBecomesVisible() {
        flicker.assertLayers {
            isInvisible(ActivityEmbeddingAppHelper.PLACEHOLDER_PRIMARY_COMPONENT)
    fun placeholderSplitWindowsBecomeVisible() {
        flicker.assertWm {
            notContains(ActivityEmbeddingAppHelper.PLACEHOLDER_PRIMARY_COMPONENT)
                .then()
                .isVisible(ActivityEmbeddingAppHelper.PLACEHOLDER_PRIMARY_COMPONENT)
                .isAppWindowInvisible(ActivityEmbeddingAppHelper.PLACEHOLDER_PRIMARY_COMPONENT)
                .then()
                .isAppWindowVisible(ActivityEmbeddingAppHelper.PLACEHOLDER_PRIMARY_COMPONENT)
        }
        flicker.assertLayers {
            isInvisible(ActivityEmbeddingAppHelper.PLACEHOLDER_SECONDARY_COMPONENT)
        flicker.assertWm {
            notContains(ActivityEmbeddingAppHelper.PLACEHOLDER_SECONDARY_COMPONENT)
                .then()
                .isVisible(ActivityEmbeddingAppHelper.PLACEHOLDER_SECONDARY_COMPONENT)
                .isAppWindowInvisible(ActivityEmbeddingAppHelper.PLACEHOLDER_SECONDARY_COMPONENT)
                .then()
                .isAppWindowVisible(ActivityEmbeddingAppHelper.PLACEHOLDER_SECONDARY_COMPONENT)
        }
    }

    /** {@inheritDoc} */
    @Presubmit @Test override fun entireScreenCovered() = super.entireScreenCovered()

    /** {@inheritDoc} */
    @Presubmit
    @Test
    override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()

    /** {@inheritDoc} */
    @Presubmit
    @Test
    override fun navBarWindowIsAlwaysVisible() = super.navBarWindowIsAlwaysVisible()

    /** {@inheritDoc} */
    @Presubmit
    @Test
    override fun navBarLayerIsVisibleAtStartAndEnd() = super.navBarLayerIsVisibleAtStartAndEnd()

    /** {@inheritDoc} */
    /** Placeholder primary and secondary should become visible together after launch. */
    @Presubmit
    @Test
    override fun taskBarWindowIsAlwaysVisible() = super.taskBarWindowIsAlwaysVisible()

    /** {@inheritDoc} */
    @Presubmit
    @Test
    override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd()

    /** {@inheritDoc} */
    @Presubmit
    @Test
    override fun statusBarLayerIsVisibleAtStartAndEnd() =
        super.statusBarLayerIsVisibleAtStartAndEnd()

    /** {@inheritDoc} */
    @Presubmit
    @Test
    override fun statusBarLayerPositionAtStartAndEnd() = super.statusBarLayerPositionAtStartAndEnd()

    /** {@inheritDoc} */
    @Presubmit
    @Test
    override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible()

    /** {@inheritDoc} */
    @Presubmit
    @Test
    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
        super.visibleWindowsShownMoreThanOneConsecutiveEntry()

    /** {@inheritDoc} */
    @Presubmit
    @Test
    override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
        super.visibleLayersShownMoreThanOneConsecutiveEntry()
    fun placeholderSplitLayersBecomeVisible() {
        flicker.assertLayers {
            isInvisible(ActivityEmbeddingAppHelper.PLACEHOLDER_PRIMARY_COMPONENT)
            isInvisible(ActivityEmbeddingAppHelper.PLACEHOLDER_SECONDARY_COMPONENT)
                .then()
                .isVisible(ActivityEmbeddingAppHelper.PLACEHOLDER_PRIMARY_COMPONENT)
                .isVisible(ActivityEmbeddingAppHelper.PLACEHOLDER_SECONDARY_COMPONENT)
        }
    }

    companion object {
        /**
+124 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.wm.flicker.activityembedding

import android.platform.test.annotations.Presubmit
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.FlickerBuilder
import com.android.server.wm.flicker.FlickerTest
import com.android.server.wm.flicker.FlickerTestFactory
import com.android.server.wm.flicker.helpers.ActivityEmbeddingAppHelper
import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
import com.android.server.wm.traces.common.ComponentNameMatcher
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
import org.junit.runners.Parameterized

/**
 * Test opening a secondary activity that will split with the main activity.
 *
 * To run this test: `atest FlickerTests:OpenActivityEmbeddingSecondaryToSplitTest`
 */
@RequiresDevice
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
class OpenActivityEmbeddingSecondaryToSplitTest(flicker: FlickerTest) :
    ActivityEmbeddingTestBase(flicker) {

    /** {@inheritDoc} */
    override val transition: FlickerBuilder.() -> Unit = {
        setup {
            tapl.setExpectedRotationCheckEnabled(false)
            testApp.launchViaIntent(wmHelper)
        }
        transitions { testApp.launchSecondaryActivity(wmHelper) }
        teardown {
            tapl.goHome()
            testApp.exit(wmHelper)
        }
    }

    /** Main activity should remain visible when enter split from fullscreen. */
    @Presubmit
    @Test
    fun mainActivityWindowIsAlwaysVisible() {
        flicker.assertWm {
            isAppWindowVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
        }
    }

    /**
     * Main activity surface is animated from fullscreen to ActivityEmbedding split.
     * During the transition, there is a period of time that it is covered by a snapshot of itself.
     */
    @Presubmit
    @Test
    fun mainActivityLayerIsAlwaysVisible() {
        flicker.assertLayers {
            isVisible(
                ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT.or(
                    ComponentNameMatcher.TRANSITION_SNAPSHOT
                )
            )
        }
        flicker.assertLayersEnd {
            isVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
                .isInvisible(ComponentNameMatcher.TRANSITION_SNAPSHOT)
        }
    }

    /** Secondary activity should become visible after launching into split. */
    @Presubmit
    @Test
    fun secondaryActivityWindowBecomesVisible() {
        flicker.assertWm {
            notContains(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
                .then()
                .isAppWindowInvisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
                .then()
                .isAppWindowVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
        }
    }

    /** Secondary activity should become visible after launching into split. */
    @Presubmit
    @Test
    fun secondaryActivityLayerBecomesVisible() {
        flicker.assertLayers {
            isInvisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
                .then()
                .isVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
        }
    }

    companion object {
        /**
         * Creates the test configurations.
         *
         * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
         * navigation modes.
         */
        @Parameterized.Parameters(name = "{0}")
        @JvmStatic
        fun getParams(): Collection<FlickerTest> {
            return FlickerTestFactory.nonRotationTests()
        }
    }
}
+22 −0
Original line number Diff line number Diff line
@@ -38,6 +38,25 @@ constructor(
    component: ComponentNameMatcher = MAIN_ACTIVITY_COMPONENT
) : StandardAppHelper(instr, launcherName, component) {

    /**
     * Clicks the button to launch the secondary activity, which should split with the main activity
     * based on the split pair rule.
     */
    fun launchSecondaryActivity(wmHelper: WindowManagerStateHelper) {
        val launchButton =
            uiDevice.wait(
                Until.findObject(By.res(getPackage(), "launch_secondary_activity_button")),
                FIND_TIMEOUT
            )
        require(launchButton != null) { "Can't find launch secondary activity button on screen." }
        launchButton.click()
        wmHelper
            .StateSyncBuilder()
            .withActivityState(SECONDARY_ACTIVITY_COMPONENT, STATE_RESUMED)
            .withActivityState(MAIN_ACTIVITY_COMPONENT, STATE_RESUMED)
            .waitForAndVerify()
    }

    /**
     * Clicks the button to launch the placeholder primary activity, which should launch the
     * placeholder secondary activity based on the placeholder rule.
@@ -63,6 +82,9 @@ constructor(
        val MAIN_ACTIVITY_COMPONENT =
            ActivityOptions.ActivityEmbedding.MainActivity.COMPONENT.toFlickerComponent()

        val SECONDARY_ACTIVITY_COMPONENT =
            ActivityOptions.ActivityEmbedding.SecondaryActivity.COMPONENT.toFlickerComponent()

        val PLACEHOLDER_PRIMARY_COMPONENT =
            ActivityOptions.ActivityEmbedding.PlaceholderPrimaryActivity.COMPONENT
                .toFlickerComponent()
+7 −0
Original line number Diff line number Diff line
@@ -178,6 +178,13 @@
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <activity
            android:name=".ActivityEmbeddingSecondaryActivity"
            android:label="ActivityEmbedding Secondary"
            android:taskAffinity="com.android.server.wm.flicker.testapp.ActivityEmbedding"
            android:theme="@style/CutoutShortEdges"
            android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
            android:exported="false"/>
        <activity
            android:name=".ActivityEmbeddingPlaceholderPrimaryActivity"
            android:label="ActivityEmbedding Placeholder Primary"
Loading