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.graphics.R;
     20 
     21 import android.content.res.Resources;
     22 import android.graphics.Bitmap;
     23 import android.graphics.Bitmap.Config;
     24 import android.graphics.Canvas;
     25 import android.graphics.drawable.Drawable;
     26 import android.graphics.drawable.TransitionDrawable;
     27 import android.test.InstrumentationTestCase;
     28 
     29 public class TransitionDrawableTest extends InstrumentationTestCase {
     30     private static final int COLOR1 = 0xff0000ff;
     31 
     32     private static final int COLOR0 = 0xffff0000;
     33 
     34     private static final int CANVAS_WIDTH = 10;
     35 
     36     private static final int CANVAS_HEIGHT = 10;
     37 
     38     private TransitionDrawable mTransitionDrawable;
     39 
     40     private Bitmap mBitmap;
     41 
     42     private Canvas mCanvas;
     43 
     44     @Override
     45     protected void setUp() throws Exception {
     46         super.setUp();
     47         mTransitionDrawable = (TransitionDrawable) getInstrumentation().getTargetContext()
     48                 .getResources().getDrawable(R.drawable.transition_test);
     49         mTransitionDrawable.setBounds(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
     50 
     51         mBitmap = Bitmap.createBitmap(CANVAS_WIDTH, CANVAS_HEIGHT, Config.ARGB_8888);
     52         mCanvas = new Canvas(mBitmap);
     53     }
     54 
     55     public void testConstructor() {
     56         Resources resources = getInstrumentation().getTargetContext().getResources();
     57         Drawable[] drawables = new Drawable[] {
     58                 resources.getDrawable(R.drawable.testimage),
     59                 resources.getDrawable(R.drawable.levellistdrawable)
     60         };
     61         new TransitionDrawable(drawables);
     62     }
     63 
     64     public void testStartTransition() {
     65         MockCallBack cb = new MockCallBack();
     66         mTransitionDrawable.setCallback(cb);
     67 
     68         // start when there is no transition
     69         cb.reset();
     70         mTransitionDrawable.startTransition(2000);
     71         assertTrue(cb.hasCalledInvalidateDrawable());
     72         assertTransition(COLOR0, COLOR1, 2000);
     73 
     74         // start when there is a transition in progress
     75         makeTransitionInProgress(2000, 1000);
     76         cb.reset();
     77         mTransitionDrawable.startTransition(2000);
     78         assertTrue(cb.hasCalledInvalidateDrawable());
     79         assertTransition(COLOR0, COLOR1, 2000);
     80 
     81         // start when there is a reverse transition in progress
     82         makeReverseTransitionInProgress(2000, 1000);
     83         cb.reset();
     84         mTransitionDrawable.startTransition(2000);
     85         assertTrue(cb.hasCalledInvalidateDrawable());
     86         assertTransition(COLOR0, COLOR1, 2000);
     87 
     88         // should not accept negative duration
     89         mTransitionDrawable.startTransition(-1);
     90     }
     91 
     92     public void testResetTransition() {
     93         MockCallBack cb = new MockCallBack();
     94         mTransitionDrawable.setCallback(cb);
     95 
     96         // reset when there is no transition
     97         cb.reset();
     98         mTransitionDrawable.resetTransition();
     99         assertTrue(cb.hasCalledInvalidateDrawable());
    100 
    101         // reset when there is a transition in progress
    102         makeTransitionInProgress(2000, 1000);
    103         cb.reset();
    104         mTransitionDrawable.resetTransition();
    105         assertTrue(cb.hasCalledInvalidateDrawable());
    106         assertTransitionStart(COLOR0);
    107         assertTransitionEnd(COLOR0, 2000);
    108 
    109         // reset when there is a reverse transition in progress
    110         makeReverseTransitionInProgress(2000, 1000);
    111         cb.reset();
    112         mTransitionDrawable.resetTransition();
    113         assertTrue(cb.hasCalledInvalidateDrawable());
    114         assertTransitionStart(COLOR0);
    115         assertTransitionEnd(COLOR0, 2000);
    116     }
    117 
    118     public void testReverseTransition() {
    119         MockCallBack cb = new MockCallBack();
    120         mTransitionDrawable.setCallback(cb);
    121 
    122         // reverse when there is no transition
    123         cb.reset();
    124         mTransitionDrawable.reverseTransition(2000);
    125         assertTrue(cb.hasCalledInvalidateDrawable());
    126         assertTransition(COLOR0, COLOR1, 2000);
    127 
    128         // reverse after the other transition ends
    129         cb.reset();
    130         mTransitionDrawable.reverseTransition(2000);
    131         assertTrue(cb.hasCalledInvalidateDrawable());
    132         assertTransition(COLOR1, COLOR0, 2000);
    133 
    134         // reverse when there is a transition in progress
    135         makeTransitionInProgress(2000, 1000);
    136         cb.reset();
    137         mTransitionDrawable.reverseTransition(20000);
    138         assertFalse(cb.hasCalledInvalidateDrawable());
    139         int colorFrom = mBitmap.getPixel(0, 0);
    140         assertTransition(colorFrom, COLOR0, 1500);
    141 
    142         // reverse when there is a reverse transition in progress
    143         makeReverseTransitionInProgress(2000, 1000);
    144         cb.reset();
    145         mTransitionDrawable.reverseTransition(20000);
    146         assertFalse(cb.hasCalledInvalidateDrawable());
    147         colorFrom = mBitmap.getPixel(0, 0);
    148         assertTransition(colorFrom, COLOR1, 1500);
    149 
    150         // should not accept negative duration
    151         mTransitionDrawable.reverseTransition(-1);
    152     }
    153 
    154     public void testDrawWithNUllCanvas() {
    155         try {
    156             mTransitionDrawable.draw(null);
    157             fail("The method should check whether the canvas is null.");
    158         } catch (NullPointerException e) {
    159         }
    160     }
    161 
    162     //  This boolean takes effect when the drawable is drawn and the effect can not be tested.
    163     public void testAccessCrossFadeEnabled() {
    164         assertFalse(mTransitionDrawable.isCrossFadeEnabled());
    165 
    166         mTransitionDrawable.setCrossFadeEnabled(true);
    167         assertTrue(mTransitionDrawable.isCrossFadeEnabled());
    168 
    169         mTransitionDrawable.setCrossFadeEnabled(false);
    170         assertFalse(mTransitionDrawable.isCrossFadeEnabled());
    171     }
    172 
    173     private void assertTransition(int colorFrom, int colorTo, long delay) {
    174         assertTransitionStart(colorFrom);
    175         assertTransitionInProgress(colorFrom, colorTo, delay / 2);
    176         assertTransitionEnd(colorTo, delay);
    177     }
    178 
    179     private void assertTransitionStart(int colorFrom) {
    180         mBitmap.eraseColor(0x00000000);
    181         mTransitionDrawable.draw(mCanvas);
    182         assertColorFillRect(mBitmap, 0, 0, CANVAS_WIDTH, CANVAS_HEIGHT, colorFrom);
    183     }
    184 
    185     private void assertTransitionInProgress(int colorFrom, int colorTo, long delay) {
    186         drawAfterDelaySync(delay);
    187         assertColorNotFillRect(mBitmap, 0, 0, CANVAS_WIDTH, CANVAS_HEIGHT, colorFrom);
    188         assertColorNotFillRect(mBitmap, 0, 0, CANVAS_WIDTH, CANVAS_HEIGHT, colorTo);
    189     }
    190 
    191     private void assertTransitionEnd(int colorTo, long delay) {
    192         drawAfterDelaySync(delay);
    193         assertColorFillRect(mBitmap, 0, 0, CANVAS_WIDTH, CANVAS_HEIGHT, colorTo);
    194     }
    195 
    196     private void assertColorFillRect(Bitmap bmp, int x, int y, int w, int h, int color) {
    197         for (int i = x; i < x + w; i++) {
    198             for (int j = y; j < y + h; j++) {
    199                 assertEquals(color, bmp.getPixel(i, j));
    200             }
    201         }
    202     }
    203 
    204     private void assertColorNotFillRect(Bitmap bmp, int x, int y, int w, int h, int color) {
    205         for (int i = x; i < x + w; i++) {
    206             for (int j = y; j < y + h; j++) {
    207                 assertTrue(color != bmp.getPixel(i, j));
    208             }
    209         }
    210     }
    211 
    212     private void makeReverseTransitionInProgress(int duration, int delay) {
    213         mTransitionDrawable.resetTransition();
    214         mTransitionDrawable.startTransition(2000);
    215         assertTransition(COLOR0, COLOR1, 2000);
    216         mTransitionDrawable.reverseTransition(duration);
    217         assertTransitionStart(COLOR1);
    218         assertTransitionInProgress(COLOR1, COLOR0, delay);
    219     }
    220 
    221     private void makeTransitionInProgress(int duration, int delay) {
    222         mTransitionDrawable.resetTransition();
    223         mTransitionDrawable.startTransition(duration);
    224         assertTransitionStart(COLOR0);
    225         assertTransitionInProgress(COLOR0, COLOR1, delay);
    226     }
    227 
    228     private void drawAfterDelaySync(long delay) {
    229         Thread t = new Thread(new Runnable() {
    230             public void run() {
    231                 mBitmap.eraseColor(0x00000000);
    232                 mTransitionDrawable.draw(mCanvas);
    233             }
    234         });
    235         try {
    236             Thread.sleep(delay);
    237             t.start();
    238             t.join();
    239         } catch (InterruptedException e) {
    240             // catch and fail, because propagating this all the way up is messy
    241             fail(e.getMessage());
    242         }
    243     }
    244 
    245     private class MockCallBack implements Drawable.Callback {
    246         private boolean mHasCalledInvalidateDrawable;
    247 
    248         public boolean hasCalledInvalidateDrawable() {
    249             return mHasCalledInvalidateDrawable;
    250         }
    251         public void reset() {
    252             mHasCalledInvalidateDrawable = false;
    253         }
    254 
    255         public void invalidateDrawable(Drawable who) {
    256             mHasCalledInvalidateDrawable = true;
    257         }
    258 
    259         public void scheduleDrawable(Drawable who, Runnable what, long when) {
    260         }
    261 
    262         public void unscheduleDrawable(Drawable who, Runnable what) {
    263         }
    264 
    265         public int getResolvedLayoutDirection(Drawable who) {
    266             return 0;
    267         }
    268     }
    269 }
    270