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.graphics.Rect 20 import android.platform.systemui_tapl.utils.DeviceUtils.LONG_WAIT 21 import android.platform.systemui_tapl.utils.DeviceUtils.sysuiResSelector 22 import android.platform.uiautomatorhelpers.BetterSwipe 23 import android.platform.uiautomatorhelpers.DeviceHelpers.assertVisibility 24 import android.platform.uiautomatorhelpers.DeviceHelpers.waitForObj 25 import android.platform.uiautomatorhelpers.PRECISE_GESTURE_INTERPOLATOR 26 import androidx.test.uiautomator.UiObject2 27 import com.android.systemui.Flags 28 import com.google.common.truth.Truth.assertThat 29 import java.time.Duration 30 31 /** System UI test automation object representing the quick settings' brightness slider. */ 32 class BrightnessSlider internal constructor() { 33 private val slider: UiObject2 34 35 init { 36 val selector = sysuiResSelector(UI_BRIGHTNESS_SLIDER_ID) 37 slider = <lambda>null38 waitForObj(selector, LONG_WAIT) { "$selector not found" } 39 .waitForObj(sysuiResSelector(UI_TOGGLE_SEEKBAR_ID)) 40 } 41 42 /** Slides from left to right */ swipeFromLeftToRightnull43 fun swipeFromLeftToRight() { 44 swipeFromLeftToRight(Duration.ofMillis(500)) 45 } 46 47 /** Slides from left to right with specifying [swipeDuration] */ swipeFromLeftToRightnull48 fun swipeFromLeftToRight(swipeDuration: Duration) { 49 val sliderBounds = slider.visibleBounds 50 val pointFrom = 51 PointF( 52 (sliderBounds.centerX() - sliderBounds.width() / 3).toFloat(), 53 sliderBounds.centerY().toFloat(), 54 ) 55 val pointTo = 56 PointF( 57 (sliderBounds.centerX() + sliderBounds.width() / 3).toFloat(), 58 sliderBounds.centerY().toFloat(), 59 ) 60 // NOTE: This control logic is less than clean. 61 if (Flags.qsUiRefactorComposeFragment()) { 62 BetterSwipe.swipe(pointFrom, pointTo, swipeDuration, PRECISE_GESTURE_INTERPOLATOR) 63 if (Flags.qsUiRefactorComposeFragment()) { 64 // In this case, the slider is moved to an overlay, then we verify: 65 // The notification shade is not visible, but 66 assertVisibility(sysuiResSelector(UI_NOTIFICATION_SHADE_ID), visible = false) 67 // The actual slider is visible, and 68 assertVisibility(sysuiResSelector(UI_BRIGHTNESS_SLIDER_ID), visible = true) 69 // The bounds haven't changed. 70 assertThat(slider.visibleBounds).isEqualTo(sliderBounds) 71 } 72 } else { 73 var mirrorBounds: Rect? = null 74 BetterSwipe.swipe(pointFrom) { 75 to(pointTo, swipeDuration, PRECISE_GESTURE_INTERPOLATOR) 76 mirrorBounds = brightnessSliderMirror.visibleBounds 77 assertThat(sliderBounds).isEqualTo(mirrorBounds) 78 } 79 assertThat(mirrorBounds).isEqualTo(slider.visibleBounds) 80 } 81 } 82 83 // The Mirror slider has the same id as the original one, so we get it from the container 84 private val brightnessSliderMirror: UiObject2 85 get() { 86 // The Mirror slider has the same id as the original one, so we get it from the 87 // container 88 return waitForObj(sysuiResSelector(UI_BRIGHTNESS_MIRROR_CONTAINER_ID)) 89 .waitForObj(sysuiResSelector(UI_TOGGLE_SEEKBAR_ID)) 90 } 91 92 private companion object { 93 const val UI_TOGGLE_SEEKBAR_ID = "slider" 94 const val UI_BRIGHTNESS_SLIDER_ID = "brightness_slider" 95 const val UI_BRIGHTNESS_MIRROR_CONTAINER_ID = "brightness_mirror_container" 96 const val UI_NOTIFICATION_SHADE_ID = "notification_shade" 97 } 98 } 99