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