1 /*
2  * Copyright (C) 2020 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.wm.shell.flicker.pip.tv
18 
19 import android.app.Instrumentation
20 import android.tools.traces.parsers.WindowManagerStateHelper
21 import androidx.test.uiautomator.By
22 import androidx.test.uiautomator.BySelector
23 import androidx.test.uiautomator.UiObject2
24 import androidx.test.uiautomator.Until
25 import com.android.server.wm.flicker.helpers.PipAppHelper
26 
27 /** Helper class for PIP app on AndroidTV */
28 open class PipAppHelperTv(instrumentation: Instrumentation) : PipAppHelper(instrumentation) {
29     private val appSelector = By.pkg(packageName).depth(0)
30 
31     val ui: UiObject2?
32         get() = uiDevice.findObject(appSelector)
33 
focusOnObjectnull34     private fun focusOnObject(selector: BySelector): Boolean {
35         // We expect all the focusable UI elements to be arranged in a way so that it is possible
36         // to "cycle" over all them by clicking the D-Pad DOWN button, going back up to "the top"
37         // from "the bottom".
38         repeat(FOCUS_ATTEMPTS) {
39             uiDevice.findObject(selector)?.apply { if (isFocusedOrHasFocusedChild) return true }
40                 ?: error("The object we try to focus on is gone.")
41 
42             uiDevice.pressDPadDown()
43             uiDevice.waitForIdle()
44         }
45         return false
46     }
47 
clickObjectnull48     override fun clickObject(resId: String) {
49         val selector = By.res(packageName, resId)
50         focusOnObject(selector) || error("Could not focus on `$resId` object")
51         uiDevice.pressDPadCenter()
52     }
53 
54     @Deprecated(
55         "Use PipAppHelper.closePipWindow(wmHelper) instead",
56         ReplaceWith("closePipWindow(wmHelper)")
57     )
closePipWindownull58     override fun closePipWindow() {
59         uiDevice.closeTvPipWindow()
60     }
61 
62     /** Taps the pip window and dismisses it by clicking on the X button. */
closePipWindownull63     override fun closePipWindow(wmHelper: WindowManagerStateHelper) {
64         uiDevice.closeTvPipWindow()
65 
66         // Wait for animation to complete.
67         wmHelper.StateSyncBuilder().withPipGone().withHomeActivityVisible().waitForAndVerify()
68     }
69 
waitUntilClosednull70     fun waitUntilClosed(): Boolean {
71         val appSelector = By.pkg(packageName).depth(0)
72         return uiDevice.wait(Until.gone(appSelector), APP_CLOSE_WAIT_TIME_MS)
73     }
74 
75     companion object {
76         private const val FOCUS_ATTEMPTS = 20
77         private const val APP_CLOSE_WAIT_TIME_MS = 3_000L
78     }
79 }
80