• 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.media.AudioManager
20 import android.platform.systemui_tapl.utils.DeviceUtils.SHORT_WAIT
21 import android.platform.systemui_tapl.utils.DeviceUtils.androidResSelector
22 import android.platform.systemui_tapl.utils.DeviceUtils.settingsResSelector
23 import android.platform.uiautomatorhelpers.DeviceHelpers.assertInvisible
24 import android.platform.uiautomatorhelpers.DeviceHelpers.betterSwipe
25 import android.platform.uiautomatorhelpers.DeviceHelpers.context
26 import android.platform.uiautomatorhelpers.DeviceHelpers.uiDevice
27 import android.platform.uiautomatorhelpers.DeviceHelpers.waitForObj
28 import android.platform.uiautomatorhelpers.PRECISE_GESTURE_INTERPOLATOR
29 import android.platform.uiautomatorhelpers.WaitUtils.ensureThat
30 import android.widget.SeekBar
31 import androidx.test.uiautomator.By
32 import androidx.test.uiautomator.UiObject2
33 import com.google.common.collect.Range
34 import com.google.common.truth.Truth.assertWithMessage
35 import java.util.regex.Pattern
36 
37 /**
38  * Volume settings panel which is opened after click setting button on the volume dialog.
39  *
40  * https://hsv.googleplex.com/5613609590718464?node=6
41  */
42 class VolumePanelDialog internal constructor() {
43     private val container: UiObject2 =
<lambda>null44         waitForObj(settingsResSelector("panel_container")) { "Can't find volume menu dialog" }
45 
46     private val audioManager =
47         context.getSystemService(AudioManager::class.java)
48             ?: error("Unable to get the AudioManager for ${VolumePanelDialog::class}")
49 
50     /**
51      * Convert volume index to the percentage.
52      *
53      * @param[stream] The volume stream to get the max/min volume.
54      * @param[volumeIndex] The volume index to set.
55      * @return The percentage of the max volume.
56      */
volumeToPercentagenull57     private fun volumeToPercentage(stream: Int, volumeIndex: Int): Float {
58         val maxVol: Int = audioManager.getStreamMaxVolume(stream)
59         val minVol: Int = audioManager.getStreamMinVolume(stream)
60         assertWithMessage("input volume is of out range.")
61             .that(volumeIndex)
62             .isIn(Range.closed(minVol, maxVol))
63         return (volumeIndex - minVol).toFloat() / (maxVol - minVol)
64     }
65 
66     /**
67      * Adjust ring volume by dragging "Ring & notification volume", or "Ring volume" slider.
68      *
69      * https://hsv.googleplex.com/5613609590718464?node=47
70      *
71      * @param[volume] The target volume index.
72      */
adjustRingVolumenull73     fun adjustRingVolume(volume: Int): VolumePanelDialog {
74         val pattern = Pattern.compile("(Ring & notification volume)|(Ring volume)")
75         val ringContainerSel = androidResSelector("content").hasDescendant(By.text(pattern))
76         val ringContainer = container.waitForObj(ringContainerSel, SHORT_WAIT)
77         val seekBar =
78             ringContainer.waitForObj(By.clazz(SeekBar::class.java)) {
79                 "Can't find ring volume slider."
80             }
81         val bound = seekBar.visibleBounds
82         val rate = volumeToPercentage(AudioManager.STREAM_RING, volume)
83         val x = ((bound.right - bound.left) * rate + bound.left).toInt()
84         uiDevice.betterSwipe(
85             startX = bound.centerX(),
86             startY = bound.centerY(),
87             endX = x,
88             endY = bound.centerY(),
89             interpolator = PRECISE_GESTURE_INTERPOLATOR,
90         )
91         ensureThat("Volume is set to $volume.") {
92             audioManager.getStreamVolume(AudioManager.STREAM_RING) == volume
93         }
94         return this
95     }
96 
97     /**
98      * Click done button.
99      *
100      * https://hsv.googleplex.com/5613609590718464?node=63
101      */
clickDonenull102     fun clickDone() {
103         val btnSel = settingsResSelector("done")
104         waitForObj(btnSel).click()
105         btnSel.assertInvisible {
106             "Volume panel dialog's done button should be invisible after clicking."
107         }
108     }
109 }
110