[DO NOT MERGE] Compatibilize flicker from master to sc-v2-dev

This is necessary to fix  "Unable to save trace file /sdcard/flicker/startRotationServiceTest_layers_trace.winscope" in the library self tests

Bug: 202288112
Bug: 202366188
Bug: 188993244
Test: atest FlickerTests WMShellFlickerTests
Change-Id: I9d6d6025be8b659d2f062771cfbd2f6c0982c2be
This commit is contained in:
Nataniel Borges
2021-10-11 09:24:23 +00:00
parent ff265fecb9
commit 2af16463ee
55 changed files with 1548 additions and 175 deletions

View File

@@ -42,6 +42,9 @@
<uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL"/>
<!-- ATM.removeRootTasksWithActivityTypes() -->
<uses-permission android:name="android.permission.MANAGE_ACTIVITY_TASKS" />
<!-- Enable bubble notification-->
<uses-permission android:name="android.permission.STATUS_BAR_SERVICE" />
<!-- Allow the test to write directly to /sdcard/ -->
<application android:requestLegacyExternalStorage="true">
<uses-library android:name="android.test.runner"/>

View File

@@ -20,13 +20,11 @@ import android.app.Instrumentation
import android.content.Context
import android.platform.test.annotations.Presubmit
import android.system.helpers.ActivityHelper
import android.view.Surface
import androidx.test.filters.FlakyTest
import androidx.test.platform.app.InstrumentationRegistry
import com.android.server.wm.flicker.FlickerBuilderProvider
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.endRotation
import com.android.server.wm.flicker.helpers.isRotated
import com.android.server.wm.flicker.helpers.setRotation
import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
@@ -179,15 +177,9 @@ abstract class AppPairsTransition(protected val testSpec: FlickerTestParameter)
@Presubmit
@Test
open fun navBarLayerRotatesAndScales() {
testSpec.navBarLayerRotatesAndScales(Surface.ROTATION_0,
testSpec.config.endRotation)
}
open fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
@Presubmit
@Test
open fun statusBarLayerRotatesScales() {
testSpec.statusBarLayerRotatesScales(Surface.ROTATION_0,
testSpec.config.endRotation)
}
open fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
}

View File

@@ -0,0 +1,118 @@
/*
* Copyright (C) 2021 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.wm.shell.flicker.bubble
import android.app.INotificationManager
import android.app.Instrumentation
import android.app.NotificationManager
import android.content.Context
import android.os.ServiceManager
import android.view.Surface
import androidx.test.filters.FlakyTest
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiObject2
import androidx.test.uiautomator.Until
import com.android.server.wm.flicker.FlickerBuilderProvider
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.helpers.SYSTEMUI_PACKAGE
import com.android.server.wm.flicker.repetitions
import com.android.wm.shell.flicker.helpers.LaunchBubbleHelper
import org.junit.Test
import org.junit.runners.Parameterized
/**
* Base configurations for Bubble flicker tests
*/
abstract class BaseBubbleScreen(protected val testSpec: FlickerTestParameter) {
protected val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
protected val context: Context = instrumentation.context
protected val testApp = LaunchBubbleHelper(instrumentation)
protected val notifyManager = INotificationManager.Stub.asInterface(
ServiceManager.getService(Context.NOTIFICATION_SERVICE))
protected val packageManager = context.getPackageManager()
protected val uid = packageManager.getApplicationInfo(
testApp.component.packageName, 0).uid
protected lateinit var addBubbleBtn: UiObject2
protected lateinit var cancelAllBtn: UiObject2
protected abstract val transition: FlickerBuilder.(Map<String, Any?>) -> Unit
@JvmOverloads
protected open fun buildTransition(
extraSpec: FlickerBuilder.(Map<String, Any?>) -> Unit = {}
): FlickerBuilder.(Map<String, Any?>) -> Unit {
return { configuration ->
setup {
test {
notifyManager.setBubblesAllowed(testApp.component.packageName,
uid, NotificationManager.BUBBLE_PREFERENCE_ALL)
testApp.launchViaIntent(wmHelper)
addBubbleBtn = device.wait(Until.findObject(
By.text("Add Bubble")), FIND_OBJECT_TIMEOUT)
cancelAllBtn = device.wait(Until.findObject(
By.text("Cancel All Bubble")), FIND_OBJECT_TIMEOUT)
}
}
teardown {
notifyManager.setBubblesAllowed(testApp.component.packageName,
uid, NotificationManager.BUBBLE_PREFERENCE_NONE)
testApp.exit()
}
extraSpec(this, configuration)
}
}
@FlakyTest
@Test
fun testAppIsAlwaysVisible() {
testSpec.assertLayers {
this.isVisible(testApp.component)
}
}
@FlickerBuilderProvider
fun buildFlicker(): FlickerBuilder {
return FlickerBuilder(instrumentation).apply {
repeat { testSpec.config.repetitions }
transition(this, testSpec.config)
}
}
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): List<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
.getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0),
repetitions = 5)
}
const val FIND_OBJECT_TIMEOUT = 2000L
const val SYSTEM_UI_PACKAGE = SYSTEMUI_PACKAGE
const val BUBBLE_RES_NAME = "bubble_view"
}
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright (C) 2021 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.wm.shell.flicker.bubble
import android.content.Context
import android.graphics.Point
import android.util.DisplayMetrics
import android.view.WindowManager
import androidx.test.filters.RequiresDevice
import androidx.test.uiautomator.By
import androidx.test.uiautomator.Until
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.annotation.Group4
import com.android.server.wm.flicker.dsl.FlickerBuilder
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
/**
* Test launching a new activity from bubble.
*
* To run this test: `atest WMShellFlickerTests:DismissBubbleScreen`
*
* Actions:
* Dismiss a bubble notification
*/
@RequiresDevice
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@Group4
class DismissBubbleScreen(testSpec: FlickerTestParameter) : BaseBubbleScreen(testSpec) {
val wm = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
val displaySize = DisplayMetrics()
override val transition: FlickerBuilder.(Map<String, Any?>) -> Unit
get() = buildTransition() {
setup {
eachRun {
addBubbleBtn?.run { addBubbleBtn.click() } ?: error("Add Bubble not found")
}
}
transitions {
wm?.run { wm.getDefaultDisplay().getMetrics(displaySize) } ?: error("WM not found")
val dist = Point((displaySize.widthPixels / 2), displaySize.heightPixels)
val showBubble = device.wait(Until.findObject(
By.res(SYSTEM_UI_PACKAGE, BUBBLE_RES_NAME)), FIND_OBJECT_TIMEOUT)
showBubble?.run { drag(dist, 1000) } ?: error("Show bubble not found")
}
}
}

View File

@@ -0,0 +1,59 @@
/*
* Copyright (C) 2021 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.wm.shell.flicker.bubble
import androidx.test.filters.RequiresDevice
import androidx.test.uiautomator.By
import androidx.test.uiautomator.Until
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.annotation.Group4
import com.android.server.wm.flicker.dsl.FlickerBuilder
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
/**
* Test launching a new activity from bubble.
*
* To run this test: `atest WMShellFlickerTests:ExpandBubbleScreen`
*
* Actions:
* Launch an app and enable app's bubble notification
* Send a bubble notification
* The activity for the bubble is launched
*/
@RequiresDevice
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@Group4
class ExpandBubbleScreen(testSpec: FlickerTestParameter) : BaseBubbleScreen(testSpec) {
override val transition: FlickerBuilder.(Map<String, Any?>) -> Unit
get() = buildTransition() {
setup {
test {
addBubbleBtn?.run { addBubbleBtn.click() } ?: error("Bubble widget not found")
}
}
transitions {
val showBubble = device.wait(Until.findObject(
By.res("com.android.systemui", "bubble_view")), FIND_OBJECT_TIMEOUT)
showBubble?.run { showBubble.click() } ?: error("Bubble notify not found")
device.pressBack()
}
}
}

View File

@@ -0,0 +1,48 @@
/*
* Copyright (C) 2021 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.wm.shell.flicker.bubble
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.annotation.Group4
import com.android.server.wm.flicker.dsl.FlickerBuilder
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
/**
* Test creating a bubble notification
*
* To run this test: `atest WMShellFlickerTests:LaunchBubbleScreen`
*
* Actions:
* Launch an app and enable app's bubble notification
* Send a bubble notification
*/
@RequiresDevice
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@Group4
class LaunchBubbleScreen(testSpec: FlickerTestParameter) : BaseBubbleScreen(testSpec) {
override val transition: FlickerBuilder.(Map<String, Any?>) -> Unit
get() = buildTransition() {
transitions {
addBubbleBtn?.run { addBubbleBtn.click() } ?: error("Bubble widget not found")
}
}
}

View File

@@ -0,0 +1,66 @@
/*
* Copyright (C) 2021 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.wm.shell.flicker.bubble
import android.os.SystemClock
import androidx.test.filters.RequiresDevice
import androidx.test.uiautomator.By
import androidx.test.uiautomator.Until
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.annotation.Group4
import com.android.server.wm.flicker.dsl.FlickerBuilder
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
/**
* Test launching a new activity from bubble.
*
* To run this test: `atest WMShellFlickerTests:MultiBubblesScreen`
*
* Actions:
* Switch in different bubble notifications
*/
@RequiresDevice
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@Group4
class MultiBubblesScreen(testSpec: FlickerTestParameter) : BaseBubbleScreen(testSpec) {
override val transition: FlickerBuilder.(Map<String, Any?>) -> Unit
get() = buildTransition() {
setup {
test {
for (i in 1..3) {
addBubbleBtn?.run { addBubbleBtn.click() } ?: error("Add Bubble not found")
}
val showBubble = device.wait(Until.findObject(
By.res(SYSTEM_UI_PACKAGE, BUBBLE_RES_NAME)), FIND_OBJECT_TIMEOUT)
showBubble?.run { showBubble.click() } ?: error("Show bubble not found")
SystemClock.sleep(1000)
}
}
transitions {
val bubbles = device.wait(Until.findObjects(
By.res(SYSTEM_UI_PACKAGE, BUBBLE_RES_NAME)), FIND_OBJECT_TIMEOUT)
for (entry in bubbles) {
entry?.run { entry.click() } ?: error("Bubble not found")
SystemClock.sleep(1000)
}
}
}
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright (C) 2021 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.wm.shell.flicker.helpers
import android.app.Instrumentation
import com.android.server.wm.traces.parser.toFlickerComponent
import com.android.wm.shell.flicker.testapp.Components
class LaunchBubbleHelper(instrumentation: Instrumentation) : BaseAppHelper(
instrumentation,
Components.LaunchBubbleActivity.LABEL,
Components.LaunchBubbleActivity.COMPONENT.toFlickerComponent()
) {
companion object {
const val TEST_REPETITIONS = 1
const val TIMEOUT_MS = 3_000L
}
}

View File

@@ -107,13 +107,11 @@ class LegacySplitScreenToLauncher(
@Presubmit
@Test
fun navBarLayerRotatesAndScales() =
testSpec.navBarLayerRotatesAndScales(testSpec.config.endRotation)
fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
@Presubmit
@Test
fun statusBarLayerRotatesScales() =
testSpec.statusBarLayerRotatesScales(testSpec.config.endRotation)
fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
@Presubmit
@Test

View File

@@ -27,7 +27,6 @@ import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.annotation.Group2
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.endRotation
import com.android.server.wm.flicker.entireScreenCovered
import com.android.server.wm.flicker.helpers.ImeAppHelper
import com.android.server.wm.flicker.helpers.WindowUtils
@@ -133,12 +132,10 @@ class ResizeLegacySplitScreen(
fun entireScreenCovered() = testSpec.entireScreenCovered()
@Test
fun navBarLayerRotatesAndScales() =
testSpec.navBarLayerRotatesAndScales(testSpec.config.endRotation)
fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
@Test
fun statusBarLayerRotatesScales() =
testSpec.statusBarLayerRotatesScales(testSpec.config.endRotation)
fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
@Test
fun topAppLayerIsAlwaysVisible() {

View File

@@ -25,7 +25,6 @@ import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.annotation.Group2
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.endRotation
import com.android.server.wm.flicker.helpers.launchSplitScreen
import com.android.server.wm.flicker.helpers.setRotation
import com.android.server.wm.flicker.navBarLayerRotatesAndScales
@@ -75,15 +74,11 @@ class RotateOneLaunchedAppAndEnterSplitScreen(
@Presubmit
@Test
fun navBarLayerRotatesAndScales() =
testSpec.navBarLayerRotatesAndScales(testSpec.config.startRotation,
testSpec.config.endRotation)
fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
@Presubmit
@Test
fun statusBarLayerRotatesScales() =
testSpec.statusBarLayerRotatesScales(testSpec.config.startRotation,
testSpec.config.endRotation)
fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
@Presubmit
@Test

View File

@@ -25,7 +25,6 @@ import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.annotation.Group2
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.endRotation
import com.android.server.wm.flicker.helpers.launchSplitScreen
import com.android.server.wm.flicker.helpers.setRotation
import com.android.server.wm.flicker.navBarLayerRotatesAndScales
@@ -74,13 +73,11 @@ class RotateOneLaunchedAppInSplitScreenMode(
@Presubmit
@Test
fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales(
testSpec.config.startRotation, testSpec.config.endRotation)
fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
@Presubmit
@Test
fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales(
testSpec.config.startRotation, testSpec.config.endRotation)
fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
@Presubmit
@Test

View File

@@ -24,7 +24,6 @@ import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.annotation.Group2
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.endRotation
import com.android.server.wm.flicker.helpers.launchSplitScreen
import com.android.server.wm.flicker.helpers.reopenAppFromOverview
import com.android.server.wm.flicker.helpers.setRotation
@@ -83,14 +82,11 @@ class RotateTwoLaunchedAppAndEnterSplitScreen(
@Presubmit
@Test
fun navBarLayerRotatesAndScales() =
testSpec.navBarLayerRotatesAndScales(testSpec.config.startRotation,
testSpec.config.endRotation)
fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
@Presubmit
@Test
fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales(
testSpec.config.startRotation, testSpec.config.endRotation)
fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
@Presubmit
@Test

View File

@@ -25,7 +25,6 @@ import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.annotation.Group2
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.endRotation
import com.android.server.wm.flicker.helpers.launchSplitScreen
import com.android.server.wm.flicker.helpers.reopenAppFromOverview
import com.android.server.wm.flicker.helpers.setRotation
@@ -89,15 +88,11 @@ class RotateTwoLaunchedAppInSplitScreenMode(
@Presubmit
@Test
fun navBarLayerRotatesAndScales() =
testSpec.navBarLayerRotatesAndScales(testSpec.config.startRotation,
testSpec.config.endRotation)
fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
@Presubmit
@Test
fun statusBarLayerRotatesScales() =
testSpec.statusBarLayerRotatesScales(testSpec.config.startRotation,
testSpec.config.endRotation)
fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
@FlakyTest
@Test

View File

@@ -111,8 +111,7 @@ class EnterPipToOtherOrientationTest(
*/
@FlakyTest
@Test
override fun navBarLayerRotatesAndScales() =
testSpec.navBarLayerRotatesAndScales(Surface.ROTATION_90, Surface.ROTATION_0)
override fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
/**
* Checks that the [FlickerComponentName.STATUS_BAR] has the correct position at
@@ -120,8 +119,7 @@ class EnterPipToOtherOrientationTest(
*/
@Presubmit
@Test
override fun statusBarLayerRotatesScales() =
testSpec.statusBarLayerRotatesScales(Surface.ROTATION_90, Surface.ROTATION_0)
override fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
/**
* Checks that all parts of the screen are covered at the start and end of the transition

View File

@@ -16,7 +16,6 @@
package com.android.wm.shell.flicker.pip
import android.platform.test.annotations.Postsubmit
import android.view.Surface
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
@@ -25,7 +24,6 @@ import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.annotation.Group3
import com.android.server.wm.flicker.dsl.FlickerBuilder
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
import org.junit.runners.Parameterized
@@ -62,14 +60,6 @@ class ExitPipWithDismissButtonTest(testSpec: FlickerTestParameter) : ExitPipTran
}
}
@Postsubmit
@Test
override fun pipLayerBecomesInvisible() = super.pipLayerBecomesInvisible()
@Postsubmit
@Test
override fun pipWindowBecomesInvisible() = super.pipWindowBecomesInvisible()
companion object {
/**
* Creates the test configurations.

View File

@@ -25,7 +25,6 @@ import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.annotation.Group3
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.startRotation
import com.android.server.wm.flicker.statusBarLayerRotatesScales
import org.junit.FixMethodOrder
import org.junit.Test
@@ -97,8 +96,7 @@ class ExitPipWithSwipeDownTest(testSpec: FlickerTestParameter) : ExitPipTransiti
@Presubmit
@Test
override fun statusBarLayerRotatesScales() =
testSpec.statusBarLayerRotatesScales(testSpec.config.startRotation, Surface.ROTATION_0)
override fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
@Presubmit
@Test

View File

@@ -16,7 +16,6 @@
package com.android.wm.shell.flicker.pip
import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
import android.view.Surface
import androidx.test.filters.FlakyTest
@@ -90,7 +89,7 @@ class ExpandPipOnDoubleClickTest(testSpec: FlickerTestParameter) : PipTransition
/**
* Checks [pipApp] window remains visible throughout the animation
*/
@Postsubmit
@Presubmit
@Test
fun pipWindowIsAlwaysVisible() {
testSpec.assertWm {

View File

@@ -95,18 +95,14 @@ class PipRotationTest(testSpec: FlickerTestParameter) : PipTransition(testSpec)
*/
@FlakyTest
@Test
override fun navBarLayerRotatesAndScales() =
testSpec.navBarLayerRotatesAndScales(testSpec.config.startRotation,
testSpec.config.endRotation)
override fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
/**
* Checks the position of the status bar at the start and end of the transition
*/
@Presubmit
@Test
override fun statusBarLayerRotatesScales() =
testSpec.statusBarLayerRotatesScales(testSpec.config.startRotation,
testSpec.config.endRotation)
override fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
/**
* Checks that [fixedApp] layer is within [screenBoundsStart] at the start of the transition

View File

@@ -177,13 +177,11 @@ abstract class PipTransition(protected val testSpec: FlickerTestParameter) {
@Presubmit
@Test
open fun navBarLayerRotatesAndScales() =
testSpec.navBarLayerRotatesAndScales(testSpec.config.startRotation, Surface.ROTATION_0)
open fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
@Presubmit
@Test
open fun statusBarLayerRotatesScales() =
testSpec.statusBarLayerRotatesScales(testSpec.config.startRotation, Surface.ROTATION_0)
open fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
@Presubmit
@Test

View File

@@ -107,5 +107,20 @@
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity
android:name=".LaunchBubbleActivity"
android:label="LaunchBubbleApp"
android:exported="true"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.VIEW" />
</intent-filter>
</activity>
<activity
android:name=".BubbleActivity"
android:label="BubbleApp"
android:exported="false"
android:resizeableActivity="true" />
</application>
</manifest>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2021 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M7.2,14.4m-3.2,0a3.2,3.2 0,1 1,6.4 0a3.2,3.2 0,1 1,-6.4 0"/>
<path
android:fillColor="#FF000000"
android:pathData="M14.8,18m-2,0a2,2 0,1 1,4 0a2,2 0,1 1,-4 0"/>
<path
android:fillColor="#FF000000"
android:pathData="M15.2,8.8m-4.8,0a4.8,4.8 0,1 1,9.6 0a4.8,4.8 0,1 1,-9.6 0"/>
</vector>

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2021 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M12,4c-4.97,0 -9,3.58 -9,8c0,1.53 0.49,2.97 1.33,4.18c0.12,0.18 0.2,0.46 0.1,0.66c-0.33,0.68 -0.79,1.52 -1.38,2.39c-0.12,0.17 0.01,0.41 0.21,0.39c0.63,-0.05 1.86,-0.26 3.38,-0.91c0.17,-0.07 0.36,-0.06 0.52,0.03C8.55,19.54 10.21,20 12,20c4.97,0 9,-3.58 9,-8S16.97,4 12,4zM16.94,11.63l-3.29,3.29c-0.13,0.13 -0.34,0.04 -0.34,-0.14v-1.57c0,-0.11 -0.1,-0.21 -0.21,-0.2c-2.19,0.06 -3.65,0.65 -5.14,1.95c-0.15,0.13 -0.38,0 -0.33,-0.19c0.7,-2.57 2.9,-4.57 5.5,-4.75c0.1,-0.01 0.18,-0.09 0.18,-0.19V8.2c0,-0.18 0.22,-0.27 0.34,-0.14l3.29,3.29C17.02,11.43 17.02,11.55 16.94,11.63z"
android:fillColor="#000000"
android:fillType="evenOdd"/>
</vector>

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2021 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:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/button_finish"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:layout_marginStart="8dp"
android:text="Finish" />
<Button
android:id="@+id/button_new_task"
android:layout_width="wrap_content"
android:layout_height="46dp"
android:layout_marginStart="8dp"
android:text="New Task" />
<Button
android:id="@+id/button_new_bubble"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:text="New Bubble" />
<Button
android:id="@+id/button_activity_for_result"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:text="Activity For Result" />
</LinearLayout>

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2021 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.
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@android:color/black">
<Button
android:id="@+id/button_create"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="Add Bubble" />
<Button
android:id="@+id/button_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/button_create"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp"
android:text="Cancel Bubble" />
<Button
android:id="@+id/button_cancel_all"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/button_cancel"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp"
android:text="Cancel All Bubble" />
</RelativeLayout>

View File

@@ -0,0 +1,77 @@
/*
* Copyright (C) 2020 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.wm.shell.flicker.testapp;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;
public class BubbleActivity extends Activity {
private int mNotifId = 0;
public BubbleActivity() {
super();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
if (intent != null) {
mNotifId = intent.getIntExtra(BubbleHelper.EXTRA_BUBBLE_NOTIF_ID, -1);
} else {
mNotifId = -1;
}
setContentView(R.layout.activity_bubble);
}
@Override
protected void onStart() {
super.onStart();
}
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onPause() {
super.onPause();
}
@Override
protected void onStop() {
super.onStop();
}
@Override
protected void onDestroy() {
super.onDestroy();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
String result = resultCode == Activity.RESULT_OK ? "OK" : "CANCELLED";
Toast.makeText(this, "Activity result: " + result, Toast.LENGTH_SHORT).show();
}
}

View File

@@ -0,0 +1,178 @@
/*
* Copyright (C) 2021 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.wm.shell.flicker.testapp;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Person;
import android.app.RemoteInput;
import android.content.Context;
import android.content.Intent;
import android.graphics.Point;
import android.graphics.drawable.Icon;
import android.os.SystemClock;
import android.service.notification.StatusBarNotification;
import android.view.WindowManager;
import java.util.HashMap;
public class BubbleHelper {
static final String EXTRA_BUBBLE_NOTIF_ID = "EXTRA_BUBBLE_NOTIF_ID";
static final String CHANNEL_ID = "bubbles";
static final String CHANNEL_NAME = "Bubbles";
static final int DEFAULT_HEIGHT_DP = 300;
private static BubbleHelper sInstance;
private final Context mContext;
private NotificationManager mNotificationManager;
private float mDisplayHeight;
private HashMap<Integer, BubbleInfo> mBubbleMap = new HashMap<>();
private int mNextNotifyId = 0;
private int mColourIndex = 0;
public static class BubbleInfo {
public int id;
public int height;
public Icon icon;
public BubbleInfo(int id, int height, Icon icon) {
this.id = id;
this.height = height;
this.icon = icon;
}
}
public static BubbleHelper getInstance(Context context) {
if (sInstance == null) {
sInstance = new BubbleHelper(context);
}
return sInstance;
}
private BubbleHelper(Context context) {
mContext = context;
mNotificationManager = context.getSystemService(NotificationManager.class);
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME,
NotificationManager.IMPORTANCE_DEFAULT);
channel.setDescription("Channel that posts bubbles");
channel.setAllowBubbles(true);
mNotificationManager.createNotificationChannel(channel);
Point p = new Point();
WindowManager wm = context.getSystemService(WindowManager.class);
wm.getDefaultDisplay().getRealSize(p);
mDisplayHeight = p.y;
}
private int getNextNotifyId() {
int id = mNextNotifyId;
mNextNotifyId++;
return id;
}
private Icon getIcon() {
return Icon.createWithResource(mContext, R.drawable.bg);
}
public int addNewBubble(boolean autoExpand, boolean suppressNotif) {
int id = getNextNotifyId();
BubbleInfo info = new BubbleInfo(id, DEFAULT_HEIGHT_DP, getIcon());
mBubbleMap.put(info.id, info);
Notification.BubbleMetadata data = getBubbleBuilder(info)
.setSuppressNotification(suppressNotif)
.setAutoExpandBubble(false)
.build();
Notification notification = getNotificationBuilder(info.id)
.setBubbleMetadata(data).build();
mNotificationManager.notify(info.id, notification);
return info.id;
}
private Notification.Builder getNotificationBuilder(int id) {
Person chatBot = new Person.Builder()
.setBot(true)
.setName("BubbleBot")
.setImportant(true)
.build();
RemoteInput remoteInput = new RemoteInput.Builder("key")
.setLabel("Reply")
.build();
String shortcutId = "BubbleChat";
return new Notification.Builder(mContext, CHANNEL_ID)
.setChannelId(CHANNEL_ID)
.setShortcutId(shortcutId)
.setContentIntent(PendingIntent.getActivity(mContext, 0,
new Intent(mContext, LaunchBubbleActivity.class),
PendingIntent.FLAG_UPDATE_CURRENT))
.setStyle(new Notification.MessagingStyle(chatBot)
.setConversationTitle("Bubble Chat")
.addMessage("Hello? This is bubble: " + id,
SystemClock.currentThreadTimeMillis() - 300000, chatBot)
.addMessage("Is it me, " + id + ", you're looking for?",
SystemClock.currentThreadTimeMillis(), chatBot)
)
.setSmallIcon(R.drawable.ic_bubble);
}
private Notification.BubbleMetadata.Builder getBubbleBuilder(BubbleInfo info) {
Intent target = new Intent(mContext, BubbleActivity.class);
target.putExtra(EXTRA_BUBBLE_NOTIF_ID, info.id);
PendingIntent bubbleIntent = PendingIntent.getActivity(mContext, info.id, target,
PendingIntent.FLAG_UPDATE_CURRENT);
return new Notification.BubbleMetadata.Builder()
.setIntent(bubbleIntent)
.setIcon(info.icon)
.setDesiredHeight(info.height);
}
public void cancel(int id) {
mNotificationManager.cancel(id);
}
public void cancelAll() {
mNotificationManager.cancelAll();
}
public void cancelLast() {
StatusBarNotification[] activeNotifications = mNotificationManager.getActiveNotifications();
if (activeNotifications.length > 0) {
mNotificationManager.cancel(
activeNotifications[activeNotifications.length - 1].getId());
}
}
public void cancelFirst() {
StatusBarNotification[] activeNotifications = mNotificationManager.getActiveNotifications();
if (activeNotifications.length > 0) {
mNotificationManager.cancel(activeNotifications[0].getId());
}
}
}

View File

@@ -87,4 +87,16 @@ public class Components {
public static final ComponentName COMPONENT = new ComponentName(PACKAGE_NAME,
PACKAGE_NAME + ".SplitScreenSecondaryActivity");
}
public static class LaunchBubbleActivity {
public static final String LABEL = "LaunchBubbleApp";
public static final ComponentName COMPONENT = new ComponentName(PACKAGE_NAME,
PACKAGE_NAME + ".LaunchBubbleActivity");
}
public static class BubbleActivity {
public static final String LABEL = "BubbleApp";
public static final ComponentName COMPONENT = new ComponentName(PACKAGE_NAME,
PACKAGE_NAME + ".BubbleActivity");
}
}

View File

@@ -0,0 +1,82 @@
/*
* Copyright (C) 2021 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.wm.shell.flicker.testapp;
import android.app.Activity;
import android.app.Person;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager;
import android.graphics.drawable.Icon;
import android.os.Bundle;
import android.view.View;
import java.util.Arrays;
public class LaunchBubbleActivity extends Activity {
private BubbleHelper mBubbleHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addInboxShortcut(getApplicationContext());
mBubbleHelper = BubbleHelper.getInstance(this);
setContentView(R.layout.activity_main);
findViewById(R.id.button_create).setOnClickListener(this::add);
findViewById(R.id.button_cancel).setOnClickListener(this::cancel);
findViewById(R.id.button_cancel_all).setOnClickListener(this::cancelAll);
}
private void add(View v) {
mBubbleHelper.addNewBubble(false /* autoExpand */, false /* suppressNotif */);
}
private void cancel(View v) {
mBubbleHelper.cancelLast();
}
private void cancelAll(View v) {
mBubbleHelper.cancelAll();
}
private void addInboxShortcut(Context context) {
Icon icon = Icon.createWithResource(this, R.drawable.bg);
Person[] persons = new Person[4];
for (int i = 0; i < persons.length; i++) {
persons[i] = new Person.Builder()
.setBot(false)
.setIcon(icon)
.setName("google" + i)
.setImportant(true)
.build();
}
ShortcutInfo shortcut = new ShortcutInfo.Builder(context, "BubbleChat")
.setShortLabel("BubbleChat")
.setLongLived(true)
.setIntent(new Intent(Intent.ACTION_VIEW))
.setIcon(Icon.createWithResource(context, R.drawable.ic_message))
.setPersons(persons)
.build();
ShortcutManager scmanager = context.getSystemService(ShortcutManager.class);
scmanager.addDynamicShortcuts(Arrays.asList(shortcut));
}
}

View File

@@ -102,35 +102,33 @@ fun FlickerTestParameter.statusBarLayerIsVisible() {
}
}
@JvmOverloads
fun FlickerTestParameter.navBarLayerRotatesAndScales(
beginRotation: Int,
endRotation: Int = beginRotation
) {
val startingPos = WindowUtils.getNavigationBarPosition(beginRotation)
val endingPos = WindowUtils.getNavigationBarPosition(endRotation)
fun FlickerTestParameter.navBarLayerRotatesAndScales() {
assertLayersStart {
this.visibleRegion(FlickerComponentName.NAV_BAR).coversExactly(startingPos)
val display = this.entry.displays.minByOrNull { it.id }
?: throw RuntimeException("There is no display!")
this.visibleRegion(FlickerComponentName.NAV_BAR)
.coversExactly(WindowUtils.getNavigationBarPosition(display))
}
assertLayersEnd {
this.visibleRegion(FlickerComponentName.NAV_BAR).coversExactly(endingPos)
val display = this.entry.displays.minByOrNull { it.id }
?: throw RuntimeException("There is no display!")
this.visibleRegion(FlickerComponentName.NAV_BAR)
.coversExactly(WindowUtils.getNavigationBarPosition(display))
}
}
@JvmOverloads
fun FlickerTestParameter.statusBarLayerRotatesScales(
beginRotation: Int,
endRotation: Int = beginRotation
) {
val startingPos = WindowUtils.getStatusBarPosition(beginRotation)
val endingPos = WindowUtils.getStatusBarPosition(endRotation)
fun FlickerTestParameter.statusBarLayerRotatesScales() {
assertLayersStart {
this.visibleRegion(FlickerComponentName.STATUS_BAR).coversExactly(startingPos)
val display = this.entry.displays.minByOrNull { it.id }
?: throw RuntimeException("There is no display!")
this.visibleRegion(FlickerComponentName.STATUS_BAR)
.coversExactly(WindowUtils.getStatusBarPosition(display))
}
assertLayersEnd {
this.visibleRegion(FlickerComponentName.STATUS_BAR).coversExactly(endingPos)
val display = this.entry.displays.minByOrNull { it.id }
?: throw RuntimeException("There is no display!")
this.visibleRegion(FlickerComponentName.STATUS_BAR)
.coversExactly(WindowUtils.getStatusBarPosition(display))
}
}

View File

@@ -17,7 +17,6 @@
package com.android.server.wm.flicker.close
import android.platform.test.annotations.Postsubmit
import androidx.test.filters.FlakyTest
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
@@ -80,11 +79,6 @@ class CloseAppBackButtonTest(testSpec: FlickerTestParameter) : CloseAppTransitio
@Test
override fun navBarLayerRotatesAndScales() = super.navBarLayerRotatesAndScales()
/** {@inheritDoc} */
@Postsubmit
@Test
override fun navBarLayerIsVisible() = super.navBarLayerIsVisible()
companion object {
/**
* Creates the test configurations.

View File

@@ -16,7 +16,6 @@
package com.android.server.wm.flicker.close
import android.platform.test.annotations.Postsubmit
import androidx.test.filters.FlakyTest
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
@@ -79,11 +78,6 @@ class CloseAppHomeButtonTest(testSpec: FlickerTestParameter) : CloseAppTransitio
@Test
override fun navBarLayerRotatesAndScales() = super.navBarLayerRotatesAndScales()
/** {@inheritDoc} */
@Postsubmit
@Test
override fun navBarLayerIsVisible() = super.navBarLayerIsVisible()
companion object {
/**
* Creates the test configurations.

View File

@@ -18,7 +18,6 @@ package com.android.server.wm.flicker.close
import android.app.Instrumentation
import android.platform.test.annotations.Presubmit
import android.view.Surface
import androidx.test.platform.app.InstrumentationRegistry
import com.android.server.wm.flicker.FlickerBuilderProvider
import com.android.server.wm.flicker.FlickerTestParameter
@@ -114,18 +113,14 @@ abstract class CloseAppTransition(protected val testSpec: FlickerTestParameter)
*/
@Presubmit
@Test
open fun navBarLayerRotatesAndScales() {
testSpec.navBarLayerRotatesAndScales(testSpec.config.startRotation, Surface.ROTATION_0)
}
open fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
/**
* Checks the position of the status bar at the start and end of the transition
*/
@Presubmit
@Test
open fun statusBarLayerRotatesScales() {
testSpec.statusBarLayerRotatesScales(testSpec.config.startRotation, Surface.ROTATION_0)
}
open fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
/**
* Checks that all windows that are visible on the trace, are visible for at least 2

View File

@@ -0,0 +1,52 @@
/*
* Copyright (C) 2021 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.helpers
import android.app.Instrumentation
import android.support.test.launcherhelper.ILauncherStrategy
import android.support.test.launcherhelper.LauncherStrategyFactory
import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiDevice
import androidx.test.uiautomator.Until
import com.android.server.wm.flicker.testapp.ActivityOptions
import com.android.server.wm.traces.common.FlickerComponentName
import com.android.server.wm.traces.parser.toFlickerComponent
import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
class NewTasksAppHelper @JvmOverloads constructor(
instr: Instrumentation,
launcherName: String = ActivityOptions.LAUNCH_NEW_TASK_ACTIVITY_LAUNCHER_NAME,
component: FlickerComponentName =
ActivityOptions.LAUNCH_NEW_TASK_ACTIVITY_COMPONENT_NAME.toFlickerComponent(),
launcherStrategy: ILauncherStrategy = LauncherStrategyFactory
.getInstance(instr)
.launcherStrategy
) : StandardAppHelper(instr, launcherName, component, launcherStrategy) {
fun openNewTask(device: UiDevice, wmHelper: WindowManagerStateHelper) {
val button = device.wait(
Until.findObject(By.res(getPackage(), "launch_new_task")),
FIND_TIMEOUT)
require(button != null) {
"Button not found, this usually happens when the device " +
"was left in an unknown state (e.g. in split screen)"
}
button.click()
wmHelper.waitForAppTransitionIdle()
wmHelper.waitForFullScreenApp(component)
}
}

View File

@@ -151,15 +151,11 @@ class CloseImeAutoOpenWindowToAppTest(private val testSpec: FlickerTestParameter
@Presubmit
@Test
fun navBarLayerRotatesAndScales() {
testSpec.navBarLayerRotatesAndScales(testSpec.config.startRotation)
}
fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
@Presubmit
@Test
fun statusBarLayerRotatesScales() {
testSpec.statusBarLayerRotatesScales(testSpec.config.startRotation)
}
fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
@Presubmit
@Test

View File

@@ -150,15 +150,11 @@ class CloseImeAutoOpenWindowToHomeTest(private val testSpec: FlickerTestParamete
@Presubmit
@Test
fun navBarLayerRotatesAndScales() {
testSpec.navBarLayerRotatesAndScales(testSpec.config.startRotation, Surface.ROTATION_0)
}
fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
@Presubmit
@Test
fun statusBarLayerRotatesScales() {
testSpec.statusBarLayerRotatesScales(testSpec.config.startRotation, Surface.ROTATION_0)
}
fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
@Presubmit
@Test

View File

@@ -32,7 +32,6 @@ import com.android.server.wm.flicker.navBarLayerIsVisible
import com.android.server.wm.flicker.navBarLayerRotatesAndScales
import com.android.server.wm.flicker.navBarWindowIsVisible
import com.android.server.wm.flicker.entireScreenCovered
import com.android.server.wm.flicker.startRotation
import com.android.server.wm.flicker.statusBarLayerRotatesScales
import com.android.server.wm.flicker.statusBarWindowIsVisible
import com.android.server.wm.traces.common.FlickerComponentName
@@ -121,21 +120,19 @@ class CloseImeWindowToAppTest(private val testSpec: FlickerTestParameter) {
@Test
fun navBarLayerRotatesAndScales() {
Assume.assumeFalse(testSpec.isRotated)
testSpec.navBarLayerRotatesAndScales(testSpec.config.startRotation)
testSpec.navBarLayerRotatesAndScales()
}
@FlakyTest
@Test
fun navBarLayerRotatesAndScales_Flaky() {
Assume.assumeTrue(testSpec.isRotated)
testSpec.navBarLayerRotatesAndScales(testSpec.config.startRotation)
testSpec.navBarLayerRotatesAndScales()
}
@Presubmit
@Test
fun statusBarLayerRotatesScales() {
testSpec.statusBarLayerRotatesScales(testSpec.config.startRotation)
}
fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
@Presubmit
@Test

View File

@@ -34,7 +34,6 @@ import com.android.server.wm.flicker.navBarLayerIsVisible
import com.android.server.wm.flicker.navBarLayerRotatesAndScales
import com.android.server.wm.flicker.navBarWindowIsVisible
import com.android.server.wm.flicker.entireScreenCovered
import com.android.server.wm.flicker.startRotation
import com.android.server.wm.flicker.statusBarLayerRotatesScales
import com.android.server.wm.flicker.statusBarWindowIsVisible
import com.android.server.wm.traces.common.FlickerComponentName
@@ -143,14 +142,11 @@ class CloseImeWindowToHomeTest(private val testSpec: FlickerTestParameter) {
@Presubmit
@Test
fun navBarLayerRotatesAndScales() =
testSpec.navBarLayerRotatesAndScales(testSpec.config.startRotation, Surface.ROTATION_0)
fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
@Presubmit
@Test
fun statusBarLayerRotatesScales() {
testSpec.statusBarLayerRotatesScales(testSpec.config.startRotation, Surface.ROTATION_0)
}
fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
@Presubmit
@Test

View File

@@ -0,0 +1,153 @@
/*
* Copyright (C) 2021 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.ime
import android.app.Instrumentation
import android.platform.test.annotations.Presubmit
import android.view.Surface
import android.view.WindowManagerPolicyConstants
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
import com.android.server.wm.flicker.FlickerBuilderProvider
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper
import com.android.server.wm.flicker.helpers.setRotation
import com.android.server.wm.flicker.startRotation
import com.android.server.wm.traces.common.FlickerComponentName
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
import org.junit.runners.Parameterized
/**
* Launch an app that automatically displays the IME
*
* To run this test: `atest FlickerTests:LaunchAppShowImeOnStartTest`
*
* Actions:
* Make sure no apps are running on the device
* Launch an app [testApp] that automatically displays IME and wait animation to complete
*
* To run only the presubmit assertions add: `--
* --module-arg FlickerTests:exclude-annotation:androidx.test.filters.FlakyTest
* --module-arg FlickerTests:include-annotation:android.platform.test.annotations.Presubmit`
*
* To run only the postsubmit assertions add: `--
* --module-arg FlickerTests:exclude-annotation:androidx.test.filters.FlakyTest
* --module-arg FlickerTests:include-annotation:android.platform.test.annotations.Postsubmit`
*
* To run only the flaky assertions add: `--
* --module-arg FlickerTests:include-annotation:androidx.test.filters.FlakyTest`
*
* Notes:
* 1. Some default assertions (e.g., nav bar, status bar and screen covered)
* are inherited [CloseAppTransition]
* 2. Part of the test setup occurs automatically via
* [com.android.server.wm.flicker.TransitionRunnerWithRules],
* including configuring navigation mode, initial orientation and ensuring no
* apps are running before setup
*/
@RequiresDevice
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
class LaunchAppShowImeOnStartTest(private val testSpec: FlickerTestParameter) {
private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
private val testApp = ImeAppAutoFocusHelper(instrumentation, testSpec.config.startRotation)
@FlickerBuilderProvider
fun buildFlicker(): FlickerBuilder {
return FlickerBuilder(instrumentation).apply {
setup {
eachRun {
this.setRotation(testSpec.config.startRotation)
}
}
teardown {
eachRun {
testApp.exit()
}
}
transitions {
testApp.launchViaIntent(wmHelper)
wmHelper.waitImeShown()
}
}
}
/**
* Checks that [FlickerComponentName.IME] window becomes visible during the transition
*/
@Presubmit
@Test
fun imeWindowBecomesVisible() = testSpec.imeWindowBecomesVisible()
/**
* Checks that [FlickerComponentName.IME] layer becomes visible during the transition
*/
@Presubmit
@Test
fun imeLayerBecomesVisible() = testSpec.imeLayerBecomesVisible()
/**
* Checks that [FlickerComponentName.IME] layer is invisible at the start of the transition
*/
@Presubmit
@Test
fun imeLayerNotExistsStart() {
testSpec.assertLayersStart {
this.isInvisible(FlickerComponentName.IME)
}
}
/**
* Checks that [FlickerComponentName.IME] layer is visible at the end of the transition
*/
@Presubmit
@Test
fun imeLayerExistsEnd() {
testSpec.assertLayersEnd {
this.isVisible(FlickerComponentName.IME)
}
}
companion object {
/**
* Creates the test configurations.
*
* See [FlickerTestParameterFactory.getConfigNonRotationTests] for configuring
* repetitions, screen orientation and navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
.getConfigNonRotationTests(
repetitions = 5,
supportedRotations = listOf(Surface.ROTATION_0),
supportedNavigationModes = listOf(
WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY,
WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
)
)
}
}
}

View File

@@ -34,7 +34,6 @@ import com.android.server.wm.flicker.navBarLayerRotatesAndScales
import com.android.server.wm.flicker.navBarWindowIsVisible
import com.android.server.wm.flicker.entireScreenCovered
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.startRotation
import com.android.server.wm.flicker.statusBarLayerIsVisible
import com.android.server.wm.flicker.statusBarLayerRotatesScales
import com.android.server.wm.flicker.statusBarWindowIsVisible
@@ -125,15 +124,11 @@ class OpenImeWindowTest(private val testSpec: FlickerTestParameter) {
@Presubmit
@Test
fun navBarLayerRotatesAndScales() {
testSpec.navBarLayerRotatesAndScales(testSpec.config.startRotation)
}
fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
@Presubmit
@Test
fun statusBarLayerRotatesScales() {
testSpec.statusBarLayerRotatesScales(testSpec.config.startRotation)
}
fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
@Presubmit
@Test

View File

@@ -38,7 +38,6 @@ import com.android.server.wm.flicker.navBarWindowIsVisible
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.entireScreenCovered
import com.android.server.wm.flicker.startRotation
import com.android.server.wm.flicker.endRotation
import com.android.server.wm.flicker.statusBarLayerIsVisible
import com.android.server.wm.flicker.statusBarLayerRotatesScales
import com.android.server.wm.flicker.statusBarWindowIsVisible
@@ -207,15 +206,11 @@ class ReOpenImeWindowTest(private val testSpec: FlickerTestParameter) {
@Presubmit
@Test
fun navBarLayerRotatesAndScales() {
testSpec.navBarLayerRotatesAndScales(Surface.ROTATION_0, testSpec.config.endRotation)
}
fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
@Presubmit
@Test
fun statusBarLayerRotatesScales() {
testSpec.statusBarLayerRotatesScales(Surface.ROTATION_0, testSpec.config.endRotation)
}
fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
@Presubmit
@Test

View File

@@ -27,6 +27,7 @@ import com.android.server.wm.flicker.helpers.reopenAppFromOverview
import com.android.server.wm.flicker.helpers.setRotation
import com.android.server.wm.flicker.startRotation
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.traces.common.WindowManagerConditionsFactory
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -78,6 +79,11 @@ class OpenAppFromOverviewTest(testSpec: FlickerTestParameter) : OpenAppTransitio
}
transitions {
device.reopenAppFromOverview(wmHelper)
wmHelper.waitFor(
WindowManagerConditionsFactory.hasLayersAnimating().negate(),
WindowManagerConditionsFactory.isWMStateComplete(),
WindowManagerConditionsFactory.isHomeActivityVisible().negate()
)
wmHelper.waitForFullScreenApp(testApp.component)
}
}

View File

@@ -28,6 +28,7 @@ import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.annotation.Group1
import com.android.server.wm.flicker.helpers.NonResizeableAppHelper
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.statusBarWindowIsVisible
import com.android.server.wm.traces.common.FlickerComponentName
import com.google.common.truth.Truth
import org.junit.FixMethodOrder
@@ -107,7 +108,7 @@ class OpenAppNonResizeableTest(testSpec: FlickerTestParameter) : OpenAppTransiti
* Checks that the app layer doesn't exist at the start of the transition, that it is
* created (invisible) and becomes visible during the transition
*/
@Presubmit
@FlakyTest
@Test
fun appLayerBecomesVisible() {
testSpec.assertLayers {
@@ -165,6 +166,11 @@ class OpenAppNonResizeableTest(testSpec: FlickerTestParameter) : OpenAppTransiti
}
}
/** {@inheritDoc} */
@FlakyTest
@Test
override fun statusBarWindowIsVisible() = super.statusBarWindowIsVisible()
/** {@inheritDoc} */
@FlakyTest
@Test

View File

@@ -18,13 +18,11 @@ package com.android.server.wm.flicker.launch
import android.app.Instrumentation
import android.platform.test.annotations.Presubmit
import android.view.Surface
import androidx.test.platform.app.InstrumentationRegistry
import com.android.server.wm.flicker.FlickerBuilderProvider
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.LAUNCHER_COMPONENT
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.endRotation
import com.android.server.wm.flicker.entireScreenCovered
import com.android.server.wm.flicker.helpers.SimpleAppHelper
import com.android.server.wm.flicker.helpers.StandardAppHelper
@@ -98,9 +96,7 @@ abstract class OpenAppTransition(protected val testSpec: FlickerTestParameter) {
*/
@Presubmit
@Test
open fun navBarLayerRotatesAndScales() {
testSpec.navBarLayerRotatesAndScales(Surface.ROTATION_0, testSpec.config.endRotation)
}
open fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
/**
* Checks that the status bar window is visible during the whole transition
@@ -125,9 +121,7 @@ abstract class OpenAppTransition(protected val testSpec: FlickerTestParameter) {
*/
@Presubmit
@Test
open fun statusBarLayerRotatesScales() {
testSpec.statusBarLayerRotatesScales(Surface.ROTATION_0, testSpec.config.endRotation)
}
open fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
/**
* Checks that all windows that are visible on the trace, are visible for at least 2

View File

@@ -0,0 +1,248 @@
/*
* Copyright (C) 2021 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.launch
import android.app.Instrumentation
import android.app.WallpaperManager
import android.platform.test.annotations.Postsubmit
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
import com.android.server.wm.flicker.FlickerBuilderProvider
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.LAUNCHER_COMPONENT
import com.android.server.wm.flicker.annotation.Group4
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.entireScreenCovered
import com.android.server.wm.flicker.helpers.NewTasksAppHelper
import com.android.server.wm.flicker.helpers.WindowUtils
import com.android.server.wm.flicker.navBarLayerIsVisible
import com.android.server.wm.flicker.navBarWindowIsVisible
import com.android.server.wm.flicker.repetitions
import com.android.server.wm.flicker.startRotation
import com.android.server.wm.flicker.statusBarLayerIsVisible
import com.android.server.wm.flicker.statusBarWindowIsVisible
import com.android.server.wm.flicker.testapp.ActivityOptions.LAUNCH_NEW_TASK_ACTIVITY_COMPONENT_NAME
import com.android.server.wm.flicker.testapp.ActivityOptions.SIMPLE_ACTIVITY_AUTO_FOCUS_COMPONENT_NAME
import com.android.server.wm.traces.common.FlickerComponentName
import com.android.server.wm.traces.common.FlickerComponentName.Companion.SPLASH_SCREEN
import com.android.server.wm.traces.common.FlickerComponentName.Companion.WALLPAPER_BBQ_WRAPPER
import com.android.server.wm.traces.parser.toFlickerComponent
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
import org.junit.runners.Parameterized
/**
* Test the back and forward transition between 2 activities.
*
* To run this test: `atest FlickerTests:ActivitiesTransitionTest`
*
* Actions:
* Launch the NewTaskLauncherApp [mTestApp]
* Open a new task (SimpleActivity) from the NewTaskLauncherApp [mTestApp]
* Go back to the NewTaskLauncherApp [mTestApp]
*/
@RequiresDevice
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Group4
class TaskTransitionTest(val testSpec: FlickerTestParameter) {
val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
private val mTestApp: NewTasksAppHelper = NewTasksAppHelper(instrumentation)
@FlickerBuilderProvider
fun buildFlicker(): FlickerBuilder {
return FlickerBuilder(instrumentation).apply {
withTestName { testSpec.name }
repeat { testSpec.config.repetitions }
setup {
eachRun {
mTestApp.launchViaIntent(wmHelper)
wmHelper.waitForFullScreenApp(mTestApp.component)
}
}
teardown {
test {
mTestApp.exit()
}
}
transitions {
mTestApp.openNewTask(device, wmHelper)
device.pressBack()
wmHelper.waitForAppTransitionIdle()
wmHelper.waitForFullScreenApp(mTestApp.component)
}
}
}
/**
* Checks that the wallpaper window is never visible when performing task transitions.
* A solid color background should be shown instead.
*/
@Postsubmit
@Test
fun wallpaperWindowIsNeverVisible() {
testSpec.assertWm {
this.isNonAppWindowInvisible(WALLPAPER)
}
}
/**
* Checks that the wallpaper layer is never visible when performing task transitions.
* A solid color background should be shown instead.
*/
@Postsubmit
@Test
fun wallpaperLayerIsNeverVisible() {
testSpec.assertLayers {
this.isInvisible(WALLPAPER)
this.isInvisible(WALLPAPER_BBQ_WRAPPER)
}
}
/**
* Check that the launcher window is never visible when performing task transitions.
* A solid color background should be shown above it.
*/
@Postsubmit
@Test
fun launcherWindowIsNeverVisible() {
testSpec.assertWm {
this.isAppWindowInvisible(LAUNCHER_COMPONENT)
}
}
/**
* Checks that the launcher layer is never visible when performing task transitions.
* A solid color background should be shown above it.
*/
@Postsubmit
@Test
fun launcherLayerIsNeverVisible() {
testSpec.assertLayers {
this.isInvisible(LAUNCHER_COMPONENT)
}
}
/**
* Checks that a color background is visible while the task transition is occurring.
*/
@Postsubmit
@Test
fun colorLayerIsVisibleDuringTransition() {
val bgColorLayer = FlickerComponentName("", "colorBackgroundLayer")
val displayBounds = WindowUtils.getDisplayBounds(testSpec.config.startRotation)
testSpec.assertLayers {
this.coversExactly(displayBounds, LAUNCH_NEW_TASK_ACTIVITY)
.isInvisible(bgColorLayer)
.then()
// Transitioning
.isVisible(bgColorLayer)
.then()
// Fully transitioned to simple SIMPLE_ACTIVITY
.coversExactly(displayBounds, SIMPLE_ACTIVITY)
.isInvisible(bgColorLayer)
.then()
// Transitioning back
.isVisible(bgColorLayer)
.then()
// Fully transitioned back to LAUNCH_NEW_TASK_ACTIVITY
.isInvisible(bgColorLayer)
.coversExactly(displayBounds, LAUNCH_NEW_TASK_ACTIVITY)
}
}
/**
* Checks that we start with the LaunchNewTask activity on top and then open up
* the SimpleActivity and then go back to the LaunchNewTask activity.
*/
@Postsubmit
@Test
fun newTaskOpensOnTopAndThenCloses() {
testSpec.assertWm {
this.isAppWindowOnTop(LAUNCH_NEW_TASK_ACTIVITY)
.then()
.isAppWindowOnTop(SPLASH_SCREEN, isOptional = true)
.then()
.isAppWindowOnTop(SIMPLE_ACTIVITY)
.then()
.isAppWindowOnTop(SPLASH_SCREEN, isOptional = true)
.then()
.isAppWindowOnTop(LAUNCH_NEW_TASK_ACTIVITY)
}
}
/**
* Checks that all parts of the screen are covered at the start and end of the transition
*/
@Postsubmit
@Test
fun entireScreenCovered() = testSpec.entireScreenCovered()
/**
* Checks that the navbar window is visible throughout the transition
*/
@Postsubmit
@Test
fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
/**
* Checks that the navbar layer is visible throughout the transition
*/
@Postsubmit
@Test
fun navBarLayerIsVisible() = testSpec.navBarLayerIsVisible()
/**
* Checks that the status bar window is visible throughout the transition
*/
@Postsubmit
@Test
fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
/**
* Checks that the status bar layer is visible throughout the transition
*/
@Postsubmit
@Test
fun statusBarLayerIsVisible() = testSpec.statusBarLayerIsVisible()
companion object {
private val WALLPAPER = getWallpaperPackage(InstrumentationRegistry.getInstrumentation())
private val LAUNCH_NEW_TASK_ACTIVITY =
LAUNCH_NEW_TASK_ACTIVITY_COMPONENT_NAME.toFlickerComponent()
private val SIMPLE_ACTIVITY = SIMPLE_ACTIVITY_AUTO_FOCUS_COMPONENT_NAME.toFlickerComponent()
private fun getWallpaperPackage(instrumentation: Instrumentation): FlickerComponentName {
val wallpaperManager = WallpaperManager.getInstance(instrumentation.targetContext)
return wallpaperManager.wallpaperInfo.component.toFlickerComponent()
}
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
.getConfigNonRotationTests(repetitions = 5)
}
}
}

View File

@@ -297,8 +297,7 @@ class QuickSwitchBetweenTwoAppsBackTest(private val testSpec: FlickerTestParamet
*/
@Postsubmit
@Test
fun navbarIsAlwaysInRightPosition() =
testSpec.navBarLayerRotatesAndScales(testSpec.config.startRotation)
fun navbarIsAlwaysInRightPosition() = testSpec.navBarLayerRotatesAndScales()
/**
* Checks that the status bar window is visible throughout the entire transition.

View File

@@ -314,8 +314,7 @@ class QuickSwitchBetweenTwoAppsForwardTest(private val testSpec: FlickerTestPara
*/
@Postsubmit
@Test
fun navbarIsAlwaysInRightPosition() =
testSpec.navBarLayerRotatesAndScales(testSpec.config.startRotation)
fun navbarIsAlwaysInRightPosition() = testSpec.navBarLayerRotatesAndScales()
/**
* Checks that the status bar window is visible throughout the entire transition.

View File

@@ -305,8 +305,7 @@ class QuickSwitchFromLauncherTest(private val testSpec: FlickerTestParameter) {
*/
@Presubmit
@Test
fun navbarIsAlwaysInRightPosition() =
testSpec.navBarLayerRotatesAndScales(testSpec.config.startRotation)
fun navbarIsAlwaysInRightPosition() = testSpec.navBarLayerRotatesAndScales()
/**
* Checks that the status bar window is visible throughout the entire transition.

View File

@@ -16,6 +16,7 @@
package com.android.server.wm.flicker.rotation
import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
import androidx.test.filters.FlakyTest
import androidx.test.filters.RequiresDevice
@@ -24,14 +25,14 @@ import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.annotation.Group3
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.endRotation
import com.android.server.wm.flicker.helpers.SimpleAppHelper
import com.android.server.wm.flicker.startRotation
import com.android.server.wm.flicker.rules.WMFlickerServiceRuleForTestSpec
import com.android.server.wm.flicker.statusBarLayerIsVisible
import com.android.server.wm.flicker.statusBarLayerRotatesScales
import com.android.server.wm.flicker.statusBarWindowIsVisible
import com.android.server.wm.traces.common.FlickerComponentName
import org.junit.FixMethodOrder
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -80,6 +81,9 @@ import org.junit.runners.Parameterized
class ChangeAppRotationTest(
testSpec: FlickerTestParameter
) : RotationTransition(testSpec) {
@get:Rule
val flickerRule = WMFlickerServiceRuleForTestSpec(testSpec)
override val testApp = SimpleAppHelper(instrumentation)
override val transition: FlickerBuilder.(Map<String, Any?>) -> Unit
get() = {
@@ -91,6 +95,24 @@ class ChangeAppRotationTest(
}
}
@Postsubmit
@Test
fun runPresubmitAssertion() {
flickerRule.checkPresubmitAssertions()
}
@Postsubmit
@Test
fun runPostsubmitAssertion() {
flickerRule.checkPostsubmitAssertions()
}
@FlakyTest
@Test
fun runFlakyAssertion() {
flickerRule.checkFlakyAssertions()
}
/** {@inheritDoc} */
@FlakyTest(bugId = 190185577)
@Test
@@ -111,6 +133,7 @@ class ChangeAppRotationTest(
.isVisible(FlickerComponentName.ROTATION)
.then()
.isVisible(testApp.component)
.isInvisible(FlickerComponentName.ROTATION)
}
}
@@ -138,10 +161,7 @@ class ChangeAppRotationTest(
*/
@Presubmit
@Test
fun statusBarLayerRotatesScales() {
testSpec.statusBarLayerRotatesScales(
testSpec.config.startRotation, testSpec.config.endRotation)
}
fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
/** {@inheritDoc} */
@FlakyTest

View File

@@ -92,10 +92,7 @@ abstract class RotationTransition(protected val testSpec: FlickerTestParameter)
*/
@Presubmit
@Test
open fun navBarLayerRotatesAndScales() {
testSpec.navBarLayerRotatesAndScales(
testSpec.config.startRotation, testSpec.config.endRotation)
}
open fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
/**
* Checks that all layers that are visible on the trace, are visible for at least 2

View File

@@ -80,5 +80,15 @@
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name=".LaunchNewTaskActivity"
android:taskAffinity="com.android.server.wm.flicker.testapp.LaunchNewTaskActivity"
android:configChanges="orientation|screenSize"
android:label="LaunchNewTaskActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2018 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:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/holo_orange_light">
<Button
android:id="@+id/launch_new_task"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New task" />
</LinearLayout>

View File

@@ -51,4 +51,9 @@ public class ActivityOptions {
public static final ComponentName BUTTON_ACTIVITY_COMPONENT_NAME =
new ComponentName(FLICKER_APP_PACKAGE,
FLICKER_APP_PACKAGE + ".ButtonActivity");
public static final String LAUNCH_NEW_TASK_ACTIVITY_LAUNCHER_NAME = "LaunchNewTaskApp";
public static final ComponentName LAUNCH_NEW_TASK_ACTIVITY_COMPONENT_NAME =
new ComponentName(FLICKER_APP_PACKAGE,
FLICKER_APP_PACKAGE + ".LaunchNewTaskActivity");
}

View File

@@ -0,0 +1,44 @@
/*
* Copyright (C) 2018 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.testapp;
import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.WindowManager;
import android.widget.Button;
public class LaunchNewTaskActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WindowManager.LayoutParams p = getWindow().getAttributes();
p.layoutInDisplayCutoutMode = WindowManager.LayoutParams
.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
getWindow().setAttributes(p);
setContentView(R.layout.task_button);
Button button = findViewById(R.id.launch_new_task);
button.setOnClickListener(v -> {
Intent intent = new Intent(LaunchNewTaskActivity.this, SimpleActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK);
startActivity(intent);
});
}
}