1 /* 2 * Copyright 2020 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 com.android.bluetooth.avrcp; 18 19 import static com.google.common.truth.Truth.assertThat; 20 import static com.google.common.truth.Truth.assertWithMessage; 21 22 import android.content.Context; 23 import android.content.pm.PackageManager; 24 import android.content.res.Resources; 25 import android.graphics.Bitmap; 26 import android.graphics.BitmapFactory; 27 28 import androidx.test.InstrumentationRegistry; 29 import androidx.test.runner.AndroidJUnit4; 30 31 import com.android.bluetooth.audio_util.Image; 32 import com.android.bluetooth.avrcpcontroller.BipEncoding; 33 import com.android.bluetooth.avrcpcontroller.BipImageDescriptor; 34 import com.android.bluetooth.avrcpcontroller.BipImageFormat; 35 import com.android.bluetooth.avrcpcontroller.BipImageProperties; 36 import com.android.bluetooth.avrcpcontroller.BipPixel; 37 38 import org.junit.After; 39 import org.junit.Before; 40 import org.junit.Test; 41 import org.junit.runner.RunWith; 42 43 import java.io.ByteArrayInputStream; 44 import java.io.ByteArrayOutputStream; 45 import java.io.InputStream; 46 import java.util.Arrays; 47 48 @RunWith(AndroidJUnit4.class) 49 public class CoverArtTest { 50 private Context mTargetContext; 51 private Resources mTestResources; 52 53 private static final BipPixel PIXEL_THUMBNAIL = BipPixel.createFixed(200, 200); 54 private static final String IMAGE_HANDLE_1 = "0000001"; 55 56 private Bitmap m200by200Image = null; 57 private Bitmap m200by200ImageBlue = null; 58 59 private Image mImage = null; 60 private Image mImage2 = null; 61 62 @Before setUp()63 public void setUp() throws Exception { 64 mTargetContext = InstrumentationRegistry.getTargetContext(); 65 try { 66 mTestResources = mTargetContext.getPackageManager() 67 .getResourcesForApplication("com.android.bluetooth.tests"); 68 } catch (PackageManager.NameNotFoundException e) { 69 assertWithMessage("Setup Failure Unable to get resources" + e.toString()).fail(); 70 } 71 72 m200by200Image = loadImage(com.android.bluetooth.tests.R.raw.image_200_200); 73 m200by200ImageBlue = loadImage(com.android.bluetooth.tests.R.raw.image_200_200_blue); 74 mImage = new Image(null, m200by200Image); 75 mImage2 = new Image(null, m200by200ImageBlue); 76 } 77 78 @After tearDown()79 public void tearDown() throws Exception { 80 mImage2 = null; 81 mImage = null; 82 m200by200ImageBlue = null; 83 m200by200Image = null; 84 mTestResources = null; 85 mTargetContext = null; 86 } 87 loadImage(int resId)88 private Bitmap loadImage(int resId) { 89 InputStream imageInputStream = mTestResources.openRawResource(resId); 90 return BitmapFactory.decodeStream(imageInputStream); 91 } 92 toInputSteam(Bitmap bitmap)93 private InputStream toInputSteam(Bitmap bitmap) { 94 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 95 bitmap.compress(Bitmap.CompressFormat.PNG, 0, outputStream); 96 byte[] imageBytes = outputStream.toByteArray(); 97 return new ByteArrayInputStream(imageBytes); 98 } 99 toBitmap(byte[] imageBytes)100 private Bitmap toBitmap(byte[] imageBytes) { 101 ByteArrayInputStream inputStream = new ByteArrayInputStream(imageBytes); 102 return BitmapFactory.decodeStream(inputStream); 103 } 104 getDescriptor(int encoding, int width, int height)105 private BipImageDescriptor getDescriptor(int encoding, int width, int height) { 106 return new BipImageDescriptor.Builder() 107 .setEncoding(encoding) 108 .setFixedDimensions(width, height) 109 .build(); 110 } 111 containsThumbnailFormat(BipImageProperties properties)112 private boolean containsThumbnailFormat(BipImageProperties properties) { 113 if (properties == null) return false; 114 115 for (BipImageFormat format : properties.getNativeFormats()) { 116 BipEncoding encoding = format.getEncoding(); 117 BipPixel pixel = format.getPixel(); 118 if (encoding == null || pixel == null) continue; 119 if (encoding.getType() == BipEncoding.JPEG && PIXEL_THUMBNAIL.equals(pixel)) { 120 return true; 121 } 122 } 123 124 for (BipImageFormat format : properties.getVariantFormats()) { 125 BipEncoding encoding = format.getEncoding(); 126 BipPixel pixel = format.getPixel(); 127 if (encoding == null || pixel == null) continue; 128 if (encoding.getType() == BipEncoding.JPEG && PIXEL_THUMBNAIL.equals(pixel)) { 129 return true; 130 } 131 } 132 133 return false; 134 } 135 isThumbnailFormat(Bitmap image)136 private boolean isThumbnailFormat(Bitmap image) { 137 if (image == null) return false; 138 return (200 == image.getHeight() && 200 == image.getWidth()); 139 } 140 141 /** 142 * Make sure you can create an image from an Image object 143 */ 144 @Test testCreateCoverArtFromImage()145 public void testCreateCoverArtFromImage() { 146 CoverArt artwork = new CoverArt(mImage); 147 assertThat(artwork.getImage()).isNotNull(); 148 } 149 150 /** 151 * Make sure you get an image hash from a valid image 152 */ 153 @Test testGetImageHash()154 public void testGetImageHash() { 155 CoverArt artwork = new CoverArt(mImage); 156 String hash = artwork.getImageHash(); 157 assertThat(hash).isNotNull(); 158 } 159 160 /** 161 * Make sure you get the same image hash from several calls to the same object 162 */ 163 @Test testGetImageHashSameForMultipleCalls()164 public void testGetImageHashSameForMultipleCalls() { 165 CoverArt artwork = new CoverArt(mImage); 166 String hash = artwork.getImageHash(); 167 assertThat(hash).isNotNull(); 168 assertThat(artwork.getImageHash()).isEqualTo(hash); // extra call 1 169 assertThat(artwork.getImageHash()).isEqualTo(hash); // extra call 2 170 } 171 172 /** 173 * Make sure you get the same image hash from separate objects created from the same image 174 */ 175 @Test testGetImageHashSameForSameImages()176 public void testGetImageHashSameForSameImages() { 177 CoverArt artwork = new CoverArt(mImage); 178 CoverArt artwork2 = new CoverArt(mImage); 179 String hash = artwork.getImageHash(); 180 String hash2 = artwork2.getImageHash(); 181 182 assertThat(hash).isNotNull(); 183 assertThat(hash2).isNotNull(); 184 assertThat(hash).isEqualTo(hash2); 185 } 186 187 /** 188 * Make sure you get different image hashes from separate objects created from different images 189 */ 190 @Test testGetImageHashDifferentForDifferentImages()191 public void testGetImageHashDifferentForDifferentImages() { 192 CoverArt artwork = new CoverArt(mImage); 193 CoverArt artwork2 = new CoverArt(mImage2); 194 String hash = artwork.getImageHash(); 195 String hash2 = artwork2.getImageHash(); 196 197 assertThat(hash).isNotNull(); 198 assertThat(hash2).isNotNull(); 199 assertThat(hash).isNotEqualTo(hash2); 200 } 201 202 /** 203 * Make sure you get an image when asking for the native image 204 */ 205 @Test testGetNativeImage()206 public void testGetNativeImage() { 207 CoverArt artwork = new CoverArt(mImage); 208 byte[] image = artwork.getImage(); 209 assertThat(image).isNotNull(); 210 } 211 212 /** 213 * Make sure you getThumbnailImage returns an image as a 200 by 200 JPEG 214 */ 215 @Test testGetThumbnailImage()216 public void testGetThumbnailImage() { 217 CoverArt artwork = new CoverArt(mImage); 218 byte[] imageBytes = artwork.getThumbnail(); 219 assertThat(imageBytes).isNotNull(); 220 Bitmap image = toBitmap(imageBytes); 221 assertThat(isThumbnailFormat(image)).isTrue(); 222 } 223 224 /** 225 * Make sure you can set the image handle associated with this object 226 */ 227 @Test testGetAndSetImageHandle()228 public void testGetAndSetImageHandle() { 229 CoverArt artwork = new CoverArt(mImage); 230 assertThat(artwork.getImageHandle()).isNull(); 231 artwork.setImageHandle(IMAGE_HANDLE_1); 232 assertThat(artwork.getImageHandle()).isEqualTo(IMAGE_HANDLE_1); 233 } 234 235 /** 236 * Make sure a getImageProperties() yields a set of image properties. The thumbnail format 237 * MUST be contained in that set 238 */ 239 @Test testGetImageProperties()240 public void testGetImageProperties() { 241 CoverArt artwork = new CoverArt(mImage); 242 artwork.setImageHandle(IMAGE_HANDLE_1); 243 BipImageProperties properties = artwork.getImageProperties(); 244 assertThat(properties).isNotNull(); 245 assertThat(containsThumbnailFormat(properties)).isTrue(); 246 } 247 248 /** 249 * Make sure a getImage(<valid descriptor>) yield an image in the format you asked for 250 */ 251 @Test testGetImageWithValidDescriptor()252 public void testGetImageWithValidDescriptor() { 253 CoverArt artwork = new CoverArt(mImage); 254 BipImageDescriptor descriptor = getDescriptor(BipEncoding.JPEG, 200, 200); 255 byte[] image = artwork.getImage(descriptor); 256 assertThat(image).isNotNull(); 257 } 258 259 /** 260 * Make sure a getImage(<thumbnail descriptor>) yields the image in the thumbnail format 261 */ 262 @Test testGetImageWithThumbnailDescriptor()263 public void testGetImageWithThumbnailDescriptor() { 264 CoverArt artwork = new CoverArt(mImage); 265 BipImageDescriptor descriptor = getDescriptor(BipEncoding.JPEG, 200, 200); 266 byte[] imageBytes = artwork.getImage(descriptor); 267 assertThat(imageBytes).isNotNull(); 268 Bitmap image = toBitmap(imageBytes); 269 assertThat(isThumbnailFormat(image)).isTrue(); 270 } 271 272 /** 273 * Make sure a getImage(<invalid descriptor>) yields a null 274 */ 275 @Test testGetImageWithInvalidDescriptor()276 public void testGetImageWithInvalidDescriptor() { 277 CoverArt artwork = new CoverArt(mImage); 278 BipImageDescriptor descriptor = getDescriptor(BipEncoding.BMP, 1200, 1200); 279 byte[] image = artwork.getImage(descriptor); 280 assertThat(image).isNull(); 281 } 282 283 /** 284 * Make sure a getImage(<null descriptor>) yields the native image 285 */ 286 @Test testGetImageWithoutDescriptor()287 public void testGetImageWithoutDescriptor() { 288 CoverArt artwork = new CoverArt(mImage); 289 byte[] image = artwork.getImage(null); 290 byte[] nativeImage = artwork.getImage(); 291 assertThat(Arrays.equals(nativeImage, image)).isTrue(); 292 } 293 294 /** 295 * Make sure we can get a valid string representation of the CoverArt 296 */ 297 @Test testGetSize()298 public void testGetSize() { 299 CoverArt artwork = new CoverArt(mImage); 300 assertThat(artwork.size() > 0).isTrue(); 301 } 302 303 /** 304 * Make sure we can get a valid string representation of the CoverArt 305 */ 306 @Test testToString()307 public void testToString() { 308 CoverArt artwork = new CoverArt(mImage); 309 assertThat(artwork.toString()).isNotNull(); 310 } 311 } 312