1 /* 2 * Copyright (C) 2023 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 com.android.wm.shell.flicker.appcompat 18 19 import android.app.Instrumentation 20 import android.system.helpers.CommandsHelper 21 import androidx.test.platform.app.InstrumentationRegistry 22 import org.junit.rules.TestRule 23 import org.junit.runner.Description 24 import org.junit.runners.model.Statement 25 26 /** 27 * JUnit Rule to handle letterboxStyles and states 28 */ 29 class LetterboxRule( 30 private val withLetterboxEducationEnabled: Boolean = false, 31 private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation(), 32 private val cmdHelper: CommandsHelper = CommandsHelper.getInstance(instrumentation) 33 ) : TestRule { 34 35 private val execAdb: (String) -> String = {cmd -> cmdHelper.executeShellCommand(cmd)} 36 private lateinit var _letterboxStyle: MutableMap<String, String> 37 38 val letterboxStyle: Map<String, String> 39 get() { 40 if (!::_letterboxStyle.isInitialized) { 41 _letterboxStyle = mapLetterboxStyle() 42 } 43 return _letterboxStyle 44 } 45 46 val cornerRadius: Int? 47 get() = asInt(letterboxStyle["Corner radius"]) 48 49 val hasCornerRadius: Boolean 50 get() { 51 val radius = cornerRadius 52 return radius != null && radius > 0 53 } 54 55 val isIgnoreOrientationRequest: Boolean 56 get() = execAdb("wm get-ignore-orientation-request")?.contains("true") ?: false 57 58 override fun apply(base: Statement?, description: Description?): Statement { 59 resetLetterboxStyle() 60 _letterboxStyle = mapLetterboxStyle() 61 val isLetterboxEducationEnabled = _letterboxStyle.getValue("Is education enabled") 62 var hasLetterboxEducationStateChanged = false 63 if ("$withLetterboxEducationEnabled" != isLetterboxEducationEnabled) { 64 hasLetterboxEducationStateChanged = true 65 execAdb("wm set-letterbox-style --isEducationEnabled " + 66 withLetterboxEducationEnabled) 67 } 68 return try { 69 object : Statement() { 70 @Throws(Throwable::class) 71 override fun evaluate() { 72 base!!.evaluate() 73 } 74 } 75 } finally { 76 if (hasLetterboxEducationStateChanged) { 77 execAdb("wm set-letterbox-style --isEducationEnabled " + 78 isLetterboxEducationEnabled 79 ) 80 } 81 resetLetterboxStyle() 82 } 83 } 84 85 private fun mapLetterboxStyle(): HashMap<String, String> { 86 val res = execAdb("wm get-letterbox-style") 87 val lines = res.lines() 88 val map = HashMap<String, String>() 89 for (line in lines) { 90 val keyValuePair = line.split(":") 91 if (keyValuePair.size == 2) { 92 val key = keyValuePair[0].trim() 93 map[key] = keyValuePair[1].trim() 94 } 95 } 96 return map 97 } 98 99 private fun resetLetterboxStyle() { 100 execAdb("wm reset-letterbox-style") 101 } 102 103 private fun asInt(str: String?): Int? = try { 104 str?.toInt() 105 } catch (e: NumberFormatException) { 106 null 107 } 108 }