• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 android.platform.systemui_tapl.ui
18 
19 import android.graphics.PointF
20 import android.platform.systemui_tapl.controller.LockscreenController
21 import android.platform.systemui_tapl.ui.CommunalHub.Companion.COMMUNAL_SELECTOR
22 import android.platform.systemui_tapl.utils.DeviceUtils.sysuiResSelector
23 import android.platform.uiautomatorhelpers.BetterSwipe
24 import android.platform.uiautomatorhelpers.DeviceHelpers.assertInvisible
25 import android.platform.uiautomatorhelpers.DeviceHelpers.assertVisible
26 import android.platform.uiautomatorhelpers.DeviceHelpers.betterSwipe
27 import android.platform.uiautomatorhelpers.DeviceHelpers.uiDevice
28 import android.platform.uiautomatorhelpers.DeviceHelpers.waitForObj
29 import android.platform.uiautomatorhelpers.FLING_GESTURE_INTERPOLATOR
30 import androidx.test.uiautomator.By
31 import com.android.launcher3.tapl.LauncherInstrumentation
32 import com.android.launcher3.tapl.Workspace
33 import com.android.systemui.Flags.sceneContainer
34 import com.google.common.truth.Truth.assertWithMessage
35 
36 /** System UI test automation object representing the lock screen. */
37 class LockScreen internal constructor() {
38     init {
<lambda>null39         LOCKSCREEN_SELECTOR.assertVisible { "Lockscreen is not visible" }
40     }
41 
42     /**
43      * Opens expanded quick settings shade via swipe on the portrait lock screen. When you swipe
44      * from the top area of the screen instead of opening normal notification shade we open expanded
45      * quick settings. This helper methods allows to perform this gesture. The difference from
46      * opening normal shade gesture is that the startY position is higher. It is handled in
47      * [NotificationPanelViewController.shouldQuickSettingsIntercept].
48      */
openQuickSettingsnull49     fun openQuickSettings(): QuickSettings {
50         val device = uiDevice
51         device.betterSwipe(
52             startX = device.displayWidth / 2,
53             startY = 0,
54             endX = device.displayWidth / 2,
55             endY = device.displayHeight * 2 / 3,
56             interpolator = FLING_GESTURE_INTERPOLATOR,
57         )
58         return QuickSettings()
59     }
60 
61     /**
62      * Returns the lockscreen shade (the one visible without the need to pull it down). Fails if not
63      * visible.
64      */
65     val notificationShade: LockscreenNotificationShade
66         get() = LockscreenNotificationShade()
67 
68     /** Swipes up to the unlocked state. */
swipeUpToUnlocknull69     fun swipeUpToUnlock(): Workspace {
70         swipeUp()
71         LOCKSCREEN_SELECTOR.assertInvisible { "Lockscreen still visible after swiping up." }
72         assertWithMessage("Device is still locked after swiping up")
73             .that(LockscreenController.get().isDeviceLocked)
74             .isFalse()
75         return Root.get().goHomeViaKeycode()
76     }
77 
78     /** Uses home key to get to the unlocked state, skipping potentially flaky gesture. */
unlockDirectlynull79     fun unlockDirectly() {
80         uiDevice.pressMenu()
81         LOCKSCREEN_SELECTOR.assertInvisible { "Lockscreen still visible after swiping up." }
82         assertWithMessage("Device is still locked after swiping up")
83             .that(LockscreenController.get().isDeviceLocked)
84             .isFalse()
85 
86         // Without this part, the launcher might not be ready when tests start to exercise it.
87         uiDevice.pressHome()
88         val instrumentation = LauncherInstrumentation()
89         instrumentation.setExpectedRotation(uiDevice.displayRotation)
90         instrumentation.waitForLauncherInitialized()
91     }
92 
93     /** Swipes left to access the Communal Hub */
swipeLeftToCommunalnull94     fun swipeLeftToCommunal(): CommunalHub {
95         swipeLeft()
96         COMMUNAL_SELECTOR.assertVisible { "Communal Hub is not visible after swiping left" }
97         return CommunalHub()
98     }
99 
100     /**
101      * Returns bounds of the lock icon at the bottom of the screen. HSV:
102      * https://hsv.googleplex.com/5632535322165248
103      */
104     val lockIcon: LockscreenLockIcon
105         get() {
<lambda>null106             val lockIcon = waitForObj(LOCK_ICON_SELECTOR) { "Lockscreen lock icon not found" }
107             return LockscreenLockIcon(/* rect= */ lockIcon.visibleBounds)
108         }
109 
110     /**
111      * Returns user switcher on the lockscreen. HSV:
112      * https://hsv.googleplex.com/5452172222267392?node=50
113      */
114     val userSwitcher: LockscreenUserSwitcher
115         get() = LockscreenUserSwitcher()
116 
117     /** Returns the lockscreen StatusBar. Fails if not visible. */
118     val statusBar: LockscreenStatusBar
119         get() = LockscreenStatusBar()
120 
121     /** Swipes up to the bouncer. */
swipeUpToBouncernull122     fun swipeUpToBouncer(): Bouncer {
123         swipeUp()
124         return Bouncer(null)
125     }
126 
127     /** Returns the bouncer. Fails if the bouncer is not visible. */
getBouncernull128     fun getBouncer(): Bouncer {
129         return Bouncer(null)
130     }
131 
swipeUpnull132     private fun swipeUp() {
133         LOCKSCREEN_SELECTOR.assertVisible { "Lockscreen is not visible" }
134         val swipeableArea = waitForObj(SWIPEABLE_AREA) { "Swipeable area not found" }
135         // shift swipe gesture over to left so we don't begin the gesture on the lock icon
136         //   this can be removed if b/229696938 gets resolved to allow for swiping on the icon
137         val bounds = swipeableArea.visibleBounds
138         val swipeX = bounds.left + bounds.width() / 4f
139         BetterSwipe.swipe(PointF(swipeX, bounds.bottom - 1f), PointF(swipeX, bounds.top.toFloat()))
140     }
141 
swipeLeftnull142     private fun swipeLeft() {
143         LOCKSCREEN_SELECTOR.assertVisible { "Lockscreen is not visible" }
144         val swipeableArea = waitForObj(SWIPEABLE_AREA) { "Swipeable area not found" }
145         val bounds = swipeableArea.visibleBounds
146         val swipeY = bounds.top + bounds.height() / 2f
147         BetterSwipe.swipe(
148             PointF(bounds.right - 1f, swipeY),
149             PointF(bounds.left + bounds.width() / 2f, swipeY),
150         )
151     }
152 
153     companion object {
154         private val LOCK_ICON_SELECTOR = sysuiResSelector("device_entry_icon_view")
155 
156         // https://hsv.googleplex.com/5130837462876160?node=117
157         val LOCKSCREEN_SELECTOR =
158             if (sceneContainer()) {
159                 By.res("element:lockscreen")
160             } else {
161 
162                 sysuiResSelector("keyguard_indication_area")
163             }
164         private val SWIPEABLE_AREA =
165             if (com.android.systemui.Flags.sceneContainer()) {
166                 sysuiResSelector("shared_notification_container")
167             } else {
168                 sysuiResSelector("notification_panel")
169             }
170     }
171 }
172