Skip to content
Snippets Groups Projects
Commit 39bf0644 authored by Orhan Uysal's avatar Orhan Uysal Committed by Android (Google) Code Review
Browse files

Merge "Add enterDesktopWithDrag scenario." into main

parents 81b273a7 4ed00d31
No related branches found
No related tags found
No related merge requests found
# Android > Android OS & Apps > Framework (Java + Native) > Window Manager > WM Shell > Freeform
# Bug component: 929241
uysalorhan@google.com
pragyabajoria@google.com
\ No newline at end of file
/*
* Copyright (C) 2024 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.service.desktopmode.flicker
import android.tools.Rotation
import android.tools.flicker.AssertionInvocationGroup
import android.tools.flicker.FlickerConfig
import android.tools.flicker.annotation.ExpectedScenarios
import android.tools.flicker.annotation.FlickerConfigProvider
import android.tools.flicker.assertors.assertions.AppLayerIsVisibleAlways
import android.tools.flicker.assertors.assertions.AppWindowHasDesktopModeInitialBoundsAtTheEnd
import android.tools.flicker.assertors.assertions.AppWindowOnTopAtEnd
import android.tools.flicker.config.AssertionTemplates
import android.tools.flicker.config.FlickerConfig
import android.tools.flicker.config.FlickerConfigEntry
import android.tools.flicker.config.FlickerServiceConfig
import android.tools.flicker.config.ScenarioId
import android.tools.flicker.config.desktopmode.Components
import android.tools.flicker.extractors.ITransitionMatcher
import android.tools.flicker.extractors.ShellTransitionScenarioExtractor
import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
import android.tools.traces.wm.Transition
import android.tools.traces.wm.TransitionType
import com.android.wm.shell.flicker.service.desktopmode.scenarios.EnterDesktopWithDrag
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(FlickerServiceJUnit4ClassRunner::class)
class EnterDesktopWithDragLandscape : EnterDesktopWithDrag(Rotation.ROTATION_90) {
@ExpectedScenarios(["END_DRAG_TO_DESKTOP"]) @Test override fun enterDesktopWithDrag() =
super.enterDesktopWithDrag()
companion object {
private val END_DRAG_TO_DESKTOP = FlickerConfigEntry(
scenarioId = ScenarioId("END_DRAG_TO_DESKTOP"),
extractor = ShellTransitionScenarioExtractor(
transitionMatcher = object : ITransitionMatcher {
override fun findAll(
transitions: Collection<Transition>
): Collection<Transition> {
return transitions.filter {
it.type == TransitionType.DESKTOP_MODE_END_DRAG_TO_DESKTOP}
}
}),
assertions = AssertionTemplates.COMMON_ASSERTIONS +
listOf(
AppLayerIsVisibleAlways(Components.DESKTOP_MODE_APP),
AppWindowOnTopAtEnd(Components.DESKTOP_MODE_APP),
AppWindowHasDesktopModeInitialBoundsAtTheEnd(Components.DESKTOP_MODE_APP)
).associateBy({ it }, { AssertionInvocationGroup.BLOCKING }),
)
@JvmStatic
@FlickerConfigProvider
fun flickerConfigProvider(): FlickerConfig =
FlickerConfig()
.use(FlickerServiceConfig.DEFAULT)
.use(END_DRAG_TO_DESKTOP)
}
}
/*
* Copyright (C) 2024 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.service.desktopmode.flicker
import android.tools.Rotation
import android.tools.flicker.AssertionInvocationGroup
import android.tools.flicker.FlickerConfig
import android.tools.flicker.annotation.ExpectedScenarios
import android.tools.flicker.annotation.FlickerConfigProvider
import android.tools.flicker.assertors.assertions.AppLayerIsVisibleAlways
import android.tools.flicker.assertors.assertions.AppWindowHasDesktopModeInitialBoundsAtTheEnd
import android.tools.flicker.assertors.assertions.AppWindowOnTopAtEnd
import android.tools.flicker.config.AssertionTemplates
import android.tools.flicker.config.FlickerConfig
import android.tools.flicker.config.FlickerConfigEntry
import android.tools.flicker.config.FlickerServiceConfig
import android.tools.flicker.config.ScenarioId
import android.tools.flicker.config.desktopmode.Components
import android.tools.flicker.extractors.ITransitionMatcher
import android.tools.flicker.extractors.ShellTransitionScenarioExtractor
import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
import android.tools.traces.wm.Transition
import android.tools.traces.wm.TransitionType
import com.android.wm.shell.flicker.service.desktopmode.scenarios.EnterDesktopWithDrag
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(FlickerServiceJUnit4ClassRunner::class)
class EnterDesktopWithDragPortrait : EnterDesktopWithDrag(Rotation.ROTATION_0) {
@ExpectedScenarios(["END_DRAG_TO_DESKTOP"]) @Test override fun enterDesktopWithDrag() =
super.enterDesktopWithDrag()
companion object {
private val END_DRAG_TO_DESKTOP = FlickerConfigEntry(
scenarioId = ScenarioId("END_DRAG_TO_DESKTOP"),
extractor = ShellTransitionScenarioExtractor(
transitionMatcher = object : ITransitionMatcher {
override fun findAll(
transitions: Collection<Transition>
): Collection<Transition> {
return transitions.filter {
it.type == TransitionType.DESKTOP_MODE_END_DRAG_TO_DESKTOP}
}
}),
assertions = AssertionTemplates.COMMON_ASSERTIONS +
listOf(
AppLayerIsVisibleAlways(Components.DESKTOP_MODE_APP),
AppWindowOnTopAtEnd(Components.DESKTOP_MODE_APP),
AppWindowHasDesktopModeInitialBoundsAtTheEnd(Components.DESKTOP_MODE_APP)
).associateBy({ it }, { AssertionInvocationGroup.BLOCKING }),
)
@JvmStatic
@FlickerConfigProvider
fun flickerConfigProvider(): FlickerConfig =
FlickerConfig()
.use(FlickerServiceConfig.DEFAULT)
.use(END_DRAG_TO_DESKTOP)
}
}
/*
* Copyright (C) 2024 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.service.desktopmode.scenarios
import android.app.Instrumentation
import android.tools.NavBar
import android.tools.Rotation
import android.tools.traces.parsers.WindowManagerStateHelper
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiDevice
import com.android.launcher3.tapl.LauncherInstrumentation
import com.android.server.wm.flicker.helpers.SimpleAppHelper
import com.android.wm.shell.flicker.service.common.Utils
import com.android.wm.shell.flicker.utils.DesktopModeUtils
import org.junit.After
import org.junit.Before
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
@Ignore("Base Test Class")
abstract class EnterDesktopWithDrag
@JvmOverloads
constructor(val rotation: Rotation = Rotation.ROTATION_0) {
private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
private val tapl = LauncherInstrumentation()
private val wmHelper = WindowManagerStateHelper(instrumentation)
private val device = UiDevice.getInstance(instrumentation)
private val testApp = SimpleAppHelper(instrumentation)
@Rule @JvmField val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, rotation)
@Before
fun setup() {
tapl.setEnableRotation(true)
tapl.setExpectedRotation(rotation.value)
}
@Test
open fun enterDesktopWithDrag() {
DesktopModeUtils.enterDesktopWithDrag(wmHelper, device, testApp)
}
@After
fun teardown() {
testApp.exit(wmHelper)
}
}
/*
* Copyright (C) 2024 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.utils
import android.tools.device.apphelpers.StandardAppHelper
import android.tools.helpers.SYSTEMUI_PACKAGE
import android.tools.traces.component.IComponentMatcher
import android.tools.traces.parsers.WindowManagerStateHelper
import android.tools.traces.wm.WindowingMode
import androidx.test.uiautomator.By
import androidx.test.uiautomator.BySelector
import androidx.test.uiautomator.UiDevice
import androidx.test.uiautomator.Until
/**
* Provides a collection of utility functions for desktop mode testing.
*/
object DesktopModeUtils {
private const val TIMEOUT_MS = 3_000L
private const val CAPTION = "desktop_mode_caption"
private const val CAPTION_HANDLE = "caption_handle"
private const val MAXIMIZE_BUTTON = "maximize_button_view"
private val captionFullscreen: BySelector
get() = By.res(SYSTEMUI_PACKAGE, CAPTION)
private val captionHandle: BySelector
get() = By.res(SYSTEMUI_PACKAGE, CAPTION_HANDLE)
private val maximizeButton: BySelector
get() = By.res(SYSTEMUI_PACKAGE, MAXIMIZE_BUTTON)
/**
* Wait for an app moved to desktop to finish its transition.
*/
private fun waitForAppToMoveToDesktop(
wmHelper: WindowManagerStateHelper,
currentApp: IComponentMatcher,
) {
wmHelper
.StateSyncBuilder()
.withWindowSurfaceAppeared(currentApp)
.withFreeformApp(currentApp)
.withAppTransitionIdle()
.waitForAndVerify()
}
/**
* Click maximise button on the app header for the given app.
*/
fun maximiseDesktopApp(
wmHelper: WindowManagerStateHelper,
device: UiDevice,
currentApp: StandardAppHelper
) {
if (wmHelper.getWindow(currentApp)?.windowingMode
!= WindowingMode.WINDOWING_MODE_FREEFORM.value)
error("expected a freeform window to maximise but window is not in freefrom mode")
val maximizeButton =
device.wait(Until.findObject(maximizeButton), TIMEOUT_MS)
?: error("Unable to find view $maximizeButton\n")
maximizeButton.click()
}
/**
* Move an app to Desktop by dragging the app handle at the top.
*/
fun enterDesktopWithDrag(
wmHelper: WindowManagerStateHelper,
device: UiDevice,
currentApp: StandardAppHelper,
) {
currentApp.launchViaIntent(wmHelper)
dragToDesktop(wmHelper, currentApp, device)
waitForAppToMoveToDesktop(wmHelper, currentApp)
}
private fun dragToDesktop(
wmHelper: WindowManagerStateHelper,
currentApp: StandardAppHelper,
device: UiDevice
) {
val windowRect = wmHelper.getWindowRegion(currentApp).bounds
val startX = windowRect.centerX()
// Start dragging a little under the top to prevent dragging the notification shade.
val startY = 10
val displayRect =
wmHelper.currentState.wmState.getDefaultDisplay()?.displayRect
?: throw IllegalStateException("Default display is null")
// The position we want to drag to
val endY = displayRect.centerY() / 2
// drag the window to move to desktop
device.drag(startX, startY, startX, endY, 100)
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment