• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.wm.flicker.helpers
18 
19 import android.app.Instrumentation
20 import android.graphics.Rect
21 import android.graphics.Region
22 import android.tools.device.apphelpers.StandardAppHelper
23 import android.tools.helpers.FIND_TIMEOUT
24 import android.tools.helpers.GestureHelper
25 import android.tools.helpers.SYSTEMUI_PACKAGE
26 import android.tools.traces.component.ComponentNameMatcher
27 import android.tools.traces.parsers.WindowManagerStateHelper
28 import android.tools.traces.parsers.toFlickerComponent
29 import androidx.test.uiautomator.By
30 import androidx.test.uiautomator.Until
31 import com.android.server.wm.flicker.testapp.ActivityOptions
32 
33 class LetterboxAppHelper
34 @JvmOverloads
35 constructor(
36     instr: Instrumentation,
37     launcherName: String = ActivityOptions.NonResizeableFixedAspectRatioPortraitActivity.LABEL,
38     component: ComponentNameMatcher =
39         ActivityOptions.NonResizeableFixedAspectRatioPortraitActivity.COMPONENT.toFlickerComponent()
40 ) : StandardAppHelper(instr, launcherName, component) {
41 
42     private val gestureHelper: GestureHelper =
43         GestureHelper(instrumentation)
44 
clickRestartnull45     fun clickRestart(wmHelper: WindowManagerStateHelper) {
46         val restartButton =
47             uiDevice.wait(
48                 Until.findObject(By.res(SYSTEMUI_PACKAGE, "size_compat_restart_button")),
49                 FIND_TIMEOUT
50             )
51         restartButton?.run { restartButton.click() } ?: error("Restart button not found")
52 
53         // size compat mode restart confirmation dialog button
54         val restartDialogButton =
55             uiDevice.wait(
56                 Until.findObject(
57                     By.res(SYSTEMUI_PACKAGE, "letterbox_restart_dialog_restart_button")
58                 ),
59                 FIND_TIMEOUT
60             )
61         restartDialogButton?.run { restartDialogButton.click() }
62             ?: error("Restart dialog button not found")
63         wmHelper.StateSyncBuilder().withAppTransitionIdle().waitForAndVerify()
64     }
65 
repositionHorizontallynull66     fun repositionHorizontally(displayBounds: Rect, right: Boolean) {
67         val x = if (right) displayBounds.right - BOUNDS_OFFSET else BOUNDS_OFFSET
68         reposition(x.toFloat(), displayBounds.centerY().toFloat())
69     }
70 
repositionVerticallynull71     fun repositionVertically(displayBounds: Rect, bottom: Boolean) {
72         val y = if (bottom) displayBounds.bottom - BOUNDS_OFFSET else BOUNDS_OFFSET
73         reposition(displayBounds.centerX().toFloat(), y.toFloat())
74     }
75 
repositionnull76     private fun reposition(x: Float, y: Float) {
77         val coords = GestureHelper.Tuple(x, y)
78         require(gestureHelper.tap(coords, 2)) { "Failed to reposition letterbox app" }
79     }
80 
waitForAppToMoveHorizontallyTonull81     fun waitForAppToMoveHorizontallyTo(
82         wmHelper: WindowManagerStateHelper,
83         displayBounds: Rect,
84         right: Boolean
85     ) {
86         wmHelper
87             .StateSyncBuilder()
88             .add("letterboxAppRepositioned") {
89                 val letterboxAppWindow = getWindowRegion(wmHelper)
90                 val appRegionBounds = letterboxAppWindow.bounds
91                 val appWidth = appRegionBounds.width()
92                 return@add if (right)
93                     appRegionBounds.left == displayBounds.right - appWidth &&
94                         appRegionBounds.right == displayBounds.right
95                 else
96                     appRegionBounds.left == displayBounds.left &&
97                         appRegionBounds.right == displayBounds.left + appWidth
98             }
99             .waitForAndVerify()
100     }
101 
waitForAppToMoveVerticallyTonull102     fun waitForAppToMoveVerticallyTo(
103         wmHelper: WindowManagerStateHelper,
104         displayBounds: Rect,
105         navBarHeight: Int,
106         bottom: Boolean
107     ) {
108         wmHelper
109             .StateSyncBuilder()
110             .add("letterboxAppRepositioned") {
111                 val letterboxAppWindow = getWindowRegion(wmHelper)
112                 val appRegionBounds = letterboxAppWindow.bounds
113                 val appHeight = appRegionBounds.height()
114                 return@add if (bottom)
115                     appRegionBounds.bottom == displayBounds.bottom &&
116                         appRegionBounds.top == (displayBounds.bottom - appHeight + navBarHeight)
117                 else
118                     appRegionBounds.top == displayBounds.top &&
119                         appRegionBounds.bottom == displayBounds.top + appHeight
120             }
121             .waitForAndVerify()
122     }
123 
getWindowRegionnull124     private fun getWindowRegion(wmHelper: WindowManagerStateHelper): Region {
125         val windowRegion = wmHelper.getWindowRegion(this)
126         require(!windowRegion.isEmpty) {
127             "Unable to find letterbox app window in the current state"
128         }
129         return windowRegion
130     }
131 
132     companion object {
133         private const val BOUNDS_OFFSET: Int = 50
134     }
135 }
136