Home | History | Annotate | Download | only in cts
      1 /*
      2  * Copyright (C) 2008 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.graphics.cts;
     17 
     18 import static androidx.test.InstrumentationRegistry.getInstrumentation;
     19 
     20 import static org.junit.Assert.assertEquals;
     21 import static org.junit.Assert.assertTrue;
     22 
     23 import android.content.res.Resources;
     24 import android.graphics.Color;
     25 import android.util.Log;
     26 import android.util.TypedValue;
     27 
     28 import androidx.test.filters.SmallTest;
     29 import androidx.test.runner.AndroidJUnit4;
     30 
     31 import org.junit.Test;
     32 import org.junit.runner.RunWith;
     33 
     34 import java.lang.annotation.Annotation;
     35 import java.lang.reflect.Field;
     36 import java.util.Arrays;
     37 import java.util.List;
     38 
     39 @SmallTest
     40 @RunWith(AndroidJUnit4.class)
     41 public class ColorTest {
     42 
     43     private static final String LOG_TAG = ColorTest.class.getSimpleName();
     44 
     45     @Test
     46     public void resourceColor() {
     47         int colors [][] = {
     48                 { 0xff000000, android.R.color.background_dark  },
     49                 { 0xffffffff, android.R.color.background_light },
     50                 { 0xff000000, android.R.color.black },
     51                 { 0xffaaaaaa, android.R.color.darker_gray },
     52                 { 0xff00ddff, android.R.color.holo_blue_bright },
     53                 { 0xff0099cc, android.R.color.holo_blue_dark },
     54                 { 0xff33b5e5, android.R.color.holo_blue_light },
     55                 { 0xff669900, android.R.color.holo_green_dark },
     56                 { 0xff99cc00, android.R.color.holo_green_light },
     57                 { 0xffff8800, android.R.color.holo_orange_dark },
     58                 { 0xffffbb33, android.R.color.holo_orange_light },
     59                 { 0xffaa66cc, android.R.color.holo_purple },
     60                 { 0xffcc0000, android.R.color.holo_red_dark },
     61                 { 0xffff4444, android.R.color.holo_red_light },
     62                 { 0xffffffff, android.R.color.primary_text_dark },
     63                 { 0xffffffff, android.R.color.primary_text_dark_nodisable },
     64                 { 0xff000000, android.R.color.primary_text_light },
     65                 { 0xff000000, android.R.color.primary_text_light_nodisable },
     66                 { 0xffbebebe, android.R.color.secondary_text_dark },
     67                 { 0xffbebebe, android.R.color.secondary_text_dark_nodisable },
     68                 { 0xff323232, android.R.color.secondary_text_light },
     69                 { 0xffbebebe, android.R.color.secondary_text_light_nodisable },
     70                 { 0xff808080, android.R.color.tab_indicator_text },
     71                 { 0xff808080, android.R.color.tertiary_text_dark },
     72                 { 0xff808080, android.R.color.tertiary_text_light },
     73                 { 0x00000000, android.R.color.transparent },
     74                 { 0xffffffff, android.R.color.white },
     75                 { 0xff000000, android.R.color.widget_edittext_dark },
     76         };
     77 
     78         List<Integer> expectedColorStateLists = Arrays.asList(
     79                 android.R.color.primary_text_dark,
     80                 android.R.color.primary_text_dark_nodisable,
     81                 android.R.color.primary_text_light,
     82                 android.R.color.primary_text_light_nodisable,
     83                 android.R.color.secondary_text_dark,
     84                 android.R.color.secondary_text_dark_nodisable,
     85                 android.R.color.secondary_text_light,
     86                 android.R.color.secondary_text_light_nodisable,
     87                 android.R.color.tab_indicator_text,
     88                 android.R.color.tertiary_text_dark,
     89                 android.R.color.tertiary_text_light,
     90                 android.R.color.widget_edittext_dark
     91         );
     92 
     93         Resources resources = getInstrumentation().getTargetContext().getResources();
     94         for (int[] pair : colors) {
     95             final int resourceId = pair[1];
     96             final int expectedColor = pair[0];
     97 
     98             // validate color from getColor
     99             int observedColor = resources.getColor(resourceId, null);
    100             assertEquals("Color = " + Integer.toHexString(observedColor) + ", "
    101                             + Integer.toHexString(expectedColor) + " expected",
    102                     expectedColor,
    103                     observedColor);
    104 
    105             // validate color from getValue
    106             TypedValue value = new TypedValue();
    107             resources.getValue(resourceId, value, true);
    108 
    109             // colors shouldn't depend on config changes
    110             assertEquals(0, value.changingConfigurations);
    111 
    112             if (expectedColorStateLists.contains(resourceId)) {
    113                 // ColorStateLists are strings
    114                 assertEquals("CSLs should be strings", TypedValue.TYPE_STRING, value.type);
    115             } else {
    116                 // colors should be raw ints
    117                 assertTrue("Type should be int",
    118                         value.type >= TypedValue.TYPE_FIRST_INT
    119                         && value.type <= TypedValue.TYPE_LAST_INT);
    120 
    121                 // Validate color from getValue
    122                 assertEquals("Color should be expected value", expectedColor, value.data);
    123             }
    124         }
    125 
    126         // System-API colors are used to allow updateable platform components to use the same colors
    127         // as the system. The actualy value of the color does not matter. Hence only enforce that
    128         // 'colors' contains all the public colors and ignore System-api colors.
    129         int numPublicApiColors = 0;
    130         for (Field declaredColor : android.R.color.class.getDeclaredFields()) {
    131             if (Arrays.stream(declaredColor.getDeclaredAnnotations()).anyMatch(
    132                     (Annotation a) -> a.toString().contains("SystemApi"))) {
    133                 Log.i(LOG_TAG, declaredColor.getName() + " is SystemApi");
    134             } else {
    135                 numPublicApiColors++;
    136             }
    137         }
    138 
    139         assertEquals("Test no longer in sync with colors in android.R.color",
    140                 colors.length, numPublicApiColors);
    141     }
    142 
    143     @Test
    144     public void testAlpha() {
    145         assertEquals(0xff, Color.alpha(Color.RED));
    146         assertEquals(0xff, Color.alpha(Color.YELLOW));
    147     }
    148 
    149     @Test
    150     public void testArgb() {
    151         assertEquals(Color.RED, Color.argb(0xff, 0xff, 0x00, 0x00));
    152         assertEquals(Color.YELLOW, Color.argb(0xff, 0xff, 0xff, 0x00));
    153         assertEquals(Color.RED, Color.argb(1.0f, 1.0f, 0.0f, 0.0f));
    154         assertEquals(Color.YELLOW, Color.argb(1.0f, 1.0f, 1.0f, 0.0f));
    155     }
    156 
    157     @Test
    158     public void testBlue() {
    159         assertEquals(0x00, Color.blue(Color.RED));
    160         assertEquals(0x00, Color.blue(Color.YELLOW));
    161     }
    162 
    163     @Test
    164     public void testGreen() {
    165         assertEquals(0x00, Color.green(Color.RED));
    166         assertEquals(0xff, Color.green(Color.GREEN));
    167     }
    168 
    169     @Test(expected=RuntimeException.class)
    170     public void testHSVToColorArrayTooShort() {
    171         // abnormal case: hsv length less than 3
    172         float[] hsv = new float[2];
    173         Color.HSVToColor(hsv);
    174     }
    175 
    176     @Test
    177     public void testHSVToColor() {
    178         float[] hsv = new float[3];
    179         Color.colorToHSV(Color.RED, hsv);
    180         assertEquals(Color.RED, Color.HSVToColor(hsv));
    181     }
    182 
    183     @Test
    184     public void testHSVToColorWithAlpha() {
    185         float[] hsv = new float[3];
    186         Color.colorToHSV(Color.RED, hsv);
    187         assertEquals(Color.RED, Color.HSVToColor(0xff, hsv));
    188     }
    189 
    190     @Test(expected=IllegalArgumentException.class)
    191     public void testParseColorStringOfInvalidLength() {
    192         // abnormal case: colorString starts with '#' but length is neither 7 nor 9
    193         Color.parseColor("#ff00ff0");
    194     }
    195 
    196     @Test
    197     public void testParseColor() {
    198         assertEquals(Color.RED, Color.parseColor("#ff0000"));
    199         assertEquals(Color.RED, Color.parseColor("#ffff0000"));
    200 
    201         assertEquals(Color.BLACK, Color.parseColor("black"));
    202         assertEquals(Color.DKGRAY, Color.parseColor("darkgray"));
    203         assertEquals(Color.GRAY, Color.parseColor("gray"));
    204         assertEquals(Color.LTGRAY, Color.parseColor("lightgray"));
    205         assertEquals(Color.WHITE, Color.parseColor("white"));
    206         assertEquals(Color.RED, Color.parseColor("red"));
    207         assertEquals(Color.GREEN, Color.parseColor("green"));
    208         assertEquals(Color.BLUE, Color.parseColor("blue"));
    209         assertEquals(Color.YELLOW, Color.parseColor("yellow"));
    210         assertEquals(Color.CYAN, Color.parseColor("cyan"));
    211         assertEquals(Color.MAGENTA, Color.parseColor("magenta"));
    212     }
    213 
    214     @Test(expected=IllegalArgumentException.class)
    215     public void testParseColorUnsupportedFormat() {
    216         // abnormal case: colorString doesn't start with '#' and is unknown color
    217         Color.parseColor("hello");
    218     }
    219 
    220     @Test
    221     public void testRed() {
    222         assertEquals(0xff, Color.red(Color.RED));
    223         assertEquals(0xff, Color.red(Color.YELLOW));
    224     }
    225 
    226     @Test
    227     public void testRgb() {
    228         assertEquals(Color.RED, Color.rgb(0xff, 0x00, 0x00));
    229         assertEquals(Color.YELLOW, Color.rgb(0xff, 0xff, 0x00));
    230         assertEquals(Color.RED, Color.rgb(1.0f, 0.0f, 0.0f));
    231         assertEquals(Color.YELLOW, Color.rgb(1.0f, 1.0f, 0.0f));
    232     }
    233 
    234     @Test(expected=RuntimeException.class)
    235     public void testRGBToHSVArrayTooShort() {
    236         // abnormal case: hsv length less than 3
    237         float[] hsv = new float[2];
    238         Color.RGBToHSV(0xff, 0x00, 0x00, hsv);
    239     }
    240 
    241     @Test
    242     public void testRGBToHSV() {
    243         float[] hsv = new float[3];
    244         Color.RGBToHSV(0xff, 0x00, 0x00, hsv);
    245         assertEquals(Color.RED, Color.HSVToColor(hsv));
    246     }
    247 
    248     @Test
    249     public void testLuminance() {
    250         assertEquals(0, Color.luminance(Color.BLACK), 0);
    251         float eps = 0.000001f;
    252         assertEquals(0.0722, Color.luminance(Color.BLUE), eps);
    253         assertEquals(0.2126, Color.luminance(Color.RED), eps);
    254         assertEquals(0.7152, Color.luminance(Color.GREEN), eps);
    255         assertEquals(1, Color.luminance(Color.WHITE), 0);
    256     }
    257 }
    258