189d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes/* 289d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes * Copyright (C) 2016 The Android Open Source Project 389d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes * 489d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes * Licensed under the Apache License, Version 2.0 (the "License"); 589d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes * you may not use this file except in compliance with the License. 689d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes * You may obtain a copy of the License at 789d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes * 889d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes * http://www.apache.org/licenses/LICENSE-2.0 989d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes * 1089d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes * Unless required by applicable law or agreed to in writing, software 1189d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes * distributed under the License is distributed on an "AS IS" BASIS, 1289d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1389d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes * See the License for the specific language governing permissions and 1489d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes * limitations under the License. 1589d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes */ 1689d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes 1789d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banespackage android.support.v4.graphics; 1889d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes 19754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport static org.junit.Assert.assertEquals; 20754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport static org.junit.Assert.assertNotNull; 21754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport static org.junit.Assert.assertNotSame; 22754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport static org.junit.Assert.assertSame; 23754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport static org.mockito.Mockito.mock; 24754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport static org.mockito.Mockito.times; 25754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport static org.mockito.Mockito.verify; 26754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikas 27be678137d44778590a6220ae0ef13649e83363a9Chris Banesimport android.content.res.ColorStateList; 28be678137d44778590a6220ae0ef13649e83363a9Chris Banesimport android.graphics.Color; 29be678137d44778590a6220ae0ef13649e83363a9Chris Banesimport android.graphics.PorterDuff; 3089d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banesimport android.graphics.Rect; 3189d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banesimport android.graphics.drawable.Drawable; 3289d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banesimport android.graphics.drawable.GradientDrawable; 33be678137d44778590a6220ae0ef13649e83363a9Chris Banesimport android.os.Build; 34754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport android.support.test.filters.SmallTest; 35f5ec4487510a0e7226636704860a884f4c1d0ab6Kirill Grouchnikovimport android.support.test.runner.AndroidJUnit4; 3689d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banesimport android.support.v4.graphics.drawable.DrawableCompat; 37754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikas 38881c193f64d35ea2a106a2f76c30bd711a971bb1Kirill Grouchnikovimport org.junit.Test; 39881c193f64d35ea2a106a2f76c30bd711a971bb1Kirill Grouchnikovimport org.junit.runner.RunWith; 4089d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes 41881c193f64d35ea2a106a2f76c30bd711a971bb1Kirill Grouchnikov@RunWith(AndroidJUnit4.class) 42881c193f64d35ea2a106a2f76c30bd711a971bb1Kirill Grouchnikov@SmallTest 43881c193f64d35ea2a106a2f76c30bd711a971bb1Kirill Grouchnikovpublic class DrawableCompatTest { 44881c193f64d35ea2a106a2f76c30bd711a971bb1Kirill Grouchnikov @Test 45be678137d44778590a6220ae0ef13649e83363a9Chris Banes public void testDrawableWrap() { 46be678137d44778590a6220ae0ef13649e83363a9Chris Banes final Drawable original = new GradientDrawable(); 47be678137d44778590a6220ae0ef13649e83363a9Chris Banes final Drawable wrappedDrawable = DrawableCompat.wrap(original); 48be678137d44778590a6220ae0ef13649e83363a9Chris Banes 49be678137d44778590a6220ae0ef13649e83363a9Chris Banes if (Build.VERSION.SDK_INT < 23) { 50be678137d44778590a6220ae0ef13649e83363a9Chris Banes assertNotSame(original, wrappedDrawable); 51be678137d44778590a6220ae0ef13649e83363a9Chris Banes } else { 52be678137d44778590a6220ae0ef13649e83363a9Chris Banes assertSame(original, wrappedDrawable); 53be678137d44778590a6220ae0ef13649e83363a9Chris Banes } 54be678137d44778590a6220ae0ef13649e83363a9Chris Banes } 55be678137d44778590a6220ae0ef13649e83363a9Chris Banes 565f5ffb9bea7e6db394d6879f37ab1aadb8d2fdebChris Banes @Test 5789d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes public void testDrawableUnwrap() { 5889d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes final Drawable original = new GradientDrawable(); 5989d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes final Drawable wrappedDrawable = DrawableCompat.wrap(original); 6089d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes assertSame(original, DrawableCompat.unwrap(wrappedDrawable)); 6189d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes } 6289d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes 63881c193f64d35ea2a106a2f76c30bd711a971bb1Kirill Grouchnikov @Test 6489d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes public void testDrawableChangeBoundsCopy() { 6589d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes final Rect bounds = new Rect(0, 0, 10, 10); 6689d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes 67be61247c92b085602d3f671be6f506e9813aba19Chris Banes final Drawable drawable = new GradientDrawable(); 68be61247c92b085602d3f671be6f506e9813aba19Chris Banes 69be61247c92b085602d3f671be6f506e9813aba19Chris Banes final Drawable wrapper = DrawableCompat.wrap(drawable); 70be61247c92b085602d3f671be6f506e9813aba19Chris Banes wrapper.setBounds(bounds); 7189d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes 72be61247c92b085602d3f671be6f506e9813aba19Chris Banes // Assert that the bounds were given to the original drawable 73be61247c92b085602d3f671be6f506e9813aba19Chris Banes assertEquals(bounds, drawable.getBounds()); 7489d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes } 7589d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes 76881c193f64d35ea2a106a2f76c30bd711a971bb1Kirill Grouchnikov @Test 77d8ae10da39a28468fad19ed564799c52354a8d1fChris Banes public void testWrapCopiesDrawableState() { 78d8ae10da39a28468fad19ed564799c52354a8d1fChris Banes final Rect bounds = new Rect(0, 0, 10, 10); 79d8ae10da39a28468fad19ed564799c52354a8d1fChris Banes 80d8ae10da39a28468fad19ed564799c52354a8d1fChris Banes // Create a drawable and set some bounds 81d8ae10da39a28468fad19ed564799c52354a8d1fChris Banes final Drawable drawable = new GradientDrawable(); 82d8ae10da39a28468fad19ed564799c52354a8d1fChris Banes drawable.setBounds(bounds); 83d8ae10da39a28468fad19ed564799c52354a8d1fChris Banes 84d8ae10da39a28468fad19ed564799c52354a8d1fChris Banes // Now wrap it 85d8ae10da39a28468fad19ed564799c52354a8d1fChris Banes final Drawable wrapper = DrawableCompat.wrap(drawable); 86d8ae10da39a28468fad19ed564799c52354a8d1fChris Banes 87d8ae10da39a28468fad19ed564799c52354a8d1fChris Banes // Assert that the bounds were copied to the wrapper 88d8ae10da39a28468fad19ed564799c52354a8d1fChris Banes assertEquals(bounds, wrapper.getBounds()); 89d8ae10da39a28468fad19ed564799c52354a8d1fChris Banes } 90d8ae10da39a28468fad19ed564799c52354a8d1fChris Banes 91d8ae10da39a28468fad19ed564799c52354a8d1fChris Banes @Test 9289d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes public void testDrawableWrapOnlyWrapsOnce() { 9389d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes final Drawable wrappedDrawable = DrawableCompat.wrap(new GradientDrawable()); 9489d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes assertSame(wrappedDrawable, DrawableCompat.wrap(wrappedDrawable)); 9589d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes } 9689d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes 97a0af9ab1fbfa7f4e1c1d90278ec3ff3167a7ec60Chris Banes @Test 984da36b0dfa8436b197314094337fa3102fcca1bcChris Banes public void testWrapMutatedDrawableHasConstantState() { 994da36b0dfa8436b197314094337fa3102fcca1bcChris Banes // First create a Drawable, and mutated it so that it has a constant state 1004da36b0dfa8436b197314094337fa3102fcca1bcChris Banes Drawable drawable = new GradientDrawable(); 1014da36b0dfa8436b197314094337fa3102fcca1bcChris Banes drawable = drawable.mutate(); 1024da36b0dfa8436b197314094337fa3102fcca1bcChris Banes assertNotNull(drawable.getConstantState()); 1034da36b0dfa8436b197314094337fa3102fcca1bcChris Banes 1044da36b0dfa8436b197314094337fa3102fcca1bcChris Banes // Now wrap and assert that the wrapper also returns a constant state 1054da36b0dfa8436b197314094337fa3102fcca1bcChris Banes final Drawable wrapper = DrawableCompat.wrap(drawable); 1064da36b0dfa8436b197314094337fa3102fcca1bcChris Banes assertNotNull(wrapper.getConstantState()); 1074da36b0dfa8436b197314094337fa3102fcca1bcChris Banes } 1084da36b0dfa8436b197314094337fa3102fcca1bcChris Banes 109134f9096b97a77898c34c4f4751c2fb687b191feChris Banes @Test 110c3b9589f61cbfda8c60344a47f8f87c0ded98554Chris Banes public void testWrappedDrawableHasCallbackSet() { 111c3b9589f61cbfda8c60344a47f8f87c0ded98554Chris Banes // First create a Drawable 112c3b9589f61cbfda8c60344a47f8f87c0ded98554Chris Banes final Drawable drawable = new GradientDrawable(); 113c3b9589f61cbfda8c60344a47f8f87c0ded98554Chris Banes 114c3b9589f61cbfda8c60344a47f8f87c0ded98554Chris Banes // Now wrap it and set a mock as the wrapper's callback 115c3b9589f61cbfda8c60344a47f8f87c0ded98554Chris Banes final Drawable wrapper = DrawableCompat.wrap(drawable); 116c3b9589f61cbfda8c60344a47f8f87c0ded98554Chris Banes final Drawable.Callback mockCallback = mock(Drawable.Callback.class); 117c3b9589f61cbfda8c60344a47f8f87c0ded98554Chris Banes wrapper.setCallback(mockCallback); 118c3b9589f61cbfda8c60344a47f8f87c0ded98554Chris Banes 119c3b9589f61cbfda8c60344a47f8f87c0ded98554Chris Banes // Now make the wrapped drawable invalidate itself 120c3b9589f61cbfda8c60344a47f8f87c0ded98554Chris Banes drawable.invalidateSelf(); 121c3b9589f61cbfda8c60344a47f8f87c0ded98554Chris Banes 122c3b9589f61cbfda8c60344a47f8f87c0ded98554Chris Banes // ...and verify that the wrapper calls to be invalidated 123c3b9589f61cbfda8c60344a47f8f87c0ded98554Chris Banes verify(mockCallback, times(1)).invalidateDrawable(wrapper); 124c3b9589f61cbfda8c60344a47f8f87c0ded98554Chris Banes } 125c3b9589f61cbfda8c60344a47f8f87c0ded98554Chris Banes 1265f5ffb9bea7e6db394d6879f37ab1aadb8d2fdebChris Banes @Test 127be678137d44778590a6220ae0ef13649e83363a9Chris Banes public void testDoesNotWrapTintAwareDrawable() { 128be678137d44778590a6220ae0ef13649e83363a9Chris Banes final TestTintAwareDrawable tintAwareDrawable = new TestTintAwareDrawable(); 129be678137d44778590a6220ae0ef13649e83363a9Chris Banes final Drawable wrapped = DrawableCompat.wrap(tintAwareDrawable); 130be678137d44778590a6220ae0ef13649e83363a9Chris Banes // Assert that the tint aware drawable was not wrapped 131be678137d44778590a6220ae0ef13649e83363a9Chris Banes assertSame(tintAwareDrawable, wrapped); 132be678137d44778590a6220ae0ef13649e83363a9Chris Banes } 133be678137d44778590a6220ae0ef13649e83363a9Chris Banes 1345f5ffb9bea7e6db394d6879f37ab1aadb8d2fdebChris Banes @Test 135be678137d44778590a6220ae0ef13649e83363a9Chris Banes public void testTintAwareDrawableGetsTintCallsDirectly() { 136be678137d44778590a6220ae0ef13649e83363a9Chris Banes final TestTintAwareDrawable d = mock(TestTintAwareDrawable.class); 137be678137d44778590a6220ae0ef13649e83363a9Chris Banes 138be678137d44778590a6220ae0ef13649e83363a9Chris Banes final ColorStateList tint = ColorStateList.valueOf(Color.BLACK); 139be678137d44778590a6220ae0ef13649e83363a9Chris Banes final PorterDuff.Mode tintMode = PorterDuff.Mode.DST; 140be678137d44778590a6220ae0ef13649e83363a9Chris Banes 141be678137d44778590a6220ae0ef13649e83363a9Chris Banes // Now set the tint list and mode using DrawableCompat 142be678137d44778590a6220ae0ef13649e83363a9Chris Banes DrawableCompat.setTintList(d, tint); 143be678137d44778590a6220ae0ef13649e83363a9Chris Banes DrawableCompat.setTintMode(d, tintMode); 144be678137d44778590a6220ae0ef13649e83363a9Chris Banes 145be678137d44778590a6220ae0ef13649e83363a9Chris Banes // Verify that the calls were directly on to the TintAwareDrawable 146be678137d44778590a6220ae0ef13649e83363a9Chris Banes verify(d).setTintList(tint); 147be678137d44778590a6220ae0ef13649e83363a9Chris Banes verify(d).setTintMode(tintMode); 148be678137d44778590a6220ae0ef13649e83363a9Chris Banes } 149be678137d44778590a6220ae0ef13649e83363a9Chris Banes 15089d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes}