diff --git a/build.gradle b/build.gradle index a9aef10c..f455de40 100644 --- a/build.gradle +++ b/build.gradle @@ -23,6 +23,10 @@ buildscript { } } +plugins { + id "net.ltgt.errorprone" version "0.0.13" +} + apply plugin: 'com.android.library' repositories { diff --git a/rules.gradle b/rules.gradle index 21df8985..d131f873 100644 --- a/rules.gradle +++ b/rules.gradle @@ -15,6 +15,10 @@ android { } } +tasks.withType(JavaCompile) { + options.compilerArgs << "-Werror" +} + // Check if the android plugin version supports unit testing. if (configurations.findByName("testCompile")) { dependencies { diff --git a/src/main/java/com/android/volley/DefaultRetryPolicy.java b/src/main/java/com/android/volley/DefaultRetryPolicy.java index d8abab06..cf57edc7 100644 --- a/src/main/java/com/android/volley/DefaultRetryPolicy.java +++ b/src/main/java/com/android/volley/DefaultRetryPolicy.java @@ -90,7 +90,7 @@ public float getBackoffMultiplier() { @Override public void retry(VolleyError error) throws VolleyError { mCurrentRetryCount++; - mCurrentTimeoutMs += (mCurrentTimeoutMs * mBackoffMultiplier); + mCurrentTimeoutMs += (int) (mCurrentTimeoutMs * mBackoffMultiplier); if (!hasAttemptRemaining()) { throw error; } diff --git a/src/main/java/com/android/volley/ExecutorDelivery.java b/src/main/java/com/android/volley/ExecutorDelivery.java index f36fb759..e692f518 100644 --- a/src/main/java/com/android/volley/ExecutorDelivery.java +++ b/src/main/java/com/android/volley/ExecutorDelivery.java @@ -74,7 +74,7 @@ public void postError(Request request, VolleyError error) { * main thread. */ @SuppressWarnings("rawtypes") - private class ResponseDeliveryRunnable implements Runnable { + private static class ResponseDeliveryRunnable implements Runnable { private final Request mRequest; private final Response mResponse; private final Runnable mRunnable; diff --git a/src/main/java/com/android/volley/toolbox/ByteArrayPool.java b/src/main/java/com/android/volley/toolbox/ByteArrayPool.java index c8ca2c21..770e90ff 100644 --- a/src/main/java/com/android/volley/toolbox/ByteArrayPool.java +++ b/src/main/java/com/android/volley/toolbox/ByteArrayPool.java @@ -19,7 +19,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; -import java.util.LinkedList; import java.util.List; /** @@ -53,7 +52,7 @@ */ public class ByteArrayPool { /** The buffer pool, arranged both by last use and by buffer size */ - private final List mBuffersByLastUse = new LinkedList(); + private final List mBuffersByLastUse = new ArrayList<>(); private final List mBuffersBySize = new ArrayList(64); /** The total size of the buffers in the pool */ diff --git a/src/main/java/com/android/volley/toolbox/HttpHeaderParser.java b/src/main/java/com/android/volley/toolbox/HttpHeaderParser.java index 211c3292..660c2497 100644 --- a/src/main/java/com/android/volley/toolbox/HttpHeaderParser.java +++ b/src/main/java/com/android/volley/toolbox/HttpHeaderParser.java @@ -74,7 +74,7 @@ public static Cache.Entry parseCacheHeaders(NetworkResponse response) { headerValue = headers.get("Cache-Control"); if (headerValue != null) { hasCacheControl = true; - String[] tokens = headerValue.split(","); + String[] tokens = headerValue.split(",", 0); for (int i = 0; i < tokens.length; i++) { String token = tokens[i].trim(); if (token.equals("no-cache") || token.equals("no-store")) { @@ -170,9 +170,9 @@ private static SimpleDateFormat newRfc1123Formatter() { public static String parseCharset(Map headers, String defaultCharset) { String contentType = headers.get(HEADER_CONTENT_TYPE); if (contentType != null) { - String[] params = contentType.split(";"); + String[] params = contentType.split(";", 0); for (int i = 1; i < params.length; i++) { - String[] pair = params[i].trim().split("="); + String[] pair = params[i].trim().split("=", 0); if (pair.length == 2) { if (pair[0].equals("charset")) { return pair[1]; diff --git a/src/main/java/com/android/volley/toolbox/ImageLoader.java b/src/main/java/com/android/volley/toolbox/ImageLoader.java index 33a119bc..8ded858e 100644 --- a/src/main/java/com/android/volley/toolbox/ImageLoader.java +++ b/src/main/java/com/android/volley/toolbox/ImageLoader.java @@ -21,14 +21,16 @@ import android.os.Looper; import android.widget.ImageView; import android.widget.ImageView.ScaleType; + import com.android.volley.Request; import com.android.volley.RequestQueue; import com.android.volley.Response.ErrorListener; import com.android.volley.Response.Listener; import com.android.volley.VolleyError; +import java.util.ArrayList; import java.util.HashMap; -import java.util.LinkedList; +import java.util.List; /** * Helper that handles loading and caching images from remote URLs. @@ -387,7 +389,7 @@ public String getRequestUrl() { * Wrapper class used to map a Request to the set of active ImageContainer objects that are * interested in its results. */ - private class BatchedImageRequest { + private static class BatchedImageRequest { /** The request being tracked */ private final Request mRequest; @@ -398,7 +400,7 @@ private class BatchedImageRequest { private VolleyError mError; /** List of all of the active ImageContainers that are interested in the request */ - private final LinkedList mContainers = new LinkedList(); + private final List mContainers = new ArrayList<>(); /** * Constructs a new BatchedImageRequest object @@ -433,7 +435,7 @@ public void addContainer(ImageContainer container) { } /** - * Detatches the bitmap container from the request and cancels the request if no one is + * Detaches the bitmap container from the request and cancels the request if no one is * left listening. * @param container The container to remove from the list * @return True if the request was canceled, false otherwise. diff --git a/src/main/java/com/android/volley/toolbox/PoolingByteArrayOutputStream.java b/src/main/java/com/android/volley/toolbox/PoolingByteArrayOutputStream.java index 99715666..fc47f79b 100644 --- a/src/main/java/com/android/volley/toolbox/PoolingByteArrayOutputStream.java +++ b/src/main/java/com/android/volley/toolbox/PoolingByteArrayOutputStream.java @@ -68,6 +68,7 @@ public void finalize() { /** * Ensures there is enough space in the buffer for the given number of additional bytes. */ + @SuppressWarnings("UnsafeFinalization") private void expand(int i) { /* Can the buffer handle @i more bytes, if not expand it */ if (count + i <= buf.length) { diff --git a/src/main/java/com/android/volley/toolbox/RequestFuture.java b/src/main/java/com/android/volley/toolbox/RequestFuture.java index 173c44cc..8e864d3d 100644 --- a/src/main/java/com/android/volley/toolbox/RequestFuture.java +++ b/src/main/java/com/android/volley/toolbox/RequestFuture.java @@ -16,6 +16,8 @@ package com.android.volley.toolbox; +import android.os.SystemClock; + import com.android.volley.Request; import com.android.volley.Response; import com.android.volley.VolleyError; @@ -108,9 +110,16 @@ private synchronized T doGet(Long timeoutMs) } if (timeoutMs == null) { - wait(0); + while (!isDone()) { + wait(0); + } } else if (timeoutMs > 0) { - wait(timeoutMs); + long nowMs = SystemClock.uptimeMillis(); + long deadlineMs = nowMs + timeoutMs; + while (!isDone() && nowMs < deadlineMs) { + wait(deadlineMs - nowMs); + nowMs = SystemClock.uptimeMillis(); + } } if (mException != null) { diff --git a/src/main/java/com/android/volley/toolbox/StringRequest.java b/src/main/java/com/android/volley/toolbox/StringRequest.java index 9deba1d5..4785c766 100644 --- a/src/main/java/com/android/volley/toolbox/StringRequest.java +++ b/src/main/java/com/android/volley/toolbox/StringRequest.java @@ -80,11 +80,15 @@ protected void deliverResponse(String response) { } @Override + @SuppressWarnings("DefaultCharset") protected Response parseNetworkResponse(NetworkResponse response) { String parsed; try { parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers)); } catch (UnsupportedEncodingException e) { + // Since minSdkVersion = 8, we can't call + // new String(response.data, Charset.defaultCharset()) + // So suppress the warning instead. parsed = new String(response.data); } return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response)); diff --git a/src/test/java/com/android/volley/NetworkDispatcherTest.java b/src/test/java/com/android/volley/NetworkDispatcherTest.java index c5763bdb..799c44c2 100644 --- a/src/test/java/com/android/volley/NetworkDispatcherTest.java +++ b/src/test/java/com/android/volley/NetworkDispatcherTest.java @@ -27,6 +27,7 @@ import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; +import java.nio.charset.StandardCharsets; import java.util.Arrays; import static org.junit.Assert.*; @@ -40,7 +41,8 @@ public class NetworkDispatcherTest { private MockCache mCache; private MockRequest mRequest; - private static final byte[] CANNED_DATA = "Ceci n'est pas une vraie reponse".getBytes(); + private static final byte[] CANNED_DATA = + "Ceci n'est pas une vraie reponse".getBytes(StandardCharsets.UTF_8); private static final long TIMEOUT_MILLIS = 5000; @Before public void setUp() throws Exception { diff --git a/src/test/java/com/android/volley/RequestTest.java b/src/test/java/com/android/volley/RequestTest.java index d5beca5f..c5c70bec 100644 --- a/src/test/java/com/android/volley/RequestTest.java +++ b/src/test/java/com/android/volley/RequestTest.java @@ -45,7 +45,7 @@ public class RequestTest { assertTrue(immediate.compareTo(high) < 0); } - private class TestRequest extends Request { + private static class TestRequest extends Request { private Priority mPriority = Priority.NORMAL; public TestRequest(Priority priority) { super(Request.Method.GET, "", null); @@ -80,7 +80,7 @@ protected Response parseNetworkResponse(NetworkResponse response) { assertFalse(0 == goodProtocol.getTrafficStatsTag()); } - private class UrlParseRequest extends Request { + private static class UrlParseRequest extends Request { public UrlParseRequest(String url) { super(Request.Method.GET, url, null); } diff --git a/src/test/java/com/android/volley/toolbox/BasicNetworkTest.java b/src/test/java/com/android/volley/toolbox/BasicNetworkTest.java index 7f0d5e22..a5bc6f4f 100644 --- a/src/test/java/com/android/volley/toolbox/BasicNetworkTest.java +++ b/src/test/java/com/android/volley/toolbox/BasicNetworkTest.java @@ -39,6 +39,7 @@ import java.io.InputStream; import java.net.HttpURLConnection; import java.net.SocketTimeoutException; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -68,7 +69,7 @@ public class BasicNetworkTest { @Test public void headersAndPostParams() throws Exception { MockHttpStack mockHttpStack = new MockHttpStack(); InputStream responseStream = - new ByteArrayInputStream("foobar".getBytes()); + new ByteArrayInputStream("foobar".getBytes(StandardCharsets.UTF_8)); HttpResponse fakeResponse = new HttpResponse(200, Collections.
emptyList(), 6, responseStream); mockHttpStack.setResponseToReturn(fakeResponse); @@ -83,7 +84,8 @@ public class BasicNetworkTest { assertEquals("foobar", mockHttpStack.getLastHeaders().get("If-None-Match")); assertEquals("Sat, 19 Aug 2017 00:20:02 GMT", mockHttpStack.getLastHeaders().get("If-Modified-Since")); - assertEquals("requestpost=foo&", new String(mockHttpStack.getLastPostBody())); + assertEquals("requestpost=foo&", + new String(mockHttpStack.getLastPostBody(), StandardCharsets.UTF_8)); } @Test public void notModified() throws Exception { diff --git a/src/test/java/com/android/volley/toolbox/ImageRequestTest.java b/src/test/java/com/android/volley/toolbox/ImageRequestTest.java index a99363eb..a3e5c229 100644 --- a/src/test/java/com/android/volley/toolbox/ImageRequestTest.java +++ b/src/test/java/com/android/volley/toolbox/ImageRequestTest.java @@ -31,6 +31,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.nio.charset.StandardCharsets; import static org.junit.Assert.*; @@ -45,7 +46,7 @@ public class ImageRequestTest { // "file:" + name in its lookaside map. I write all this because it will // probably break mysteriously at some point and I feel terrible about your // having to debug it. - byte[] jpegBytes = "file:fake".getBytes(); + byte[] jpegBytes = "file:fake".getBytes(StandardCharsets.UTF_8); ShadowBitmapFactory.provideWidthAndHeightHints("fake", 1024, 500); NetworkResponse jpeg = new NetworkResponse(jpegBytes); diff --git a/src/test/java/com/android/volley/toolbox/NetworkImageViewTest.java b/src/test/java/com/android/volley/toolbox/NetworkImageViewTest.java index 055005f2..2f42446a 100644 --- a/src/test/java/com/android/volley/toolbox/NetworkImageViewTest.java +++ b/src/test/java/com/android/volley/toolbox/NetworkImageViewTest.java @@ -52,7 +52,7 @@ public class NetworkImageViewTest { // // instrumentation test. Write this test once it's figured out. // } - private class MockImageLoader extends ImageLoader { + private static class MockImageLoader extends ImageLoader { public MockImageLoader() { super(null, null); } @@ -61,6 +61,7 @@ public MockImageLoader() { public int lastMaxWidth; public int lastMaxHeight; + @Override public ImageContainer get(String requestUrl, ImageListener imageListener, int maxWidth, int maxHeight, ScaleType scaleType) { lastRequestUrl = requestUrl;