> copyHeaders() {
/**
* Ensures that the default header will pass OkHttp3's checks for header values.
*
- * See #2331.
+ * @see #2331
*/
@VisibleForTesting
static String getSanitizedUserAgent() {
diff --git a/library/src/main/java/com/bumptech/glide/load/model/MultiModelLoader.java b/library/src/main/java/com/bumptech/glide/load/model/MultiModelLoader.java
index 684dc76b00..443304fccb 100644
--- a/library/src/main/java/com/bumptech/glide/load/model/MultiModelLoader.java
+++ b/library/src/main/java/com/bumptech/glide/load/model/MultiModelLoader.java
@@ -68,8 +68,7 @@ public boolean handles(@NonNull Model model) {
@Override
public String toString() {
- return "MultiModelLoader{" + "modelLoaders=" + Arrays
- .toString(modelLoaders.toArray(new ModelLoader, ?>[modelLoaders.size()])) + '}';
+ return "MultiModelLoader{" + "modelLoaders=" + Arrays.toString(modelLoaders.toArray()) + '}';
}
static class MultiFetcher implements DataFetcher, DataCallback {
diff --git a/library/src/main/java/com/bumptech/glide/load/model/StringLoader.java b/library/src/main/java/com/bumptech/glide/load/model/StringLoader.java
index 9ce67c102d..16bb6cfde5 100644
--- a/library/src/main/java/com/bumptech/glide/load/model/StringLoader.java
+++ b/library/src/main/java/com/bumptech/glide/load/model/StringLoader.java
@@ -42,7 +42,8 @@ private static Uri parseUri(String model) {
Uri uri;
if (TextUtils.isEmpty(model)) {
return null;
- } else if (model.startsWith("/")) {
+ // See https://pmd.github.io/pmd-6.0.0/pmd_rules_java_performance.html#simplifystartswith
+ } else if (model.charAt(0) == '/') {
uri = toFileUri(model);
} else {
uri = Uri.parse(model);
diff --git a/library/src/main/java/com/bumptech/glide/load/model/UnitModelLoader.java b/library/src/main/java/com/bumptech/glide/load/model/UnitModelLoader.java
index 4ca9dd16a7..670e869869 100644
--- a/library/src/main/java/com/bumptech/glide/load/model/UnitModelLoader.java
+++ b/library/src/main/java/com/bumptech/glide/load/model/UnitModelLoader.java
@@ -25,6 +25,8 @@ public static UnitModelLoader getInstance() {
/**
* @deprecated Use {@link #getInstance()} instead.
*/
+ // Need constructor to document deprecation, will be removed, when constructor is privatized.
+ @SuppressWarnings({"PMD.UnnecessaryConstructor", "DeprecatedIsStillUsed"})
@Deprecated
public UnitModelLoader() {
// Intentionally empty.
@@ -84,7 +86,7 @@ public DataSource getDataSource() {
*
* @param The type of model that will also be returned as decodable data.
*/
- // PMD seems to be just wrong here, maybe confused by getInstance in UnitModelLoader.
+ // PMD.SingleMethodSingleton false positive: https://github.com/pmd/pmd/issues/816
@SuppressWarnings("PMD.SingleMethodSingleton")
public static class Factory implements ModelLoaderFactory {
@SuppressWarnings("deprecation")
@@ -96,6 +98,8 @@ public static Factory getInstance() {
}
/** @deprecated Use {@link #getInstance()} instead. */
+ // Need constructor to document deprecation, will be removed, when constructor is privatized.
+ @SuppressWarnings("PMD.UnnecessaryConstructor")
@Deprecated
public Factory() {
// Intentionally empty.
diff --git a/library/src/main/java/com/bumptech/glide/load/model/stream/BaseGlideUrlLoader.java b/library/src/main/java/com/bumptech/glide/load/model/stream/BaseGlideUrlLoader.java
index 68c606f00d..20c7657760 100644
--- a/library/src/main/java/com/bumptech/glide/load/model/stream/BaseGlideUrlLoader.java
+++ b/library/src/main/java/com/bumptech/glide/load/model/stream/BaseGlideUrlLoader.java
@@ -11,6 +11,7 @@
import com.bumptech.glide.load.model.ModelLoader;
import java.io.InputStream;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -69,7 +70,9 @@ public LoadData buildLoadData(@NonNull Model model, int width, int
}
}
- private static List getAlternateKeys(List alternateUrls) {
+ // Creating a limited number of objects as the sole purpose of the loop.
+ @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops")
+ private static List getAlternateKeys(Collection alternateUrls) {
List result = new ArrayList<>(alternateUrls.size());
for (String alternate : alternateUrls) {
result.add(new GlideUrl(alternate));
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/DefaultImageHeaderParser.java b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/DefaultImageHeaderParser.java
index 6a64cf121b..a2252613bc 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/DefaultImageHeaderParser.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/DefaultImageHeaderParser.java
@@ -79,7 +79,7 @@ public int getOrientation(ByteBuffer byteBuffer, ArrayPool byteArrayPool) throws
}
private ImageType getType(Reader reader) throws IOException {
- int firstTwoBytes = reader.getUInt16();
+ final int firstTwoBytes = reader.getUInt16();
// JPEG.
if (firstTwoBytes == EXIF_MAGIC_NUMBER) {
@@ -208,10 +208,8 @@ private boolean hasJpegExifPreamble(byte[] exifData, int exifSegmentLength) {
* {@code -1} if no exif segment is found.
*/
private int moveToExifSegmentAndGetLength(Reader reader) throws IOException {
- short segmentId, segmentType;
- int segmentLength;
while (true) {
- segmentId = reader.getUInt8();
+ short segmentId = reader.getUInt8();
if (segmentId != SEGMENT_START_ID) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "Unknown segmentId=" + segmentId);
@@ -219,8 +217,7 @@ private int moveToExifSegmentAndGetLength(Reader reader) throws IOException {
return -1;
}
- segmentType = reader.getUInt8();
-
+ short segmentType = reader.getUInt8();
if (segmentType == SEGMENT_SOS) {
return -1;
} else if (segmentType == MARKER_EOI) {
@@ -231,8 +228,7 @@ private int moveToExifSegmentAndGetLength(Reader reader) throws IOException {
}
// Segment length includes bytes for segment length.
- segmentLength = reader.getUInt16() - 2;
-
+ int segmentLength = reader.getUInt16() - 2;
if (segmentType != EXIF_SEGMENT_TYPE) {
long skipped = reader.skip(segmentLength);
if (skipped != segmentLength) {
@@ -274,19 +270,16 @@ private static int parseExifSegment(RandomAccessReader segmentData) {
int firstIfdOffset = segmentData.getInt32(headerOffsetSize + 4) + headerOffsetSize;
int tagCount = segmentData.getInt16(firstIfdOffset);
-
- int tagOffset, tagType, formatCode, componentCount;
for (int i = 0; i < tagCount; i++) {
- tagOffset = calcTagOffset(firstIfdOffset, i);
- tagType = segmentData.getInt16(tagOffset);
+ final int tagOffset = calcTagOffset(firstIfdOffset, i);
+ final int tagType = segmentData.getInt16(tagOffset);
// We only want orientation.
if (tagType != ORIENTATION_TAG_TYPE) {
continue;
}
- formatCode = segmentData.getInt16(tagOffset + 2);
-
+ final int formatCode = segmentData.getInt16(tagOffset + 2);
// 12 is max format code.
if (formatCode < 1 || formatCode > 12) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
@@ -295,8 +288,7 @@ private static int parseExifSegment(RandomAccessReader segmentData) {
continue;
}
- componentCount = segmentData.getInt32(tagOffset + 4);
-
+ final int componentCount = segmentData.getInt32(tagOffset + 4);
if (componentCount < 0) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "Negative tiff component count");
@@ -310,7 +302,6 @@ private static int parseExifSegment(RandomAccessReader segmentData) {
}
final int byteCount = componentCount + BYTES_PER_FORMAT[formatCode];
-
if (byteCount > 4) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "Got byte count > 4, not orientation, continuing, formatCode=" + formatCode);
@@ -319,7 +310,6 @@ private static int parseExifSegment(RandomAccessReader segmentData) {
}
final int tagValueOffset = tagOffset + 8;
-
if (tagValueOffset < 0 || tagValueOffset > segmentData.length()) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "Illegal tagValueOffset=" + tagValueOffset + " tagType=" + tagType);
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/DrawableTransformation.java b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/DrawableTransformation.java
index 9275e34297..dee51f7a2f 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/DrawableTransformation.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/DrawableTransformation.java
@@ -69,6 +69,7 @@ public Resource transform(@NonNull Context context,
}
}
+ // It's clearer to cast the result in a separate line from obtaining it.
@SuppressWarnings({"unchecked", "PMD.UnnecessaryLocalBeforeReturn"})
private Resource newDrawableResource(
Context context, Resource transformed) {
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/RecyclableBufferedInputStream.java b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/RecyclableBufferedInputStream.java
index 0a041908d6..aa21f9ce9b 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/RecyclableBufferedInputStream.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/RecyclableBufferedInputStream.java
@@ -368,15 +368,15 @@ public synchronized void reset() throws IOException {
*/
@Override
public synchronized long skip(long byteCount) throws IOException {
+ if (byteCount < 1) {
+ return 0;
+ }
// Use local refs since buf and in may be invalidated by an unsynchronized close()
byte[] localBuf = buf;
- InputStream localIn = in;
if (localBuf == null) {
throw streamClosed();
}
- if (byteCount < 1) {
- return 0;
- }
+ InputStream localIn = in;
if (localIn == null) {
throw streamClosed();
}
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/TransformationUtils.java b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/TransformationUtils.java
index 16e61a0d62..8978e818ce 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/TransformationUtils.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/TransformationUtils.java
@@ -121,13 +121,16 @@ public static Bitmap centerCrop(@NonNull BitmapPool pool, @NonNull Bitmap inBitm
}
// From ImageView/Bitmap.createScaledBitmap.
final float scale;
- float dx = 0, dy = 0;
+ final float dx;
+ final float dy;
Matrix m = new Matrix();
if (inBitmap.getWidth() * height > width * inBitmap.getHeight()) {
scale = (float) height / (float) inBitmap.getHeight();
dx = (width - inBitmap.getWidth() * scale) * 0.5f;
+ dy = 0;
} else {
scale = (float) width / (float) inBitmap.getWidth();
+ dx = 0;
dy = (height - inBitmap.getHeight() * scale) * 0.5f;
}
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/bytes/BytesResource.java b/library/src/main/java/com/bumptech/glide/load/resource/bytes/BytesResource.java
index 6b8fde35e4..88068855d0 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/bytes/BytesResource.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/bytes/BytesResource.java
@@ -20,8 +20,18 @@ public Class getResourceClass() {
return byte[].class;
}
+ /**
+ * In most cases it will only be retrieved once (see linked methods).
+ *
+ * @return the same array every time, do not mutate the contents. Not a copy returned, because
+ * copying the array can be prohibitively expensive and/or lead to OOMs.
+ * @see com.bumptech.glide.load.ResourceEncoder
+ * @see com.bumptech.glide.load.resource.transcode.ResourceTranscoder
+ * @see com.bumptech.glide.request.SingleRequest#onResourceReady
+ */
@NonNull
@Override
+ @SuppressWarnings("PMD.MethodReturnsInternalArray")
public byte[] get() {
return bytes;
}
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/gif/ByteBufferGifDecoder.java b/library/src/main/java/com/bumptech/glide/load/resource/gif/ByteBufferGifDecoder.java
index 6781b922ad..dbab1827cf 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/gif/ByteBufferGifDecoder.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/gif/ByteBufferGifDecoder.java
@@ -92,34 +92,36 @@ public GifDrawableResource decode(@NonNull ByteBuffer source, int width, int hei
private GifDrawableResource decode(
ByteBuffer byteBuffer, int width, int height, GifHeaderParser parser, Options options) {
long startTime = LogTime.getLogTime();
- final GifHeader header = parser.parseHeader();
- if (header.getNumFrames() <= 0 || header.getStatus() != GifDecoder.STATUS_OK) {
- // If we couldn't decode the GIF, we will end up with a frame count of 0.
- return null;
- }
+ try {
+ final GifHeader header = parser.parseHeader();
+ if (header.getNumFrames() <= 0 || header.getStatus() != GifDecoder.STATUS_OK) {
+ // If we couldn't decode the GIF, we will end up with a frame count of 0.
+ return null;
+ }
- Bitmap.Config config = options.get(GifOptions.DECODE_FORMAT) == DecodeFormat.PREFER_RGB_565
- ? Bitmap.Config.RGB_565 : Bitmap.Config.ARGB_8888;
+ Bitmap.Config config = options.get(GifOptions.DECODE_FORMAT) == DecodeFormat.PREFER_RGB_565
+ ? Bitmap.Config.RGB_565 : Bitmap.Config.ARGB_8888;
- int sampleSize = getSampleSize(header, width, height);
- GifDecoder gifDecoder = gifDecoderFactory.build(provider, header, byteBuffer, sampleSize);
- gifDecoder.setDefaultBitmapConfig(config);
- gifDecoder.advance();
- Bitmap firstFrame = gifDecoder.getNextFrame();
- if (firstFrame == null) {
- return null;
- }
+ int sampleSize = getSampleSize(header, width, height);
+ GifDecoder gifDecoder = gifDecoderFactory.build(provider, header, byteBuffer, sampleSize);
+ gifDecoder.setDefaultBitmapConfig(config);
+ gifDecoder.advance();
+ Bitmap firstFrame = gifDecoder.getNextFrame();
+ if (firstFrame == null) {
+ return null;
+ }
- Transformation unitTransformation = UnitTransformation.get();
+ Transformation unitTransformation = UnitTransformation.get();
- GifDrawable gifDrawable =
- new GifDrawable(context, gifDecoder, unitTransformation, width, height, firstFrame);
+ GifDrawable gifDrawable =
+ new GifDrawable(context, gifDecoder, unitTransformation, width, height, firstFrame);
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "Decoded GIF from stream in " + LogTime.getElapsedMillis(startTime));
+ return new GifDrawableResource(gifDrawable);
+ } finally {
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "Decoded GIF from stream in " + LogTime.getElapsedMillis(startTime));
+ }
}
-
- return new GifDrawableResource(gifDrawable);
}
private static int getSampleSize(GifHeader gifHeader, int targetWidth, int targetHeight) {
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/gif/GifFrameLoader.java b/library/src/main/java/com/bumptech/glide/load/resource/gif/GifFrameLoader.java
index bee286b776..c46775bd2b 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/gif/GifFrameLoader.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/gif/GifFrameLoader.java
@@ -37,9 +37,9 @@ class GifFrameLoader {
@SuppressWarnings("WeakerAccess") @Synthetic final RequestManager requestManager;
private final BitmapPool bitmapPool;
- private boolean isRunning = false;
- private boolean isLoadPending = false;
- private boolean startFromFirstFrame = false;
+ private boolean isRunning;
+ private boolean isLoadPending;
+ private boolean startFromFirstFrame;
private RequestBuilder requestBuilder;
private DelayTarget current;
private boolean isCleared;
@@ -111,10 +111,10 @@ void subscribe(FrameCallback frameCallback) {
if (isCleared) {
throw new IllegalStateException("Cannot subscribe to a cleared frame loader");
}
- boolean start = callbacks.isEmpty();
if (callbacks.contains(frameCallback)) {
throw new IllegalStateException("Cannot subscribe twice in a row");
}
+ boolean start = callbacks.isEmpty();
callbacks.add(frameCallback);
if (start) {
start();
diff --git a/library/src/main/java/com/bumptech/glide/request/RequestOptions.java b/library/src/main/java/com/bumptech/glide/request/RequestOptions.java
index 9bf9b5205a..3dc929ef2b 100644
--- a/library/src/main/java/com/bumptech/glide/request/RequestOptions.java
+++ b/library/src/main/java/com/bumptech/glide/request/RequestOptions.java
@@ -810,7 +810,11 @@ public RequestOptions signature(@NonNull Key signature) {
* Even if this object was locked, the cloned object returned from this method will not be
* locked.
*/
- @SuppressWarnings("unchecked")
+ @SuppressWarnings({
+ "unchecked",
+ // we don't want to throw to be user friendly
+ "PMD.CloneThrowsCloneNotSupportedException"
+ })
@CheckResult
@Override
public RequestOptions clone() {
@@ -1647,14 +1651,20 @@ private boolean isSet(int flag) {
return isSet(fields, flag);
}
+ // get is just as clear.
+ @SuppressWarnings("PMD.BooleanGetMethodName")
public final boolean getUseUnlimitedSourceGeneratorsPool() {
return useUnlimitedSourceGeneratorsPool;
}
+ // get is just as clear.
+ @SuppressWarnings("PMD.BooleanGetMethodName")
public final boolean getUseAnimationPool() {
return useAnimationPool;
}
+ // get is just as clear.
+ @SuppressWarnings("PMD.BooleanGetMethodName")
public final boolean getOnlyRetrieveFromCache() {
return onlyRetrieveFromCache;
}
diff --git a/library/src/main/java/com/bumptech/glide/request/target/ViewTarget.java b/library/src/main/java/com/bumptech/glide/request/target/ViewTarget.java
index be500d87ca..635b6b5d08 100644
--- a/library/src/main/java/com/bumptech/glide/request/target/ViewTarget.java
+++ b/library/src/main/java/com/bumptech/glide/request/target/ViewTarget.java
@@ -43,8 +43,8 @@
*/
public abstract class ViewTarget extends BaseTarget {
private static final String TAG = "ViewTarget";
- private static boolean isTagUsedAtLeastOnce = false;
- @Nullable private static Integer tagId = null;
+ private static boolean isTagUsedAtLeastOnce;
+ @Nullable private static Integer tagId;
protected final T view;
private final SizeDeterminer sizeDeterminer;
@@ -74,8 +74,7 @@ public ViewTarget(@NonNull T view) {
*
* @deprecated Use {@link #waitForLayout()} instead.
*/
- // Public API.
- @SuppressWarnings("WeakerAccess")
+ @SuppressWarnings("WeakerAccess") // Public API
@Deprecated
public ViewTarget(@NonNull T view, boolean waitForLayout) {
this(view);
@@ -161,7 +160,7 @@ public void onViewDetachedFromWindow(View v) {
* still be used instead of the {@link View}'s dimensions even if this method is called. This
* parameter is a fallback only.
*/
- @SuppressWarnings("WeakerAccess")
+ @SuppressWarnings("WeakerAccess") // Public API
@NonNull
public final ViewTarget waitForLayout() {
sizeDeterminer.waitForLayout = true;
diff --git a/library/src/main/java/com/bumptech/glide/signature/ApplicationVersionSignature.java b/library/src/main/java/com/bumptech/glide/signature/ApplicationVersionSignature.java
index 2bcd360c06..21d86931d9 100644
--- a/library/src/main/java/com/bumptech/glide/signature/ApplicationVersionSignature.java
+++ b/library/src/main/java/com/bumptech/glide/signature/ApplicationVersionSignature.java
@@ -4,18 +4,21 @@
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
+import android.util.Log;
import com.bumptech.glide.load.Key;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
/**
* A utility class for obtaining a {@link com.bumptech.glide.load.Key} signature containing the
* application version name using {@link android.content.pm.PackageInfo#versionCode}.
*/
public final class ApplicationVersionSignature {
- private static final ConcurrentHashMap PACKAGE_NAME_TO_KEY =
- new ConcurrentHashMap<>();
+ private static final String TAG = "AppVersionSignature";
+ private static final ConcurrentMap PACKAGE_NAME_TO_KEY = new ConcurrentHashMap<>();
/**
* Returns the signature {@link com.bumptech.glide.load.Key} for version code of the Application
@@ -44,20 +47,30 @@ static void reset() {
@NonNull
private static Key obtainVersionSignature(@NonNull Context context) {
- PackageInfo pInfo = null;
- try {
- pInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
- } catch (PackageManager.NameNotFoundException e) {
- // Should never happen.
- e.printStackTrace();
- }
- final String versionCode;
- if (pInfo != null) {
- versionCode = String.valueOf(pInfo.versionCode);
+ PackageInfo packageInfo = getPackageInfo(context);
+ String versionCode = getVersionCode(packageInfo);
+ return new ObjectKey(versionCode);
+ }
+
+ @NonNull
+ private static String getVersionCode(@Nullable PackageInfo packageInfo) {
+ String versionCode;
+ if (packageInfo != null) {
+ versionCode = String.valueOf(packageInfo.versionCode);
} else {
versionCode = UUID.randomUUID().toString();
}
- return new ObjectKey(versionCode);
+ return versionCode;
+ }
+
+ @Nullable
+ private static PackageInfo getPackageInfo(@NonNull Context context) {
+ try {
+ return context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.e(TAG, "Cannot resolve info for" + context.getPackageName(), e);
+ return null;
+ }
}
private ApplicationVersionSignature() {
diff --git a/library/src/main/java/com/bumptech/glide/util/ByteBufferUtil.java b/library/src/main/java/com/bumptech/glide/util/ByteBufferUtil.java
index e1b73aa342..8f0bee837b 100644
--- a/library/src/main/java/com/bumptech/glide/util/ByteBufferUtil.java
+++ b/library/src/main/java/com/bumptech/glide/util/ByteBufferUtil.java
@@ -15,8 +15,7 @@
/**
* Utilities for interacting with {@link java.nio.ByteBuffer}s.
*/
-// Public API.
-@SuppressWarnings({"unused", "WeakerAccess"})
+@SuppressWarnings({"unused", "WeakerAccess"}) // Public API
public final class ByteBufferUtil {
// 16 Kb
private static final int BUFFER_SIZE = 16384;
@@ -167,6 +166,8 @@ static final class SafeArray {
@Synthetic final int limit;
@Synthetic final byte[] data;
+ // PMD.ArrayIsStoredDirectly Copying would be prohibitively expensive and/or lead to OOMs.
+ @SuppressWarnings("PMD.ArrayIsStoredDirectly")
SafeArray(@NonNull byte[] data, int offset, int limit) {
this.data = data;
this.offset = offset;
@@ -207,7 +208,7 @@ public boolean markSupported() {
}
@Override
- public int read(byte[] buffer, int byteOffset, int byteCount) throws IOException {
+ public int read(@NonNull byte[] buffer, int byteOffset, int byteCount) throws IOException {
if (!byteBuffer.hasRemaining()) {
return -1;
}
diff --git a/library/src/main/java/com/bumptech/glide/util/FixedPreloadSizeProvider.java b/library/src/main/java/com/bumptech/glide/util/FixedPreloadSizeProvider.java
index 92daaf11ba..08b7ed3ba5 100644
--- a/library/src/main/java/com/bumptech/glide/util/FixedPreloadSizeProvider.java
+++ b/library/src/main/java/com/bumptech/glide/util/FixedPreloadSizeProvider.java
@@ -25,6 +25,9 @@ public FixedPreloadSizeProvider(int width, int height) {
@Nullable
@Override
+ // It's better to take on the risk that callers may mutate the array when there isn't any reason
+ // for them to do so than it the performance overhead of copying the array with every call.
+ @SuppressWarnings("PMD.MethodReturnsInternalArray")
public int[] getPreloadSize(@NonNull T item, int adapterPosition, int itemPosition) {
return size;
}
diff --git a/library/src/main/java/com/bumptech/glide/util/LruCache.java b/library/src/main/java/com/bumptech/glide/util/LruCache.java
index 5f7402aea2..a2cd7d8223 100644
--- a/library/src/main/java/com/bumptech/glide/util/LruCache.java
+++ b/library/src/main/java/com/bumptech/glide/util/LruCache.java
@@ -15,10 +15,10 @@
* @param The type of the values.
*/
public class LruCache {
- private final LinkedHashMap cache = new LinkedHashMap<>(100, 0.75f, true);
+ private final Map cache = new LinkedHashMap<>(100, 0.75f, true);
private final long initialMaxSize;
private long maxSize;
- private long currentSize = 0;
+ private long currentSize;
/**
* Constructor for LruCache.
diff --git a/library/src/main/java/com/bumptech/glide/util/Util.java b/library/src/main/java/com/bumptech/glide/util/Util.java
index 7e294e2c79..b5cae5cbad 100644
--- a/library/src/main/java/com/bumptech/glide/util/Util.java
+++ b/library/src/main/java/com/bumptech/glide/util/Util.java
@@ -81,7 +81,7 @@ public static int getBitmapByteSize(@NonNull Bitmap bitmap) {
// Workaround for KitKat initial release NPE in Bitmap, fixed in MR1. See issue #148.
try {
return bitmap.getAllocationByteCount();
- } catch (NullPointerException e) {
+ } catch (@SuppressWarnings("PMD.AvoidCatchingNPE") NullPointerException e) {
// Do nothing.
}
}
diff --git a/library/src/test/java/com/bumptech/glide/signature/ApplicationVersionSignatureTest.java b/library/src/test/java/com/bumptech/glide/signature/ApplicationVersionSignatureTest.java
index 2757c0873d..0d2c90bb85 100644
--- a/library/src/test/java/com/bumptech/glide/signature/ApplicationVersionSignatureTest.java
+++ b/library/src/test/java/com/bumptech/glide/signature/ApplicationVersionSignatureTest.java
@@ -1,8 +1,11 @@
package com.bumptech.glide.signature;
import static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
import android.content.Context;
+import android.content.pm.PackageManager.NameNotFoundException;
import com.bumptech.glide.load.Key;
import com.bumptech.glide.tests.KeyTester;
import java.io.UnsupportedEncodingException;
@@ -12,6 +15,7 @@
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Answers;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
@@ -51,4 +55,29 @@ public void testKeyForSignatureIsTheSameAcrossCallsInTheSamePackage()
"5feceb66ffc86f38d952786c6d696c79c2dbc239dd4e91b46729d73a27fb57e9")
.test();
}
+
+ @Test
+ public void testUnresolvablePackageInfo() throws NameNotFoundException {
+ Context context = mock(Context.class, Answers.RETURNS_DEEP_STUBS.get());
+ String packageName = "my.package";
+ when(context.getPackageName()).thenReturn(packageName);
+ when(context.getPackageManager().getPackageInfo(packageName, 0))
+ .thenThrow(new NameNotFoundException("test"));
+
+ Key key = ApplicationVersionSignature.obtain(context);
+
+ assertNotNull(key);
+ }
+
+ @Test
+ public void testMissingPackageInfo() throws NameNotFoundException {
+ Context context = mock(Context.class, Answers.RETURNS_DEEP_STUBS.get());
+ String packageName = "my.package";
+ when(context.getPackageName()).thenReturn(packageName);
+ when(context.getPackageManager().getPackageInfo(packageName, 0)).thenReturn(null);
+
+ Key key = ApplicationVersionSignature.obtain(context);
+
+ assertNotNull(key);
+ }
}