1 /* 2 * Copyright 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 com.android.photopicker.core.theme 18 19 import android.content.Intent 20 import android.provider.MediaStore 21 import androidx.compose.ui.graphics.Color 22 import androidx.test.ext.junit.runners.AndroidJUnit4 23 import androidx.test.filters.SmallTest 24 import com.google.common.truth.Truth.assertThat 25 import org.junit.Assert 26 import org.junit.Test 27 import org.junit.runner.RunWith 28 29 @SmallTest 30 @RunWith(AndroidJUnit4::class) 31 class AccentColorHelperTest { 32 @Test testAccentColorHelper_differentIntentActions_accentColorsNotSetnull33 fun testAccentColorHelper_differentIntentActions_accentColorsNotSet() { 34 // helper class reads colors from input intent and validates it. 35 // create input intent: 36 var pickerIntent = Intent() 37 val validAccentColor: Long = 0xFF0000 38 39 // Verify that the helper does not work with [MediaStore.ACTION_USER_SELECT_IMAGES_FOR_APP] 40 // intent action. 41 pickerIntent.setAction(MediaStore.ACTION_USER_SELECT_IMAGES_FOR_APP) 42 pickerIntent.putExtra(MediaStore.EXTRA_PICK_IMAGES_ACCENT_COLOR, validAccentColor) 43 assertExceptionThrownDueToInvalidInput(pickerIntent) 44 45 // Verify that the helper does not work with [Intent.ACTION_GET_CONTENT] intent action. 46 pickerIntent.setAction(Intent.ACTION_GET_CONTENT) 47 pickerIntent.putExtra(MediaStore.EXTRA_PICK_IMAGES_ACCENT_COLOR, validAccentColor) 48 assertExceptionThrownDueToInvalidInput(pickerIntent) 49 50 // Verify that the helper does not work with [Intent.ACTION_GET_CONTENT] intent action. 51 pickerIntent.setAction(MediaStore.ACTION_PICK_IMAGES) 52 pickerIntent.putExtra(MediaStore.EXTRA_PICK_IMAGES_ACCENT_COLOR, validAccentColor) 53 val accentColorHelperPickImagesMode = AccentColorHelper.withIntent(pickerIntent) 54 assertThat(accentColorHelperPickImagesMode.getAccentColor()).isNotEqualTo(Color.Unspecified) 55 assertThat(accentColorHelperPickImagesMode.getAccentColor()) 56 .isEqualTo( 57 createColorFromLongFormat(validAccentColor), 58 ) 59 } 60 61 @Test testAccentColorHelper_invalidInputColors_accentColorsNotSetnull62 fun testAccentColorHelper_invalidInputColors_accentColorsNotSet() { 63 // helper class reads colors from input intent and validates it. 64 // create input intent: 65 var pickerIntent = Intent(MediaStore.ACTION_PICK_IMAGES) 66 val invalidInputColor: Long = 0 67 val colorWithLowLuminance: Long = 0xFFFFF0 // a color close to white 68 val colorWithHighLuminance: Long = 0x000001 // a color close to black 69 70 // Verify that the helper does not work with invalid colors 71 72 pickerIntent.putExtra(MediaStore.EXTRA_PICK_IMAGES_ACCENT_COLOR, invalidInputColor) 73 assertExceptionThrownDueToInvalidInput(pickerIntent) 74 75 pickerIntent.putExtra(MediaStore.EXTRA_PICK_IMAGES_ACCENT_COLOR, colorWithLowLuminance) 76 assertExceptionThrownDueToInvalidInput(pickerIntent) 77 78 pickerIntent.putExtra(MediaStore.EXTRA_PICK_IMAGES_ACCENT_COLOR, colorWithHighLuminance) 79 assertExceptionThrownDueToInvalidInput(pickerIntent) 80 } 81 82 @Test testAccentColorHelper_validInputColor_accentColorsSetnull83 fun testAccentColorHelper_validInputColor_accentColorsSet() { 84 // helper class reads colors from input intent and validates it. 85 // create input intent: 86 var pickerIntent = Intent(MediaStore.ACTION_PICK_IMAGES) 87 val validAccentColor: Long = 0xFF0000 88 89 // Verify that the helper works with valid color 90 pickerIntent.putExtra(MediaStore.EXTRA_PICK_IMAGES_ACCENT_COLOR, validAccentColor) 91 val accentColorHelperInvalidInputColor = AccentColorHelper.withIntent(pickerIntent) 92 assertThat(accentColorHelperInvalidInputColor.getAccentColor()) 93 .isNotEqualTo(Color.Unspecified) 94 assertThat(accentColorHelperInvalidInputColor.getAccentColor()) 95 .isEqualTo( 96 createColorFromLongFormat(validAccentColor), 97 ) 98 } 99 100 @Test testAccentColorHelper_textColorAlwaysUnspecifiedIfAccentColorUnspecifiednull101 fun testAccentColorHelper_textColorAlwaysUnspecifiedIfAccentColorUnspecified() { 102 103 // Intent with no custom color set 104 var pickerIntent = Intent(MediaStore.ACTION_PICK_IMAGES) 105 106 val accentColorHelper = AccentColorHelper.withIntent(pickerIntent) 107 assertThat(accentColorHelper.getAccentColor()).isEqualTo(Color.Unspecified) 108 assertThat(accentColorHelper.getTextColorForAccentComponents()).isEqualTo(Color.Unspecified) 109 } 110 111 @Test testAccentColorHelper_textColorForDifferentLuminance_changesAccordinglynull112 fun testAccentColorHelper_textColorForDifferentLuminance_changesAccordingly() { 113 // helper class reads colors from input intent and validates it. 114 // create input intent: 115 var pickerIntent = Intent(MediaStore.ACTION_PICK_IMAGES) 116 val validAccentColorWithHighLuminance: Long = 0x144F28 // dark green 117 val validAccentColorWithLowLuminance: Long = 0xd6E0D7 // light pink 118 119 // Verify that the helper works with validAccentColorWithHighLuminance. In this case the 120 // text color set should be white since the accent color is dark. 121 pickerIntent.putExtra( 122 MediaStore.EXTRA_PICK_IMAGES_ACCENT_COLOR, 123 validAccentColorWithHighLuminance 124 ) 125 val accentColorHelperHighLuminance = AccentColorHelper.withIntent(pickerIntent) 126 assertThat(accentColorHelperHighLuminance.getAccentColor()).isNotEqualTo(Color.Unspecified) 127 assertThat(accentColorHelperHighLuminance.getAccentColor()) 128 .isEqualTo( 129 createColorFromLongFormat(validAccentColorWithHighLuminance), 130 ) 131 assertThat(accentColorHelperHighLuminance.getTextColorForAccentComponents()) 132 .isEqualTo( 133 Color.White, 134 ) 135 136 // Verify that the helper works with validAccentColorWithLowLuminance. In this case the 137 // text color set should be black since the accent color is light. 138 pickerIntent.putExtra( 139 MediaStore.EXTRA_PICK_IMAGES_ACCENT_COLOR, 140 validAccentColorWithLowLuminance 141 ) 142 val accentColorHelperLowLuminance = AccentColorHelper.withIntent(pickerIntent) 143 assertThat(accentColorHelperLowLuminance.getAccentColor()).isNotEqualTo(Color.Unspecified) 144 assertThat(accentColorHelperLowLuminance.getAccentColor()) 145 .isEqualTo( 146 createColorFromLongFormat(validAccentColorWithLowLuminance), 147 ) 148 assertThat(accentColorHelperLowLuminance.getTextColorForAccentComponents()) 149 .isEqualTo( 150 Color.Black, 151 ) 152 } 153 createColorFromLongFormatnull154 private fun createColorFromLongFormat(color: Long): Color { 155 // Gives us the formatted color string where the mask gives us the color in the RRGGBB 156 // format and the %06X gives zero-padded hex (6 characters long) 157 val hexColor = String.format("#%06X", (0xFFFFFF.toLong() and color)) 158 val inputColor = android.graphics.Color.parseColor(hexColor) 159 return Color(inputColor) 160 } 161 assertExceptionThrownDueToInvalidInputnull162 private fun assertExceptionThrownDueToInvalidInput(pickerIntent: Intent) { 163 try { 164 AccentColorHelper.withIntent(pickerIntent) 165 Assert.fail("Should have failed since the input was invalid") 166 } catch (exception: IllegalArgumentException) { 167 // expected result, yippee!! 168 } 169 } 170 } 171