Prohibit Config.HARDWARE in factory methods, that create mutable bitmaps
Test: android.cts.graphics.BitmapTest#testCreateMutableBitmapWithHardwareConfig bug:30999911 Change-Id: I7cd4e2625563b6659613ccd180a57c56dcf7c2b1
This commit is contained in:
@@ -11779,6 +11779,7 @@ package android.graphics {
|
||||
enum_constant public static final android.graphics.Bitmap.Config ALPHA_8;
|
||||
enum_constant public static final deprecated android.graphics.Bitmap.Config ARGB_4444;
|
||||
enum_constant public static final android.graphics.Bitmap.Config ARGB_8888;
|
||||
enum_constant public static final android.graphics.Bitmap.Config HARDWARE;
|
||||
enum_constant public static final android.graphics.Bitmap.Config RGB_565;
|
||||
}
|
||||
|
||||
|
||||
@@ -12265,6 +12265,7 @@ package android.graphics {
|
||||
enum_constant public static final android.graphics.Bitmap.Config ALPHA_8;
|
||||
enum_constant public static final deprecated android.graphics.Bitmap.Config ARGB_4444;
|
||||
enum_constant public static final android.graphics.Bitmap.Config ARGB_8888;
|
||||
enum_constant public static final android.graphics.Bitmap.Config HARDWARE;
|
||||
enum_constant public static final android.graphics.Bitmap.Config RGB_565;
|
||||
}
|
||||
|
||||
|
||||
@@ -11810,6 +11810,7 @@ package android.graphics {
|
||||
enum_constant public static final android.graphics.Bitmap.Config ALPHA_8;
|
||||
enum_constant public static final deprecated android.graphics.Bitmap.Config ARGB_4444;
|
||||
enum_constant public static final android.graphics.Bitmap.Config ARGB_8888;
|
||||
enum_constant public static final android.graphics.Bitmap.Config HARDWARE;
|
||||
enum_constant public static final android.graphics.Bitmap.Config RGB_565;
|
||||
}
|
||||
|
||||
|
||||
@@ -276,6 +276,11 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding
|
||||
}
|
||||
}
|
||||
|
||||
if (isMutable && isHardware) {
|
||||
doThrowIAE(env, "Bitmaps with Config.HARWARE are always immutable");
|
||||
return nullObjectReturn("Cannot create mutable hardware bitmap");
|
||||
}
|
||||
|
||||
// Create the codec.
|
||||
NinePatchPeeker peeker;
|
||||
std::unique_ptr<SkAndroidCodec> codec(SkAndroidCodec::NewFromStream(streamDeleter.release(),
|
||||
|
||||
@@ -467,7 +467,11 @@ public final class Bitmap implements Parcelable {
|
||||
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* Special configuration, when bitmap is stored only in graphic memory.
|
||||
* Bitmaps in this configuration are always immutable.
|
||||
*
|
||||
* It is optimal for cases, when the only operation with the bitmap is to draw it on a
|
||||
* screen.
|
||||
*/
|
||||
HARDWARE (6);
|
||||
|
||||
@@ -810,7 +814,8 @@ public final class Bitmap implements Parcelable {
|
||||
* @param width The width of the bitmap
|
||||
* @param height The height of the bitmap
|
||||
* @param config The bitmap config to create.
|
||||
* @throws IllegalArgumentException if the width or height are <= 0
|
||||
* @throws IllegalArgumentException if the width or height are <= 0, or if
|
||||
* Config is Config.HARDWARE, because hardware bitmaps are always immutable
|
||||
*/
|
||||
public static Bitmap createBitmap(int width, int height, Config config) {
|
||||
return createBitmap(width, height, config, true);
|
||||
@@ -825,7 +830,8 @@ public final class Bitmap implements Parcelable {
|
||||
* @param width The width of the bitmap
|
||||
* @param height The height of the bitmap
|
||||
* @param config The bitmap config to create.
|
||||
* @throws IllegalArgumentException if the width or height are <= 0
|
||||
* @throws IllegalArgumentException if the width or height are <= 0, or if
|
||||
* Config is Config.HARDWARE, because hardware bitmaps are always immutable
|
||||
*/
|
||||
public static Bitmap createBitmap(DisplayMetrics display, int width,
|
||||
int height, Config config) {
|
||||
@@ -843,7 +849,8 @@ public final class Bitmap implements Parcelable {
|
||||
* bitmap as opaque. Doing so will clear the bitmap in black
|
||||
* instead of transparent.
|
||||
*
|
||||
* @throws IllegalArgumentException if the width or height are <= 0
|
||||
* @throws IllegalArgumentException if the width or height are <= 0, or if
|
||||
* Config is Config.HARDWARE, because hardware bitmaps are always immutable
|
||||
*/
|
||||
private static Bitmap createBitmap(int width, int height, Config config, boolean hasAlpha) {
|
||||
return createBitmap(null, width, height, config, hasAlpha);
|
||||
@@ -862,13 +869,17 @@ public final class Bitmap implements Parcelable {
|
||||
* bitmap as opaque. Doing so will clear the bitmap in black
|
||||
* instead of transparent.
|
||||
*
|
||||
* @throws IllegalArgumentException if the width or height are <= 0
|
||||
* @throws IllegalArgumentException if the width or height are <= 0, or if
|
||||
* Config is Config.HARDWARE, because hardware bitmaps are always immutable
|
||||
*/
|
||||
private static Bitmap createBitmap(DisplayMetrics display, int width, int height,
|
||||
Config config, boolean hasAlpha) {
|
||||
if (width <= 0 || height <= 0) {
|
||||
throw new IllegalArgumentException("width and height must be > 0");
|
||||
}
|
||||
if (config == Config.HARDWARE) {
|
||||
throw new IllegalArgumentException("can't create mutable bitmap with Config.HARDWARE");
|
||||
}
|
||||
Bitmap bm = nativeCreate(null, 0, width, width, height, config.nativeInt, true);
|
||||
if (display != null) {
|
||||
bm.mDensity = display.densityDpi;
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package android.graphics;
|
||||
|
||||
import static android.graphics.BitmapFactory.Options.validate;
|
||||
|
||||
import android.content.res.AssetManager;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Trace;
|
||||
@@ -103,6 +105,9 @@ public class BitmapFactory {
|
||||
* If set, decode methods will always return a mutable Bitmap instead of
|
||||
* an immutable one. This can be used for instance to programmatically apply
|
||||
* effects to a Bitmap loaded through BitmapFactory.
|
||||
* <p>Can not be set simultaneously with inPreferredConfig =
|
||||
* {@link android.graphics.Bitmap.Config#HARDWARE},
|
||||
* because hardware bitmaps are always immutable.
|
||||
*/
|
||||
@SuppressWarnings({"UnusedDeclaration"}) // used in native code
|
||||
public boolean inMutable;
|
||||
@@ -381,6 +386,12 @@ public class BitmapFactory {
|
||||
public void requestCancelDecode() {
|
||||
mCancel = true;
|
||||
}
|
||||
|
||||
static void validate(Options opts) {
|
||||
if (opts != null && opts.inMutable && opts.inPreferredConfig == Bitmap.Config.HARDWARE) {
|
||||
throw new IllegalArgumentException("Bitmaps with Config.HARWARE are always immutable");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -393,8 +404,12 @@ public class BitmapFactory {
|
||||
* @return The decoded bitmap, or null if the image data could not be
|
||||
* decoded, or, if opts is non-null, if opts requested only the
|
||||
* size be returned (in opts.outWidth and opts.outHeight)
|
||||
* @throws IllegalArgumentException if {@link BitmapFactory.Options#inPreferredConfig}
|
||||
* is {@link android.graphics.Bitmap.Config#HARDWARE}
|
||||
* and {@link BitmapFactory.Options#inMutable} is set.
|
||||
*/
|
||||
public static Bitmap decodeFile(String pathName, Options opts) {
|
||||
validate(opts);
|
||||
Bitmap bm = null;
|
||||
InputStream stream = null;
|
||||
try {
|
||||
@@ -431,10 +446,13 @@ public class BitmapFactory {
|
||||
/**
|
||||
* Decode a new Bitmap from an InputStream. This InputStream was obtained from
|
||||
* resources, which we pass to be able to scale the bitmap accordingly.
|
||||
* @throws IllegalArgumentException if {@link BitmapFactory.Options#inPreferredConfig}
|
||||
* is {@link android.graphics.Bitmap.Config#HARDWARE}
|
||||
* and {@link BitmapFactory.Options#inMutable} is set.
|
||||
*/
|
||||
public static Bitmap decodeResourceStream(Resources res, TypedValue value,
|
||||
InputStream is, Rect pad, Options opts) {
|
||||
|
||||
validate(opts);
|
||||
if (opts == null) {
|
||||
opts = new Options();
|
||||
}
|
||||
@@ -466,8 +484,12 @@ public class BitmapFactory {
|
||||
* @return The decoded bitmap, or null if the image data could not be
|
||||
* decoded, or, if opts is non-null, if opts requested only the
|
||||
* size be returned (in opts.outWidth and opts.outHeight)
|
||||
* @throws IllegalArgumentException if {@link BitmapFactory.Options#inPreferredConfig}
|
||||
* is {@link android.graphics.Bitmap.Config#HARDWARE}
|
||||
* and {@link BitmapFactory.Options#inMutable} is set.
|
||||
*/
|
||||
public static Bitmap decodeResource(Resources res, int id, Options opts) {
|
||||
validate(opts);
|
||||
Bitmap bm = null;
|
||||
InputStream is = null;
|
||||
|
||||
@@ -520,11 +542,15 @@ public class BitmapFactory {
|
||||
* @return The decoded bitmap, or null if the image data could not be
|
||||
* decoded, or, if opts is non-null, if opts requested only the
|
||||
* size be returned (in opts.outWidth and opts.outHeight)
|
||||
* @throws IllegalArgumentException if {@link BitmapFactory.Options#inPreferredConfig}
|
||||
* is {@link android.graphics.Bitmap.Config#HARDWARE}
|
||||
* and {@link BitmapFactory.Options#inMutable} is set.
|
||||
*/
|
||||
public static Bitmap decodeByteArray(byte[] data, int offset, int length, Options opts) {
|
||||
if ((offset | length) < 0 || data.length < offset + length) {
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
validate(opts);
|
||||
|
||||
Bitmap bm;
|
||||
|
||||
@@ -598,6 +624,9 @@ public class BitmapFactory {
|
||||
* @return The decoded bitmap, or null if the image data could not be
|
||||
* decoded, or, if opts is non-null, if opts requested only the
|
||||
* size be returned (in opts.outWidth and opts.outHeight)
|
||||
* @throws IllegalArgumentException if {@link BitmapFactory.Options#inPreferredConfig}
|
||||
* is {@link android.graphics.Bitmap.Config#HARDWARE}
|
||||
* and {@link BitmapFactory.Options#inMutable} is set.
|
||||
*
|
||||
* <p class="note">Prior to {@link android.os.Build.VERSION_CODES#KITKAT},
|
||||
* if {@link InputStream#markSupported is.markSupported()} returns true,
|
||||
@@ -610,6 +639,7 @@ public class BitmapFactory {
|
||||
if (is == null) {
|
||||
return null;
|
||||
}
|
||||
validate(opts);
|
||||
|
||||
Bitmap bm = null;
|
||||
|
||||
@@ -673,8 +703,12 @@ public class BitmapFactory {
|
||||
* @param opts null-ok; Options that control downsampling and whether the
|
||||
* image should be completely decoded, or just its size returned.
|
||||
* @return the decoded bitmap, or null
|
||||
* @throws IllegalArgumentException if {@link BitmapFactory.Options#inPreferredConfig}
|
||||
* is {@link android.graphics.Bitmap.Config#HARDWARE}
|
||||
* and {@link BitmapFactory.Options#inMutable} is set.
|
||||
*/
|
||||
public static Bitmap decodeFileDescriptor(FileDescriptor fd, Rect outPadding, Options opts) {
|
||||
validate(opts);
|
||||
Bitmap bm;
|
||||
|
||||
Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, "decodeFileDescriptor");
|
||||
|
||||
@@ -178,8 +178,12 @@ public final class BitmapRegionDecoder {
|
||||
* inPurgeable is not supported.
|
||||
* @return The decoded bitmap, or null if the image data could not be
|
||||
* decoded.
|
||||
* @throws IllegalArgumentException if {@link BitmapFactory.Options#inPreferredConfig}
|
||||
* is {@link android.graphics.Bitmap.Config#HARDWARE}
|
||||
* and {@link BitmapFactory.Options#inMutable} is set.
|
||||
*/
|
||||
public Bitmap decodeRegion(Rect rect, BitmapFactory.Options options) {
|
||||
BitmapFactory.Options.validate(options);
|
||||
synchronized (mNativeLock) {
|
||||
checkRecycled("decodeRegion called on recycled region decoder");
|
||||
if (rect.right <= 0 || rect.bottom <= 0 || rect.left >= getWidth()
|
||||
|
||||
Reference in New Issue
Block a user