1 /* <lambda>null2 * Copyright 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 17 package platform.test.screenshot 18 19 import android.content.Context 20 import android.util.Log 21 import android.util.SparseIntArray 22 import android.widget.RemoteViews 23 import androidx.annotation.VisibleForTesting 24 import androidx.test.platform.app.InstrumentationRegistry 25 import org.junit.rules.TestRule 26 import org.junit.runner.Description 27 import org.junit.runners.model.Statement 28 29 /** 30 * A rule to overload the target context system colors by [colors]. 31 * 32 * This is especially useful to apply the colors before you start an activity using an 33 * [ActivityScenarioRule] or any other rule, given that the colors must be [applied] 34 * [MaterialYouColors.apply] *before* doing any resource resolution. 35 */ 36 class MaterialYouColorsRule(private val colors: MaterialYouColors = MaterialYouColors.GreenBlue) : 37 TestRule { 38 override fun apply(base: Statement, description: Description): Statement { 39 return object : Statement() { 40 override fun evaluate() { 41 colors.apply(InstrumentationRegistry.getInstrumentation().targetContext) 42 base.evaluate() 43 } 44 } 45 } 46 } 47 48 /** 49 * A util class to overload the Material You colors of a [Context] to some fixed values. This can be 50 * used by screenshot tests so that device-specific colors don't impact the outcome of the test. 51 * 52 * @see apply 53 */ 54 class MaterialYouColors( 55 @get:VisibleForTesting val colors: SparseIntArray, 56 ) { 57 /** 58 * Apply these colors to [context]. 59 * 60 * Important: No resource resolution must have be done on the context given to that method. 61 */ applynull62 fun apply(context: Context) { 63 RemoteViews.ColorResources.create(context, colors)?.apply(context) 64 } 65 66 companion object { 67 private const val FIRST_RESOURCE_COLOR_ID = android.R.color.system_neutral1_0 68 private const val LAST_RESOURCE_COLOR_ID = android.R.color.system_error_1000 69 70 /** 71 * An instance of [MaterialYouColors] with green/blue colors seed, that can be used directly 72 * by tests. 73 */ 74 val GreenBlue = fromColors(GREEN_BLUE) 75 76 /** 77 * Create a [MaterialYouColors] from [colors], where: 78 * - `colors[i]` should be the value of `FIRST_RESOURCE_COLOR_ID + i`. 79 * - [colors] are recommended to contain all values of all system colors, i.e. `colors.size` 80 * is best to be `LAST_RESOURCE_COLOR_ID - FIRST_RESOURCE_COLOR_ID + 1`, otherwise we are 81 * expected to observed unused values in the sparse array (more elements in the array) or 82 * unconfigured system colors (fewer elements in the array). 83 */ fromColorsnull84 private fun fromColors(colors: IntArray): MaterialYouColors { 85 val expectedSize = LAST_RESOURCE_COLOR_ID - FIRST_RESOURCE_COLOR_ID + 1 86 if (colors.size != expectedSize) { 87 Log.d( 88 "MaterialYouColors.fromColors", 89 "colors are best to have exactly $expectedSize elements for a complete " + 90 "configuration for system colors") 91 } 92 93 val sparseArray = SparseIntArray(/* initialCapacity= */ expectedSize) 94 colors.forEachIndexed { i, color -> 95 sparseArray.put(FIRST_RESOURCE_COLOR_ID + i, color) 96 } 97 98 return MaterialYouColors(sparseArray) 99 } 100 } 101 } 102 103 /** 104 * Some green/blue colors, from system_neutral1_0 to system_accent3_1000, extracted using 0xB1EBFF 105 * as seed color and "FRUIT_SALAD" as theme style. 106 */ 107 private val GREEN_BLUE = 108 intArrayOf( 109 -1, 110 -393729, 111 -1641480, 112 -2562838, 113 -4405043, 114 -6181454, 115 -7892073, 116 -9668483, 117 -11181979, 118 -12760755, 119 -14208458, 120 -15590111, 121 -16777216, 122 -1, 123 -393729, 124 -2296322, 125 -3217680, 126 -4994349, 127 -6770760, 128 -8547171, 129 -10257790, 130 -11836822, 131 -13350318, 132 -14863301, 133 -16376283, 134 -16777216, 135 -1, 136 -720905, 137 -4456478, 138 -8128307, 139 -10036302, 140 -12075112, 141 -14638210, 142 -16742810, 143 -16749487, 144 -16756420, 145 -16762839, 146 -16768746, 147 -16777216, 148 -1, 149 -720905, 150 -4456478, 151 -5901613, 152 -7678281, 153 -9454947, 154 -11231613, 155 -13139095, 156 -15111342, 157 -16756420, 158 -16762839, 159 -16768746, 160 -16777216, 161 -1, 162 -393729, 163 -2361857, 164 -5051393, 165 -7941655, 166 -9783603, 167 -11625551, 168 -13729642, 169 -16750723, 170 -16757153, 171 -16763326, 172 -16769241, 173 -16777216, 174 /* "system_primary_container_light" */ -2432257, 175 /* "system_on_primary_container_light" */ -16770999, 176 /* "system_primary_light" */ -11969134, 177 /* "system_on_primary_light" */ -1, 178 /* "system_secondary_container_light" */ -2235655, 179 /* "system_on_secondary_container_light" */ -15394004, 180 /* "system_secondary_light" */ -10985871, 181 /* "system_on_secondary_light" */ -1, 182 /* "system_tertiary_container_light" */ -76039, 183 /* "system_on_tertiary_container_light" */ -13954517, 184 /* "system_tertiary_light" */ -9218959, 185 /* "system_on_tertiary_light" */ -1, 186 /* "system_background_light" */ -329473, 187 /* "system_on_background_light" */ -15066335, 188 /* "system_surface_light" */ -329473, 189 /* "system_on_surface_light" */ -15066335, 190 /* "system_surface_container_low_light" */ -723974, 191 /* "system_surface_container_lowest_light" */ -1, 192 /* "system_surface_container_light" */ -1118732, 193 /* "system_surface_container_high_light" */ -1513489, 194 /* "system_surface_container_highest_light" */ -1842455, 195 /* "system_surface_bright_light" */ -329473, 196 /* "system_surface_dim_light" */ -2434592, 197 /* "system_surface_variant_light" */ -1973524, 198 /* "system_on_surface_variant_light" */ -12237233, 199 /* "system_outline_light" */ -9078912, 200 /* "system_error_light" */ -4580838, 201 /* "system_on_error_light" */ -1, 202 /* "system_error_container_light" */ -9514, 203 /* "system_on_error_container_light" */ -12517374, 204 /* "system_control_activated_light" */ -2432257, 205 /* "system_control_normal_light" */ -12237233, 206 /* "system_control_highlight_light" */ 520093696, 207 /* "system_text_primary_inverse_light" */ -1842455, 208 /* "system_text_secondary_and_tertiary_inverse_light" */ -3815728, 209 /* "system_text_primary_inverse_disable_only_light" */ -1842455, 210 /* "system_text_secondary_and_tertiary_inverse_disabled_light" */ -1842455, 211 /* "system_text_hint_inverse_light" */ -1842455, 212 /* "system_palette_key_color_primary_light" */ -10324564, 213 /* "system_palette_key_color_secondary_light" */ -9341301, 214 /* "system_palette_key_color_tertiary_light" */ -7443061, 215 /* "system_palette_key_color_neutral_light" */ -9013379, 216 /* "system_palette_key_color_neutral_variant_light" */ -9013376, 217 /* "system_primary_container_dark" */ -13548168, 218 /* "system_on_primary_container_dark" */ -2432257, 219 /* "system_primary_dark" */ -5061121, 220 /* "system_on_primary_dark" */ -15192480, 221 /* "system_secondary_container_dark" */ -12499367, 222 /* "system_on_secondary_container_dark" */ -2235655, 223 /* "system_secondary_dark" */ -4143395, 224 /* "system_on_secondary_dark" */ -14012350, 225 /* "system_tertiary_container_dark" */ -10863271, 226 /* "system_on_tertiary_container_dark" */ -76039, 227 /* "system_tertiary_dark" */ -1983524, 228 /* "system_on_tertiary_dark" */ -12441791, 229 /* "system_background_dark" */ -15592680, 230 /* "system_on_background_dark" */ -1842455, 231 /* "system_surface_dark" */ -15592680, 232 /* "system_on_surface_dark" */ -1842455, 233 /* "system_surface_container_low_dark" */ -15066335, 234 /* "system_surface_container_lowest_dark" */ -15921645, 235 /* "system_surface_container_dark" */ -14803163, 236 /* "system_surface_container_high_dark" */ -14079441, 237 /* "system_surface_container_highest_dark" */ -13421510, 238 /* "system_surface_bright_dark" */ -13092545, 239 /* "system_surface_dim_dark" */ -15592680, 240 /* "system_surface_variant_dark" */ -12237233, 241 /* "system_on_surface_variant_dark" */ -3815728, 242 /* "system_outline_dark" */ -7368550, 243 /* "system_error_dark" */ -19285, 244 /* "system_on_error_dark" */ -9895931, 245 /* "system_error_container_dark" */ -7143414, 246 /* "system_on_error_container_dark" */ -9514, 247 /* "system_control_activated_dark" */ -13548168, 248 /* "system_control_normal_dark" */ -3815728, 249 /* "system_control_highlight_dark" */ 872415231, 250 /* "system_text_primary_inverse_dark" */ -15066335, 251 /* "system_text_secondary_and_tertiary_inverse_dark" */ -12237233, 252 /* "system_text_primary_inverse_disable_only_dark" */ -15066335, 253 /* "system_text_secondary_and_tertiary_inverse_disabled_dark" */ -15066335, 254 /* "system_text_hint_inverse_dark" */ -15066335, 255 /* "system_palette_key_color_primary_dark" */ -10324564, 256 /* "system_palette_key_color_secondary_dark" */ -9341301, 257 /* "system_palette_key_color_tertiary_dark" */ -7443061, 258 /* "system_palette_key_color_neutral_dark" */ -9013379, 259 /* "system_palette_key_color_neutral_variant_dark" */ -9013376, 260 /* "system_primary_fixed" */ -2432257, 261 /* "system_primary_fixed_dim" */ -5061121, 262 /* "system_on_primary_fixed" */ -16770999, 263 /* "system_on_primary_fixed_variant" */ -13548168, 264 /* "system_secondary_fixed" */ -2235655, 265 /* "system_secondary_fixed_dim" */ -4143395, 266 /* "system_on_secondary_fixed" */ -15394004, 267 /* "system_on_secondary_fixed_variant" */ -12499367, 268 /* "system_tertiary_fixed" */ -76039, 269 /* "system_tertiary_fixed_dim" */ -1983524, 270 /* "system_on_tertiary_fixed" */ -13954517, 271 /* "system_on_tertiary_fixed_variant" */ -10863271, 272 /* "system_outline_variant_light" */ -3815728, 273 /* "system_outline_variant_dark" */ -12237233, 274 /* "system_surface_disabled" */ 1123743999, 275 /* "system_on_surface_disabled" */ 1109007137, 276 /* "system_outline_disabled" */ 1114994560, 277 /* "system_error_0" */ -1, 278 /* "system_error_10" */ -1031, 279 /* "system_error_50" */ -200978, 280 /* "system_error_100" */ -401700, 281 /* "system_error_200" */ -870219, 282 /* "system_error_300" */ -1273202, 283 /* "system_error_400" */ -1808030, 284 /* "system_error_500" */ -2345426, 285 /* "system_error_600" */ -5036514, 286 /* "system_error_700" */ -7594728, 287 /* "system_error_800" */ -10480624, 288 /* "system_error_900" */ -12513781, 289 /* "system_error_1000" */ -16777216, 290 ) 291