1 package org.robolectric.shadows; 2 3 import static android.os.Build.VERSION_CODES.M; 4 import static android.os.Build.VERSION_CODES.N; 5 import static android.os.Build.VERSION_CODES.N_MR1; 6 import static android.os.Build.VERSION_CODES.O; 7 import static android.os.Build.VERSION_CODES.P; 8 import static android.os.Build.VERSION_CODES.Q; 9 import static android.os.Build.VERSION_CODES.R; 10 import static android.os.Build.VERSION_CODES.S; 11 import static org.robolectric.util.reflector.Reflector.reflector; 12 13 import android.graphics.Bitmap; 14 import android.graphics.ColorSpace; 15 import android.graphics.ColorSpace.Rgb.TransferParameters; 16 import android.graphics.Matrix; 17 import android.hardware.HardwareBuffer; 18 import android.os.Parcel; 19 import android.os.Parcelable; 20 import java.io.InputStream; 21 import java.io.OutputStream; 22 import java.nio.Buffer; 23 import java.util.ArrayList; 24 import java.util.Collections; 25 import java.util.List; 26 import java.util.Map; 27 import org.robolectric.RuntimeEnvironment; 28 import org.robolectric.annotation.ClassName; 29 import org.robolectric.annotation.Implementation; 30 import org.robolectric.annotation.Implements; 31 import org.robolectric.annotation.Resetter; 32 import org.robolectric.nativeruntime.BitmapNatives; 33 import org.robolectric.nativeruntime.ColorSpaceRgbNatives; 34 import org.robolectric.nativeruntime.DefaultNativeRuntimeLoader; 35 import org.robolectric.nativeruntime.NativeAllocationRegistryNatives; 36 import org.robolectric.util.reflector.Accessor; 37 import org.robolectric.util.reflector.ForType; 38 import org.robolectric.util.reflector.Static; 39 import org.robolectric.versioning.AndroidVersions.U; 40 import org.robolectric.versioning.AndroidVersions.V; 41 42 /** Shadow for {@link Bitmap} that is backed by native code */ 43 @Implements( 44 value = Bitmap.class, 45 minSdk = O, 46 isInAndroidSdk = false, 47 callNativeMethodsByDefault = true) 48 public class ShadowNativeBitmap extends ShadowBitmap { 49 private int createdFromResId; 50 51 private static final List<Long> colorSpaceAllocationsP = 52 Collections.synchronizedList(new ArrayList<>()); 53 54 /** Called by {@link ShadowNativeBitmapFactory}. */ setCreatedFromResId(int createdFromResId)55 void setCreatedFromResId(int createdFromResId) { 56 this.createdFromResId = createdFromResId; 57 } 58 59 @Implementation(minSdk = Q, maxSdk = U.SDK_INT) nativeCreate( int[] colors, int offset, int stride, int width, int height, int nativeConfig, boolean mutable, long nativeColorSpace)60 protected static Bitmap nativeCreate( 61 int[] colors, 62 int offset, 63 int stride, 64 int width, 65 int height, 66 int nativeConfig, 67 boolean mutable, 68 long nativeColorSpace) { 69 DefaultNativeRuntimeLoader.injectAndLoad(); 70 return BitmapNatives.nativeCreate( 71 colors, offset, stride, width, height, nativeConfig, mutable, nativeColorSpace); 72 } 73 74 @Implementation(minSdk = O, maxSdk = P) nativeCreate( int[] colors, int offset, int stride, int width, int height, int nativeConfig, boolean mutable, float[] xyzD50, ColorSpace.Rgb.TransferParameters p)75 protected static Bitmap nativeCreate( 76 int[] colors, 77 int offset, 78 int stride, 79 int width, 80 int height, 81 int nativeConfig, 82 boolean mutable, 83 float[] xyzD50, 84 ColorSpace.Rgb.TransferParameters p) { 85 DefaultNativeRuntimeLoader.injectAndLoad(); 86 long colorSpacePtr = 0; 87 if (xyzD50 != null && p != null) { 88 colorSpacePtr = 89 ColorSpaceRgbNatives.nativeCreate( 90 (float) p.a, 91 (float) p.b, 92 (float) p.c, 93 (float) p.d, 94 (float) p.e, 95 (float) p.f, 96 (float) p.g, 97 xyzD50); 98 colorSpaceAllocationsP.add(colorSpacePtr); 99 } 100 return nativeCreate( 101 colors, offset, stride, width, height, nativeConfig, mutable, colorSpacePtr); 102 } 103 104 @Implementation(maxSdk = U.SDK_INT) nativeCopy(long nativeSrcBitmap, int nativeConfig, boolean isMutable)105 protected static Bitmap nativeCopy(long nativeSrcBitmap, int nativeConfig, boolean isMutable) { 106 return BitmapNatives.nativeCopy(nativeSrcBitmap, nativeConfig, isMutable); 107 } 108 109 @Implementation(minSdk = M, maxSdk = U.SDK_INT) nativeCopyAshmem(long nativeSrcBitmap)110 protected static Bitmap nativeCopyAshmem(long nativeSrcBitmap) { 111 return BitmapNatives.nativeCopyAshmem(nativeSrcBitmap); 112 } 113 114 @Implementation(minSdk = N, maxSdk = U.SDK_INT) nativeCopyAshmemConfig(long nativeSrcBitmap, int nativeConfig)115 protected static Bitmap nativeCopyAshmemConfig(long nativeSrcBitmap, int nativeConfig) { 116 return BitmapNatives.nativeCopyAshmemConfig(nativeSrcBitmap, nativeConfig); 117 } 118 119 @Implementation(minSdk = N, maxSdk = U.SDK_INT) nativeGetNativeFinalizer()120 protected static long nativeGetNativeFinalizer() { 121 return BitmapNatives.nativeGetNativeFinalizer(); 122 } 123 124 @Implementation(maxSdk = P, methodName = "nativeRecycle") nativeRecyclePreQ(long nativeBitmap)125 protected static boolean nativeRecyclePreQ(long nativeBitmap) { 126 BitmapNatives.nativeRecycle(nativeBitmap); 127 return true; 128 } 129 130 @Implementation(minSdk = Q, maxSdk = U.SDK_INT) nativeRecycle(long nativeBitmap)131 protected static void nativeRecycle(long nativeBitmap) { 132 BitmapNatives.nativeRecycle(nativeBitmap); 133 } 134 135 @Implementation(minSdk = O, maxSdk = U.SDK_INT) nativeReconfigure( long nativeBitmap, int width, int height, int config, boolean isPremultiplied)136 protected static void nativeReconfigure( 137 long nativeBitmap, int width, int height, int config, boolean isPremultiplied) { 138 BitmapNatives.nativeReconfigure(nativeBitmap, width, height, config, isPremultiplied); 139 } 140 141 @Implementation(maxSdk = U.SDK_INT) nativeCompress( long nativeBitmap, int format, int quality, OutputStream stream, byte[] tempStorage)142 protected static boolean nativeCompress( 143 long nativeBitmap, int format, int quality, OutputStream stream, byte[] tempStorage) { 144 return BitmapNatives.nativeCompress(nativeBitmap, format, quality, stream, tempStorage); 145 } 146 147 @Implementation(maxSdk = U.SDK_INT) nativeErase(long nativeBitmap, int color)148 protected static void nativeErase(long nativeBitmap, int color) { 149 BitmapNatives.nativeErase(nativeBitmap, color); 150 } 151 152 @Implementation(minSdk = Q, maxSdk = U.SDK_INT) nativeErase(long nativeBitmap, long colorSpacePtr, long color)153 protected static void nativeErase(long nativeBitmap, long colorSpacePtr, long color) { 154 BitmapNatives.nativeErase(nativeBitmap, colorSpacePtr, color); 155 } 156 157 @Implementation(maxSdk = U.SDK_INT) nativeRowBytes(long nativeBitmap)158 protected static int nativeRowBytes(long nativeBitmap) { 159 return BitmapNatives.nativeRowBytes(nativeBitmap); 160 } 161 162 @Implementation(maxSdk = U.SDK_INT) nativeConfig(long nativeBitmap)163 protected static int nativeConfig(long nativeBitmap) { 164 return BitmapNatives.nativeConfig(nativeBitmap); 165 } 166 167 @Implementation(maxSdk = U.SDK_INT) nativeGetPixel(long nativeBitmap, int x, int y)168 protected static int nativeGetPixel(long nativeBitmap, int x, int y) { 169 return BitmapNatives.nativeGetPixel(nativeBitmap, x, y); 170 } 171 172 @Implementation(minSdk = Q, maxSdk = U.SDK_INT) nativeGetColor(long nativeBitmap, int x, int y)173 protected static long nativeGetColor(long nativeBitmap, int x, int y) { 174 return BitmapNatives.nativeGetColor(nativeBitmap, x, y); 175 } 176 177 @Implementation(maxSdk = U.SDK_INT) nativeGetPixels( long nativeBitmap, int[] pixels, int offset, int stride, int x, int y, int width, int height)178 protected static void nativeGetPixels( 179 long nativeBitmap, 180 int[] pixels, 181 int offset, 182 int stride, 183 int x, 184 int y, 185 int width, 186 int height) { 187 BitmapNatives.nativeGetPixels(nativeBitmap, pixels, offset, stride, x, y, width, height); 188 } 189 190 @Implementation(maxSdk = U.SDK_INT) nativeSetPixel(long nativeBitmap, int x, int y, int color)191 protected static void nativeSetPixel(long nativeBitmap, int x, int y, int color) { 192 BitmapNatives.nativeSetPixel(nativeBitmap, x, y, color); 193 } 194 195 @Implementation(maxSdk = U.SDK_INT) nativeSetPixels( long nativeBitmap, int[] colors, int offset, int stride, int x, int y, int width, int height)196 protected static void nativeSetPixels( 197 long nativeBitmap, 198 int[] colors, 199 int offset, 200 int stride, 201 int x, 202 int y, 203 int width, 204 int height) { 205 BitmapNatives.nativeSetPixels(nativeBitmap, colors, offset, stride, x, y, width, height); 206 } 207 208 @Implementation(maxSdk = U.SDK_INT) nativeCopyPixelsToBuffer(long nativeBitmap, Buffer dst)209 protected static void nativeCopyPixelsToBuffer(long nativeBitmap, Buffer dst) { 210 BitmapNatives.nativeCopyPixelsToBuffer(nativeBitmap, dst); 211 } 212 213 @Implementation(maxSdk = U.SDK_INT) nativeCopyPixelsFromBuffer(long nativeBitmap, Buffer src)214 protected static void nativeCopyPixelsFromBuffer(long nativeBitmap, Buffer src) { 215 BitmapNatives.nativeCopyPixelsFromBuffer(nativeBitmap, src); 216 } 217 218 @Implementation(maxSdk = U.SDK_INT) nativeGenerationId(long nativeBitmap)219 protected static int nativeGenerationId(long nativeBitmap) { 220 return BitmapNatives.nativeGenerationId(nativeBitmap); 221 } 222 223 // returns a new bitmap built from the native bitmap's alpha, and the paint 224 @Implementation(maxSdk = U.SDK_INT) nativeExtractAlpha(long nativeBitmap, long nativePaint, int[] offsetXY)225 protected static Bitmap nativeExtractAlpha(long nativeBitmap, long nativePaint, int[] offsetXY) { 226 return BitmapNatives.nativeExtractAlpha(nativeBitmap, nativePaint, offsetXY); 227 } 228 229 @Implementation(maxSdk = U.SDK_INT) nativeHasAlpha(long nativeBitmap)230 protected static boolean nativeHasAlpha(long nativeBitmap) { 231 return BitmapNatives.nativeHasAlpha(nativeBitmap); 232 } 233 234 @Implementation(maxSdk = U.SDK_INT) nativeIsPremultiplied(long nativeBitmap)235 protected static boolean nativeIsPremultiplied(long nativeBitmap) { 236 return BitmapNatives.nativeIsPremultiplied(nativeBitmap); 237 } 238 239 @Implementation(maxSdk = U.SDK_INT) nativeSetPremultiplied(long nativeBitmap, boolean isPremul)240 protected static void nativeSetPremultiplied(long nativeBitmap, boolean isPremul) { 241 BitmapNatives.nativeSetPremultiplied(nativeBitmap, isPremul); 242 } 243 244 @Implementation(maxSdk = U.SDK_INT) nativeSetHasAlpha( long nativeBitmap, boolean hasAlpha, boolean requestPremul)245 protected static void nativeSetHasAlpha( 246 long nativeBitmap, boolean hasAlpha, boolean requestPremul) { 247 BitmapNatives.nativeSetHasAlpha(nativeBitmap, hasAlpha, requestPremul); 248 } 249 250 @Implementation(maxSdk = U.SDK_INT) nativeHasMipMap(long nativeBitmap)251 protected static boolean nativeHasMipMap(long nativeBitmap) { 252 return BitmapNatives.nativeHasMipMap(nativeBitmap); 253 } 254 255 @Implementation(maxSdk = U.SDK_INT) nativeSetHasMipMap(long nativeBitmap, boolean hasMipMap)256 protected static void nativeSetHasMipMap(long nativeBitmap, boolean hasMipMap) { 257 BitmapNatives.nativeSetHasMipMap(nativeBitmap, hasMipMap); 258 } 259 260 @Implementation(maxSdk = U.SDK_INT) nativeSameAs(long nativeBitmap0, long nativeBitmap1)261 protected static boolean nativeSameAs(long nativeBitmap0, long nativeBitmap1) { 262 return BitmapNatives.nativeSameAs(nativeBitmap0, nativeBitmap1); 263 } 264 265 @Implementation(minSdk = N_MR1, maxSdk = U.SDK_INT) nativePrepareToDraw(long nativeBitmap)266 protected static void nativePrepareToDraw(long nativeBitmap) { 267 BitmapNatives.nativePrepareToDraw(nativeBitmap); 268 } 269 270 @Implementation(minSdk = O, maxSdk = U.SDK_INT) nativeGetAllocationByteCount(long nativeBitmap)271 protected static int nativeGetAllocationByteCount(long nativeBitmap) { 272 return BitmapNatives.nativeGetAllocationByteCount(nativeBitmap); 273 } 274 275 @Implementation(minSdk = O, maxSdk = U.SDK_INT) nativeCopyPreserveInternalConfig(long nativeBitmap)276 protected static Bitmap nativeCopyPreserveInternalConfig(long nativeBitmap) { 277 return BitmapNatives.nativeCopyPreserveInternalConfig(nativeBitmap); 278 } 279 280 @Implementation(minSdk = Q, maxSdk = U.SDK_INT) nativeWrapHardwareBufferBitmap( HardwareBuffer buffer, long nativeColorSpace)281 protected static Bitmap nativeWrapHardwareBufferBitmap( 282 HardwareBuffer buffer, long nativeColorSpace) { 283 return BitmapNatives.nativeWrapHardwareBufferBitmap(buffer, nativeColorSpace); 284 } 285 286 @Implementation(minSdk = R, maxSdk = U.SDK_INT) nativeGetHardwareBuffer(long nativeBitmap)287 protected static HardwareBuffer nativeGetHardwareBuffer(long nativeBitmap) { 288 return BitmapNatives.nativeGetHardwareBuffer(nativeBitmap); 289 } 290 291 @Implementation(minSdk = O, maxSdk = P) nativeGetColorSpace(long nativePtr, float[] xyz, float[] params)292 protected static boolean nativeGetColorSpace(long nativePtr, float[] xyz, float[] params) { 293 ColorSpace colorSpace = nativeComputeColorSpace(nativePtr); 294 if (colorSpace == null) { 295 return false; 296 } 297 // In Android P, 'nativeGetColorSpace' is responsible for filling out the 'xyz' and 'params' 298 // float arrays. However, in Q and above, 'nativeGetColorSpace' was removed, and 299 // 'nativeComputeColorSpace' returns the ColorSpace object itself. This means for P, we need to 300 // do the reverse operations and generate the float arrays given the detected color space. 301 if (colorSpace instanceof ColorSpace.Rgb) { 302 TransferParameters transferParameters = ((ColorSpace.Rgb) colorSpace).getTransferParameters(); 303 params[0] = (float) transferParameters.a; 304 params[1] = (float) transferParameters.b; 305 params[2] = (float) transferParameters.c; 306 params[3] = (float) transferParameters.d; 307 params[4] = (float) transferParameters.e; 308 params[5] = (float) transferParameters.f; 309 params[6] = (float) transferParameters.g; 310 ColorSpace.Rgb rgb = 311 (ColorSpace.Rgb) 312 ColorSpace.adapt( 313 colorSpace, reflector(ColorSpaceReflector.class).getIlluminantD50XYZ()); 314 rgb.getTransform(xyz); 315 } 316 return true; 317 } 318 319 @Implementation(minSdk = Q, maxSdk = U.SDK_INT) nativeComputeColorSpace(long nativePtr)320 protected static ColorSpace nativeComputeColorSpace(long nativePtr) { 321 return BitmapNatives.nativeComputeColorSpace(nativePtr); 322 } 323 324 @Implementation(minSdk = Q, maxSdk = U.SDK_INT) nativeSetColorSpace(long nativePtr, long nativeColorSpace)325 protected static void nativeSetColorSpace(long nativePtr, long nativeColorSpace) { 326 BitmapNatives.nativeSetColorSpace(nativePtr, nativeColorSpace); 327 } 328 329 @Implementation(minSdk = O, maxSdk = U.SDK_INT) nativeIsSRGB(long nativePtr)330 protected static boolean nativeIsSRGB(long nativePtr) { 331 return BitmapNatives.nativeIsSRGB(nativePtr); 332 } 333 334 @Implementation(minSdk = P, maxSdk = U.SDK_INT) nativeIsSRGBLinear(long nativePtr)335 protected static boolean nativeIsSRGBLinear(long nativePtr) { 336 return BitmapNatives.nativeIsSRGBLinear(nativePtr); 337 } 338 339 @Implementation(minSdk = Q, maxSdk = U.SDK_INT) nativeSetImmutable(long nativePtr)340 protected static void nativeSetImmutable(long nativePtr) { 341 BitmapNatives.nativeSetImmutable(nativePtr); 342 } 343 344 @Implementation(minSdk = Q, maxSdk = U.SDK_INT) nativeIsImmutable(long nativePtr)345 protected static boolean nativeIsImmutable(long nativePtr) { 346 return BitmapNatives.nativeIsImmutable(nativePtr); 347 } 348 349 @Implementation(minSdk = S, maxSdk = U.SDK_INT) nativeIsBackedByAshmem(long nativePtr)350 protected static boolean nativeIsBackedByAshmem(long nativePtr) { 351 return BitmapNatives.nativeIsBackedByAshmem(nativePtr); 352 } 353 354 /** 355 * This is called by {@link Bitmap#getGainmap} to check if a Gainmap exists for the Bitmap. This 356 * method must be present in Android U and below to avoid an UnsatisfiedLinkError. 357 */ 358 @Implementation(minSdk = U.SDK_INT) nativeExtractGainmap( long nativePtr)359 protected static @ClassName("android.graphics.Gainmap") Object nativeExtractGainmap( 360 long nativePtr) { 361 // No-op implementation 362 return null; 363 } 364 365 @ForType(ColorSpace.class) 366 interface ColorSpaceReflector { 367 @Accessor("ILLUMINANT_D50_XYZ") 368 @Static getIlluminantD50XYZ()369 float[] getIlluminantD50XYZ(); 370 371 @Accessor("sNamedColorSpaces") getNamedColorSpaces()372 ColorSpace[] getNamedColorSpaces(); 373 374 @Accessor("sNamedColorSpaceMap") getNamedColorSpaceMap()375 Map<Integer, ColorSpace> getNamedColorSpaceMap(); 376 } 377 378 @Implementation writeToParcel(Parcel p, int flags)379 protected void writeToParcel(Parcel p, int flags) { 380 // Modeled after 381 // https://cs.android.com/android/platform/superproject/+/android-12.0.0_r1:frameworks/base/libs/hwui/jni/Bitmap.cpp;l=872. 382 reflector(BitmapReflector.class, realBitmap).checkRecycled("Can't parcel a recycled bitmap"); 383 int width = realBitmap.getWidth(); 384 int height = realBitmap.getHeight(); 385 p.writeInt(width); 386 p.writeInt(height); 387 p.writeInt(realBitmap.getDensity()); 388 p.writeBoolean(realBitmap.isMutable()); 389 p.writeSerializable(realBitmap.getConfig()); 390 ColorSpace colorSpace = realBitmap.getColorSpace(); 391 boolean hasColorSpace = colorSpace != null; 392 p.writeBoolean(hasColorSpace); 393 if (hasColorSpace) { 394 p.writeString(colorSpace.getName()); 395 } 396 p.writeBoolean(realBitmap.hasAlpha()); 397 int[] pixels = new int[width * height]; 398 realBitmap.getPixels(pixels, 0, width, 0, 0, width, height); 399 p.writeIntArray(pixels); 400 401 if (RuntimeEnvironment.getApiLevel() >= U.SDK_INT) { 402 Object gainmap = reflector(BitmapReflector.class, realBitmap).getGainmap(); 403 if (gainmap != null) { 404 p.writeBoolean(true); 405 p.writeTypedObject((Parcelable) gainmap, flags); 406 } else { 407 p.writeBoolean(false); 408 } 409 } 410 } 411 412 @Implementation nativeCreateFromParcel(Parcel p)413 protected static Bitmap nativeCreateFromParcel(Parcel p) { 414 int parceledWidth = p.readInt(); 415 int parceledHeight = p.readInt(); 416 int density = p.readInt(); 417 boolean mutable = p.readBoolean(); 418 Bitmap.Config parceledConfig = (Bitmap.Config) p.readSerializable(); 419 ColorSpace colorSpace = null; 420 boolean hasColorSpace = p.readBoolean(); 421 if (hasColorSpace) { 422 String colorSpaceName = p.readString(); 423 ColorSpace[] namedColorSpaces; 424 if (RuntimeEnvironment.getApiLevel() >= V.SDK_INT) { 425 // Starting Android V, we need to access the color space map to get all supported color 426 // spaces. 427 Map<Integer, ColorSpace> namedColorSpaceMap = 428 reflector(ColorSpaceReflector.class).getNamedColorSpaceMap(); 429 namedColorSpaces = 430 namedColorSpaceMap.values().toArray(new ColorSpace[namedColorSpaceMap.size()]); 431 } else { 432 // Before V, we directly access the color space array. 433 namedColorSpaces = reflector(ColorSpaceReflector.class).getNamedColorSpaces(); 434 } 435 436 for (ColorSpace named : namedColorSpaces) { 437 if (named.getName().equals(colorSpaceName)) { 438 colorSpace = named; 439 break; 440 } 441 } 442 } 443 boolean hasAlpha = p.readBoolean(); 444 int[] parceledColors = new int[parceledHeight * parceledWidth]; 445 p.readIntArray(parceledColors); 446 Bitmap bitmap; 447 if (colorSpace != null) { 448 bitmap = 449 Bitmap.createBitmap(parceledWidth, parceledHeight, parceledConfig, hasAlpha, colorSpace); 450 } else { 451 bitmap = Bitmap.createBitmap(parceledWidth, parceledHeight, parceledConfig, hasAlpha); 452 } 453 bitmap.setPixels(parceledColors, 0, parceledWidth, 0, 0, parceledWidth, parceledHeight); 454 bitmap.setDensity(density); 455 if (!mutable) { 456 bitmap = bitmap.copy(parceledConfig, false); 457 } 458 return bitmap; 459 } 460 461 @Implementation(minSdk = O, maxSdk = P) nativeCopyColorSpace(long srcBitmap, long dstBitmap)462 protected static void nativeCopyColorSpace(long srcBitmap, long dstBitmap) { 463 BitmapNatives.nativeCopyColorSpaceP(srcBitmap, dstBitmap); 464 } 465 466 @Override getCreatedFromBitmap()467 public Bitmap getCreatedFromBitmap() { 468 throw new UnsupportedOperationException("Legacy ShadowBitmap APIs are not supported"); 469 } 470 471 /** 472 * Resource ID from which this Bitmap was created. 473 * 474 * @return Resource ID from which this Bitmap was created, or {@code 0} if this Bitmap was not 475 * created from a resource. 476 */ 477 @Override getCreatedFromResId()478 public int getCreatedFromResId() { 479 return createdFromResId; 480 } 481 482 @Override getCreatedFromPath()483 public String getCreatedFromPath() { 484 throw new UnsupportedOperationException("Legacy ShadowBitmap APIs are not supported"); 485 } 486 487 @Override getCreatedFromStream()488 public InputStream getCreatedFromStream() { 489 throw new UnsupportedOperationException("Legacy ShadowBitmap APIs are not supported"); 490 } 491 492 @Override getCreatedFromBytes()493 public byte[] getCreatedFromBytes() { 494 throw new UnsupportedOperationException("Legacy ShadowBitmap APIs are not supported"); 495 } 496 497 @Override getCreatedFromX()498 public int getCreatedFromX() { 499 throw new UnsupportedOperationException("Legacy ShadowBitmap APIs are not supported"); 500 } 501 502 @Override getCreatedFromY()503 public int getCreatedFromY() { 504 throw new UnsupportedOperationException("Legacy ShadowBitmap APIs are not supported"); 505 } 506 507 @Override getCreatedFromWidth()508 public int getCreatedFromWidth() { 509 throw new UnsupportedOperationException("Legacy ShadowBitmap APIs are not supported"); 510 } 511 512 @Override getCreatedFromHeight()513 public int getCreatedFromHeight() { 514 throw new UnsupportedOperationException("Legacy ShadowBitmap APIs are not supported"); 515 } 516 517 @Override getCreatedFromColors()518 public int[] getCreatedFromColors() { 519 throw new UnsupportedOperationException("Legacy ShadowBitmap APIs are not supported"); 520 } 521 522 @Override getCreatedFromMatrix()523 public Matrix getCreatedFromMatrix() { 524 throw new UnsupportedOperationException("Legacy ShadowBitmap APIs are not supported"); 525 } 526 527 @Override getCreatedFromFilter()528 public boolean getCreatedFromFilter() { 529 throw new UnsupportedOperationException("Legacy ShadowBitmap APIs are not supported"); 530 } 531 532 @Override setMutable(boolean mutable)533 public void setMutable(boolean mutable) { 534 throw new UnsupportedOperationException("Legacy ShadowBitmap APIs are not supported"); 535 } 536 537 @Override appendDescription(String s)538 public void appendDescription(String s) { 539 throw new UnsupportedOperationException("Legacy ShadowBitmap APIs are not supported"); 540 } 541 542 @Override getDescription()543 public String getDescription() { 544 throw new UnsupportedOperationException("Legacy ShadowBitmap APIs are not supported"); 545 } 546 547 @Override setDescription(String s)548 public void setDescription(String s) { 549 throw new UnsupportedOperationException("Legacy ShadowBitmap APIs are not supported"); 550 } 551 552 @Resetter reset()553 public static void reset() { 554 synchronized (colorSpaceAllocationsP) { 555 for (Long ptr : colorSpaceAllocationsP) { 556 NativeAllocationRegistryNatives.applyFreeFunction( 557 ColorSpaceRgbNatives.nativeGetNativeFinalizer(), ptr); 558 } 559 colorSpaceAllocationsP.clear(); 560 } 561 } 562 } 563