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 17ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikaspackage androidx.core.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; 369dede51868bbbe16aadcd65e04860bea8ea50e05Aurimas Liutikas 37ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.core.graphics.drawable.DrawableCompat; 38754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikas 39881c193f64d35ea2a106a2f76c30bd711a971bb1Kirill Grouchnikovimport org.junit.Test; 40881c193f64d35ea2a106a2f76c30bd711a971bb1Kirill Grouchnikovimport org.junit.runner.RunWith; 4189d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes 42881c193f64d35ea2a106a2f76c30bd711a971bb1Kirill Grouchnikov@RunWith(AndroidJUnit4.class) 43881c193f64d35ea2a106a2f76c30bd711a971bb1Kirill Grouchnikov@SmallTest 44881c193f64d35ea2a106a2f76c30bd711a971bb1Kirill Grouchnikovpublic class DrawableCompatTest { 45881c193f64d35ea2a106a2f76c30bd711a971bb1Kirill Grouchnikov @Test 46be678137d44778590a6220ae0ef13649e83363a9Chris Banes public void testDrawableWrap() { 47be678137d44778590a6220ae0ef13649e83363a9Chris Banes final Drawable original = new GradientDrawable(); 48be678137d44778590a6220ae0ef13649e83363a9Chris Banes final Drawable wrappedDrawable = DrawableCompat.wrap(original); 49be678137d44778590a6220ae0ef13649e83363a9Chris Banes 50be678137d44778590a6220ae0ef13649e83363a9Chris Banes if (Build.VERSION.SDK_INT < 23) { 51be678137d44778590a6220ae0ef13649e83363a9Chris Banes assertNotSame(original, wrappedDrawable); 52be678137d44778590a6220ae0ef13649e83363a9Chris Banes } else { 53be678137d44778590a6220ae0ef13649e83363a9Chris Banes assertSame(original, wrappedDrawable); 54be678137d44778590a6220ae0ef13649e83363a9Chris Banes } 55be678137d44778590a6220ae0ef13649e83363a9Chris Banes } 56be678137d44778590a6220ae0ef13649e83363a9Chris Banes 575f5ffb9bea7e6db394d6879f37ab1aadb8d2fdebChris Banes @Test 5889d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes public void testDrawableUnwrap() { 5989d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes final Drawable original = new GradientDrawable(); 6089d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes final Drawable wrappedDrawable = DrawableCompat.wrap(original); 6189d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes assertSame(original, DrawableCompat.unwrap(wrappedDrawable)); 6289d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes } 6389d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes 64881c193f64d35ea2a106a2f76c30bd711a971bb1Kirill Grouchnikov @Test 6589d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes public void testDrawableChangeBoundsCopy() { 6689d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes final Rect bounds = new Rect(0, 0, 10, 10); 6789d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes 68be61247c92b085602d3f671be6f506e9813aba19Chris Banes final Drawable drawable = new GradientDrawable(); 69be61247c92b085602d3f671be6f506e9813aba19Chris Banes 70be61247c92b085602d3f671be6f506e9813aba19Chris Banes final Drawable wrapper = DrawableCompat.wrap(drawable); 71be61247c92b085602d3f671be6f506e9813aba19Chris Banes wrapper.setBounds(bounds); 7289d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes 73be61247c92b085602d3f671be6f506e9813aba19Chris Banes // Assert that the bounds were given to the original drawable 74be61247c92b085602d3f671be6f506e9813aba19Chris Banes assertEquals(bounds, drawable.getBounds()); 7589d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes } 7689d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes 77881c193f64d35ea2a106a2f76c30bd711a971bb1Kirill Grouchnikov @Test 78d8ae10da39a28468fad19ed564799c52354a8d1fChris Banes public void testWrapCopiesDrawableState() { 79d8ae10da39a28468fad19ed564799c52354a8d1fChris Banes final Rect bounds = new Rect(0, 0, 10, 10); 80d8ae10da39a28468fad19ed564799c52354a8d1fChris Banes 81d8ae10da39a28468fad19ed564799c52354a8d1fChris Banes // Create a drawable and set some bounds 82d8ae10da39a28468fad19ed564799c52354a8d1fChris Banes final Drawable drawable = new GradientDrawable(); 83d8ae10da39a28468fad19ed564799c52354a8d1fChris Banes drawable.setBounds(bounds); 84d8ae10da39a28468fad19ed564799c52354a8d1fChris Banes 85d8ae10da39a28468fad19ed564799c52354a8d1fChris Banes // Now wrap it 86d8ae10da39a28468fad19ed564799c52354a8d1fChris Banes final Drawable wrapper = DrawableCompat.wrap(drawable); 87d8ae10da39a28468fad19ed564799c52354a8d1fChris Banes 88d8ae10da39a28468fad19ed564799c52354a8d1fChris Banes // Assert that the bounds were copied to the wrapper 89d8ae10da39a28468fad19ed564799c52354a8d1fChris Banes assertEquals(bounds, wrapper.getBounds()); 90d8ae10da39a28468fad19ed564799c52354a8d1fChris Banes } 91d8ae10da39a28468fad19ed564799c52354a8d1fChris Banes 92d8ae10da39a28468fad19ed564799c52354a8d1fChris Banes @Test 9389d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes public void testDrawableWrapOnlyWrapsOnce() { 9489d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes final Drawable wrappedDrawable = DrawableCompat.wrap(new GradientDrawable()); 9589d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes assertSame(wrappedDrawable, DrawableCompat.wrap(wrappedDrawable)); 9689d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes } 9789d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes 98a0af9ab1fbfa7f4e1c1d90278ec3ff3167a7ec60Chris Banes @Test 994da36b0dfa8436b197314094337fa3102fcca1bcChris Banes public void testWrapMutatedDrawableHasConstantState() { 1004da36b0dfa8436b197314094337fa3102fcca1bcChris Banes // First create a Drawable, and mutated it so that it has a constant state 1014da36b0dfa8436b197314094337fa3102fcca1bcChris Banes Drawable drawable = new GradientDrawable(); 1024da36b0dfa8436b197314094337fa3102fcca1bcChris Banes drawable = drawable.mutate(); 1034da36b0dfa8436b197314094337fa3102fcca1bcChris Banes assertNotNull(drawable.getConstantState()); 1044da36b0dfa8436b197314094337fa3102fcca1bcChris Banes 1054da36b0dfa8436b197314094337fa3102fcca1bcChris Banes // Now wrap and assert that the wrapper also returns a constant state 1064da36b0dfa8436b197314094337fa3102fcca1bcChris Banes final Drawable wrapper = DrawableCompat.wrap(drawable); 1074da36b0dfa8436b197314094337fa3102fcca1bcChris Banes assertNotNull(wrapper.getConstantState()); 1084da36b0dfa8436b197314094337fa3102fcca1bcChris Banes } 1094da36b0dfa8436b197314094337fa3102fcca1bcChris Banes 110134f9096b97a77898c34c4f4751c2fb687b191feChris Banes @Test 111c3b9589f61cbfda8c60344a47f8f87c0ded98554Chris Banes public void testWrappedDrawableHasCallbackSet() { 112c3b9589f61cbfda8c60344a47f8f87c0ded98554Chris Banes // First create a Drawable 113c3b9589f61cbfda8c60344a47f8f87c0ded98554Chris Banes final Drawable drawable = new GradientDrawable(); 114c3b9589f61cbfda8c60344a47f8f87c0ded98554Chris Banes 115c3b9589f61cbfda8c60344a47f8f87c0ded98554Chris Banes // Now wrap it and set a mock as the wrapper's callback 116c3b9589f61cbfda8c60344a47f8f87c0ded98554Chris Banes final Drawable wrapper = DrawableCompat.wrap(drawable); 117c3b9589f61cbfda8c60344a47f8f87c0ded98554Chris Banes final Drawable.Callback mockCallback = mock(Drawable.Callback.class); 118c3b9589f61cbfda8c60344a47f8f87c0ded98554Chris Banes wrapper.setCallback(mockCallback); 119c3b9589f61cbfda8c60344a47f8f87c0ded98554Chris Banes 120c3b9589f61cbfda8c60344a47f8f87c0ded98554Chris Banes // Now make the wrapped drawable invalidate itself 121c3b9589f61cbfda8c60344a47f8f87c0ded98554Chris Banes drawable.invalidateSelf(); 122c3b9589f61cbfda8c60344a47f8f87c0ded98554Chris Banes 123c3b9589f61cbfda8c60344a47f8f87c0ded98554Chris Banes // ...and verify that the wrapper calls to be invalidated 124c3b9589f61cbfda8c60344a47f8f87c0ded98554Chris Banes verify(mockCallback, times(1)).invalidateDrawable(wrapper); 125c3b9589f61cbfda8c60344a47f8f87c0ded98554Chris Banes } 126c3b9589f61cbfda8c60344a47f8f87c0ded98554Chris Banes 1275f5ffb9bea7e6db394d6879f37ab1aadb8d2fdebChris Banes @Test 128be678137d44778590a6220ae0ef13649e83363a9Chris Banes public void testDoesNotWrapTintAwareDrawable() { 129be678137d44778590a6220ae0ef13649e83363a9Chris Banes final TestTintAwareDrawable tintAwareDrawable = new TestTintAwareDrawable(); 130be678137d44778590a6220ae0ef13649e83363a9Chris Banes final Drawable wrapped = DrawableCompat.wrap(tintAwareDrawable); 131be678137d44778590a6220ae0ef13649e83363a9Chris Banes // Assert that the tint aware drawable was not wrapped 132be678137d44778590a6220ae0ef13649e83363a9Chris Banes assertSame(tintAwareDrawable, wrapped); 133be678137d44778590a6220ae0ef13649e83363a9Chris Banes } 134be678137d44778590a6220ae0ef13649e83363a9Chris Banes 1355f5ffb9bea7e6db394d6879f37ab1aadb8d2fdebChris Banes @Test 136be678137d44778590a6220ae0ef13649e83363a9Chris Banes public void testTintAwareDrawableGetsTintCallsDirectly() { 137be678137d44778590a6220ae0ef13649e83363a9Chris Banes final TestTintAwareDrawable d = mock(TestTintAwareDrawable.class); 138be678137d44778590a6220ae0ef13649e83363a9Chris Banes 139be678137d44778590a6220ae0ef13649e83363a9Chris Banes final ColorStateList tint = ColorStateList.valueOf(Color.BLACK); 140be678137d44778590a6220ae0ef13649e83363a9Chris Banes final PorterDuff.Mode tintMode = PorterDuff.Mode.DST; 141be678137d44778590a6220ae0ef13649e83363a9Chris Banes 142be678137d44778590a6220ae0ef13649e83363a9Chris Banes // Now set the tint list and mode using DrawableCompat 143be678137d44778590a6220ae0ef13649e83363a9Chris Banes DrawableCompat.setTintList(d, tint); 144be678137d44778590a6220ae0ef13649e83363a9Chris Banes DrawableCompat.setTintMode(d, tintMode); 145be678137d44778590a6220ae0ef13649e83363a9Chris Banes 146be678137d44778590a6220ae0ef13649e83363a9Chris Banes // Verify that the calls were directly on to the TintAwareDrawable 147be678137d44778590a6220ae0ef13649e83363a9Chris Banes verify(d).setTintList(tint); 148be678137d44778590a6220ae0ef13649e83363a9Chris Banes verify(d).setTintMode(tintMode); 149be678137d44778590a6220ae0ef13649e83363a9Chris Banes } 150be678137d44778590a6220ae0ef13649e83363a9Chris Banes 15189d63e9cbc1daf9e04ba6261cfd141e6dd68ec63Chris Banes}