Home | History | Annotate | Download | only in testclasses
      1 /*
      2  * Copyright (C) 2016 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.uirendering.cts.testclasses;
     17 
     18 import static org.junit.Assert.assertEquals;
     19 import static org.junit.Assert.assertFalse;
     20 import static org.junit.Assert.assertNotNull;
     21 import static org.junit.Assert.assertNotSame;
     22 import static org.junit.Assert.assertNull;
     23 import static org.junit.Assert.assertSame;
     24 import static org.junit.Assert.assertTrue;
     25 import static org.junit.Assert.fail;
     26 
     27 import android.content.res.Resources.Theme;
     28 import android.graphics.BitmapFactory;
     29 import android.graphics.Rect;
     30 
     31 import org.junit.Before;
     32 import org.junit.Test;
     33 import org.junit.runner.RunWith;
     34 import android.content.Context;
     35 import android.content.res.Configuration;
     36 import android.content.res.Resources;
     37 import android.content.res.XmlResourceParser;
     38 import android.graphics.Bitmap;
     39 import android.graphics.Canvas;
     40 import android.graphics.Color;
     41 import android.graphics.drawable.BitmapDrawable;
     42 import android.graphics.drawable.Drawable;
     43 import android.graphics.drawable.Drawable.ConstantState;
     44 import android.support.test.InstrumentationRegistry;
     45 import android.support.test.filters.MediumTest;
     46 import android.support.test.runner.AndroidJUnit4;
     47 import android.uirendering.cts.R;
     48 import android.uirendering.cts.bitmapverifiers.RectVerifier;
     49 import android.uirendering.cts.testinfrastructure.ActivityTestBase;
     50 import android.uirendering.cts.testinfrastructure.CanvasClient;
     51 import android.util.LayoutDirection;
     52 
     53 import java.io.ByteArrayInputStream;
     54 import java.io.File;
     55 import java.io.FileOutputStream;
     56 import java.io.IOException;
     57 import java.io.InputStream;
     58 
     59 @MediumTest
     60 @RunWith(AndroidJUnit4.class)
     61 public class BitmapDrawableTest extends ActivityTestBase {
     62 
     63     // The target context.
     64     private Context mContext;
     65 
     66     @Before
     67     public void setup() {
     68         mContext = InstrumentationRegistry.getTargetContext();
     69     }
     70 
     71     private static final int[] DENSITY_VALUES = new int[] {
     72             160, 80, 320
     73     };
     74 
     75     private static final int[] DENSITY_IMAGES = new int[] {
     76             R.drawable.bitmap_density,
     77             R.drawable.bitmap_shader_density,
     78             R.drawable.bitmap_shader_am_density,
     79     };
     80 
     81     @Test
     82     public void testPreloadDensity() throws IOException {
     83         final Resources res = mContext.getResources();
     84         final int densityDpi = res.getConfiguration().densityDpi;
     85         try {
     86             for (int i = 0; i < DENSITY_IMAGES.length; i++) {
     87                 verifyPreloadDensityInner(res, DENSITY_IMAGES[i], DENSITY_VALUES);
     88             }
     89         } finally {
     90             setResourcesDensity(res, densityDpi);
     91         }
     92     }
     93 
     94     private void verifyPreloadDensityInner(Resources res, int sourceResId, int[] densities)
     95             throws IOException {
     96         final Rect tempPadding = new Rect();
     97 
     98         // Capture initial state at preload density.
     99         final int preloadDensityDpi = densities[0];
    100         setResourcesDensity(res, preloadDensityDpi);
    101 
    102         final BitmapDrawable preloadedDrawable = (BitmapDrawable) res.getDrawable(sourceResId);
    103         final ConstantState preloadedConstantState = preloadedDrawable.getConstantState();
    104         final int origWidth = preloadedDrawable.getIntrinsicWidth();
    105         final int origHeight = preloadedDrawable.getIntrinsicHeight();
    106         assertFalse(preloadedDrawable.getPadding(tempPadding));
    107 
    108         runTest(preloadedDrawable);
    109 
    110         for (int i = 1; i < densities.length; i++) {
    111             final int scaledDensityDpi = densities[i];
    112             final float scale = scaledDensityDpi / (float) preloadDensityDpi;
    113             setResourcesDensity(res, scaledDensityDpi);
    114 
    115             final BitmapDrawable scaledDrawable =
    116                     (BitmapDrawable) preloadedConstantState.newDrawable(res);
    117             scaledDrawable.setLayoutDirection(LayoutDirection.RTL);
    118 
    119             // Sizes are rounded.
    120             assertEquals(Math.round(origWidth * scale), scaledDrawable.getIntrinsicWidth());
    121             assertEquals(Math.round(origHeight * scale), scaledDrawable.getIntrinsicHeight());
    122 
    123             // Bitmaps have no padding.
    124             assertFalse(scaledDrawable.getPadding(tempPadding));
    125 
    126             runTest(scaledDrawable);
    127 
    128             // Ensure theme density is applied correctly. Unlike most
    129             // drawables, we don't have any loss of accuracy because density
    130             // changes are re-computed from the source every time.
    131             setResourcesDensity(res, preloadDensityDpi);
    132 
    133             final Theme t = res.newTheme();
    134             scaledDrawable.applyTheme(t);
    135             assertEquals(origWidth, scaledDrawable.getIntrinsicWidth());
    136             assertEquals(origHeight, scaledDrawable.getIntrinsicHeight());
    137             assertFalse(scaledDrawable.getPadding(tempPadding));
    138         }
    139     }
    140 
    141     private void runTest(Drawable dr) {
    142         final Rect drBounds = new Rect(0, 0, dr.getIntrinsicWidth(), dr.getIntrinsicHeight());
    143         CanvasClient canvasClient = (canvas, width, height) -> {
    144             assertTrue(width > drBounds.width());
    145             assertTrue(height > drBounds.height());
    146             dr.setBounds(drBounds);
    147             dr.draw(canvas);
    148         };
    149         createTest()
    150                 .addCanvasClient(canvasClient)
    151                 .runWithVerifier(new RectVerifier(Color.WHITE, Color.BLUE, drBounds));
    152     }
    153 
    154     private static void setResourcesDensity(Resources res, int densityDpi) {
    155         final Configuration config = new Configuration();
    156         config.setTo(res.getConfiguration());
    157         config.densityDpi = densityDpi;
    158         res.updateConfiguration(config, null);
    159     }
    160 }
    161