Commit 286b61cc authored by Brandon Wylie's avatar Brandon Wylie Committed by Commit Bot

Consolidate CachedImageFetcher unittests and expand coverage

Did some refactoring to allow for better test support.

TBR=arbesser@google.com

Bug: 1067714
Change-Id: Id18a0e1973c18c1ed9422748d6671cb012ce0f3a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2133174
Commit-Queue: Brandon Wylie <wylieb@chromium.org>
Reviewed-by: default avatarPatrick Noland <pnoland@chromium.org>
Cr-Commit-Position: refs/heads/master@{#756400}
parent 0366599e
...@@ -79,7 +79,7 @@ import jp.tomorrowkey.android.gifplayer.BaseGifImage; ...@@ -79,7 +79,7 @@ import jp.tomorrowkey.android.gifplayer.BaseGifImage;
*/ */
class AutofillAssistantUiTestUtil { class AutofillAssistantUiTestUtil {
/** Image fetcher which synchronously returns a preset image. */ /** Image fetcher which synchronously returns a preset image. */
static class MockImageFetcher extends ImageFetcher { static class MockImageFetcher extends ImageFetcher.ImageFetcherForTesting {
private final Bitmap mBitmapToFetch; private final Bitmap mBitmapToFetch;
private final BaseGifImage mGifToFetch; private final BaseGifImage mGifToFetch;
......
...@@ -15,6 +15,7 @@ import android.graphics.Bitmap; ...@@ -15,6 +15,7 @@ import android.graphics.Bitmap;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito; import org.mockito.Mockito;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config; import org.robolectric.annotation.Config;
...@@ -37,6 +38,10 @@ public class ImageFetcherTest { ...@@ -37,6 +38,10 @@ public class ImageFetcherTest {
* Concrete implementation for testing purposes. * Concrete implementation for testing purposes.
*/ */
private class ImageFetcherForTest extends ImageFetcher { private class ImageFetcherForTest extends ImageFetcher {
ImageFetcherForTest(ImageFetcherBridge imageFetcherBridge) {
super(imageFetcherBridge);
}
@Override @Override
public void fetchGif(String url, String clientName, Callback<BaseGifImage> callback) {} public void fetchGif(String url, String clientName, Callback<BaseGifImage> callback) {}
...@@ -56,6 +61,9 @@ public class ImageFetcherTest { ...@@ -56,6 +61,9 @@ public class ImageFetcherTest {
public void destroy() {} public void destroy() {}
} }
@Mock
ImageFetcherBridge mBridge;
private final Bitmap mBitmap = private final Bitmap mBitmap =
Bitmap.createBitmap(WIDTH_PX, HEIGHT_PX, Bitmap.Config.ARGB_8888); Bitmap.createBitmap(WIDTH_PX, HEIGHT_PX, Bitmap.Config.ARGB_8888);
...@@ -64,33 +72,33 @@ public class ImageFetcherTest { ...@@ -64,33 +72,33 @@ public class ImageFetcherTest {
@Before @Before
public void setUp() { public void setUp() {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
mImageFetcher = Mockito.spy(new ImageFetcherForTest()); mImageFetcher = Mockito.spy(new ImageFetcherForTest(mBridge));
} }
@Test @Test
public void testResize() { public void testResize() {
Bitmap result = ImageFetcher.tryToResizeImage(mBitmap, WIDTH_PX / 2, HEIGHT_PX / 2); Bitmap result = ImageFetcher.resizeImage(mBitmap, WIDTH_PX / 2, HEIGHT_PX / 2);
assertNotEquals(result, mBitmap); assertNotEquals(result, mBitmap);
} }
@Test @Test
public void testResizeBailsOutIfSizeIsZeroOrLess() { public void testResizeBailsOutIfSizeIsZeroOrLess() {
Bitmap result = ImageFetcher.tryToResizeImage(mBitmap, WIDTH_PX - 1, HEIGHT_PX - 1); Bitmap result = ImageFetcher.resizeImage(mBitmap, WIDTH_PX - 1, HEIGHT_PX - 1);
assertNotEquals(result, mBitmap); assertNotEquals(result, mBitmap);
result = ImageFetcher.tryToResizeImage(mBitmap, 0, HEIGHT_PX); result = ImageFetcher.resizeImage(mBitmap, 0, HEIGHT_PX);
assertEquals(result, mBitmap); assertEquals(result, mBitmap);
result = ImageFetcher.tryToResizeImage(mBitmap, WIDTH_PX, 0); result = ImageFetcher.resizeImage(mBitmap, WIDTH_PX, 0);
assertEquals(result, mBitmap); assertEquals(result, mBitmap);
result = ImageFetcher.tryToResizeImage(mBitmap, 0, 0); result = ImageFetcher.resizeImage(mBitmap, 0, 0);
assertEquals(result, mBitmap); assertEquals(result, mBitmap);
result = ImageFetcher.tryToResizeImage(mBitmap, -1, HEIGHT_PX); result = ImageFetcher.resizeImage(mBitmap, -1, HEIGHT_PX);
assertEquals(result, mBitmap); assertEquals(result, mBitmap);
result = ImageFetcher.tryToResizeImage(mBitmap, WIDTH_PX, -1); result = ImageFetcher.resizeImage(mBitmap, WIDTH_PX, -1);
assertEquals(result, mBitmap); assertEquals(result, mBitmap);
} }
......
...@@ -69,17 +69,17 @@ public class InMemoryCachedImageFetcherTest { ...@@ -69,17 +69,17 @@ public class InMemoryCachedImageFetcherTest {
@Before @Before
public void setUp() { public void setUp() {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
ImageFetcherBridge.setupForTesting(mBridge); doReturn(mBridge).when(mCachedImageFetcher).getImageFetcherBridge();
mReferencePool = new DiscardableReferencePool(); mReferencePool = new DiscardableReferencePool();
mBitmapCache = new BitmapCache(mReferencePool, DEFAULT_CACHE_SIZE); mBitmapCache = new BitmapCache(mReferencePool, DEFAULT_CACHE_SIZE);
mInMemoryCachedImageFetcher = mInMemoryCachedImageFetcher =
spy(new InMemoryCachedImageFetcher(mBitmapCache, mCachedImageFetcher)); spy(new InMemoryCachedImageFetcher(mBitmapCache, mCachedImageFetcher));
} }
public void answerFetch(Bitmap bitmap, CachedImageFetcher cachedImageFetcher, public void answerFetch(Bitmap bitmap, boolean deleteBitmapCacheOnFetch) {
boolean deleteBitmapCacheOnFetch) {
mInMemoryCachedImageFetcher = mInMemoryCachedImageFetcher =
spy(new InMemoryCachedImageFetcher(mBitmapCache, cachedImageFetcher)); spy(new InMemoryCachedImageFetcher(mBitmapCache, mCachedImageFetcher));
// clang-format off // clang-format off
doAnswer((InvocationOnMock invocation) -> { doAnswer((InvocationOnMock invocation) -> {
if (deleteBitmapCacheOnFetch) { if (deleteBitmapCacheOnFetch) {
...@@ -98,7 +98,7 @@ public class InMemoryCachedImageFetcherTest { ...@@ -98,7 +98,7 @@ public class InMemoryCachedImageFetcherTest {
@Test @Test
@SmallTest @SmallTest
public void testFetchImageCachesFirstCall() { public void testFetchImageCachesFirstCall() {
answerFetch(mBitmap, mCachedImageFetcher, false); answerFetch(mBitmap, false);
mInMemoryCachedImageFetcher.fetchImage( mInMemoryCachedImageFetcher.fetchImage(
URL, UMA_CLIENT_NAME, WIDTH_PX, HEIGHT_PX, mCallback); URL, UMA_CLIENT_NAME, WIDTH_PX, HEIGHT_PX, mCallback);
verify(mCallback).onResult(eq(mBitmap)); verify(mCallback).onResult(eq(mBitmap));
...@@ -119,7 +119,8 @@ public class InMemoryCachedImageFetcherTest { ...@@ -119,7 +119,8 @@ public class InMemoryCachedImageFetcherTest {
@Test @Test
@SmallTest @SmallTest
public void testFetchImageReturnsNullWhenFetcherIsNull() { public void testFetchImageReturnsNullWhenFetcherIsNull() {
answerFetch(mBitmap, null, false); answerFetch(mBitmap, false);
mInMemoryCachedImageFetcher.setImageFetcherForTesting(null);
doReturn(null) doReturn(null)
.when(mInMemoryCachedImageFetcher) .when(mInMemoryCachedImageFetcher)
.tryToGetBitmap(eq(URL), eq(WIDTH_PX), eq(HEIGHT_PX)); .tryToGetBitmap(eq(URL), eq(WIDTH_PX), eq(HEIGHT_PX));
...@@ -136,7 +137,7 @@ public class InMemoryCachedImageFetcherTest { ...@@ -136,7 +137,7 @@ public class InMemoryCachedImageFetcherTest {
@SmallTest @SmallTest
public void testFetchImageDoesNotCacheAfterDestroy() { public void testFetchImageDoesNotCacheAfterDestroy() {
try { try {
answerFetch(mBitmap, mCachedImageFetcher, true); answerFetch(mBitmap, true);
// No exception should be thrown here when bitmap cache is null. // No exception should be thrown here when bitmap cache is null.
mInMemoryCachedImageFetcher.fetchImage( mInMemoryCachedImageFetcher.fetchImage(
......
...@@ -27,16 +27,55 @@ import jp.tomorrowkey.android.gifplayer.BaseGifImage; ...@@ -27,16 +27,55 @@ import jp.tomorrowkey.android.gifplayer.BaseGifImage;
public class CachedImageFetcher extends ImageFetcher { public class CachedImageFetcher extends ImageFetcher {
private static final String TAG = "CachedImageFetcher"; private static final String TAG = "CachedImageFetcher";
// The native bridge. static class ImageLoader {
private ImageFetcherBridge mImageFetcherBridge; /**
* Attempt to load an image from disk with the given filepath.
*
* @param filePath The path to the image on disk (including the filename).
* @return The Bitmap that's on disk or null if the there's no file or the decoding failed.
*/
Bitmap tryToLoadImageFromDisk(String filePath) {
if (new File(filePath).exists()) {
return BitmapFactory.decodeFile(filePath, null);
} else {
return null;
}
}
/**
* Attempt to load a BaseGifImage from disk with the given filepath.
*
* @param filePath The path to the BaseGifImage on disk (including the filename).
* @return The BaseGifImage that's on disk or null if the there's no file or the decoding
* failed.
*/
BaseGifImage tryToLoadGifFromDisk(String filePath) {
try {
File file = new File(filePath);
byte[] fileBytes = new byte[(int) file.length()];
FileInputStream fileInputStream = new FileInputStream(filePath);
int bytesRead = fileInputStream.read(fileBytes);
if (bytesRead != fileBytes.length) return null;
return new BaseGifImage(fileBytes);
} catch (IOException e) {
Log.w(TAG, "Failed to read: %s", filePath, e);
return null;
}
}
}
private ImageLoader mImageLoader;
/** /**
* Creates a CachedImageFetcher with the given bridge. * Creates a CachedImageFetcher with the given bridge.
* *
* @param bridge Bridge used to interact with native. * @param imageFetcherBridge Bridge used to interact with native.
* @param imageLoader Delegate used to load
*/ */
CachedImageFetcher(ImageFetcherBridge bridge) { CachedImageFetcher(ImageFetcherBridge imageFetcherBridge, ImageLoader imageLoader) {
mImageFetcherBridge = bridge; super(imageFetcherBridge);
mImageLoader = imageLoader;
} }
@Override @Override
...@@ -52,8 +91,8 @@ public class CachedImageFetcher extends ImageFetcher { ...@@ -52,8 +91,8 @@ public class CachedImageFetcher extends ImageFetcher {
long startTimeMillis = System.currentTimeMillis(); long startTimeMillis = System.currentTimeMillis();
PostTask.postTask(TaskTraits.USER_VISIBLE, () -> { PostTask.postTask(TaskTraits.USER_VISIBLE, () -> {
// Try to read the gif from disk, then post back to the ui thread. // Try to read the gif from disk, then post back to the ui thread.
String filePath = mImageFetcherBridge.getFilePath(url); String filePath = getImageFetcherBridge().getFilePath(url);
BaseGifImage cachedGif = tryToLoadGifFromDisk(filePath); BaseGifImage cachedGif = mImageLoader.tryToLoadGifFromDisk(filePath);
PostTask.postTask(UiThreadTaskTraits.USER_VISIBLE, () -> { PostTask.postTask(UiThreadTaskTraits.USER_VISIBLE, () -> {
continueFetchGifAfterDisk(url, clientName, callback, cachedGif, startTimeMillis); continueFetchGifAfterDisk(url, clientName, callback, cachedGif, startTimeMillis);
}); });
...@@ -66,12 +105,12 @@ public class CachedImageFetcher extends ImageFetcher { ...@@ -66,12 +105,12 @@ public class CachedImageFetcher extends ImageFetcher {
if (cachedGif != null) { if (cachedGif != null) {
callback.onResult(cachedGif); callback.onResult(cachedGif);
reportEvent(clientName, ImageFetcherEvent.JAVA_DISK_CACHE_HIT); reportEvent(clientName, ImageFetcherEvent.JAVA_DISK_CACHE_HIT);
mImageFetcherBridge.reportCacheHitTime(clientName, startTimeMillis); getImageFetcherBridge().reportCacheHitTime(clientName, startTimeMillis);
} else { } else {
mImageFetcherBridge.fetchGif( getImageFetcherBridge().fetchGif(
getConfig(), url, clientName, (BaseGifImage gifFromNative) -> { getConfig(), url, clientName, (BaseGifImage gifFromNative) -> {
callback.onResult(gifFromNative); callback.onResult(gifFromNative);
mImageFetcherBridge.reportTotalFetchTimeFromNative( getImageFetcherBridge().reportTotalFetchTimeFromNative(
clientName, startTimeMillis); clientName, startTimeMillis);
}); });
} }
...@@ -86,8 +125,8 @@ public class CachedImageFetcher extends ImageFetcher { ...@@ -86,8 +125,8 @@ public class CachedImageFetcher extends ImageFetcher {
long startTimeMillis = System.currentTimeMillis(); long startTimeMillis = System.currentTimeMillis();
PostTask.postTask(TaskTraits.USER_VISIBLE, () -> { PostTask.postTask(TaskTraits.USER_VISIBLE, () -> {
// Try to read the bitmap from disk, then post back to the ui thread. // Try to read the bitmap from disk, then post back to the ui thread.
String filePath = mImageFetcherBridge.getFilePath(url); String filePath = getImageFetcherBridge().getFilePath(url);
Bitmap bitmap = tryToLoadImageFromDisk(filePath); Bitmap bitmap = mImageLoader.tryToLoadImageFromDisk(filePath);
PostTask.postTask(UiThreadTaskTraits.USER_VISIBLE, () -> { PostTask.postTask(UiThreadTaskTraits.USER_VISIBLE, () -> {
continueFetchImageAfterDisk( continueFetchImageAfterDisk(
url, clientName, width, height, callback, bitmap, startTimeMillis); url, clientName, width, height, callback, bitmap, startTimeMillis);
...@@ -99,14 +138,16 @@ public class CachedImageFetcher extends ImageFetcher { ...@@ -99,14 +138,16 @@ public class CachedImageFetcher extends ImageFetcher {
void continueFetchImageAfterDisk(String url, String clientName, int width, int height, void continueFetchImageAfterDisk(String url, String clientName, int width, int height,
Callback<Bitmap> callback, Bitmap cachedBitmap, long startTimeMillis) { Callback<Bitmap> callback, Bitmap cachedBitmap, long startTimeMillis) {
if (cachedBitmap != null) { if (cachedBitmap != null) {
// In case the image's dimensions on disk don't match the desired dimensions.
cachedBitmap = ImageFetcher.resizeImage(cachedBitmap, width, height);
callback.onResult(cachedBitmap); callback.onResult(cachedBitmap);
reportEvent(clientName, ImageFetcherEvent.JAVA_DISK_CACHE_HIT); reportEvent(clientName, ImageFetcherEvent.JAVA_DISK_CACHE_HIT);
mImageFetcherBridge.reportCacheHitTime(clientName, startTimeMillis); getImageFetcherBridge().reportCacheHitTime(clientName, startTimeMillis);
} else { } else {
mImageFetcherBridge.fetchImage( getImageFetcherBridge().fetchImage(
getConfig(), url, clientName, width, height, (Bitmap bitmapFromNative) -> { getConfig(), url, clientName, width, height, (Bitmap bitmapFromNative) -> {
callback.onResult(bitmapFromNative); callback.onResult(bitmapFromNative);
mImageFetcherBridge.reportTotalFetchTimeFromNative( getImageFetcherBridge().reportTotalFetchTimeFromNative(
clientName, startTimeMillis); clientName, startTimeMillis);
}); });
} }
...@@ -119,31 +160,4 @@ public class CachedImageFetcher extends ImageFetcher { ...@@ -119,31 +160,4 @@ public class CachedImageFetcher extends ImageFetcher {
public @ImageFetcherConfig int getConfig() { public @ImageFetcherConfig int getConfig() {
return ImageFetcherConfig.DISK_CACHE_ONLY; return ImageFetcherConfig.DISK_CACHE_ONLY;
} }
/** Wrapper function to decode a file for disk, useful for testing. */
@VisibleForTesting
Bitmap tryToLoadImageFromDisk(String filePath) {
if (new File(filePath).exists()) {
return BitmapFactory.decodeFile(filePath, null);
} else {
return null;
}
}
@VisibleForTesting
BaseGifImage tryToLoadGifFromDisk(String filePath) {
try {
File file = new File(filePath);
byte[] fileBytes = new byte[(int) file.length()];
FileInputStream fileInputStream = new FileInputStream(filePath);
int bytesRead = fileInputStream.read(fileBytes);
if (bytesRead != fileBytes.length) return null;
return new BaseGifImage(fileBytes);
} catch (IOException e) {
Log.w(TAG, "Failed to read: %s", filePath, e);
return null;
}
}
} }
...@@ -27,6 +27,31 @@ public abstract class ImageFetcher { ...@@ -27,6 +27,31 @@ public abstract class ImageFetcher {
public static final String FEED_UMA_CLIENT_NAME = "Feed"; public static final String FEED_UMA_CLIENT_NAME = "Feed";
public static final String NTP_ANIMATED_LOGO_UMA_CLIENT_NAME = "NewTabPageAnimatedLogo"; public static final String NTP_ANIMATED_LOGO_UMA_CLIENT_NAME = "NewTabPageAnimatedLogo";
/** Base class that can be used for testing. */
public abstract static class ImageFetcherForTesting extends ImageFetcher {
public ImageFetcherForTesting() {}
}
// Singleton ImageFetcherBridge.
private ImageFetcherBridge mImageFetcherBridge;
/** Copy-constructor to support composite instances of ImageFetcher. */
public ImageFetcher(ImageFetcher imageFetcher) {
mImageFetcherBridge = imageFetcher.getImageFetcherBridge();
}
/** Base constructor that takes an ImageFetcherBridge. */
public ImageFetcher(ImageFetcherBridge imageFetcherBridge) {
mImageFetcherBridge = imageFetcherBridge;
}
/** Test constructor */
private ImageFetcher() {}
protected ImageFetcherBridge getImageFetcherBridge() {
return mImageFetcherBridge;
}
/** /**
* Try to resize the given image if the conditions are met. * Try to resize the given image if the conditions are met.
* *
...@@ -37,7 +62,7 @@ public abstract class ImageFetcher { ...@@ -37,7 +62,7 @@ public abstract class ImageFetcher {
* @return The resized image, or the original image if the conditions aren't met. * @return The resized image, or the original image if the conditions aren't met.
*/ */
@VisibleForTesting @VisibleForTesting
public static Bitmap tryToResizeImage(@Nullable Bitmap bitmap, int width, int height) { public static Bitmap resizeImage(@Nullable Bitmap bitmap, int width, int height) {
if (bitmap != null && width > 0 && height > 0 && bitmap.getWidth() != width if (bitmap != null && width > 0 && height > 0 && bitmap.getWidth() != width
&& bitmap.getHeight() != height) { && bitmap.getHeight() != height) {
/* The resizing rules are the as follows: /* The resizing rules are the as follows:
...@@ -60,7 +85,7 @@ public abstract class ImageFetcher { ...@@ -60,7 +85,7 @@ public abstract class ImageFetcher {
* @param eventId The event to be reported * @param eventId The event to be reported
*/ */
public void reportEvent(String clientName, @ImageFetcherEvent int eventId) { public void reportEvent(String clientName, @ImageFetcherEvent int eventId) {
ImageFetcherBridge.getInstance().reportEvent(clientName, eventId); mImageFetcherBridge.reportEvent(clientName, eventId);
} }
/** /**
......
...@@ -100,7 +100,7 @@ public class ImageFetcherBridge { ...@@ -100,7 +100,7 @@ public class ImageFetcherBridge {
assert mNativeImageFetcherBridge != 0 : "fetchImage called after destroy"; assert mNativeImageFetcherBridge != 0 : "fetchImage called after destroy";
ImageFetcherBridgeJni.get().fetchImage(mNativeImageFetcherBridge, ImageFetcherBridge.this, ImageFetcherBridgeJni.get().fetchImage(mNativeImageFetcherBridge, ImageFetcherBridge.this,
config, url, clientName, (bitmap) -> { config, url, clientName, (bitmap) -> {
callback.onResult(ImageFetcher.tryToResizeImage(bitmap, width, height)); callback.onResult(ImageFetcher.resizeImage(bitmap, width, height));
}); });
} }
......
...@@ -62,7 +62,8 @@ public class ImageFetcherFactory { ...@@ -62,7 +62,8 @@ public class ImageFetcherFactory {
return sNetworkImageFetcher; return sNetworkImageFetcher;
case ImageFetcherConfig.DISK_CACHE_ONLY: case ImageFetcherConfig.DISK_CACHE_ONLY:
if (sCachedImageFetcher == null) { if (sCachedImageFetcher == null) {
sCachedImageFetcher = new CachedImageFetcher(imageFetcherBridge); sCachedImageFetcher = new CachedImageFetcher(
imageFetcherBridge, new CachedImageFetcher.ImageLoader());
} }
return sCachedImageFetcher; return sCachedImageFetcher;
case ImageFetcherConfig.IN_MEMORY_ONLY: case ImageFetcherConfig.IN_MEMORY_ONLY:
......
...@@ -6,6 +6,7 @@ package org.chromium.chrome.browser.image_fetcher; ...@@ -6,6 +6,7 @@ package org.chromium.chrome.browser.image_fetcher;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
...@@ -34,7 +35,9 @@ public class InMemoryCachedImageFetcher extends ImageFetcher { ...@@ -34,7 +35,9 @@ public class InMemoryCachedImageFetcher extends ImageFetcher {
* @param imageFetcher The image fetcher to back this. Must be Cached/NetworkImageFetcher. * @param imageFetcher The image fetcher to back this. Must be Cached/NetworkImageFetcher.
* @param referencePool Pool used to discard references when under memory pressure. * @param referencePool Pool used to discard references when under memory pressure.
*/ */
InMemoryCachedImageFetcher(ImageFetcher imageFetcher, DiscardableReferencePool referencePool) { InMemoryCachedImageFetcher(
@NonNull ImageFetcher imageFetcher, @NonNull DiscardableReferencePool referencePool) {
super(imageFetcher);
init(imageFetcher, new BitmapCache(referencePool, determineCacheSize(DEFAULT_CACHE_SIZE))); init(imageFetcher, new BitmapCache(referencePool, determineCacheSize(DEFAULT_CACHE_SIZE)));
} }
...@@ -45,8 +48,9 @@ public class InMemoryCachedImageFetcher extends ImageFetcher { ...@@ -45,8 +48,9 @@ public class InMemoryCachedImageFetcher extends ImageFetcher {
* @param cacheSize The cache size to use (in bytes), may be smaller depending on the device's * @param cacheSize The cache size to use (in bytes), may be smaller depending on the device's
* memory. * memory.
*/ */
InMemoryCachedImageFetcher( InMemoryCachedImageFetcher(@NonNull ImageFetcher imageFetcher,
ImageFetcher imageFetcher, DiscardableReferencePool referencePool, int cacheSize) { @NonNull DiscardableReferencePool referencePool, int cacheSize) {
super(imageFetcher);
init(imageFetcher, new BitmapCache(referencePool, determineCacheSize(cacheSize))); init(imageFetcher, new BitmapCache(referencePool, determineCacheSize(cacheSize)));
} }
...@@ -187,8 +191,14 @@ public class InMemoryCachedImageFetcher extends ImageFetcher { ...@@ -187,8 +191,14 @@ public class InMemoryCachedImageFetcher extends ImageFetcher {
/** Test constructor. */ /** Test constructor. */
@VisibleForTesting @VisibleForTesting
InMemoryCachedImageFetcher(BitmapCache bitmapCache, ImageFetcher imageFetcher) { InMemoryCachedImageFetcher(
@NonNull BitmapCache bitmapCache, @NonNull ImageFetcher imageFetcher) {
super(imageFetcher);
mBitmapCache = bitmapCache; mBitmapCache = bitmapCache;
mImageFetcher = imageFetcher; mImageFetcher = imageFetcher;
} }
void setImageFetcherForTesting(ImageFetcher imageFetcher) {
mImageFetcher = imageFetcher;
}
} }
...@@ -14,16 +14,13 @@ import jp.tomorrowkey.android.gifplayer.BaseGifImage; ...@@ -14,16 +14,13 @@ import jp.tomorrowkey.android.gifplayer.BaseGifImage;
* Image Fetcher implementation that fetches from the network. * Image Fetcher implementation that fetches from the network.
*/ */
public class NetworkImageFetcher extends ImageFetcher { public class NetworkImageFetcher extends ImageFetcher {
// The native bridge.
private ImageFetcherBridge mImageFetcherBridge;
/** /**
* Creates a NetworkImageFetcher. * Creates a NetworkImageFetcher.
* *
* @param bridge Bridge used to interact with native. * @param imageFetcherBridge Bridge used to interact with native.
*/ */
NetworkImageFetcher(ImageFetcherBridge bridge) { NetworkImageFetcher(ImageFetcherBridge imageFetcherBridge) {
mImageFetcherBridge = bridge; super(imageFetcherBridge);
} }
@Override @Override
...@@ -33,17 +30,18 @@ public class NetworkImageFetcher extends ImageFetcher { ...@@ -33,17 +30,18 @@ public class NetworkImageFetcher extends ImageFetcher {
@Override @Override
public void fetchGif(String url, String clientName, Callback<BaseGifImage> callback) { public void fetchGif(String url, String clientName, Callback<BaseGifImage> callback) {
mImageFetcherBridge.fetchGif(getConfig(), url, clientName, callback); getImageFetcherBridge().fetchGif(getConfig(), url, clientName, callback);
} }
@Override @Override
public void fetchImage( public void fetchImage(
String url, String clientName, int width, int height, Callback<Bitmap> callback) { String url, String clientName, int width, int height, Callback<Bitmap> callback) {
long startTimeMillis = System.currentTimeMillis(); long startTimeMillis = System.currentTimeMillis();
mImageFetcherBridge.fetchImage( getImageFetcherBridge().fetchImage(
getConfig(), url, clientName, width, height, (Bitmap bitmapFromNative) -> { getConfig(), url, clientName, width, height, (Bitmap bitmapFromNative) -> {
callback.onResult(bitmapFromNative); callback.onResult(bitmapFromNative);
mImageFetcherBridge.reportTotalFetchTimeFromNative(clientName, startTimeMillis); getImageFetcherBridge().reportTotalFetchTimeFromNative(
clientName, startTimeMillis);
}); });
} }
......
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