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.platform.systemui_tapl.utils.DeviceUtils.LONG_WAIT 20 import android.platform.systemui_tapl.utils.DeviceUtils.SHORT_WAIT 21 import android.platform.systemui_tapl.utils.DeviceUtils.sysuiResSelector 22 import android.platform.uiautomatorhelpers.DeviceHelpers.assertVisible 23 import android.platform.uiautomatorhelpers.DeviceHelpers.uiDevice 24 import android.platform.uiautomatorhelpers.DeviceHelpers.waitForFirstObj 25 import android.platform.uiautomatorhelpers.DeviceHelpers.waitForObj 26 import androidx.test.uiautomator.By 27 import com.android.settingslib.flags.Flags.newStatusBarIcons 28 import com.android.systemui.Flags.statusBarRootModernization 29 import java.text.SimpleDateFormat 30 import java.util.Date 31 import java.util.Locale 32 import java.util.regex.Pattern 33 34 /** 35 * Space above quick settings, similar to the status bar. Visible only when the shade is open. It 36 * what's visible inside might differ when: 37 * - in QQS state 38 * - in QS state 39 * - Large screen device https://hsv.googleplex.com/4864533182021632?node=16 40 */ 41 class QSHeader internal constructor() { 42 private val uiObject = 43 waitForFirstObj( 44 sysuiResSelector("shade_header_root"), 45 sysuiResSelector("split_shade_status_bar"), 46 timeout = LONG_WAIT, 47 ) 48 .first 49 50 /** Returns the value of the battery level on QS header. Experimental. */ getBatteryLevelnull51 fun getBatteryLevel(): String { 52 return uiDevice 53 .waitForObj(sysuiResSelector(StatusBar.BATTERY_LEVEL_TEXT_ID)) { 54 "Battery percentage not found on QS header." 55 } 56 .text 57 } 58 59 /** Verifies the clock is visible. Throws otherwise. Experimental. */ verifyTimeVisiblenull60 fun verifyTimeVisible() { 61 // Matches 12h or 24h time format 62 val timePattern = Pattern.compile("^(?:[01]?\\d|2[0-3]):[0-5]\\d") 63 By.pkg("com.android.systemui").text(timePattern).assertVisible(SHORT_WAIT) 64 } 65 66 /** Verifies the date is visible. Throws otherwise. Experimental. */ verifyDateVisiblenull67 fun verifyDateVisible() { 68 val date = Date(System.currentTimeMillis()) 69 val dateText = SimpleDateFormat("EEE, MMM d", Locale.ENGLISH).format(date) 70 By.pkg("com.android.systemui").text(dateText).assertVisible(SHORT_WAIT) 71 } 72 73 /** Verifies status icons are visible. Throws otherwise. Experimental. */ verifyStatusIconsVisiblenull74 fun verifyStatusIconsVisible() { 75 // See {@link EnsureAtLeastOneStatusBarIconVisibleRule} 76 verifySilentIconIsVisible() 77 } 78 79 /** Verifies the battery view is visible. Throws otherwise. Experimental. */ verifyBatteryMeterVisiblenull80 fun verifyBatteryMeterVisible() { 81 if (statusBarRootModernization() && newStatusBarIcons()) { 82 "battery_meter_composable_view".assertVisible() 83 } else { 84 "battery_percentage_view".assertVisible() 85 } 86 } 87 88 /** Verifies that dock defend icon is visible. */ verifyDockDefendIconVisiblenull89 fun verifyDockDefendIconVisible() { 90 uiObject.hasObject(By.descContains(StatusBar.DOCK_DEFEND_ICON_SUFFIX_STRING)) 91 } 92 93 /** Verifies that DND icon is visible. Experimental. */ verifyDndIconIsVisiblenull94 fun verifyDndIconIsVisible() { 95 By.pkg("com.android.systemui") 96 .clazz("android.widget.ImageView") 97 .desc(StatusBar.DND_ICON_DESC) 98 .assertVisible(SHORT_WAIT) 99 } 100 101 /** Verifies that silent icon is visible. */ verifySilentIconIsVisiblenull102 fun verifySilentIconIsVisible() { 103 By.pkg("com.android.systemui") 104 .clazz("android.widget.ImageView") 105 .desc("Ringer silent.") 106 .assertVisible(SHORT_WAIT) 107 } 108 assertVisiblenull109 private fun String.assertVisible() = sysuiResSelector(this).assertVisible(timeout = SHORT_WAIT) 110 } 111