1/* 2 * Copyright (C) 2010 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 17package android.graphics.drawable; 18 19import android.graphics.Canvas; 20import android.graphics.ColorFilter; 21import android.graphics.Rect; 22import android.graphics.drawable.Drawable; 23import android.graphics.drawable.MipmapDrawable; 24import android.graphics.drawable.DrawableContainer.DrawableContainerState; 25import android.test.InstrumentationTestCase; 26 27public class MipmapDrawableTest extends InstrumentationTestCase { 28 private MockMipmapDrawable mMipmapDrawable; 29 30 private DrawableContainerState mDrawableContainerState; 31 32 @Override 33 protected void setUp() throws Exception { 34 super.setUp(); 35 mMipmapDrawable = new MockMipmapDrawable(); 36 mDrawableContainerState = (DrawableContainerState) mMipmapDrawable.getConstantState(); 37 } 38 39 public void testMipmapDrawable() { 40 new MipmapDrawable(); 41 // Check the values set in the constructor 42 assertNotNull(new MipmapDrawable().getConstantState()); 43 assertTrue(new MockMipmapDrawable().hasCalledOnBoundsChanged()); 44 } 45 46 public void testAddDrawable() { 47 assertEquals(0, mDrawableContainerState.getChildCount()); 48 49 // nothing happens if drawable is null 50 mMipmapDrawable.reset(); 51 mMipmapDrawable.addDrawable(null); 52 assertEquals(0, mDrawableContainerState.getChildCount()); 53 assertFalse(mMipmapDrawable.hasCalledOnBoundsChanged()); 54 55 mMipmapDrawable.reset(); 56 mMipmapDrawable.addDrawable(new MockDrawable()); 57 assertEquals(1, mDrawableContainerState.getChildCount()); 58 assertTrue(mMipmapDrawable.hasCalledOnBoundsChanged()); 59 60 mMipmapDrawable.reset(); 61 mMipmapDrawable.addDrawable(new MockDrawable()); 62 assertEquals(2, mDrawableContainerState.getChildCount()); 63 assertTrue(mMipmapDrawable.hasCalledOnBoundsChanged()); 64 } 65 66 public void testSortedByHeight() { 67 Drawable small = new MockDrawable(8); 68 Drawable medium = new MockDrawable(32); 69 Drawable large = new MockDrawable(128); 70 71 mMipmapDrawable.addDrawable(medium); 72 assertSame(medium, mDrawableContainerState.getChildren()[0]); 73 74 mMipmapDrawable.addDrawable(small); 75 assertSame(small, mDrawableContainerState.getChildren()[0]); 76 assertSame(medium, mDrawableContainerState.getChildren()[1]); 77 78 mMipmapDrawable.addDrawable(large); 79 assertSame(small, mDrawableContainerState.getChildren()[0]); 80 assertSame(medium, mDrawableContainerState.getChildren()[1]); 81 assertSame(large, mDrawableContainerState.getChildren()[2]); 82 83 mMipmapDrawable.addDrawable(small); 84 assertSame(small, mDrawableContainerState.getChildren()[0]); 85 assertSame(small, mDrawableContainerState.getChildren()[1]); 86 assertSame(medium, mDrawableContainerState.getChildren()[2]); 87 assertSame(large, mDrawableContainerState.getChildren()[3]); 88 89 mMipmapDrawable.addDrawable(medium); 90 assertSame(small, mDrawableContainerState.getChildren()[0]); 91 assertSame(small, mDrawableContainerState.getChildren()[1]); 92 assertSame(medium, mDrawableContainerState.getChildren()[2]); 93 assertSame(medium, mDrawableContainerState.getChildren()[3]); 94 assertSame(large, mDrawableContainerState.getChildren()[4]); 95 96 mMipmapDrawable.addDrawable(large); 97 assertSame(small, mDrawableContainerState.getChildren()[0]); 98 assertSame(small, mDrawableContainerState.getChildren()[1]); 99 assertSame(medium, mDrawableContainerState.getChildren()[2]); 100 assertSame(medium, mDrawableContainerState.getChildren()[3]); 101 assertSame(large, mDrawableContainerState.getChildren()[4]); 102 assertSame(large, mDrawableContainerState.getChildren()[5]); 103 } 104 105 public void testSetBoundsOneItem() { 106 // the method is not called if same bounds are set 107 mMipmapDrawable.reset(); 108 mMipmapDrawable.setBounds(mMipmapDrawable.getBounds()); 109 assertFalse(mMipmapDrawable.hasCalledOnBoundsChanged()); 110 111 // the method is called if different bounds are set, even without drawables 112 mMipmapDrawable.reset(); 113 mMipmapDrawable.setBounds(new Rect(0, 0, 0, mMipmapDrawable.getBounds().height() + 1)); 114 assertTrue(mMipmapDrawable.hasCalledOnBoundsChanged()); 115 116 // adding an item should check bounds to see if new drawable is more appropriate 117 mMipmapDrawable.reset(); 118 Drawable item = new MockDrawable(42); 119 mMipmapDrawable.addDrawable(item); 120 assertTrue(mMipmapDrawable.hasCalledOnBoundsChanged()); 121 122 // the method is called if different bounds are set 123 mMipmapDrawable.setBounds(new Rect(0, 0, 0, mMipmapDrawable.getBounds().height() + 1)); 124 assertTrue(mMipmapDrawable.hasCalledOnBoundsChanged()); 125 126 // check that correct drawable is selected for any size. 127 mMipmapDrawable.setBounds(new Rect(0, 0, 0, item.getIntrinsicHeight() - 1)); 128 assertSame(item, mMipmapDrawable.getCurrent()); 129 130 mMipmapDrawable.setBounds(new Rect(0, 0, 0, item.getIntrinsicHeight())); 131 assertSame(item, mMipmapDrawable.getCurrent()); 132 133 mMipmapDrawable.setBounds(new Rect(0, 0, 0, item.getIntrinsicHeight() + 1)); 134 assertSame(item, mMipmapDrawable.getCurrent()); 135 } 136 137 public void testSetBounds() { 138 Drawable small = new MockDrawable(8); 139 Drawable medium = new MockDrawable(32); 140 Drawable large = new MockDrawable(128); 141 142 mMipmapDrawable.addDrawable(large); 143 mMipmapDrawable.addDrawable(small); 144 mMipmapDrawable.addDrawable(medium); 145 146 // check that correct drawable is selected. 147 mMipmapDrawable.setBounds(new Rect(0, 0, 0, small.getIntrinsicHeight() - 1)); 148 assertSame(small, mMipmapDrawable.getCurrent()); 149 150 mMipmapDrawable.setBounds(new Rect(0, 0, 0, small.getIntrinsicHeight())); 151 assertSame(small, mMipmapDrawable.getCurrent()); 152 153 mMipmapDrawable.setBounds(new Rect(0, 0, 0, small.getIntrinsicHeight() + 1)); 154 assertSame(medium, mMipmapDrawable.getCurrent()); 155 156 mMipmapDrawable.setBounds(new Rect(0, 0, 0, medium.getIntrinsicHeight() - 1)); 157 assertSame(medium, mMipmapDrawable.getCurrent()); 158 159 mMipmapDrawable.setBounds(new Rect(0, 0, 0, medium.getIntrinsicHeight())); 160 assertSame(medium, mMipmapDrawable.getCurrent()); 161 162 mMipmapDrawable.setBounds(new Rect(0, 0, 0, medium.getIntrinsicHeight() + 1)); 163 assertSame(large, mMipmapDrawable.getCurrent()); 164 165 mMipmapDrawable.setBounds(new Rect(0, 0, 0, large.getIntrinsicHeight() - 1)); 166 assertSame(large, mMipmapDrawable.getCurrent()); 167 168 mMipmapDrawable.setBounds(new Rect(0, 0, 0, large.getIntrinsicHeight())); 169 assertSame(large, mMipmapDrawable.getCurrent()); 170 171 mMipmapDrawable.setBounds(new Rect(0, 0, 0, large.getIntrinsicHeight() + 1)); 172 assertSame(large, mMipmapDrawable.getCurrent()); 173 } 174 175 public void testSizes() { 176 // Check default value with no mipmap defined 177 assertEquals(-1, mMipmapDrawable.getIntrinsicHeight()); 178 assertEquals(-1, mMipmapDrawable.getIntrinsicWidth()); 179 assertEquals(0, mMipmapDrawable.getMinimumHeight()); 180 assertEquals(0, mMipmapDrawable.getMinimumWidth()); 181 182 Drawable small = new MockDrawable(8, 4); 183 Drawable medium = new MockDrawable(32, 16); 184 Drawable large = new MockDrawable(128, 64); 185 186 mMipmapDrawable.addDrawable(medium); 187 assertEquals(medium.getIntrinsicHeight(), mMipmapDrawable.getIntrinsicHeight()); 188 assertEquals(medium.getMinimumHeight(), mMipmapDrawable.getMinimumHeight()); 189 190 mMipmapDrawable.addDrawable(large); 191 assertEquals(large.getIntrinsicHeight(), mMipmapDrawable.getIntrinsicHeight()); 192 assertEquals(medium.getMinimumHeight(), mMipmapDrawable.getMinimumHeight()); 193 194 mMipmapDrawable.addDrawable(small); 195 assertEquals(large.getIntrinsicHeight(), mMipmapDrawable.getIntrinsicHeight()); 196 assertEquals(small.getMinimumHeight(), mMipmapDrawable.getMinimumHeight()); 197 } 198 199 public void testReplacementWhenAdded() { 200 Drawable small = new MockDrawable(8); 201 Drawable medium = new MockDrawable(32); 202 Drawable large = new MockDrawable(128); 203 204 // Small bounds, so that the smallest mipmap should always be selected 205 mMipmapDrawable.setBounds(new Rect(0, 0, 0, 0)); 206 207 // Providing smaller versions, that should immediately be used as current 208 mMipmapDrawable.addDrawable(large); 209 assertSame(large, mMipmapDrawable.getCurrent()); 210 211 mMipmapDrawable.addDrawable(medium); 212 assertSame(medium, mMipmapDrawable.getCurrent()); 213 214 mMipmapDrawable.addDrawable(small); 215 assertSame(small, mMipmapDrawable.getCurrent()); 216 } 217 218 private class MockMipmapDrawable extends MipmapDrawable { 219 private boolean mHasCalledOnBoundsChanged; 220 221 public boolean hasCalledOnBoundsChanged() { 222 return mHasCalledOnBoundsChanged; 223 } 224 225 public void reset() { 226 mHasCalledOnBoundsChanged = false; 227 } 228 229 @Override 230 protected void onBoundsChange(Rect bounds) { 231 super.onBoundsChange(bounds); 232 mHasCalledOnBoundsChanged = true; 233 } 234 } 235 236 private class MockDrawable extends Drawable { 237 int mIntrinsicHeight; 238 int mMinimumHeight; 239 240 public MockDrawable() { 241 this(0); 242 } 243 244 public MockDrawable(int intrinsicHeight) { 245 this(intrinsicHeight, intrinsicHeight); 246 } 247 248 public MockDrawable(int intrinsicHeight, int minimumHeight) { 249 mIntrinsicHeight = intrinsicHeight; 250 mMinimumHeight = minimumHeight; 251 } 252 253 @Override 254 public void draw(Canvas canvas) { 255 } 256 257 @Override 258 public int getOpacity() { 259 return 0; 260 } 261 262 @Override 263 public void setAlpha(int alpha) { 264 } 265 266 @Override 267 public void setColorFilter(ColorFilter cf) { 268 } 269 270 @Override 271 public int getIntrinsicHeight() { 272 return mIntrinsicHeight; 273 } 274 275 @Override 276 public int getMinimumHeight() { 277 return mMinimumHeight; 278 } 279 } 280} 281