Commit 5b6a85f0 authored by Xing Liu's avatar Xing Liu Committed by Commit Bot

Image Fetcher: Use ImageFetcher.Params in fetchImage API.

This CL adds an fetchImage function in ImageFetcher to use the new
ImageFetcher.Params struct.

The underlying ImageFetcherBridge call also only use the Params struct
now.

TBR=sandromaggi@chromium.org

Bug: 1076515
Change-Id: I32792c695c684fbe7963df8070ed576f91c9d246
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2176422
Commit-Queue: Xing Liu <xingliu@chromium.org>
Reviewed-by: default avatarBrandon Wylie <wylieb@chromium.org>
Reviewed-by: default avatarFilip Gorski <fgorski@chromium.org>
Cr-Commit-Position: refs/heads/master@{#766570}
parent dd903b4b
......@@ -95,6 +95,11 @@ class AutofillAssistantUiTestUtil {
callback.onResult(mBitmapToFetch);
}
@Override
public void fetchImage(Params params, Callback<Bitmap> callback) {
callback.onResult(mBitmapToFetch);
}
@Override
public void clear() {}
......
......@@ -4,9 +4,9 @@
package org.chromium.chrome.browser.image_fetcher;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyObject;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
......@@ -21,7 +21,6 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
......@@ -45,7 +44,6 @@ public class CachedImageFetcherTest {
private static final String PATH = "test/path/cache/test.png";
private static final int WIDTH_PX = 10;
private static final int HEIGHT_PX = 20;
private static final long START_TIME = 274127;
@Mock
ImageFetcherBridge mBridge;
......@@ -58,9 +56,6 @@ public class CachedImageFetcherTest {
@Mock
Callback<BaseGifImage> mGifCallback;
@Captor
ArgumentCaptor<Callback<Bitmap>> mCallbackCaptor;
CachedImageFetcher mCachedImageFetcher;
Bitmap mBitmap;
......@@ -86,8 +81,7 @@ public class CachedImageFetcherTest {
return null;
})
.when(mBridge)
.fetchImage(anyInt(), eq(URL), eq(UMA_CLIENT_NAME), anyInt(), anyInt(),
bitmapCallbackCaptor.capture());
.fetchImage(anyInt(), any(), bitmapCallbackCaptor.capture());
ArgumentCaptor<Callback<BaseGifImage>> gifCallbackCaptor =
ArgumentCaptor.forClass(Callback.class);
......@@ -103,21 +97,23 @@ public class CachedImageFetcherTest {
public void testFetchImage_fileNotFoundOnDisk() {
doReturn(null).when(mImageLoader).tryToLoadImageFromDisk(PATH);
mCachedImageFetcher.fetchImage(URL, UMA_CLIENT_NAME, WIDTH_PX, HEIGHT_PX, mBitmapCallback);
ImageFetcher.Params params =
ImageFetcher.Params.create(URL, UMA_CLIENT_NAME, WIDTH_PX, HEIGHT_PX);
mCachedImageFetcher.fetchImage(params, mBitmapCallback);
verify(mBitmapCallback).onResult(mBitmap);
verify(mBridge).fetchImage(eq(ImageFetcherConfig.DISK_CACHE_ONLY), eq(URL),
eq(UMA_CLIENT_NAME), eq(WIDTH_PX), eq(HEIGHT_PX), anyObject());
verify(mBridge).fetchImage(eq(ImageFetcherConfig.DISK_CACHE_ONLY), eq(params), any());
}
@Test
public void testFetchImage_fileFoundOnDisk() {
doReturn(mBitmap).when(mImageLoader).tryToLoadImageFromDisk(PATH);
mCachedImageFetcher.fetchImage(URL, UMA_CLIENT_NAME, WIDTH_PX, HEIGHT_PX, mBitmapCallback);
ImageFetcher.Params params =
ImageFetcher.Params.create(URL, UMA_CLIENT_NAME, WIDTH_PX, HEIGHT_PX);
mCachedImageFetcher.fetchImage(params, mBitmapCallback);
verify(mBitmapCallback).onResult(mBitmap);
verify(mBridge, never())
.fetchImage(eq(ImageFetcherConfig.DISK_CACHE_ONLY), eq(URL), eq(UMA_CLIENT_NAME),
eq(WIDTH_PX), eq(HEIGHT_PX), anyObject());
.fetchImage(eq(ImageFetcherConfig.DISK_CACHE_ONLY), eq(params), any());
verify(mBridge).reportEvent(UMA_CLIENT_NAME, ImageFetcherEvent.JAVA_DISK_CACHE_HIT);
verify(mBridge).reportCacheHitTime(eq(UMA_CLIENT_NAME), anyLong());
}
......@@ -126,8 +122,9 @@ public class CachedImageFetcherTest {
public void testFetchImage_fileFoundOnDisk_imageResized() {
doReturn(mBitmap).when(mImageLoader).tryToLoadImageFromDisk(PATH);
mCachedImageFetcher.fetchImage(
URL, UMA_CLIENT_NAME, WIDTH_PX + 1, HEIGHT_PX + 1, mBitmapCallback);
ImageFetcher.Params params =
ImageFetcher.Params.create(URL, UMA_CLIENT_NAME, WIDTH_PX + 1, HEIGHT_PX + 1);
mCachedImageFetcher.fetchImage(params, mBitmapCallback);
ArgumentCaptor<Bitmap> bitmapCaptor = ArgumentCaptor.forClass(Bitmap.class);
verify(mBitmapCallback).onResult(bitmapCaptor.capture());
......@@ -137,8 +134,9 @@ public class CachedImageFetcherTest {
Assert.assertEquals(HEIGHT_PX + 1, actual.getHeight());
verify(mBridge, never())
.fetchImage(eq(ImageFetcherConfig.DISK_CACHE_ONLY), eq(URL), eq(UMA_CLIENT_NAME),
eq(WIDTH_PX), eq(HEIGHT_PX), anyObject());
.fetchImage(eq(ImageFetcherConfig.DISK_CACHE_ONLY),
eq(ImageFetcher.Params.create(URL, UMA_CLIENT_NAME, WIDTH_PX, HEIGHT_PX)),
any());
verify(mBridge).reportEvent(UMA_CLIENT_NAME, ImageFetcherEvent.JAVA_DISK_CACHE_HIT);
verify(mBridge).reportCacheHitTime(eq(UMA_CLIENT_NAME), anyLong());
}
......@@ -154,7 +152,7 @@ public class CachedImageFetcherTest {
Assert.assertEquals(mGif, gifCaptor.getValue());
verify(mBridge).fetchGif(
eq(ImageFetcherConfig.DISK_CACHE_ONLY), eq(URL), eq(UMA_CLIENT_NAME), anyObject());
eq(ImageFetcherConfig.DISK_CACHE_ONLY), eq(URL), eq(UMA_CLIENT_NAME), any());
}
@Test
......@@ -169,7 +167,7 @@ public class CachedImageFetcherTest {
verify(mBridge, never())
.fetchGif(eq(ImageFetcherConfig.DISK_CACHE_ONLY), eq(URL), eq(UMA_CLIENT_NAME),
anyObject());
any());
verify(mBridge).reportEvent(UMA_CLIENT_NAME, ImageFetcherEvent.JAVA_DISK_CACHE_HIT);
verify(mBridge).reportCacheHitTime(eq(UMA_CLIENT_NAME), anyLong());
}
......
......@@ -38,6 +38,9 @@ import jp.tomorrowkey.android.gifplayer.BaseGifImage;
@Config(manifest = Config.NONE)
public class ImageFetcherBridgeTest {
private static long sNativePointer = 100L;
private static final int WIDTH_PX = 10;
private static final int HEIGHT_PX = 20;
private static final int EXPIRATION_INTERVAL_MINS = 60;
@Rule
public ExpectedException mExpectedException = ExpectedException.none();
......@@ -76,9 +79,9 @@ public class ImageFetcherBridgeTest {
mExpectedException.expectMessage("fetchGif called after destroy");
mBridge.fetchGif(-1, "", "", null);
mExpectedException.expectMessage("fetchImage called after destroy");
mBridge.fetchImage(-1, "", "", 100, 100, null);
mBridge.fetchImage(-1, ImageFetcher.Params.create("", "", 100, 100), null);
mExpectedException.expectMessage("fetchImage called after destroy");
mBridge.fetchImage(-1, "", "", 100, 100, null);
mBridge.fetchImage(-1, ImageFetcher.Params.create("", "", 100, 100), null);
mExpectedException.expectMessage("reportEvent called after destroy");
mBridge.reportEvent("", -1);
mExpectedException.expectMessage("reportCacheHitTime called after destroy");
......@@ -90,7 +93,7 @@ public class ImageFetcherBridgeTest {
@Test
public void testFetchImage() {
ArgumentCaptor<Callback<Bitmap>> callbackCaptor = ArgumentCaptor.forClass(Callback.class);
final Bitmap bitmap = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888);
final Bitmap bitmap = Bitmap.createBitmap(WIDTH_PX, HEIGHT_PX, Bitmap.Config.ARGB_8888);
doAnswer((InvocationOnMock invocation) -> {
callbackCaptor.getValue().onResult(bitmap);
return null;
......@@ -99,7 +102,27 @@ public class ImageFetcherBridgeTest {
.fetchImage(eq(sNativePointer), eq(mBridge), anyInt(), anyString(), anyString(),
eq(0), callbackCaptor.capture());
mBridge.fetchImage(-1, "", "", 10, 10, mBitmapCallback);
mBridge.fetchImage(
-1, ImageFetcher.Params.create("", "", WIDTH_PX, HEIGHT_PX), mBitmapCallback);
verify(mBitmapCallback).onResult(bitmap);
}
@Test
public void testFetchImageWithExpirationInterval() {
ArgumentCaptor<Callback<Bitmap>> callbackCaptor = ArgumentCaptor.forClass(Callback.class);
final Bitmap bitmap = Bitmap.createBitmap(WIDTH_PX, HEIGHT_PX, Bitmap.Config.ARGB_8888);
doAnswer((InvocationOnMock invocation) -> {
callbackCaptor.getValue().onResult(bitmap);
return null;
})
.when(mNatives)
.fetchImage(eq(sNativePointer), eq(mBridge), anyInt(), anyString(), anyString(),
eq(EXPIRATION_INTERVAL_MINS), callbackCaptor.capture());
mBridge.fetchImage(-1,
ImageFetcher.Params.createWithExpirationInterval(
"url", "clientname", WIDTH_PX, HEIGHT_PX, EXPIRATION_INTERVAL_MINS),
mBitmapCallback);
verify(mBitmapCallback).onResult(bitmap);
}
......@@ -115,7 +138,7 @@ public class ImageFetcherBridgeTest {
.fetchImage(eq(sNativePointer), eq(mBridge), anyInt(), anyString(), anyString(),
eq(0), callbackCaptor.capture());
mBridge.fetchImage(-1, "", "", 100, 100, mBitmapCallback);
mBridge.fetchImage(-1, ImageFetcher.Params.create("", "", 100, 100), mBitmapCallback);
ArgumentCaptor<Bitmap> bitmapCaptor = ArgumentCaptor.forClass(Bitmap.class);
verify(mBitmapCallback).onResult(bitmapCaptor.capture());
......
......@@ -5,7 +5,9 @@
package org.chromium.chrome.browser.image_fetcher;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
......@@ -31,6 +33,8 @@ import jp.tomorrowkey.android.gifplayer.BaseGifImage;
@RunWith(BaseRobolectricTestRunner.class)
@Config(manifest = Config.NONE)
public class ImageFetcherTest {
private static final String URL = "https://www.example.com/image";
private static final String CLIENT_NAME = "client";
private static final int WIDTH_PX = 100;
private static final int HEIGHT_PX = 200;
private static final int EXPIRATION_INTERVAL = 60;
......@@ -50,6 +54,9 @@ public class ImageFetcherTest {
public void fetchImage(
String url, String clientName, int width, int height, Callback<Bitmap> callback) {}
@Override
public void fetchImage(Params params, Callback<Bitmap> callback) {}
@Override
public void clear() {}
......@@ -105,31 +112,27 @@ public class ImageFetcherTest {
@Test
public void testFetchImageNoDimensionsAlias() {
String url = "url";
String client = "client";
mImageFetcher.fetchImage(url, client, result -> {});
mImageFetcher.fetchImage(URL, CLIENT_NAME, result -> {});
// No arguments should alias to 0, 0.
verify(mImageFetcher).fetchImage(eq(url), eq(client), eq(0), eq(0), any());
verify(mImageFetcher)
.fetchImage(eq(ImageFetcher.Params.create(URL, CLIENT_NAME, 0, 0)), any());
}
@Test
public void testCreateParams() {
String url = "https://www.example.com/image";
String client = "client";
// Verifies params without size specified.
ImageFetcher.Params params = ImageFetcher.Params.create(url, client);
assertEquals(url, params.url);
assertEquals(client, params.clientName);
ImageFetcher.Params params = ImageFetcher.Params.create(URL, CLIENT_NAME);
assertEquals(URL, params.url);
assertEquals(CLIENT_NAME, params.clientName);
assertEquals(0, params.width);
assertEquals(0, params.height);
assertEquals(0, params.expirationIntervalMinutes);
// Verifies params with size.
params = ImageFetcher.Params.create(url, client, WIDTH_PX, HEIGHT_PX);
assertEquals(url, params.url);
assertEquals(client, params.clientName);
params = ImageFetcher.Params.create(URL, CLIENT_NAME, WIDTH_PX, HEIGHT_PX);
assertEquals(URL, params.url);
assertEquals(CLIENT_NAME, params.clientName);
assertEquals(WIDTH_PX, params.width);
assertEquals(HEIGHT_PX, params.height);
assertEquals(0, params.expirationIntervalMinutes);
......@@ -137,16 +140,48 @@ public class ImageFetcherTest {
@Test
public void testCreateParamsWithExpirationInterval() {
String url = "https://www.example.com/image";
String client = "client";
// Verifies params with expiration interval.
ImageFetcher.Params params = ImageFetcher.Params.createWithExpirationInterval(
url, client, WIDTH_PX, HEIGHT_PX, EXPIRATION_INTERVAL);
assertEquals(url, params.url);
assertEquals(client, params.clientName);
URL, CLIENT_NAME, WIDTH_PX, HEIGHT_PX, EXPIRATION_INTERVAL);
assertEquals(URL, params.url);
assertEquals(CLIENT_NAME, params.clientName);
assertEquals(WIDTH_PX, params.width);
assertEquals(HEIGHT_PX, params.height);
assertEquals(EXPIRATION_INTERVAL, params.expirationIntervalMinutes);
}
@Test
public void testParamsEqual() {
// Different URLs.
ImageFetcher.Params params1 = ImageFetcher.Params.create(URL, CLIENT_NAME);
ImageFetcher.Params params2 = ImageFetcher.Params.create("Not the same URL", CLIENT_NAME);
assertFalse(params1.equals(params2));
assertFalse(params2.equals(params1));
assertNotEquals(params1.hashCode(), params2.hashCode());
// Different width and height.
params2 = ImageFetcher.Params.create(URL, CLIENT_NAME, WIDTH_PX, HEIGHT_PX);
assertFalse(params1.equals(params2));
assertFalse(params2.equals(params1));
assertNotEquals(params1.hashCode(), params2.hashCode());
// Different expiration intervals.
params1 = ImageFetcher.Params.createWithExpirationInterval(
URL, CLIENT_NAME, WIDTH_PX, HEIGHT_PX, EXPIRATION_INTERVAL);
assertFalse(params1.equals(params2));
assertFalse(params2.equals(params1));
assertNotEquals(params1.hashCode(), params2.hashCode());
// Same parameters comparison.
params2 = ImageFetcher.Params.createWithExpirationInterval(
URL, CLIENT_NAME, WIDTH_PX, HEIGHT_PX, EXPIRATION_INTERVAL);
assertTrue(params1.equals(params2));
assertTrue(params2.equals(params1));
assertEquals(params1.hashCode(), params2.hashCode());
// Edge cases.
assertFalse(params1.equals(null));
assertFalse(params1.equals(new String("Params is not a string.")));
assertTrue(params1.equals(params1));
}
}
......@@ -5,8 +5,7 @@
package org.chromium.chrome.browser.image_fetcher;
import static org.junit.Assume.assumeFalse;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyObject;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
......@@ -106,8 +105,8 @@ public class InMemoryCachedImageFetcherTest {
mCallbackCaptor.getValue().onResult(bitmap);
return null;
}).when(mMockImageFetcher)
.fetchImage(eq(URL), eq(UMA_CLIENT_NAME), anyInt(),
anyInt(), mCallbackCaptor.capture());
.fetchImage(any(),
mCallbackCaptor.capture());
// clang-format on
}
......@@ -129,17 +128,16 @@ public class InMemoryCachedImageFetcherTest {
@Test
public void testFetchImageCachesFirstCall() {
answerFetch(mBitmap, false);
mInMemoryCachedImageFetcher.fetchImage(
URL, UMA_CLIENT_NAME, WIDTH_PX, HEIGHT_PX, mCallback);
ImageFetcher.Params params =
ImageFetcher.Params.create(URL, UMA_CLIENT_NAME, WIDTH_PX, HEIGHT_PX);
mInMemoryCachedImageFetcher.fetchImage(params, mCallback);
verify(mCallback).onResult(mBitmap);
reset(mCallback);
mInMemoryCachedImageFetcher.fetchImage(
URL, UMA_CLIENT_NAME, WIDTH_PX, HEIGHT_PX, mCallback);
mInMemoryCachedImageFetcher.fetchImage(params, mCallback);
verify(mCallback).onResult(mBitmap);
verify(mMockImageFetcher)
.fetchImage(eq(URL), eq(UMA_CLIENT_NAME), eq(WIDTH_PX), eq(HEIGHT_PX), anyObject());
verify(mMockImageFetcher).fetchImage(eq(params), any());
// Verify metrics are reported.
verify(mBridge).reportEvent(UMA_CLIENT_NAME, ImageFetcherEvent.JAVA_IN_MEMORY_CACHE_HIT);
......@@ -161,7 +159,7 @@ public class InMemoryCachedImageFetcherTest {
@Test
public void testFetchGif() {
mInMemoryCachedImageFetcher.fetchGif(URL, UMA_CLIENT_NAME, (BaseGifImage gif) -> {});
verify(mMockImageFetcher).fetchGif(eq(URL), eq(UMA_CLIENT_NAME), anyObject());
verify(mMockImageFetcher).fetchGif(eq(URL), eq(UMA_CLIENT_NAME), any());
}
@Test
......
......@@ -4,9 +4,9 @@
package org.chromium.chrome.browser.image_fetcher;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyObject;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.verify;
......@@ -67,8 +67,7 @@ public class NetworkImageFetcherTest {
return null;
})
.when(mBridge)
.fetchImage(anyInt(), eq(URL), eq(UMA_CLIENT_NAME), anyInt(), anyInt(),
bitmapCallbackCaptor.capture());
.fetchImage(anyInt(), any(), bitmapCallbackCaptor.capture());
ArgumentCaptor<Callback<BaseGifImage>> gifCallbackCaptor =
ArgumentCaptor.forClass(Callback.class);
......@@ -82,10 +81,11 @@ public class NetworkImageFetcherTest {
@Test
public void test_fetchImage() {
mImageFetcher.fetchImage(URL, UMA_CLIENT_NAME, WIDTH_PX, HEIGHT_PX, mBitmapCallback);
ImageFetcher.Params params =
ImageFetcher.Params.create(URL, UMA_CLIENT_NAME, WIDTH_PX, HEIGHT_PX);
mImageFetcher.fetchImage(params, mBitmapCallback);
verify(mBitmapCallback).onResult(mBitmap);
verify(mBridge).fetchImage(eq(ImageFetcherConfig.NETWORK_ONLY), eq(URL),
eq(UMA_CLIENT_NAME), eq(WIDTH_PX), eq(HEIGHT_PX), anyObject());
verify(mBridge).fetchImage(eq(ImageFetcherConfig.NETWORK_ONLY), eq(params), any());
verify(mBridge).reportTotalFetchTimeFromNative(eq(UMA_CLIENT_NAME), anyLong());
}
......
......@@ -122,34 +122,37 @@ public class CachedImageFetcher extends ImageFetcher {
@Override
public void fetchImage(
String url, String clientName, int width, int height, Callback<Bitmap> callback) {
fetchImage(ImageFetcher.Params.create(url, clientName, width, height), callback);
}
@Override
public void fetchImage(final Params params, Callback<Bitmap> callback) {
long startTimeMillis = System.currentTimeMillis();
PostTask.postTask(TaskTraits.USER_VISIBLE, () -> {
// Try to read the bitmap from disk, then post back to the ui thread.
String filePath = getImageFetcherBridge().getFilePath(url);
String filePath = getImageFetcherBridge().getFilePath(params.url);
Bitmap bitmap = mImageLoader.tryToLoadImageFromDisk(filePath);
PostTask.postTask(UiThreadTaskTraits.USER_VISIBLE, () -> {
continueFetchImageAfterDisk(
url, clientName, width, height, callback, bitmap, startTimeMillis);
continueFetchImageAfterDisk(params, callback, bitmap, startTimeMillis);
});
});
}
@VisibleForTesting
void continueFetchImageAfterDisk(String url, String clientName, int width, int height,
Callback<Bitmap> callback, Bitmap cachedBitmap, long startTimeMillis) {
void continueFetchImageAfterDisk(final ImageFetcher.Params params, Callback<Bitmap> callback,
Bitmap cachedBitmap, long startTimeMillis) {
if (cachedBitmap != null) {
// In case the image's dimensions on disk don't match the desired dimensions.
cachedBitmap = ImageFetcher.resizeImage(cachedBitmap, width, height);
cachedBitmap = ImageFetcher.resizeImage(cachedBitmap, params.width, params.height);
callback.onResult(cachedBitmap);
reportEvent(clientName, ImageFetcherEvent.JAVA_DISK_CACHE_HIT);
getImageFetcherBridge().reportCacheHitTime(clientName, startTimeMillis);
reportEvent(params.clientName, ImageFetcherEvent.JAVA_DISK_CACHE_HIT);
getImageFetcherBridge().reportCacheHitTime(params.clientName, startTimeMillis);
} else {
getImageFetcherBridge().fetchImage(
getConfig(), url, clientName, width, height, (Bitmap bitmapFromNative) -> {
callback.onResult(bitmapFromNative);
getImageFetcherBridge().reportTotalFetchTimeFromNative(
clientName, startTimeMillis);
});
getImageFetcherBridge().fetchImage(getConfig(), params, (Bitmap bitmapFromNative) -> {
callback.onResult(bitmapFromNative);
getImageFetcherBridge().reportTotalFetchTimeFromNative(
params.clientName, startTimeMillis);
});
}
}
......
......@@ -68,8 +68,6 @@ public abstract class ImageFetcher {
private Params(String url, String clientName, int width, int height,
int expirationIntervalMinutes) {
assert width >= DEFAULT_IMAGE_SIZE : "Invalid width specified.";
assert height >= DEFAULT_IMAGE_SIZE : "Invalid height specified.";
assert expirationIntervalMinutes >= INVALID_EXPIRATION_INTERVAL
: "Expiration interval should be non negative.";
......@@ -80,6 +78,27 @@ public abstract class ImageFetcher {
this.expirationIntervalMinutes = expirationIntervalMinutes;
}
@Override
public boolean equals(Object other) {
if (other == this) return true;
if (!(other instanceof ImageFetcher.Params)) return false;
ImageFetcher.Params otherParams = (ImageFetcher.Params) other;
return url.equals(otherParams.url) && clientName.equals(otherParams.clientName)
&& width == otherParams.width && height == otherParams.height
&& expirationIntervalMinutes == otherParams.expirationIntervalMinutes;
}
@Override
public int hashCode() {
int result = (url != null) ? url.hashCode() : 0;
result = 31 * result + ((clientName != null) ? clientName.hashCode() : 0);
result = 31 * result + width;
result = 31 * result + height;
result = 31 * result + expirationIntervalMinutes;
return result;
}
/**
* The url to fetch the image from.
*/
......@@ -91,14 +110,14 @@ public abstract class ImageFetcher {
public final String clientName;
/**
* The new bitmap's desired width (in pixels). Image won't be scaled if set to {@link
* #DEFAULT_IMAGE_SIZE}.
* The new bitmap's desired width (in pixels). If the given value is <= 0, the image won't
* be scaled.
*/
public final int width;
/**
* The new bitmap's desired height (in pixels). Image won't be scaled if set to {@link
* #DEFAULT_IMAGE_SIZE}.
* The new bitmap's desired height (in pixels). If the given value is <= 0, the image won't
* be scaled.
*/
public final int height;
......@@ -205,9 +224,18 @@ public abstract class ImageFetcher {
* with null result if fetching fails;
*/
public void fetchImage(String url, String clientName, Callback<Bitmap> callback) {
fetchImage(url, clientName, 0, 0, callback);
fetchImage(ImageFetcher.Params.create(url, clientName), callback);
}
/**
* Fetches the image based on customized parameters specified.
*
* @param params The parameters to specify image fetching details.
* @param callback The function which will be called when the image is ready; will be called
* with null result if fetching fails;
*/
public abstract void fetchImage(final Params params, Callback<Bitmap> callback);
/**
* Clear the cache of any bitmaps that may be in-memory.
*/
......
......@@ -90,20 +90,18 @@ public class ImageFetcherBridge {
* Fetch the image from native, then resize it to the given dimensions.
*
* @param config The configuration of the image fetcher.
* @param url The url to fetch.
* @param width The desired width of the image.
* @param height The desired height of the image.
* @param clientName The UMA client name to report the metrics to.
* @param params The parameters to specify image fetching details.
* @param callback The callback to call when the image is ready. The callback will be invoked on
* the same thread that it was called on.
*/
public void fetchImage(@ImageFetcherConfig int config, String url, String clientName, int width,
int height, Callback<Bitmap> callback) {
public void fetchImage(@ImageFetcherConfig int config, final ImageFetcher.Params params,
Callback<Bitmap> callback) {
assert mNativeImageFetcherBridge != 0 : "fetchImage called after destroy";
ImageFetcherBridgeJni.get().fetchImage(mNativeImageFetcherBridge, ImageFetcherBridge.this,
config, url, clientName, ImageFetcher.Params.INVALID_EXPIRATION_INTERVAL,
config, params.url, params.clientName, params.expirationIntervalMinutes,
(bitmap) -> {
callback.onResult(ImageFetcher.resizeImage(bitmap, width, height));
callback.onResult(
ImageFetcher.resizeImage(bitmap, params.width, params.height));
});
}
......
......@@ -94,15 +94,20 @@ public class InMemoryCachedImageFetcher extends ImageFetcher {
@Override
public void fetchImage(
String url, String clientName, int width, int height, Callback<Bitmap> callback) {
fetchImage(ImageFetcher.Params.create(url, clientName, width, height), callback);
}
@Override
public void fetchImage(final Params params, Callback<Bitmap> callback) {
assert mBitmapCache != null && mImageFetcher != null : "fetchImage called after destroy";
Bitmap cachedBitmap = tryToGetBitmap(url, width, height);
Bitmap cachedBitmap = tryToGetBitmap(params.url, params.width, params.height);
if (cachedBitmap == null) {
mImageFetcher.fetchImage(url, clientName, width, height, (@Nullable Bitmap bitmap) -> {
storeBitmap(bitmap, url, width, height);
mImageFetcher.fetchImage(params, (@Nullable Bitmap bitmap) -> {
storeBitmap(bitmap, params.url, params.width, params.height);
callback.onResult(bitmap);
});
} else {
reportEvent(clientName, ImageFetcherEvent.JAVA_IN_MEMORY_CACHE_HIT);
reportEvent(params.clientName, ImageFetcherEvent.JAVA_IN_MEMORY_CACHE_HIT);
callback.onResult(cachedBitmap);
}
}
......
......@@ -36,13 +36,17 @@ public class NetworkImageFetcher extends ImageFetcher {
@Override
public void fetchImage(
String url, String clientName, int width, int height, Callback<Bitmap> callback) {
fetchImage(ImageFetcher.Params.create(url, clientName, width, height), callback);
}
@Override
public void fetchImage(final Params params, Callback<Bitmap> callback) {
long startTimeMillis = System.currentTimeMillis();
getImageFetcherBridge().fetchImage(
getConfig(), url, clientName, width, height, (Bitmap bitmapFromNative) -> {
callback.onResult(bitmapFromNative);
getImageFetcherBridge().reportTotalFetchTimeFromNative(
clientName, startTimeMillis);
});
getImageFetcherBridge().fetchImage(getConfig(), params, (Bitmap bitmapFromNative) -> {
callback.onResult(bitmapFromNative);
getImageFetcherBridge().reportTotalFetchTimeFromNative(
params.clientName, startTimeMillis);
});
}
@Override
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment