• 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.Point
19 import android.platform.systemui_tapl.utils.DeviceUtils.sysuiResSelector
20 import android.platform.systemui_tapl.volume.panel.ui.VolumePanel
21 import android.platform.uiautomatorhelpers.BetterSwipe
22 import android.platform.uiautomatorhelpers.DeviceHelpers.assertVisible
23 import android.platform.uiautomatorhelpers.DeviceHelpers.click
24 import android.platform.uiautomatorhelpers.DeviceHelpers.uiDevice
25 import android.platform.uiautomatorhelpers.DeviceHelpers.waitForObj
26 import android.platform.uiautomatorhelpers.PRECISE_GESTURE_INTERPOLATOR
27 import androidx.test.uiautomator.BySelector
28 import com.android.systemui.Flags
29 import com.google.common.truth.Truth
30 
31 /** System UI test automation object representing the dialog for adjusting the device volume. */
32 class VolumeDialog internal constructor() {
33     init {
34         assertVolumeDialogVisible()
35     }
36 
37     /**
38      * Changes the volume by dragging the volume slider.
39      *
40      * Note: Volume value cannot be more than 25 and less than 0.
41      *
42      * @param volume new volume value
43      */
setVolumeByDraggingnull44     fun setVolumeByDragging(volume: Int) {
45         assertVolumeDialogVisible()
46         dragAndChangeVolume(volume)
47         assertVolumeDialogVisible()
48     }
49 
50     /** Open the ringer drawer by clicking the ringer mode icon on the volume dialog. */
openRingerDrawernull51     fun openRingerDrawer(): VolumeRingerDrawer {
52         val ringerIconSelector =
53             if (Flags.volumeRedesign()) {
54                 sysuiResSelector("ringer_buttons_background")
55             } else {
56                 sysuiResSelector("volume_new_ringer_active_icon_container")
57             }
58         waitForObj(ringerIconSelector).click()
59         return VolumeRingerDrawer.get()
60     }
61 
62     /** Open the volume setting panel by clicking the setting icon on the volume dialog. */
63     @Deprecated(
64         "This new volume panel is rolled out. Use openNewVolumePanel instead",
65         replaceWith = ReplaceWith("openNewVolumePanel"),
66     )
openVolumePanelnull67     fun openVolumePanel(): VolumePanelDialog {
68         if (Flags.volumeRedesign()) {
69             sysuiResSelector("volume_dialog_settings").click()
70         } else {
71             sysuiResSelector("settings").click()
72         }
73         return VolumePanelDialog()
74     }
75 
76     /** Open the volume setting panel by clicking the setting icon on the volume dialog. */
openNewVolumePanelnull77     fun openNewVolumePanel(): VolumePanel {
78         if (Flags.volumeRedesign()) {
79             waitForObj(sysuiResSelector("volume_dialog_settings")).click()
80         } else {
81             waitForObj(sysuiResSelector("settings")).click()
82         }
83         return VolumePanel()
84     }
85 
86     /**
87      * Click the live caption button on the volume dialog.
88      *
89      * https://hsv.googleplex.com/4767031439130624
90      *
91      * @return this
92      */
toggleLiveCaptionsnull93     fun toggleLiveCaptions(): VolumeDialog {
94         waitForObj(sysuiResSelector("odi_captions_icon")).click()
95         return this
96     }
97 
98     companion object {
99         val PAGE_TITLE_SELECTOR = sysuiResSelector("volume_dialog")
100         private const val MAX_VOLUME = 26
101         private const val MIN_VOLUME = -1
102 
103         /**
104          * Method used for dragging and changing the volume. Note: Volume value cannot be more than
105          * 25 and less than 0.
106          *
107          * @param volume value for volume to changed
108          */
dragAndChangeVolumenull109         private fun dragAndChangeVolume(volume: Int) {
110             val slider =
111                 if (Flags.volumeRedesign()) {
112                     sysuiResSelector("volume_dialog_slider")
113                 } else {
114                     sysuiResSelector("volume_row_slider")
115                 }
116             val coordinates = getDragCoordinates(slider, volume)
117             assertVolumeDialogVisible()
118             BetterSwipe.swipe(
119                 waitForObj(slider).visibleCenter,
120                 coordinates,
121                 interpolator = PRECISE_GESTURE_INTERPOLATOR,
122             )
123         }
124 
125         /** Asserts that the volume dialog is visible. */
assertVolumeDialogVisiblenull126         private fun assertVolumeDialogVisible() {
127             PAGE_TITLE_SELECTOR.assertVisible()
128         }
129 
130         /**
131          * This will get the co-ordinate of the for volume slider based on the volume value
132          * provided.
133          *
134          * Note: Volume value cannot be more than 25 and less than 0.
135          *
136          * Formula's used: Suppose volume slider length is 100 and volume provided is 15, therefore
137          * slider should move to:
138          *
139          * FORMULA: (Volume Provided / Max Volume) * Slider Length Hence in current scenario its:
140          * (15/25)*100
141          *
142          * Since the Android device coordinate works from top to down
143          * [https://screenshot.googleplex .com/Zm3s1rqJ2Es], therefore formula used for coordinate
144          * calculation is:
145          *
146          * X-Coordinate: TOP + ((MAX VOLUME - GIVEN VOLUME)/MAX VOLUME ) * (SLIDER BOTTOM Y
147          * COORDINATE - SLIDER TOP Y COORDINATE)
148          *
149          * Y-Coordinate: SLIDER LEFT X COORDINATE + (SLIDER RIGHT X COORDINATE - SLIDER LEFT X
150          * COORDINATE) / 2
151          *
152          * @param volume value for volume to changed
153          * @return an of Point which is the coordinate of the slider to be moved too.
154          */
getDragCoordinatesnull155         private fun getDragCoordinates(slider: BySelector, volume: Int): Point {
156             Truth.assertThat(volume).isLessThan(MAX_VOLUME)
157             Truth.assertThat(volume).isGreaterThan(MIN_VOLUME)
158             val dimension = uiDevice.waitForObj(slider).visibleBounds
159             val top = dimension.top
160             val left = dimension.left
161             val right = dimension.right
162             val bottom = dimension.bottom
163             val y = (top + (25 - volume).toFloat() / 25 * (bottom - top)).toInt()
164             val x = left + (right - left) / 2
165             return Point(x, y)
166         }
167     }
168 }
169