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 */ 16 17 package android.graphics.drawable.cts; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertNotNull; 21 import static org.junit.Assert.assertTrue; 22 import static org.mockito.Matchers.any; 23 import static org.mockito.Mockito.mock; 24 import static org.mockito.Mockito.times; 25 import static org.mockito.Mockito.verify; 26 27 import android.app.Activity; 28 import android.content.res.ColorStateList; 29 import android.graphics.Bitmap; 30 import android.graphics.Color; 31 import android.graphics.PorterDuff; 32 import android.graphics.cts.ImageViewCtsActivity; 33 import android.graphics.cts.R; 34 import android.graphics.drawable.Icon; 35 import android.net.Uri; 36 import android.os.Handler; 37 import android.os.Message; 38 import android.os.Parcel; 39 40 import androidx.test.filters.MediumTest; 41 import androidx.test.rule.ActivityTestRule; 42 import androidx.test.runner.AndroidJUnit4; 43 44 import org.junit.Before; 45 import org.junit.Rule; 46 import org.junit.Test; 47 import org.junit.runner.RunWith; 48 49 import java.io.File; 50 import java.io.FileOutputStream; 51 import java.io.IOException; 52 import java.io.InputStream; 53 import java.io.OutputStream; 54 55 @MediumTest 56 @RunWith(AndroidJUnit4.class) 57 public class IconTest { 58 private static final long TIMEOUT_MS = 1000; 59 60 private Activity mActivity; 61 private Icon mIcon; 62 63 @Rule 64 public ActivityTestRule<ImageViewCtsActivity> mActivityRule = 65 new ActivityTestRule<>(ImageViewCtsActivity.class); 66 67 @Before 68 public void setup() { 69 mActivity = mActivityRule.getActivity(); 70 } 71 72 @Test 73 public void testBitmapIcon() { 74 verifyIconValidity( 75 Icon.createWithBitmap(Bitmap.createBitmap(16, 16, Bitmap.Config.ARGB_8888))); 76 } 77 78 @Test 79 public void testDataIcon() { 80 byte[] data = new byte[4]; 81 data[0] = data[1] = data[2] = data[3] = (byte)255; 82 verifyIconValidity(Icon.createWithData(data, 0, 4)); 83 } 84 85 @Test 86 public void testFileIcon() throws IOException { 87 File file = new File(mActivity.getFilesDir(), "testimage.jpg"); 88 try { 89 writeSampleImage(file); 90 assertTrue(file.exists()); 91 92 verifyIconValidity(Icon.createWithFilePath(file.getPath())); 93 94 verifyIconValidity(Icon.createWithContentUri(Uri.fromFile(file))); 95 96 verifyIconValidity(Icon.createWithContentUri(file.toURI().toString())); 97 } finally { 98 file.delete(); 99 } 100 } 101 102 @Test 103 public void testResourceIcon() { 104 verifyIconValidity(Icon.createWithResource(mActivity, R.drawable.bmp_test)); 105 106 verifyIconValidity(Icon.createWithResource( 107 mActivity.getPackageName(), R.drawable.bmp_test)); 108 } 109 110 @Test 111 public void testLoadDrawableAsync() throws Throwable { 112 mIcon = Icon.createWithBitmap(Bitmap.createBitmap(16, 16, Bitmap.Config.ARGB_8888)); 113 114 Icon.OnDrawableLoadedListener mockListener = mock(Icon.OnDrawableLoadedListener.class); 115 mActivityRule.runOnUiThread( 116 () -> mIcon.loadDrawableAsync(mActivity, mockListener, new Handler())); 117 // Verify that there was exactly one call to the passed listener's callback within the 118 // predetermined timeout 119 Thread.sleep(TIMEOUT_MS); 120 verify(mockListener, times(1)).onDrawableLoaded(any()); 121 } 122 123 @Test 124 public void testLoadDrawableAsyncWithMessage() throws Throwable { 125 mIcon = Icon.createWithBitmap(Bitmap.createBitmap(16, 16, Bitmap.Config.ARGB_8888)); 126 127 Runnable mockRunnable = mock(Runnable.class); 128 mActivityRule.runOnUiThread( 129 () -> mIcon.loadDrawableAsync(mActivity, Message.obtain(new Handler(), 130 mockRunnable))); 131 // Verify that there was exactly one call to the passed Runnable's run within the 132 // predetermined timeout 133 Thread.sleep(TIMEOUT_MS); 134 verify(mockRunnable, times(1)).run(); 135 } 136 137 @Test 138 public void testBitmapIcon_getType() { 139 Icon icon = Icon.createWithBitmap(Bitmap.createBitmap(16, 16, Bitmap.Config.ARGB_8888)); 140 assertEquals(Icon.TYPE_BITMAP, icon.getType()); 141 } 142 143 @Test 144 public void testDataIcon_getType() { 145 byte[] data = new byte[4]; 146 data[0] = data[1] = data[2] = data[3] = (byte) 255; 147 Icon icon = Icon.createWithData(data, 0, 4); 148 assertEquals(Icon.TYPE_DATA, icon.getType()); 149 } 150 151 @Test 152 public void testFileIcon_getType() throws IOException { 153 File file = new File(mActivity.getFilesDir(), "testimage.jpg"); 154 try { 155 writeSampleImage(file); 156 assertTrue(file.exists()); 157 String filePath = file.toURI().getPath(); 158 159 Icon icon = Icon.createWithFilePath(file.getPath()); 160 assertEquals(Icon.TYPE_URI, icon.getType()); 161 assertEquals(filePath, icon.getUri().getPath()); 162 163 icon = Icon.createWithContentUri(Uri.fromFile(file)); 164 assertEquals(Icon.TYPE_URI, icon.getType()); 165 assertEquals(filePath, icon.getUri().getPath()); 166 167 icon = Icon.createWithContentUri(file.toURI().toString()); 168 assertEquals(Icon.TYPE_URI, icon.getType()); 169 assertEquals(filePath, icon.getUri().getPath()); 170 } finally { 171 file.delete(); 172 } 173 } 174 175 @Test 176 public void testResourceIcon_getType() { 177 Icon icon = Icon.createWithResource("com.android.cts.testpkg", R.drawable.bmp_test); 178 assertEquals(Icon.TYPE_RESOURCE, icon.getType()); 179 assertEquals("com.android.cts.testpkg", icon.getResPackage()); 180 assertEquals(R.drawable.bmp_test, icon.getResId()); 181 } 182 183 private void writeSampleImage(File imagefile) throws IOException { 184 try (InputStream source = mActivity.getResources().openRawResource(R.drawable.testimage); 185 OutputStream target = new FileOutputStream(imagefile)) { 186 byte[] buffer = new byte[1024]; 187 for (int len = source.read(buffer); len >= 0; len = source.read(buffer)) { 188 target.write(buffer, 0, len); 189 } 190 } 191 } 192 193 // Check if the created icon is valid and doesn't cause crashes for the public methods. 194 private void verifyIconValidity(Icon icon) { 195 assertNotNull(icon); 196 197 // tint properties. 198 icon.setTint(Color.BLUE); 199 icon.setTintList(ColorStateList.valueOf(Color.RED)); 200 icon.setTintMode(PorterDuff.Mode.XOR); 201 202 // Parcelable methods. 203 icon.describeContents(); 204 Parcel parcel = Parcel.obtain(); 205 icon.writeToParcel(parcel, 0); 206 207 parcel.setDataPosition(0); 208 assertNotNull(Icon.CREATOR.createFromParcel(parcel)); 209 210 // loading drawable synchronously. 211 assertNotNull(icon.loadDrawable(mActivity)); 212 213 parcel.recycle(); 214 } 215 } 216