Commit 6c7d201a authored by Brandon Wylie's avatar Brandon Wylie Committed by Commit Bot

[IC] Java-side CachedImageFetcher implementation

- Allows java to interact with the native CachedImageFetcher.
- Android-side tries to read from disk directly, so the JNI can be
skipped if the image is cached.

Binary-Size: Temporary increase to support quick rollback.
Bug: 897362
Change-Id: Ifd7c77e0eeef56ea49ec53b398b83f7cc134a479
Reviewed-on: https://chromium-review.googlesource.com/c/1297639Reviewed-by: default avatarTommy Nyquist <nyquist@chromium.org>
Reviewed-by: default avatarFilip Gorski <fgorski@chromium.org>
Reviewed-by: default avatarTheresa <twellington@chromium.org>
Reviewed-by: default avatarSky Malice <skym@chromium.org>
Commit-Queue: Brandon Wylie <wylieb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#605874}
parent 54c64ba3
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.cached_image_fetcher;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import org.chromium.base.Callback;
import org.chromium.base.ThreadUtils;
import org.chromium.base.VisibleForTesting;
import org.chromium.base.task.AsyncTask;
import org.chromium.chrome.browser.profiles.Profile;
/**
* Provides cached image fetching capabilities. Uses getLastUsedProfile, which
* will need to be changed when supporting multi-profile.
*/
public class CachedImageFetcher {
private static CachedImageFetcher sInstance;
public static CachedImageFetcher getInstance() {
ThreadUtils.assertOnUiThread();
if (sInstance == null) {
sInstance = new CachedImageFetcher(Profile.getLastUsedProfile());
}
return sInstance;
}
private CachedImageFetcherBridge mCachedImageFetcherBridge;
/**
* Creates a CachedImageFetcher for the current user.
*
* @param profile Profile of the user we are fetching for.
*/
private CachedImageFetcher(Profile profile) {
this(new CachedImageFetcherBridge(profile));
}
/**
* Creates a CachedImageFetcher for testing.
*
* @param bridge Mock bridge to use.
*/
@VisibleForTesting
CachedImageFetcher(CachedImageFetcherBridge bridge) {
mCachedImageFetcherBridge = bridge;
}
/**
* Fetches the image at url with the desired size. Image is null if not
* found or fails decoding.
*
* @param url The url to fetch the image from.
* @param width The new bitmap's desired width (in pixels).
* @param height The new bitmap's desired height (in pixels).
* @param callback The function which will be called when the image is ready.
*/
public void fetchImage(String url, int width, int height, Callback<Bitmap> callback) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.outWidth = width;
options.outHeight = height;
fetchImage(url, options, callback);
}
/**
* Alias of fetchImage that ignores scaling.
*
* @param url The url to fetch the image from.
* @param callback The function which will be called when the image is ready.
*/
public void fetchImage(String url, Callback<Bitmap> callback) {
fetchImage(url, new BitmapFactory.Options(), callback);
}
/**
* Starts an AsyncTask to first check the disk for the desired image, then
* fetches from the network if it isn't found.
*
* @param url The url to fetch the image from.
* @param options Settings when loading the image.
* @param callback The function which will be called when the image is ready.
*/
@VisibleForTesting
protected void fetchImage(
String url, BitmapFactory.Options options, Callback<Bitmap> callback) {
String filePath = mCachedImageFetcherBridge.getFilePath(url);
new AsyncTask<Bitmap>() {
@Override
protected Bitmap doInBackground() {
return tryToLoadImageFromDisk(filePath, options);
}
@Override
protected void onPostExecute(Bitmap bitmap) {
if (bitmap != null) {
callback.onResult(bitmap);
return;
}
mCachedImageFetcherBridge.fetchImage(
url, options.outWidth, options.outHeight, callback);
}
}
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
/** Wrapper function to decode a file for disk, useful for testing. */
@VisibleForTesting
Bitmap tryToLoadImageFromDisk(String filePath, BitmapFactory.Options options) {
return BitmapFactory.decodeFile(filePath, options);
}
}
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.cached_image_fetcher;
import android.graphics.Bitmap;
import org.chromium.base.Callback;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.chrome.browser.profiles.Profile;
/**
* Provides access to native implementations of CachedImageFetcher for the given profile.
*/
@JNINamespace("image_fetcher")
class CachedImageFetcherBridge {
private long mNativeCachedImageFetcherBridge;
/**
* Creates a CachedImageFetcherBridge for accessing the native CachedImageFetcher
* implementation.
*/
public CachedImageFetcherBridge(Profile profile) {
mNativeCachedImageFetcherBridge = nativeInit(profile);
}
/** Cleans up native half of bridge. */
public void destroy() {
assert mNativeCachedImageFetcherBridge != 0;
nativeDestroy(mNativeCachedImageFetcherBridge);
mNativeCachedImageFetcherBridge = 0;
}
/**
* Get the full path of the given url on disk.
*
* @param url The url to hash.
* @return The full path to the resource on disk.
*/
public String getFilePath(String url) {
assert mNativeCachedImageFetcherBridge != 0;
return nativeGetFilePath(mNativeCachedImageFetcherBridge, url);
}
/**
* Fetch the image from native.
*
* @param url The url to fetch.
* @param width The width to use when resizing the image.
* @param height The height to use when resizing the image.
* @param callback The callback to call when the image is ready.
*/
public void fetchImage(String url, int width, int height, Callback<Bitmap> callback) {
assert mNativeCachedImageFetcherBridge != 0;
nativeFetchImage(mNativeCachedImageFetcherBridge, url, width, height, callback);
}
// Native methods
private static native long nativeInit(Profile profile);
private native void nativeDestroy(long nativeCachedImageFetcherBridge);
private native String nativeGetFilePath(long nativeCachedImageFetcherBridge, String url);
private native void nativeFetchImage(long nativeCachedImageFetcherBridge, String url,
int widthPx, int heightPx, Callback<Bitmap> callback);
}
...@@ -1354,6 +1354,8 @@ chrome_java_sources = [ ...@@ -1354,6 +1354,8 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/subresource_filter/TestSubresourceFilterPublisher.java", "java/src/org/chromium/chrome/browser/subresource_filter/TestSubresourceFilterPublisher.java",
"java/src/org/chromium/chrome/browser/printing/PrintShareActivity.java", "java/src/org/chromium/chrome/browser/printing/PrintShareActivity.java",
"java/src/org/chromium/chrome/browser/printing/TabPrinter.java", "java/src/org/chromium/chrome/browser/printing/TabPrinter.java",
"java/src/org/chromium/chrome/browser/cached_image_fetcher/CachedImageFetcher.java",
"java/src/org/chromium/chrome/browser/cached_image_fetcher/CachedImageFetcherBridge.java",
"java/src/org/chromium/chrome/browser/profiles/Profile.java", "java/src/org/chromium/chrome/browser/profiles/Profile.java",
"java/src/org/chromium/chrome/browser/profiles/ProfileDownloader.java", "java/src/org/chromium/chrome/browser/profiles/ProfileDownloader.java",
"java/src/org/chromium/chrome/browser/profiles/ProfileManagerUtils.java", "java/src/org/chromium/chrome/browser/profiles/ProfileManagerUtils.java",
...@@ -2258,6 +2260,7 @@ chrome_junit_test_java_sources = [ ...@@ -2258,6 +2260,7 @@ chrome_junit_test_java_sources = [
"junit/src/org/chromium/chrome/browser/browserservices/OriginTest.java", "junit/src/org/chromium/chrome/browser/browserservices/OriginTest.java",
"junit/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityClientTest.java", "junit/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityClientTest.java",
"junit/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityDisclosureTest.java", "junit/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityDisclosureTest.java",
"junit/src/org/chromium/chrome/browser/cached_image_fetcher/CachedImageFetcherTest.java",
"junit/src/org/chromium/chrome/browser/compositor/animation/CompositorAnimatorTest.java", "junit/src/org/chromium/chrome/browser/compositor/animation/CompositorAnimatorTest.java",
"junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java", "junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java",
"junit/src/org/chromium/chrome/browser/compositor/CompositorSurfaceManagerImplTest.java", "junit/src/org/chromium/chrome/browser/compositor/CompositorSurfaceManagerImplTest.java",
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.cached_image_fetcher;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyObject;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.test.filters.SmallTest;
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.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
import org.robolectric.annotation.Config;
import org.chromium.base.Callback;
import org.chromium.base.task.test.CustomShadowAsyncTask;
import org.chromium.base.test.BaseRobolectricTestRunner;
import org.chromium.chrome.browser.contextmenu.ChromeContextMenuPopulatorTest.ShadowUrlUtilities;
/**
* Unit tests for CachedImageFetcher.
*/
@RunWith(BaseRobolectricTestRunner.class)
@Config(manifest = Config.NONE, shadows = {ShadowUrlUtilities.class, CustomShadowAsyncTask.class})
public class CachedImageFetcherTest {
private static String sDummyUrl = "foo.bar";
CachedImageFetcher mCachedImageFetcher;
@Mock
CachedImageFetcherBridge mCachedImageFetcherBridge;
@Mock
Bitmap mBitmap;
@Captor
ArgumentCaptor<Callback<Bitmap>> mCallbackArgument;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mCachedImageFetcher = Mockito.spy(new CachedImageFetcher(mCachedImageFetcherBridge));
Mockito.doReturn(sDummyUrl).when(mCachedImageFetcherBridge).getFilePath(anyObject());
}
private void answerCallback() {
Mockito.doAnswer((InvocationOnMock invocation) -> {
mCallbackArgument.getValue().onResult(null);
return null;
})
.when(mCachedImageFetcherBridge)
.fetchImage(anyObject(), anyInt(), anyInt(), mCallbackArgument.capture());
}
@Test
@SmallTest
public void testFetchImageWithDimensionsFoundOnDisk() {
answerCallback();
Mockito.doReturn(mBitmap)
.when(mCachedImageFetcher)
.tryToLoadImageFromDisk(anyObject(), anyObject());
mCachedImageFetcher.fetchImage(sDummyUrl, 100, 100,
(Bitmap bitmap)
-> {
// Do nothing.
});
ArgumentCaptor<BitmapFactory.Options> optionsCaptor =
ArgumentCaptor.forClass(BitmapFactory.Options.class);
verify(mCachedImageFetcher).fetchImage(eq(sDummyUrl), optionsCaptor.capture(), any());
BitmapFactory.Options opts = optionsCaptor.getValue();
assertEquals(opts.outWidth, 100);
assertEquals(opts.outHeight, 100);
verify(mCachedImageFetcherBridge, never())
.fetchImage(eq(sDummyUrl), anyInt(), anyInt(), any());
}
@Test
@SmallTest
public void testFetchImageWithNoDimensionsFoundOnDisk() {
answerCallback();
Mockito.doReturn(mBitmap)
.when(mCachedImageFetcher)
.tryToLoadImageFromDisk(anyObject(), anyObject());
mCachedImageFetcher.fetchImage(sDummyUrl,
(Bitmap bitmap)
-> {
// Do nothing.
});
ArgumentCaptor<BitmapFactory.Options> optionsCaptor =
ArgumentCaptor.forClass(BitmapFactory.Options.class);
verify(mCachedImageFetcher).fetchImage(eq(sDummyUrl), optionsCaptor.capture(), any());
BitmapFactory.Options opts = optionsCaptor.getValue();
assertEquals(opts.outWidth, 0);
assertEquals(opts.outHeight, 0);
verify(mCachedImageFetcherBridge, never())
.fetchImage(eq(sDummyUrl), anyInt(), anyInt(), any());
}
@Test
@SmallTest
public void testFetchImageWithNoDimensionsCallToNative() {
answerCallback();
Mockito.doReturn(null)
.when(mCachedImageFetcher)
.tryToLoadImageFromDisk(anyObject(), anyObject());
mCachedImageFetcher.fetchImage(sDummyUrl,
(Bitmap bitmap)
-> {
// Do nothing.
});
ArgumentCaptor<BitmapFactory.Options> optionsCaptor =
ArgumentCaptor.forClass(BitmapFactory.Options.class);
verify(mCachedImageFetcher).fetchImage(eq(sDummyUrl), optionsCaptor.capture(), any());
BitmapFactory.Options opts = optionsCaptor.getValue();
assertEquals(opts.outWidth, 0);
assertEquals(opts.outHeight, 0);
verify(mCachedImageFetcherBridge).fetchImage(eq(sDummyUrl), anyInt(), anyInt(), any());
}
}
\ No newline at end of file
...@@ -2021,6 +2021,8 @@ jumbo_split_static_library("browser") { ...@@ -2021,6 +2021,8 @@ jumbo_split_static_library("browser") {
"android/browsing_data/browsing_data_counter_bridge.h", "android/browsing_data/browsing_data_counter_bridge.h",
"android/browsing_data/url_filter_bridge.cc", "android/browsing_data/url_filter_bridge.cc",
"android/browsing_data/url_filter_bridge.h", "android/browsing_data/url_filter_bridge.h",
"android/cached_image_fetcher/cached_image_fetcher_bridge.cc",
"android/cached_image_fetcher/cached_image_fetcher_bridge.h",
"android/chrome_backup_agent.cc", "android/chrome_backup_agent.cc",
"android/chrome_backup_agent.h", "android/chrome_backup_agent.h",
"android/chrome_backup_watcher.cc", "android/chrome_backup_watcher.cc",
...@@ -4637,6 +4639,7 @@ if (is_android) { ...@@ -4637,6 +4639,7 @@ if (is_android) {
"../android/java/src/org/chromium/chrome/browser/browserservices/OriginVerifier.java", "../android/java/src/org/chromium/chrome/browser/browserservices/OriginVerifier.java",
"../android/java/src/org/chromium/chrome/browser/browserservices/UkmRecorder.java", "../android/java/src/org/chromium/chrome/browser/browserservices/UkmRecorder.java",
"../android/java/src/org/chromium/chrome/browser/browsing_data/UrlFilterBridge.java", "../android/java/src/org/chromium/chrome/browser/browsing_data/UrlFilterBridge.java",
"../android/java/src/org/chromium/chrome/browser/cached_image_fetcher/CachedImageFetcherBridge.java",
"../android/java/src/org/chromium/chrome/browser/childaccounts/ChildAccountFeedbackReporter.java", "../android/java/src/org/chromium/chrome/browser/childaccounts/ChildAccountFeedbackReporter.java",
"../android/java/src/org/chromium/chrome/browser/childaccounts/ChildAccountService.java", "../android/java/src/org/chromium/chrome/browser/childaccounts/ChildAccountService.java",
"../android/java/src/org/chromium/chrome/browser/component_updater/UpdateScheduler.java", "../android/java/src/org/chromium/chrome/browser/component_updater/UpdateScheduler.java",
......
file://components/image_fetcher/OWNERS
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/android/cached_image_fetcher/cached_image_fetcher_bridge.h"
#include <jni.h>
#include <utility>
#include "base/android/callback_android.h"
#include "base/android/jni_string.h"
#include "base/files/file_path.h"
#include "chrome/browser/cached_image_fetcher/cached_image_fetcher_service_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_android.h"
#include "components/image_fetcher/core/cache/image_cache.h"
#include "components/image_fetcher/core/cached_image_fetcher.h"
#include "components/image_fetcher/core/cached_image_fetcher_service.h"
#include "jni/CachedImageFetcherBridge_jni.h"
#include "ui/gfx/android/java_bitmap.h"
#include "ui/gfx/image/image.h"
using base::android::JavaRef;
using base::android::JavaParamRef;
using base::android::ScopedJavaGlobalRef;
using base::android::ScopedJavaLocalRef;
namespace image_fetcher {
namespace {
// Keep in sync with postfix found in image_data_store_disk.cc.
const base::FilePath::CharType kPathPostfix[] =
FILE_PATH_LITERAL("image_data_storage");
constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation =
net::DefineNetworkTrafficAnnotation("cached_image_fetcher", R"(
semantics {
sender: "Cached Image Fetcher Fetch"
description:
"Fetches and caches images for Chrome features."
trigger:
"Triggered when a feature requests an image fetch."
data: "None."
destination: WEBSITE
}
policy {
cookies_allowed: NO
setting:
"Cache can be cleared through settings."
policy_exception_justification:
"This feature allows many different Chrome features to fetch/cache "
"images and thus there is no Chrome-wide policy to disable it."
})");
} // namespace
// static
jlong JNI_CachedImageFetcherBridge_Init(
JNIEnv* j_env,
const JavaParamRef<jclass>& j_caller,
const JavaParamRef<jobject>& j_profile) {
Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile);
base::FilePath file_path =
CachedImageFetcherServiceFactory::GetCachePath(profile).Append(
kPathPostfix);
CachedImageFetcherService* cif_service =
CachedImageFetcherServiceFactory::GetForBrowserContext(profile);
CachedImageFetcherBridge* native_cif_bridge = new CachedImageFetcherBridge(
cif_service->CreateCachedImageFetcher(), file_path);
return reinterpret_cast<intptr_t>(native_cif_bridge);
}
CachedImageFetcherBridge::CachedImageFetcherBridge(
std::unique_ptr<CachedImageFetcher> cached_image_fetcher,
base::FilePath base_file_path)
: cached_image_fetcher_(std::move(cached_image_fetcher)),
base_file_path_(base_file_path),
weak_ptr_factory_(this) {}
CachedImageFetcherBridge::~CachedImageFetcherBridge() = default;
void CachedImageFetcherBridge::Destroy(JNIEnv* j_env,
const JavaRef<jobject>& j_this) {
delete this;
}
ScopedJavaLocalRef<jstring> CachedImageFetcherBridge::GetFilePath(
JNIEnv* j_env,
const JavaRef<jobject>& j_this,
const JavaRef<jstring>& j_url) {
std::string url = base::android::ConvertJavaStringToUTF8(j_url);
std::string file_path =
base_file_path_.Append(ImageCache::HashUrlToKey(url)).MaybeAsASCII();
return base::android::ConvertUTF8ToJavaString(j_env, file_path);
}
void CachedImageFetcherBridge::FetchImage(JNIEnv* j_env,
const JavaRef<jobject>& j_this,
const JavaRef<jstring>& j_url,
const jint width_px,
const jint height_px,
const JavaRef<jobject>& j_callback) {
ScopedJavaGlobalRef<jobject> callback(j_callback);
std::string url = base::android::ConvertJavaStringToUTF8(j_url);
cached_image_fetcher_->SetDesiredImageFrameSize(
gfx::Size(width_px, height_px));
// TODO(wylieb): We checked disk in Java, so provide a way to tell
// CachedImageFetcher to skip checking disk in native.
cached_image_fetcher_->FetchImage(
url, GURL(url),
base::BindOnce(&CachedImageFetcherBridge::OnImageFetched,
weak_ptr_factory_.GetWeakPtr(), callback),
kTrafficAnnotation);
}
void CachedImageFetcherBridge::OnImageFetched(
base::android::ScopedJavaGlobalRef<jobject> callback,
const std::string& id,
const gfx::Image& image,
const RequestMetadata& request_metadata) {
ScopedJavaLocalRef<jobject> j_bitmap;
if (!image.IsEmpty()) {
j_bitmap = gfx::ConvertToJavaBitmap(image.ToSkBitmap());
}
RunObjectCallbackAndroid(callback, j_bitmap);
}
} // namespace image_fetcher
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_ANDROID_CACHED_IMAGE_FETCHER_CACHED_IMAGE_FETCHER_BRIDGE_H_
#define CHROME_BROWSER_ANDROID_CACHED_IMAGE_FETCHER_CACHED_IMAGE_FETCHER_BRIDGE_H_
#include <memory>
#include <string>
#include "base/android/scoped_java_ref.h"
#include "base/files/file_path.h"
#include "base/memory/weak_ptr.h"
#include "components/image_fetcher/core/request_metadata.h"
#include "ui/gfx/image/image.h"
namespace image_fetcher {
class CachedImageFetcher;
// Native counterpart of CachedImageFetcherBridge.java. Owns an instance of
// CachedImageFetcher.
class CachedImageFetcherBridge {
public:
explicit CachedImageFetcherBridge(
std::unique_ptr<CachedImageFetcher> cached_image_fetcher,
base::FilePath base_file_path);
~CachedImageFetcherBridge();
void Destroy(JNIEnv* j_env, const base::android::JavaRef<jobject>& j_this);
base::android::ScopedJavaLocalRef<jstring> GetFilePath(
JNIEnv* j_env,
const base::android::JavaRef<jobject>& j_this,
const base::android::JavaRef<jstring>& j_url);
void FetchImage(JNIEnv* j_env,
const base::android::JavaRef<jobject>& j_this,
const base::android::JavaRef<jstring>& j_url,
const jint width_px,
const jint height_px,
const base::android::JavaRef<jobject>& j_callback);
private:
void OnImageFetched(base::android::ScopedJavaGlobalRef<jobject> callback,
const std::string& id,
const gfx::Image& image,
const RequestMetadata& request_metadata);
std::unique_ptr<CachedImageFetcher> cached_image_fetcher_;
base::FilePath base_file_path_;
base::WeakPtrFactory<CachedImageFetcherBridge> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(CachedImageFetcherBridge);
};
} // namespace image_fetcher
#endif // CHROME_BROWSER_ANDROID_CACHED_IMAGE_FETCHER_CACHED_IMAGE_FETCHER_BRIDGE_H_
...@@ -22,10 +22,6 @@ ...@@ -22,10 +22,6 @@
#include "content/public/browser/browser_context.h" #include "content/public/browser/browser_context.h"
#include "content/public/browser/storage_partition.h" #include "content/public/browser/storage_partition.h"
#if defined(OS_ANDROID)
#include "base/path_service.h"
#endif
namespace image_fetcher { namespace image_fetcher {
namespace { namespace {
...@@ -41,6 +37,13 @@ std::unique_ptr<ImageDecoder> CreateImageDecoderImpl() { ...@@ -41,6 +37,13 @@ std::unique_ptr<ImageDecoder> CreateImageDecoderImpl() {
} // namespace } // namespace
// static
base::FilePath CachedImageFetcherServiceFactory::GetCachePath(
Profile* profile) {
return profile->GetCachePath().Append(kImageCacheSubdir);
}
// static
CachedImageFetcherService* CachedImageFetcherService*
CachedImageFetcherServiceFactory::GetForBrowserContext( CachedImageFetcherServiceFactory::GetForBrowserContext(
content::BrowserContext* context) { content::BrowserContext* context) {
...@@ -48,6 +51,7 @@ CachedImageFetcherServiceFactory::GetForBrowserContext( ...@@ -48,6 +51,7 @@ CachedImageFetcherServiceFactory::GetForBrowserContext(
GetInstance()->GetServiceForBrowserContext(context, true)); GetInstance()->GetServiceForBrowserContext(context, true));
} }
// static
CachedImageFetcherServiceFactory* CachedImageFetcherServiceFactory*
CachedImageFetcherServiceFactory::GetInstance() { CachedImageFetcherServiceFactory::GetInstance() {
return base::Singleton<CachedImageFetcherServiceFactory>::get(); return base::Singleton<CachedImageFetcherServiceFactory>::get();
...@@ -62,17 +66,8 @@ CachedImageFetcherServiceFactory::~CachedImageFetcherServiceFactory() = default; ...@@ -62,17 +66,8 @@ CachedImageFetcherServiceFactory::~CachedImageFetcherServiceFactory() = default;
KeyedService* CachedImageFetcherServiceFactory::BuildServiceInstanceFor( KeyedService* CachedImageFetcherServiceFactory::BuildServiceInstanceFor(
content::BrowserContext* context) const { content::BrowserContext* context) const {
base::FilePath cache_path; Profile* profile = Profile::FromBrowserContext(context);
#if defined(OS_ANDROID) base::FilePath cache_path = GetCachePath(profile);
// On Android, get a special cache directory that is cleared under pressure.
// The subdirectory under needs to be registered file_paths.xml as well.
if (base::PathService::Get(base::DIR_CACHE, &cache_path)) {
cache_path = cache_path.Append(kImageCacheSubdir);
}
#else
// On other platforms, GetCachePath can be cleared by the user.
cache_path = context->GetCachePath().Append(kImageCacheSubdir);
#endif
scoped_refptr<base::SequencedTaskRunner> task_runner = scoped_refptr<base::SequencedTaskRunner> task_runner =
base::CreateSequencedTaskRunnerWithTraits( base::CreateSequencedTaskRunnerWithTraits(
...@@ -84,7 +79,6 @@ KeyedService* CachedImageFetcherServiceFactory::BuildServiceInstanceFor( ...@@ -84,7 +79,6 @@ KeyedService* CachedImageFetcherServiceFactory::BuildServiceInstanceFor(
auto data_store = auto data_store =
std::make_unique<ImageDataStoreDisk>(cache_path, task_runner); std::make_unique<ImageDataStoreDisk>(cache_path, task_runner);
Profile* profile = Profile::FromBrowserContext(context);
scoped_refptr<ImageCache> image_cache = base::MakeRefCounted<ImageCache>( scoped_refptr<ImageCache> image_cache = base::MakeRefCounted<ImageCache>(
std::move(data_store), std::move(metadata_store), profile->GetPrefs(), std::move(data_store), std::move(metadata_store), profile->GetPrefs(),
clock, task_runner); clock, task_runner);
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef CHROME_BROWSER_CACHED_IMAGE_FETCHER_CACHED_IMAGE_FETCHER_SERVICE_FACTORY_H_ #ifndef CHROME_BROWSER_CACHED_IMAGE_FETCHER_CACHED_IMAGE_FETCHER_SERVICE_FACTORY_H_
#define CHROME_BROWSER_CACHED_IMAGE_FETCHER_CACHED_IMAGE_FETCHER_SERVICE_FACTORY_H_ #define CHROME_BROWSER_CACHED_IMAGE_FETCHER_CACHED_IMAGE_FETCHER_SERVICE_FACTORY_H_
#include "base/files/file_path.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/singleton.h" #include "base/memory/singleton.h"
#include "components/keyed_service/content/browser_context_keyed_service_factory.h" #include "components/keyed_service/content/browser_context_keyed_service_factory.h"
...@@ -13,6 +14,8 @@ namespace content { ...@@ -13,6 +14,8 @@ namespace content {
class BrowserContext; class BrowserContext;
} // namespace content } // namespace content
class Profile;
namespace image_fetcher { namespace image_fetcher {
class CachedImageFetcherService; class CachedImageFetcherService;
...@@ -21,6 +24,9 @@ class CachedImageFetcherService; ...@@ -21,6 +24,9 @@ class CachedImageFetcherService;
class CachedImageFetcherServiceFactory class CachedImageFetcherServiceFactory
: public BrowserContextKeyedServiceFactory { : public BrowserContextKeyedServiceFactory {
public: public:
// Return the cache path for the given profile.
static base::FilePath GetCachePath(Profile* profile);
static CachedImageFetcherService* GetForBrowserContext( static CachedImageFetcherService* GetForBrowserContext(
content::BrowserContext* context); content::BrowserContext* context);
static CachedImageFetcherServiceFactory* GetInstance(); static CachedImageFetcherServiceFactory* GetInstance();
......
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