/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.graphics.drawable;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.MipmapDrawable;
import android.graphics.drawable.DrawableContainer.DrawableContainerState;
import android.test.InstrumentationTestCase;
public class MipmapDrawableTest extends InstrumentationTestCase {
private MockMipmapDrawable mMipmapDrawable;
private DrawableContainerState mDrawableContainerState;
@Override
protected void setUp() throws Exception {
super.setUp();
mMipmapDrawable = new MockMipmapDrawable();
mDrawableContainerState = (DrawableContainerState) mMipmapDrawable.getConstantState();
}
public void testMipmapDrawable() {
new MipmapDrawable();
// Check the values set in the constructor
assertNotNull(new MipmapDrawable().getConstantState());
assertTrue(new MockMipmapDrawable().hasCalledOnBoundsChanged());
}
public void testAddDrawable() {
assertEquals(0, mDrawableContainerState.getChildCount());
// nothing happens if drawable is null
mMipmapDrawable.reset();
mMipmapDrawable.addDrawable(null);
assertEquals(0, mDrawableContainerState.getChildCount());
assertFalse(mMipmapDrawable.hasCalledOnBoundsChanged());
mMipmapDrawable.reset();
mMipmapDrawable.addDrawable(new MockDrawable());
assertEquals(1, mDrawableContainerState.getChildCount());
assertTrue(mMipmapDrawable.hasCalledOnBoundsChanged());
mMipmapDrawable.reset();
mMipmapDrawable.addDrawable(new MockDrawable());
assertEquals(2, mDrawableContainerState.getChildCount());
assertTrue(mMipmapDrawable.hasCalledOnBoundsChanged());
}
public void testSortedByHeight() {
Drawable small = new MockDrawable(8);
Drawable medium = new MockDrawable(32);
Drawable large = new MockDrawable(128);
mMipmapDrawable.addDrawable(medium);
assertSame(medium, mDrawableContainerState.getChildren()[0]);
mMipmapDrawable.addDrawable(small);
assertSame(small, mDrawableContainerState.getChildren()[0]);
assertSame(medium, mDrawableContainerState.getChildren()[1]);
mMipmapDrawable.addDrawable(large);
assertSame(small, mDrawableContainerState.getChildren()[0]);
assertSame(medium, mDrawableContainerState.getChildren()[1]);
assertSame(large, mDrawableContainerState.getChildren()[2]);
mMipmapDrawable.addDrawable(small);
assertSame(small, mDrawableContainerState.getChildren()[0]);
assertSame(small, mDrawableContainerState.getChildren()[1]);
assertSame(medium, mDrawableContainerState.getChildren()[2]);
assertSame(large, mDrawableContainerState.getChildren()[3]);
mMipmapDrawable.addDrawable(medium);
assertSame(small, mDrawableContainerState.getChildren()[0]);
assertSame(small, mDrawableContainerState.getChildren()[1]);
assertSame(medium, mDrawableContainerState.getChildren()[2]);
assertSame(medium, mDrawableContainerState.getChildren()[3]);
assertSame(large, mDrawableContainerState.getChildren()[4]);
mMipmapDrawable.addDrawable(large);
assertSame(small, mDrawableContainerState.getChildren()[0]);
assertSame(small, mDrawableContainerState.getChildren()[1]);
assertSame(medium, mDrawableContainerState.getChildren()[2]);
assertSame(medium, mDrawableContainerState.getChildren()[3]);
assertSame(large, mDrawableContainerState.getChildren()[4]);
assertSame(large, mDrawableContainerState.getChildren()[5]);
}
public void testSetBoundsOneItem() {
// the method is not called if same bounds are set
mMipmapDrawable.reset();
mMipmapDrawable.setBounds(mMipmapDrawable.getBounds());
assertFalse(mMipmapDrawable.hasCalledOnBoundsChanged());
// the method is called if different bounds are set, even without drawables
mMipmapDrawable.reset();
mMipmapDrawable.setBounds(new Rect(0, 0, 0, mMipmapDrawable.getBounds().height() + 1));
assertTrue(mMipmapDrawable.hasCalledOnBoundsChanged());
// adding an item should check bounds to see if new drawable is more appropriate
mMipmapDrawable.reset();
Drawable item = new MockDrawable(42);
mMipmapDrawable.addDrawable(item);
assertTrue(mMipmapDrawable.hasCalledOnBoundsChanged());
// the method is called if different bounds are set
mMipmapDrawable.setBounds(new Rect(0, 0, 0, mMipmapDrawable.getBounds().height() + 1));
assertTrue(mMipmapDrawable.hasCalledOnBoundsChanged());
// check that correct drawable is selected for any size.
mMipmapDrawable.setBounds(new Rect(0, 0, 0, item.getIntrinsicHeight() - 1));
assertSame(item, mMipmapDrawable.getCurrent());
mMipmapDrawable.setBounds(new Rect(0, 0, 0, item.getIntrinsicHeight()));
assertSame(item, mMipmapDrawable.getCurrent());
mMipmapDrawable.setBounds(new Rect(0, 0, 0, item.getIntrinsicHeight() + 1));
assertSame(item, mMipmapDrawable.getCurrent());
}
public void testSetBounds() {
Drawable small = new MockDrawable(8);
Drawable medium = new MockDrawable(32);
Drawable large = new MockDrawable(128);
mMipmapDrawable.addDrawable(large);
mMipmapDrawable.addDrawable(small);
mMipmapDrawable.addDrawable(medium);
// check that correct drawable is selected.
mMipmapDrawable.setBounds(new Rect(0, 0, 0, small.getIntrinsicHeight() - 1));
assertSame(small, mMipmapDrawable.getCurrent());
mMipmapDrawable.setBounds(new Rect(0, 0, 0, small.getIntrinsicHeight()));
assertSame(small, mMipmapDrawable.getCurrent());
mMipmapDrawable.setBounds(new Rect(0, 0, 0, small.getIntrinsicHeight() + 1));
assertSame(medium, mMipmapDrawable.getCurrent());
mMipmapDrawable.setBounds(new Rect(0, 0, 0, medium.getIntrinsicHeight() - 1));
assertSame(medium, mMipmapDrawable.getCurrent());
mMipmapDrawable.setBounds(new Rect(0, 0, 0, medium.getIntrinsicHeight()));
assertSame(medium, mMipmapDrawable.getCurrent());
mMipmapDrawable.setBounds(new Rect(0, 0, 0, medium.getIntrinsicHeight() + 1));
assertSame(large, mMipmapDrawable.getCurrent());
mMipmapDrawable.setBounds(new Rect(0, 0, 0, large.getIntrinsicHeight() - 1));
assertSame(large, mMipmapDrawable.getCurrent());
mMipmapDrawable.setBounds(new Rect(0, 0, 0, large.getIntrinsicHeight()));
assertSame(large, mMipmapDrawable.getCurrent());
mMipmapDrawable.setBounds(new Rect(0, 0, 0, large.getIntrinsicHeight() + 1));
assertSame(large, mMipmapDrawable.getCurrent());
}
public void testSizes() {
// Check default value with no mipmap defined
assertEquals(-1, mMipmapDrawable.getIntrinsicHeight());
assertEquals(-1, mMipmapDrawable.getIntrinsicWidth());
assertEquals(0, mMipmapDrawable.getMinimumHeight());
assertEquals(0, mMipmapDrawable.getMinimumWidth());
Drawable small = new MockDrawable(8, 4);
Drawable medium = new MockDrawable(32, 16);
Drawable large = new MockDrawable(128, 64);
mMipmapDrawable.addDrawable(medium);
assertEquals(medium.getIntrinsicHeight(), mMipmapDrawable.getIntrinsicHeight());
assertEquals(medium.getMinimumHeight(), mMipmapDrawable.getMinimumHeight());
mMipmapDrawable.addDrawable(large);
assertEquals(large.getIntrinsicHeight(), mMipmapDrawable.getIntrinsicHeight());
assertEquals(medium.getMinimumHeight(), mMipmapDrawable.getMinimumHeight());
mMipmapDrawable.addDrawable(small);
assertEquals(large.getIntrinsicHeight(), mMipmapDrawable.getIntrinsicHeight());
assertEquals(small.getMinimumHeight(), mMipmapDrawable.getMinimumHeight());
}
public void testReplacementWhenAdded() {
Drawable small = new MockDrawable(8);
Drawable medium = new MockDrawable(32);
Drawable large = new MockDrawable(128);
// Small bounds, so that the smallest mipmap should always be selected
mMipmapDrawable.setBounds(new Rect(0, 0, 0, 0));
// Providing smaller versions, that should immediately be used as current
mMipmapDrawable.addDrawable(large);
assertSame(large, mMipmapDrawable.getCurrent());
mMipmapDrawable.addDrawable(medium);
assertSame(medium, mMipmapDrawable.getCurrent());
mMipmapDrawable.addDrawable(small);
assertSame(small, mMipmapDrawable.getCurrent());
}
private class MockMipmapDrawable extends MipmapDrawable {
private boolean mHasCalledOnBoundsChanged;
public boolean hasCalledOnBoundsChanged() {
return mHasCalledOnBoundsChanged;
}
public void reset() {
mHasCalledOnBoundsChanged = false;
}
@Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
mHasCalledOnBoundsChanged = true;
}
}
private class MockDrawable extends Drawable {
int mIntrinsicHeight;
int mMinimumHeight;
public MockDrawable() {
this(0);
}
public MockDrawable(int intrinsicHeight) {
this(intrinsicHeight, intrinsicHeight);
}
public MockDrawable(int intrinsicHeight, int minimumHeight) {
mIntrinsicHeight = intrinsicHeight;
mMinimumHeight = minimumHeight;
}
@Override
public void draw(Canvas canvas) {
}
@Override
public int getOpacity() {
return 0;
}
@Override
public void setAlpha(int alpha) {
}
@Override
public void setColorFilter(ColorFilter cf) {
}
@Override
public int getIntrinsicHeight() {
return mIntrinsicHeight;
}
@Override
public int getMinimumHeight() {
return mMinimumHeight;
}
}
}