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