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 
     17 package android.graphics.drawable.cts;
     18 
     19 import com.android.cts.stub.R;
     20 
     21 import dalvik.annotation.KnownFailure;
     22 
     23 import org.xmlpull.v1.XmlPullParser;
     24 import org.xmlpull.v1.XmlPullParserException;
     25 
     26 import android.content.res.Resources;
     27 import android.content.res.XmlResourceParser;
     28 import android.graphics.Bitmap;
     29 import android.graphics.BitmapFactory;
     30 import android.graphics.Canvas;
     31 import android.graphics.Color;
     32 import android.graphics.ColorFilter;
     33 import android.graphics.NinePatch;
     34 import android.graphics.Paint;
     35 import android.graphics.PixelFormat;
     36 import android.graphics.Rect;
     37 import android.graphics.Region;
     38 import android.graphics.Bitmap.Config;
     39 import android.graphics.drawable.NinePatchDrawable;
     40 import android.graphics.drawable.Drawable.ConstantState;
     41 import android.test.InstrumentationTestCase;
     42 import android.util.AttributeSet;
     43 import android.util.Xml;
     44 
     45 import java.io.IOException;
     46 
     47 public class NinePatchDrawableTest extends InstrumentationTestCase {
     48     private static final int MIN_CHUNK_SIZE = 32;
     49 
     50     private NinePatchDrawable mNinePatchDrawable;
     51 
     52     private Resources mResources;
     53 
     54     @Override
     55     protected void setUp() throws Exception {
     56         super.setUp();
     57         mResources = getInstrumentation().getTargetContext().getResources();
     58         mNinePatchDrawable = getNinePatchDrawable(R.drawable.ninepatch_0);
     59     }
     60 
     61     @SuppressWarnings("deprecation")
     62     public void testConstructors() {
     63         byte[] chunk = new byte[MIN_CHUNK_SIZE];
     64         chunk[MIN_CHUNK_SIZE - 1] = 1;
     65 
     66         Rect r = new Rect();
     67 
     68         Bitmap bmp = BitmapFactory.decodeResource(mResources, R.drawable.ninepatch_0);
     69         String name = mResources.getResourceName(R.drawable.ninepatch_0);
     70 
     71         new NinePatchDrawable(bmp, chunk, r, name);
     72 
     73         new NinePatchDrawable(new NinePatch(bmp, chunk, name));
     74 
     75         chunk = new byte[MIN_CHUNK_SIZE - 1];
     76         chunk[MIN_CHUNK_SIZE - 2] = 1;
     77         try {
     78             new NinePatchDrawable(bmp, chunk, r, name);
     79             fail("The constructor should check whether the chunk is illegal.");
     80         } catch (RuntimeException e) {
     81             // This exception is thrown by native method.
     82         }
     83     }
     84 
     85     public void testDraw() {
     86         Bitmap bmp = Bitmap.createBitmap(9, 9, Config.ARGB_8888);
     87         Canvas c = new Canvas(bmp);
     88 
     89         int ocean = Color.rgb(0, 0xFF, 0x80);
     90 
     91         mNinePatchDrawable.setBounds(0, 0, 9, 9);
     92         mNinePatchDrawable.draw(c);
     93         assertColorFillRect(bmp, 0, 0, 4, 4, Color.RED);
     94         assertColorFillRect(bmp, 5, 0, 4, 4, Color.BLUE);
     95         assertColorFillRect(bmp, 0, 5, 4, 4, ocean);
     96         assertColorFillRect(bmp, 5, 5, 4, 4, Color.YELLOW);
     97         assertColorFillRect(bmp, 4, 0, 1, 9, Color.WHITE);
     98         assertColorFillRect(bmp, 0, 4, 9, 1, Color.WHITE);
     99 
    100         bmp.eraseColor(0xff000000);
    101 
    102         mNinePatchDrawable.setBounds(0, 0, 3, 3);
    103         mNinePatchDrawable.draw(c);
    104         assertColorFillRect(bmp, 0, 0, 1, 1, Color.RED);
    105         assertColorFillRect(bmp, 2, 0, 1, 1, Color.BLUE);
    106         assertColorFillRect(bmp, 0, 2, 1, 1, ocean);
    107         assertColorFillRect(bmp, 2, 2, 1, 1, Color.YELLOW);
    108         assertColorFillRect(bmp, 1, 0, 1, 3, Color.WHITE);
    109         assertColorFillRect(bmp, 0, 1, 3, 1, Color.WHITE);
    110 
    111         try {
    112             mNinePatchDrawable.draw(null);
    113             fail("The method should check whether the canvas is null.");
    114         } catch (NullPointerException e) {
    115             // expected
    116         }
    117     }
    118 
    119     public void testGetChangingConfigurations() {
    120         ConstantState constantState = mNinePatchDrawable.getConstantState();
    121 
    122         // default
    123         assertEquals(0, constantState.getChangingConfigurations());
    124         assertEquals(0, mNinePatchDrawable.getChangingConfigurations());
    125 
    126         // change the drawable's configuration does not affect the state's configuration
    127         mNinePatchDrawable.setChangingConfigurations(0xff);
    128         assertEquals(0xff, mNinePatchDrawable.getChangingConfigurations());
    129         assertEquals(0, constantState.getChangingConfigurations());
    130 
    131         // the state's configuration get refreshed
    132         constantState = mNinePatchDrawable.getConstantState();
    133         assertEquals(0xff,  constantState.getChangingConfigurations());
    134 
    135         // set a new configuration to drawable
    136         mNinePatchDrawable.setChangingConfigurations(0xff00);
    137         assertEquals(0xff,  constantState.getChangingConfigurations());
    138         assertEquals(0xffff,  mNinePatchDrawable.getChangingConfigurations());
    139     }
    140 
    141     public void testGetPadding() {
    142         Rect r = new Rect();
    143         NinePatchDrawable npd = (NinePatchDrawable) mResources.getDrawable(R.drawable.ninepatch_0);
    144         assertTrue(npd.getPadding(r));
    145         // exact padding unknown due to possible density scaling
    146         assertEquals(0, r.left);
    147         assertEquals(0, r.top);
    148         assertTrue(r.right > 0);
    149         assertTrue(r.bottom > 0);
    150 
    151         npd = (NinePatchDrawable) mResources.getDrawable(R.drawable.ninepatch_1);
    152         assertTrue(npd.getPadding(r));
    153         assertTrue(r.left > 0);
    154         assertTrue(r.top > 0);
    155         assertTrue(r.right > 0);
    156         assertTrue(r.bottom > 0);
    157     }
    158 
    159     public void testSetAlpha() {
    160         assertEquals(0xff, mNinePatchDrawable.getPaint().getAlpha());
    161 
    162         mNinePatchDrawable.setAlpha(0);
    163         assertEquals(0, mNinePatchDrawable.getPaint().getAlpha());
    164 
    165         mNinePatchDrawable.setAlpha(-1);
    166         assertEquals(0xff, mNinePatchDrawable.getPaint().getAlpha());
    167 
    168         mNinePatchDrawable.setAlpha(0xfffe);
    169         assertEquals(0xfe, mNinePatchDrawable.getPaint().getAlpha());
    170     }
    171 
    172     public void testSetColorFilter() {
    173         assertNull(mNinePatchDrawable.getPaint().getColorFilter());
    174 
    175         MockColorFilter cf = new MockColorFilter();
    176         mNinePatchDrawable.setColorFilter(cf);
    177         assertSame(cf, mNinePatchDrawable.getPaint().getColorFilter());
    178 
    179         mNinePatchDrawable.setColorFilter(null);
    180         assertNull(mNinePatchDrawable.getPaint().getColorFilter());
    181     }
    182 
    183     public void testSetDither() {
    184         mNinePatchDrawable.setDither(false);
    185         assertFalse(mNinePatchDrawable.getPaint().isDither());
    186 
    187         mNinePatchDrawable.setDither(true);
    188         assertTrue(mNinePatchDrawable.getPaint().isDither());
    189     }
    190 
    191     public void testGetPaint() {
    192         Paint paint = mNinePatchDrawable.getPaint();
    193         assertNotNull(paint);
    194 
    195         assertSame(paint, mNinePatchDrawable.getPaint());
    196     }
    197 
    198     public void testGetIntrinsicWidth() {
    199         Bitmap bmp = getBitmapUnscaled(R.drawable.ninepatch_0);
    200         assertEquals(bmp.getWidth(), mNinePatchDrawable.getIntrinsicWidth());
    201         assertEquals(5, mNinePatchDrawable.getIntrinsicWidth());
    202 
    203         mNinePatchDrawable = getNinePatchDrawable(R.drawable.ninepatch_1);
    204         bmp = getBitmapUnscaled(R.drawable.ninepatch_1);
    205         assertEquals(bmp.getWidth(), mNinePatchDrawable.getIntrinsicWidth());
    206         assertEquals(9, mNinePatchDrawable.getIntrinsicWidth());
    207     }
    208 
    209     public void testGetMinimumWidth() {
    210         Bitmap bmp = getBitmapUnscaled(R.drawable.ninepatch_0);
    211         assertEquals(bmp.getWidth(), mNinePatchDrawable.getMinimumWidth());
    212         assertEquals(5, mNinePatchDrawable.getMinimumWidth());
    213 
    214         mNinePatchDrawable = getNinePatchDrawable(R.drawable.ninepatch_1);
    215         bmp = getBitmapUnscaled(R.drawable.ninepatch_1);
    216         assertEquals(bmp.getWidth(), mNinePatchDrawable.getMinimumWidth());
    217         assertEquals(9, mNinePatchDrawable.getMinimumWidth());
    218     }
    219 
    220     public void testGetIntrinsicHeight() {
    221         Bitmap bmp = getBitmapUnscaled(R.drawable.ninepatch_0);
    222         assertEquals(bmp.getHeight(), mNinePatchDrawable.getIntrinsicHeight());
    223         assertEquals(5, mNinePatchDrawable.getIntrinsicHeight());
    224 
    225         mNinePatchDrawable = getNinePatchDrawable(R.drawable.ninepatch_1);
    226         bmp = getBitmapUnscaled(R.drawable.ninepatch_1);
    227         assertEquals(bmp.getHeight(), mNinePatchDrawable.getIntrinsicHeight());
    228         assertEquals(9, mNinePatchDrawable.getIntrinsicHeight());
    229     }
    230 
    231     public void testGetMinimumHeight() {
    232         Bitmap bmp = getBitmapUnscaled(R.drawable.ninepatch_0);
    233         assertEquals(bmp.getHeight(), mNinePatchDrawable.getMinimumHeight());
    234         assertEquals(5, mNinePatchDrawable.getMinimumHeight());
    235 
    236         mNinePatchDrawable = getNinePatchDrawable(R.drawable.ninepatch_1);
    237         bmp = getBitmapUnscaled(R.drawable.ninepatch_1);
    238         assertEquals(bmp.getHeight(), mNinePatchDrawable.getMinimumHeight());
    239         assertEquals(9, mNinePatchDrawable.getMinimumHeight());
    240     }
    241 
    242     @KnownFailure("Bug 2834281 - Bitmap#hasAlpha seems to return true for "
    243         + "images without alpha.")
    244     public void testGetOpacity() {
    245         assertEquals(PixelFormat.OPAQUE, mNinePatchDrawable.getOpacity());
    246 
    247         mNinePatchDrawable = getNinePatchDrawable(R.drawable.ninepatch_1);
    248         assertEquals(PixelFormat.TRANSLUCENT, mNinePatchDrawable.getOpacity());
    249     }
    250 
    251     public void testGetTransparentRegion() {
    252         // opaque image
    253         Region r = mNinePatchDrawable.getTransparentRegion();
    254         assertNull(r);
    255 
    256         mNinePatchDrawable.setBounds(0, 0, 7, 7);
    257         r = mNinePatchDrawable.getTransparentRegion();
    258         assertNull(r);
    259 
    260         // translucent image
    261         mNinePatchDrawable = getNinePatchDrawable(R.drawable.ninepatch_1);
    262         r = mNinePatchDrawable.getTransparentRegion();
    263         assertNull(r);
    264 
    265         mNinePatchDrawable.setBounds(1, 1, 7, 7);
    266         r = mNinePatchDrawable.getTransparentRegion();
    267         assertNotNull(r);
    268         assertEquals(new Rect(1, 1, 7, 7), r.getBounds());
    269     }
    270 
    271     public void testGetConstantState() {
    272         assertNotNull(mNinePatchDrawable.getConstantState());
    273 
    274         ConstantState constantState = mNinePatchDrawable.getConstantState();
    275         // change the drawable's configuration does not affect the state's configuration
    276         mNinePatchDrawable.setChangingConfigurations(0xff);
    277         assertEquals(0, constantState.getChangingConfigurations());
    278         // the state's configuration refreshed when getConstantState is called.
    279         constantState = mNinePatchDrawable.getConstantState();
    280         assertEquals(0xff, constantState.getChangingConfigurations());
    281     }
    282 
    283     public void testInflate() throws XmlPullParserException, IOException {
    284         final int width = 80;
    285         final int height = 120;
    286         final int[] COLOR = new int[width * height];
    287         Bitmap bitmap = Bitmap.createBitmap(COLOR, width, height, Bitmap.Config.RGB_565);
    288         NinePatchDrawable ninePatchDrawable =
    289             new NinePatchDrawable(mResources, bitmap, new byte[1000], null, "TESTNAME");
    290 
    291         assertEquals(height, ninePatchDrawable.getIntrinsicHeight());
    292         assertEquals(width, ninePatchDrawable.getIntrinsicWidth());
    293         XmlResourceParser parser = mResources.getXml(R.drawable.ninepatchdrawable);
    294         int type;
    295         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
    296                 && type != XmlPullParser.START_TAG) {
    297         }
    298         AttributeSet attrs = Xml.asAttributeSet(parser);
    299         ninePatchDrawable.inflate(mResources, parser, attrs);
    300 
    301         assertTrue(ninePatchDrawable.getPaint().isDither());
    302         assertTrue(height != ninePatchDrawable.getIntrinsicHeight());
    303         assertTrue(width != ninePatchDrawable.getIntrinsicWidth());
    304     }
    305 
    306     public void testMutate() {
    307         NinePatchDrawable d1 =
    308             (NinePatchDrawable) mResources.getDrawable(R.drawable.ninepatchdrawable);
    309         NinePatchDrawable d2 =
    310             (NinePatchDrawable) mResources.getDrawable(R.drawable.ninepatchdrawable);
    311         NinePatchDrawable d3 =
    312             (NinePatchDrawable) mResources.getDrawable(R.drawable.ninepatchdrawable);
    313 
    314         // the state is not shared before mutate.
    315         d1.setDither(false);
    316         assertFalse(d1.getPaint().isDither());
    317         assertTrue(d2.getPaint().isDither());
    318         assertTrue(d3.getPaint().isDither());
    319 
    320         // cannot test if mutate worked, since state was not shared before
    321         d1.mutate();
    322     }
    323 
    324     private void assertColorFillRect(Bitmap bmp, int x, int y, int w, int h, int color) {
    325         for (int i = x; i < x + w; i++) {
    326             for (int j = y; j < y + h; j++) {
    327                 assertEquals(color, bmp.getPixel(i, j));
    328             }
    329         }
    330     }
    331 
    332     private NinePatchDrawable getNinePatchDrawable(int resId) {
    333         // jump through hoops to avoid scaling the tiny ninepatch, which would skew the results
    334         // depending on device density
    335         Bitmap bitmap = getBitmapUnscaled(resId);
    336         NinePatch np = new NinePatch(bitmap, bitmap.getNinePatchChunk(), null);
    337         return new NinePatchDrawable(mResources, np);
    338     }
    339 
    340     private Bitmap getBitmapUnscaled(int resId) {
    341         BitmapFactory.Options opts = new BitmapFactory.Options();
    342         opts.inDensity = opts.inTargetDensity = mResources.getDisplayMetrics().densityDpi;
    343         Bitmap bitmap = BitmapFactory.decodeResource(mResources, resId, opts);
    344         return bitmap;
    345     }
    346 
    347     private class MockColorFilter extends ColorFilter {
    348     }
    349 }
    350