1/* 2 * Copyright (C) 2015 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 */ 16package android.support.v17.leanback.graphics; 17 18import static org.junit.Assert.assertEquals; 19import static org.junit.Assert.assertNotSame; 20import static org.junit.Assert.assertTrue; 21 22import android.content.Context; 23import android.graphics.Bitmap; 24import android.graphics.Rect; 25import android.graphics.drawable.BitmapDrawable; 26import android.os.Build; 27import android.support.test.InstrumentationRegistry; 28import android.support.test.filters.SdkSuppress; 29import android.support.test.filters.SmallTest; 30import android.support.test.runner.AndroidJUnit4; 31import android.support.v17.leanback.graphics.BoundsRule.ValueRule; 32 33import org.junit.Test; 34import org.junit.runner.RunWith; 35 36/** 37 * Unit test for {@link CompositeDrawableTest} 38 */ 39@RunWith(AndroidJUnit4.class) 40@SmallTest 41public class CompositeDrawableTest { 42 43 private static final int HEIGHT = 800; 44 private static final int WIDTH = 600; 45 Bitmap mBitmap = Bitmap.createBitmap(WIDTH, HEIGHT, Bitmap.Config.ARGB_8888); 46 47 @Test 48 public void updateBounds_noBoundsRule() { 49 CompositeDrawable parentDrawable = new CompositeDrawable(); 50 FitWidthBitmapDrawable drawable = new FitWidthBitmapDrawable(); 51 drawable.setBitmap(mBitmap); 52 Rect bounds = new Rect(0, 0, WIDTH, HEIGHT); 53 parentDrawable.addChildDrawable(drawable); 54 parentDrawable.updateBounds(bounds); 55 56 Rect adjustedBounds = drawable.getBounds(); 57 assertEquals(bounds, adjustedBounds); 58 } 59 60 @Test 61 public void updateBounds_withBoundsRule() { 62 CompositeDrawable parentDrawable = new CompositeDrawable(); 63 float fraction = 0.5f; 64 FitWidthBitmapDrawable drawable = new FitWidthBitmapDrawable(); 65 drawable.setBitmap(mBitmap); 66 Rect bounds = new Rect(0, 0, WIDTH, HEIGHT); 67 assertEquals(HEIGHT, bounds.height()); 68 assertEquals(WIDTH, bounds.width()); 69 70 // inherit from parent 71 parentDrawable.addChildDrawable(drawable); 72 parentDrawable.getChildAt(0).getBoundsRule().bottom = ValueRule.inheritFromParent( 73 fraction); 74 parentDrawable.updateBounds(bounds); 75 76 Rect adjustedBounds = drawable.getBounds(); 77 Rect expectedBounds = new Rect(bounds); 78 expectedBounds.bottom = bounds.top + (int) (HEIGHT * fraction); 79 assertEquals(expectedBounds, adjustedBounds); 80 81 // absolute value 82 drawable.setBounds(bounds); 83 parentDrawable.getChildAt(0).getBoundsRule().bottom = ValueRule.absoluteValue(200); 84 parentDrawable.updateBounds(bounds); 85 86 adjustedBounds = drawable.getBounds(); 87 expectedBounds = new Rect(bounds); 88 expectedBounds.bottom = 200; 89 assertEquals(expectedBounds, adjustedBounds); 90 91 // inherit with offset 92 parentDrawable.getChildAt(0).getBoundsRule().bottom = 93 ValueRule.inheritFromParentWithOffset(fraction, 100); 94 parentDrawable.updateBounds(bounds); 95 96 adjustedBounds = drawable.getBounds(); 97 expectedBounds = new Rect(bounds); 98 expectedBounds.bottom = bounds.top + (int) (HEIGHT * fraction + 100); 99 assertEquals(expectedBounds, adjustedBounds); 100 101 // inherit from parent 2 102 bounds = new Rect(100, 200, WIDTH, HEIGHT); 103 parentDrawable.getChildAt(0).getBoundsRule().bottom = 104 ValueRule.inheritFromParent(fraction); 105 parentDrawable.updateBounds(bounds); 106 107 adjustedBounds = drawable.getBounds(); 108 expectedBounds = new Rect(bounds); 109 expectedBounds.bottom = bounds.top + (int) ((HEIGHT - 200) * fraction); 110 assertEquals(expectedBounds, adjustedBounds); 111 } 112 113 @Test 114 public void updateBounds_withOverride() { 115 CompositeDrawable parentDrawable = new CompositeDrawable(); 116 float fraction = 0.5f; 117 FitWidthBitmapDrawable drawable = new FitWidthBitmapDrawable(); 118 drawable.setBitmap(mBitmap); 119 Rect bounds = new Rect(0, 0, WIDTH, HEIGHT); 120 drawable.setBounds(bounds); 121 assertEquals(HEIGHT, drawable.getBounds().height()); 122 assertEquals(WIDTH, drawable.getBounds().width()); 123 124 parentDrawable.addChildDrawable(drawable); 125 126 // inherit from parent 127 BoundsRule boundsRule = parentDrawable.getChildAt(0).getBoundsRule(); 128 boundsRule.top = ValueRule.absoluteValue(-200); 129 boundsRule.bottom = ValueRule.inheritFromParent(fraction); 130 parentDrawable.getChildAt(0).getBoundsRule().top.setAbsoluteValue(-100); 131 132 parentDrawable.updateBounds(bounds); 133 134 Rect adjustedBounds = drawable.getBounds(); 135 Rect expectedBounds = new Rect(bounds); 136 expectedBounds.top = -100; 137 expectedBounds.bottom = (int) (HEIGHT * fraction); 138 assertEquals(expectedBounds, adjustedBounds); 139 140 // inherit from parent with offset 141 boundsRule.bottom = ValueRule.inheritFromParentWithOffset(1f, -100); 142 143 parentDrawable.updateBounds(bounds); 144 145 adjustedBounds = drawable.getBounds(); 146 expectedBounds = new Rect(bounds); 147 expectedBounds.top = -100; 148 expectedBounds.bottom = HEIGHT - 100; 149 assertEquals(expectedBounds, adjustedBounds); 150 151 // using property would change type: 152 CompositeDrawable.ChildDrawable.BOTTOM_ABSOLUTE.set(parentDrawable.getChildAt(0), 0); 153 CompositeDrawable.ChildDrawable.BOTTOM_FRACTION.set(parentDrawable.getChildAt(0), 0.5f); 154 parentDrawable.updateBounds(bounds); 155 adjustedBounds = drawable.getBounds(); 156 expectedBounds = new Rect(bounds); 157 expectedBounds.top = -100; 158 expectedBounds.bottom = (int) (0.5f * HEIGHT); 159 assertEquals(expectedBounds, adjustedBounds); 160 } 161 162 163 @SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT) 164 @Test 165 public void constantState() { 166 Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); 167 CompositeDrawable parentDrawable = new CompositeDrawable(); 168 BitmapDrawable childDrawable = new BitmapDrawable(context.getResources(), mBitmap); 169 parentDrawable.addChildDrawable(childDrawable); 170 171 // getConstantState().newDrawable() will create a new CompositeDrawable with shared states: 172 CompositeDrawable parentDrawble2 = (CompositeDrawable) 173 parentDrawable.getConstantState().newDrawable(); 174 BitmapDrawable childDrawable2 = (BitmapDrawable) parentDrawble2.getChildAt(0).getDrawable(); 175 parentDrawable.setAlpha(128); 176 assertEquals(128, parentDrawble2.getAlpha()); 177 assertEquals(128, childDrawable2.getAlpha()); 178 179 // after mutate(), parentDrawble2 will have its own state 180 parentDrawble2.mutate(); 181 childDrawable2 = (BitmapDrawable) parentDrawble2.getChildAt(0).getDrawable(); 182 parentDrawable.setAlpha(64); 183 assertEquals(64, parentDrawable.getAlpha()); 184 assertEquals(64, childDrawable.getAlpha()); 185 assertEquals(128, parentDrawble2.getAlpha()); 186 assertEquals(128, childDrawable2.getAlpha()); 187 childDrawable.setAlpha(100); 188 assertEquals(128, parentDrawble2.getAlpha()); 189 assertEquals(128, childDrawable2.getAlpha()); 190 } 191 192 @Test 193 public void copyChildDrawableTest() { 194 double delta = .005f; 195 CompositeDrawable parent = new CompositeDrawable(); 196 FitWidthBitmapDrawable child = new FitWidthBitmapDrawable(); 197 parent.addChildDrawable(child); 198 parent.getChildAt(0).getBoundsRule().bottom = 199 ValueRule.inheritFromParentWithOffset(.5f, 100); 200 201 CompositeDrawable.ChildDrawable newChild = new CompositeDrawable.ChildDrawable( 202 parent.getChildAt(0), 203 parent, 204 null); 205 assertEquals(100, newChild.getBoundsRule().bottom.getAbsoluteValue()); 206 assertEquals(.5f, newChild.getBoundsRule().bottom.getFraction(), delta); 207 } 208 209 @Test 210 public void mutateTest() { 211 double delta = .005f; 212 CompositeDrawable parent = new CompositeDrawable(); 213 FitWidthBitmapDrawable child = new FitWidthBitmapDrawable(); 214 parent.addChildDrawable(child); 215 parent.getChildAt(0).getBoundsRule().bottom = 216 ValueRule.inheritFromParentWithOffset(.5f, 100); 217 218 CompositeDrawable newDrawable = (CompositeDrawable) parent.getConstantState().newDrawable(); 219 220 parent.mutate(); 221 assertTrue(parent.mMutated); 222 223 CompositeDrawable.ChildDrawable newChild = newDrawable.getChildAt(0); 224 assertNotSame(parent.getChildAt(0), newChild); 225 assertEquals(parent.getChildAt(0).getBoundsRule().bottom.getAbsoluteValue(), 226 newChild.getBoundsRule().bottom.getAbsoluteValue()); 227 assertEquals(parent.getChildAt(0).getBoundsRule().bottom.getFraction(), 228 newChild.getBoundsRule().bottom.getFraction(), delta); 229 } 230 231} 232