Merge "[AE Flicker test] From A, start a split A|B, finish B and expect A to go fullscreen." into udc-qpr-dev

This commit is contained in:
An An Yu
2023-05-13 00:16:55 +00:00
committed by Android (Google) Code Review
5 changed files with 201 additions and 4 deletions

View File

@@ -0,0 +1,137 @@
/*
* 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 android.tools.common.datatypes.Rect
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
import android.tools.device.flicker.legacy.FlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.helpers.ActivityEmbeddingAppHelper
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
import org.junit.runners.Parameterized
/**
* Test closing a secondary activity in a split.
*
* Setup: Launch A|B in split with B being the secondary activity.
* Transitions: Finish B and expect A to become fullscreen.
*
* To run this test: `atest FlickerTests:CloseSecondaryActivityInSplitTest`
*/
@RequiresDevice
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
class CloseSecondaryActivityInSplitTest(flicker: FlickerTest) :
ActivityEmbeddingTestBase(flicker) {
override val transition: FlickerBuilder.() -> Unit = {
setup {
tapl.setExpectedRotationCheckEnabled(false)
// Launches fullscreen A.
testApp.launchViaIntent(wmHelper)
// Launches a split A|B and waits for both activities to show.
testApp.launchSecondaryActivity(wmHelper)
// Get fullscreen bounds
startDisplayBounds =
wmHelper.currentState.layerState.physicalDisplayBounds ?:
error("Can't get display bounds")
}
transitions {
// Finish secondary activity B.
testApp.finishSecondaryActivity(wmHelper)
// Expect the main activity A to expand into fullscreen.
wmHelper.StateSyncBuilder().withFullScreenApp(testApp).waitForAndVerify()
}
teardown {
tapl.goHome()
testApp.exit(wmHelper)
}
}
/** Main activity is always visible and becomes fullscreen in the end. */
@Presubmit
@Test
fun mainActivityWindowBecomesFullScreen() {
flicker.assertWm { isAppWindowVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT) }
flicker.assertWmEnd {
this.visibleRegion(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
.coversExactly(startDisplayBounds)
}
}
/** Main activity surface is animated from split to fullscreen. */
@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 destroy and become invisible. */
@Presubmit
@Test
fun secondaryActivityWindowFinishes() {
flicker.assertWm {
contains(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
.then()
.notContains(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
}
}
@Presubmit
@Test
fun secondaryActivityLayerFinishes() {
flicker.assertLayers {
isVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
.then()
.isInvisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
}
}
companion object {
/** {@inheritDoc} */
private var startDisplayBounds = Rect.EMPTY
/**
* 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()
}
}
}

View File

@@ -59,6 +59,24 @@ constructor(
.waitForAndVerify()
}
/**
* Clicks the button to finishes the secondary activity launched through
* [launchSecondaryActivity], waits for the main activity to resume.
*/
fun finishSecondaryActivity(wmHelper: WindowManagerStateHelper) {
val finishButton =
uiDevice.wait(
Until.findObject(By.res(getPackage(), "finish_secondary_activity_button")),
FIND_TIMEOUT
)
require(finishButton != null) { "Can't find finish secondary activity button on screen." }
finishButton.click()
wmHelper
.StateSyncBuilder()
.withActivityRemoved(SECONDARY_ACTIVITY_COMPONENT)
.waitForAndVerify()
}
/**
* Clicks the button to launch the placeholder primary activity, which should launch the
* placeholder secondary activity based on the placeholder rule.

View File

@@ -20,5 +20,4 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
</LinearLayout>

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 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.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/secondary_activity_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/finish_secondary_activity_button"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:text="Finish" />
</LinearLayout>

View File

@@ -16,15 +16,28 @@
package com.android.server.wm.flicker.testapp;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
/**
* Activity to be used as the secondary activity to split with
* {@link ActivityEmbeddingMainActivity}.
*/
public class ActivityEmbeddingSecondaryActivity extends ActivityEmbeddingBaseActivity {
public class ActivityEmbeddingSecondaryActivity extends Activity {
@Override
int getBackgroundColor() {
return Color.YELLOW;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_embedding_secondary_activity_layout);
findViewById(R.id.secondary_activity_layout).setBackgroundColor(Color.YELLOW);
findViewById(R.id.finish_secondary_activity_button).setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
}