• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 package android.platform.systemui_tapl.ui
17 
18 import android.graphics.PointF
19 import android.platform.systemui_tapl.utils.DeviceUtils.sysuiResSelector
20 import android.platform.systemui_tapl.utils.SETTINGS_PACKAGE
21 import android.platform.systemui_tapl.utils.SYSUI_PACKAGE
22 import android.platform.test.scenario.tapl_common.TaplUiDevice
23 import android.platform.test.scenario.tapl_common.TaplUiObject
24 import android.platform.uiautomatorhelpers.BetterSwipe
25 import android.platform.uiautomatorhelpers.DeviceHelpers.assertInvisible
26 import android.platform.uiautomatorhelpers.DeviceHelpers.assertVisible
27 import android.platform.uiautomatorhelpers.DeviceHelpers.uiDevice
28 import android.platform.uiautomatorhelpers.DeviceHelpers.waitForFirstObj
29 import android.platform.uiautomatorhelpers.DeviceHelpers.waitForObj
30 import android.platform.uiautomatorhelpers.scrollUntilFound
31 import androidx.test.uiautomator.By
32 import androidx.test.uiautomator.Direction
33 import androidx.test.uiautomator.UiSelector
34 import java.util.regex.Pattern
35 
36 /** System UI test automation object representing quick settings in the notification shade. */
37 class QuickSettings internal constructor() {
38     // TODO(279061302): Remove TaplUiObject after BetterSwipe has a scroll wrapper.
39     private val pager: TaplUiObject
40 
41     private val clazzNamePattern = Pattern.compile("android\\.widget\\.((Switch)|(Button))")
42 
43     init {
<lambda>null44         UI_QUICK_SETTINGS_CONTAINER_ID.assertVisible { "Quick settings didn't open" }
45         FOOTER_SELECTOR.assertVisible()
46         pager = TaplUiDevice.waitForObject(PAGER_UI_OBJECT_SELECTOR, "QS pager")
47     }
48 
49     /** Presses Power button to open the power panel. */
openPowerPanelnull50     fun openPowerPanel(): PowerPanel {
51         waitForObj(sysuiResSelector(POWER_BTN_RES_ID)).click()
52         return PowerPanel()
53     }
54 
55     /** Presses Settings button to open Settings. */
openSettingsnull56     fun openSettings() {
57         waitForObj(sysuiResSelector(SETTINGS_BUTTON_RES_ID)).click()
58         By.pkg(SETTINGS_PACKAGE).assertVisible()
59     }
60 
61     /** Opens the user selection panel by clicking User Switch button. */
openUserSelectionnull62     fun openUserSelection(): UserSelectionPanel {
63         // Click on the multi user switch icon. http://go/hsv/5465641194618880?node=84
64         waitForObj(sysuiResSelector(MULTI_USER_SWITCH_RES_ID)).click()
65         return UserSelectionPanel()
66     }
67 
68     /** Finds a tile by the prefix of its description */
findTilenull69     fun findTile(tileDesc: String): QuickSettingsTile {
70         // Select by title_label https://hsv.googleplex.com/5476758214148096?node=57
71         val titleLabelSelector = sysuiResSelector("tile_label").textStartsWith(tileDesc)
72         val tileSelector = By.clazz(clazzNamePattern).hasDescendant(titleLabelSelector, 3)
73         waitForObj(tileSelector)
74         return QuickSettingsTile(tileSelector)
75     }
76 
findComposeTilenull77     fun findComposeTile(tileDesc: String): ComposeQuickSettingsTile {
78         val smallTileSelector = ComposeQuickSettingsTile.smallTileSelector(tileDesc)
79         val largeTileSelector = ComposeQuickSettingsTile.largeTileSelector(tileDesc)
80         val (_, selector) = waitForFirstObj(smallTileSelector, largeTileSelector)
81         return ComposeQuickSettingsTile.createFrom(selector)
82     }
83 
84     /** Returns the brightness slider. */
85     val brightnessSlider: BrightnessSlider
86         get() = BrightnessSlider()
87 
88     /** Returns the QS header. */
89     val header: QSHeader
90         get() = QSHeader()
91 
92     /**
93      * Returns the visible UMO, or fails if it's not visible.
94      *
95      * **See:** [HSV](https://hsv.googleplex.com/6702722561605632?node=85)
96      */
97     val universalMediaObject: UniversalMediaObject
98         get() {
99             val footerTop = waitForObj(QUICK_SETTING_FOOTER_SELECTOR).visibleBounds.top
100             waitForObj(QUICK_SETTINGS_SCROLLVIEW_SELECTOR).scrollUntilFound(
101                 UniversalMediaObject.MEDIA_CAROUSEL_SCROLLER,
102                 direction = Direction.DOWN,
<lambda>null103             ) {
104                 val umoBottom = it.visibleBounds.bottom
105                 umoBottom - footerTop <= 0
106             }
107             return UniversalMediaObject()
108         }
109 
110     /** Swipes up back to QQS or closes shade in case of split shade. */
closenull111     fun close() {
112         swipeUp()
113         UI_QUICK_SETTINGS_CONTAINER_ID.assertInvisible()
114     }
115 
swipeLeftnull116     fun swipeLeft() {
117         pager.fling(Direction.LEFT, 0.5f)
118     }
119 
swipeUpnull120     private fun swipeUp() {
121         val displayWidth = uiDevice.displayWidth
122         val displayHeight = uiDevice.displayHeight
123         BetterSwipe.swipe(
124             PointF((displayWidth / 2).toFloat(), displayHeight.toFloat() - 1f),
125             PointF((displayWidth / 2).toFloat(), 0f),
126         )
127     }
128 
129     private companion object {
130         val UI_QUICK_SETTINGS_CONTAINER_ID = sysuiResSelector("quick_settings_panel")
131         val FOOTER_SELECTOR = sysuiResSelector("qs_footer_actions")
132 
133         // https://hsv.googleplex.com/5291196806070272?node=109
134         const val POWER_BTN_RES_ID = "pm_lite"
135 
136         // https://hsv.googleplex.com/5291196806070272?node=108
137         const val SETTINGS_BUTTON_RES_ID = "settings_button_container"
138 
139         // http://go/hsv/5465641194618880?node=84
140         const val MULTI_USER_SWITCH_RES_ID = "multi_user_switch"
141         const val PAGER_CLASS_NAME = "androidx.viewpager.widget.ViewPager"
142         const val PAGER_RES_ID = "$SYSUI_PACKAGE:id/qs_pager"
143         val PAGER_SELECTOR = UiSelector().className(PAGER_CLASS_NAME).resourceId(PAGER_RES_ID)
144         const val PAGER_UI_OBJECT_RES_ID = "qs_pager"
145         val PAGER_UI_OBJECT_SELECTOR = sysuiResSelector(PAGER_UI_OBJECT_RES_ID)
146         private val QUICK_SETTINGS_SCROLLVIEW_SELECTOR = sysuiResSelector("expanded_qs_scroll_view")
147         private val QUICK_SETTING_FOOTER_SELECTOR = sysuiResSelector("qs_footer_actions")
148     }
149 }
150