diff options
| author | wnwen <wnwen@chromium.org> | 2015-07-09 07:30:32 -0700 |
|---|---|---|
| committer | Commit bot <commit-bot@chromium.org> | 2015-07-09 14:31:03 +0000 |
| commit | a56aa7bcb6e1872c9daac2076ab108ef8d176084 (patch) | |
| tree | edffbd4320fd9f0c57c10b57f5915c7cfd1049ab | |
| parent | a23e16b2487eb27949a3e0c9eaf2c20385c7346a (diff) | |
| download | chromium_src-a56aa7bcb6e1872c9daac2076ab108ef8d176084.zip chromium_src-a56aa7bcb6e1872c9daac2076ab108ef8d176084.tar.gz chromium_src-a56aa7bcb6e1872c9daac2076ab108ef8d176084.tar.bz2 | |
Fetch the thumbnail directory on FILE thread.
ThumbnailCache performs I/O intensive tasks in the tab cache
directory. The directory lookup was performed on the UI thread
previously, which made the UI unresponsive.
This patch moves the directory lookup to the FILE thread,
together with the actual caching task, thus unblocking the UI
thread and reducing unresponsiveness.
BUG=500681
Review URL: https://codereview.chromium.org/1225833002
Cr-Commit-Position: refs/heads/master@{#338037}
8 files changed, 75 insertions, 53 deletions
diff --git a/base/android/java/src/org/chromium/base/PathUtils.java b/base/android/java/src/org/chromium/base/PathUtils.java index e46fc30..77affe1 100644 --- a/base/android/java/src/org/chromium/base/PathUtils.java +++ b/base/android/java/src/org/chromium/base/PathUtils.java @@ -9,12 +9,14 @@ import android.content.pm.ApplicationInfo; import android.os.AsyncTask; import android.os.Environment; +import java.io.File; import java.util.concurrent.ExecutionException; /** * This class provides the path related methods for the native library. */ public abstract class PathUtils { + private static final String THUMBNAIL_DIRECTORY = "textures"; private static final int DATA_DIRECTORY = 0; private static final int DATABASE_DIRECTORY = 1; @@ -22,6 +24,8 @@ public abstract class PathUtils { private static final int NUM_DIRECTORIES = 3; private static AsyncTask<String, Void, String[]> sDirPathFetchTask; + private static File sThumbnailDirectory; + // Prevent instantiation. private PathUtils() {} @@ -91,6 +95,18 @@ public abstract class PathUtils { return getDirectoryPath(CACHE_DIRECTORY); } + public static File getThumbnailCacheDirectory(Context appContext) { + if (sThumbnailDirectory == null) { + sThumbnailDirectory = appContext.getDir(THUMBNAIL_DIRECTORY, Context.MODE_PRIVATE); + } + return sThumbnailDirectory; + } + + @CalledByNative + public static String getThumbnailCacheDirectoryPath(Context appContext) { + return getThumbnailCacheDirectory(appContext).getAbsolutePath(); + } + /** * @return the public downloads directory. */ diff --git a/base/android/path_utils.cc b/base/android/path_utils.cc index c98007c..caad53a 100644 --- a/base/android/path_utils.cc +++ b/base/android/path_utils.cc @@ -41,6 +41,16 @@ bool GetCacheDirectory(FilePath* result) { return true; } +bool GetThumbnailCacheDirectory(FilePath* result) { + JNIEnv* env = AttachCurrentThread(); + ScopedJavaLocalRef<jstring> path = + Java_PathUtils_getThumbnailCacheDirectoryPath(env, + GetApplicationContext()); + FilePath thumbnail_cache_path(ConvertJavaStringToUTF8(path)); + *result = thumbnail_cache_path; + return true; +} + bool GetDownloadsDirectory(FilePath* result) { JNIEnv* env = AttachCurrentThread(); ScopedJavaLocalRef<jstring> path = diff --git a/base/android/path_utils.h b/base/android/path_utils.h index d3421b3..6501f1b 100644 --- a/base/android/path_utils.h +++ b/base/android/path_utils.h @@ -31,6 +31,10 @@ BASE_EXPORT bool GetDatabaseDirectory(FilePath* result); // cache dir. BASE_EXPORT bool GetCacheDirectory(FilePath* result); +// Retrieves the path to the thumbnail cache directory. The result is placed +// in the FilePath pointed to by 'result'. +BASE_EXPORT bool GetThumbnailCacheDirectory(FilePath* result); + // Retrieves the path to the public downloads directory. The result is placed // in the FilePath pointed to by 'result'. BASE_EXPORT bool GetDownloadsDirectory(FilePath* result); diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManager.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManager.java index 4abd5e8..310da01 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManager.java @@ -13,6 +13,7 @@ import android.view.View; import org.chromium.base.CalledByNative; import org.chromium.base.CommandLine; import org.chromium.base.JNINamespace; +import org.chromium.base.PathUtils; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.browser.NativePage; @@ -31,9 +32,7 @@ import java.util.List; */ @JNINamespace("chrome::android") public class TabContentManager { - private static final String THUMBNAIL_DIRECTORY = "textures"; private final Context mContext; - private final File mThumbnailsDir; private final float mThumbnailScale; private final int mFullResThumbnailsMaxSize; private final ContentOffsetProvider mContentOffsetProvider; @@ -96,9 +95,6 @@ public class TabContentManager { mContentOffsetProvider = contentOffsetProvider; mSnapshotsEnabled = snapshotsEnabled; - mThumbnailsDir = mContext.getDir(THUMBNAIL_DIRECTORY, Context.MODE_PRIVATE); - String diskCachePath = mThumbnailsDir.getAbsolutePath(); - // Override the cache size on the command line with --thumbnails=100 int defaultCacheSize = getIntegerResourceWithOverride(mContext, R.integer.default_thumbnail_cache_size, ChromeSwitches.THUMBNAILS); @@ -135,7 +131,7 @@ public class TabContentManager { mPriorityTabIds = new int[mFullResThumbnailsMaxSize]; - mNativeTabContentManager = nativeInit(diskCachePath, defaultCacheSize, + mNativeTabContentManager = nativeInit(defaultCacheSize, approximationCacheSize, compressionQueueMaxSize, writeQueueMaxSize, useApproximationThumbnails); } @@ -331,8 +327,9 @@ public class TabContentManager { * @param modelSelector The selector that answers whether a tab is currently present. */ public void cleanupPersistentData(TabModelSelector modelSelector) { - File[] files = mThumbnailsDir.listFiles(); - if (files == null || mNativeTabContentManager == 0) return; + if (mNativeTabContentManager == 0) return; + File[] files = PathUtils.getThumbnailCacheDirectory(mContext).listFiles(); + if (files == null) return; for (File file : files) { try { @@ -365,9 +362,8 @@ public class TabContentManager { } // Class Object Methods - private native long nativeInit(String diskCachePath, int defaultCacheSize, - int approximationCacheSize, int compressionQueueMaxSize, int writeQueueMaxSize, - boolean useApproximationThumbnail); + private native long nativeInit(int defaultCacheSize, int approximationCacheSize, + int compressionQueueMaxSize, int writeQueueMaxSize, boolean useApproximationThumbnail); private native boolean nativeHasFullCachedThumbnail(long nativeTabContentManager, int tabId); private native void nativeCacheTab(long nativeTabContentManager, Object tab, Object contentViewCore, float thumbnailScale); diff --git a/chrome/browser/android/compositor/tab_content_manager.cc b/chrome/browser/android/compositor/tab_content_manager.cc index 0340aac..4da3916 100644 --- a/chrome/browser/android/compositor/tab_content_manager.cc +++ b/chrome/browser/android/compositor/tab_content_manager.cc @@ -129,19 +129,16 @@ TabContentManager* TabContentManager::FromJavaObject(jobject jobj) { TabContentManager::TabContentManager(JNIEnv* env, jobject obj, - jstring disk_cache_path, jint default_cache_size, jint approximation_cache_size, jint compression_queue_max_size, jint write_queue_max_size, jboolean use_approximation_thumbnail) : weak_java_tab_content_manager_(env, obj), weak_factory_(this) { - std::string disk_cache_path_str = - base::android::ConvertJavaStringToUTF8(env, disk_cache_path); thumbnail_cache_ = make_scoped_ptr(new ThumbnailCache( - disk_cache_path_str, (size_t)default_cache_size, - (size_t)approximation_cache_size, (size_t)compression_queue_max_size, - (size_t)write_queue_max_size, use_approximation_thumbnail)); + (size_t)default_cache_size, (size_t)approximation_cache_size, + (size_t)compression_queue_max_size, (size_t)write_queue_max_size, + use_approximation_thumbnail)); thumbnail_cache_->AddThumbnailCacheObserver(this); } @@ -374,14 +371,13 @@ bool RegisterTabContentManager(JNIEnv* env) { jlong Init(JNIEnv* env, jobject obj, - jstring disk_cache_path, jint default_cache_size, jint approximation_cache_size, jint compression_queue_max_size, jint write_queue_max_size, jboolean use_approximation_thumbnail) { TabContentManager* manager = new TabContentManager( - env, obj, disk_cache_path, default_cache_size, approximation_cache_size, + env, obj, default_cache_size, approximation_cache_size, compression_queue_max_size, write_queue_max_size, use_approximation_thumbnail); return reinterpret_cast<intptr_t>(manager); diff --git a/chrome/browser/android/compositor/tab_content_manager.h b/chrome/browser/android/compositor/tab_content_manager.h index df4f897..78dec23 100644 --- a/chrome/browser/android/compositor/tab_content_manager.h +++ b/chrome/browser/android/compositor/tab_content_manager.h @@ -38,7 +38,6 @@ class TabContentManager : public ThumbnailCacheObserver { TabContentManager(JNIEnv* env, jobject obj, - jstring disk_cache_path, jint default_cache_size, jint approximation_cache_size, jint compression_queue_max_size, diff --git a/chrome/browser/android/thumbnail/thumbnail_cache.cc b/chrome/browser/android/thumbnail/thumbnail_cache.cc index 2291e7d..b484ca8 100644 --- a/chrome/browser/android/thumbnail/thumbnail_cache.cc +++ b/chrome/browser/android/thumbnail/thumbnail_cache.cc @@ -7,6 +7,7 @@ #include <algorithm> #include <cmath> +#include "base/android/path_utils.h" #include "base/big_endian.h" #include "base/files/file.h" #include "base/files/file_enumerator.h" @@ -111,14 +112,12 @@ bool WriteBigEndianFloatToFile(base::File& file, float val) { } // anonymous namespace -ThumbnailCache::ThumbnailCache(const std::string& disk_cache_path_str, - size_t default_cache_size, +ThumbnailCache::ThumbnailCache(size_t default_cache_size, size_t approximation_cache_size, size_t compression_queue_max_size, size_t write_queue_max_size, bool use_approximation_thumbnail) - : disk_cache_path_(disk_cache_path_str), - compression_queue_max_size_(compression_queue_max_size), + : compression_queue_max_size_(compression_queue_max_size), write_queue_max_size_(write_queue_max_size), use_approximation_thumbnail_(use_approximation_thumbnail), compression_tasks_count_(0), @@ -226,7 +225,6 @@ Thumbnail* ThumbnailCache::Get(TabId tab_id, void ThumbnailCache::RemoveFromDiskAtAndAboveId(TabId min_id) { base::Closure remove_task = base::Bind(&ThumbnailCache::RemoveFromDiskAtAndAboveIdTask, - disk_cache_path_, min_id); content::BrowserThread::PostTask( content::BrowserThread::FILE, FROM_HERE, remove_task); @@ -243,6 +241,17 @@ void ThumbnailCache::InvalidateThumbnailIfChanged(TabId tab_id, } } +base::FilePath ThumbnailCache::GetCacheDirectory() { + base::FilePath path; + base::android::GetThumbnailCacheDirectory(&path); + return path; +} + +base::FilePath ThumbnailCache::GetFilePath(TabId tab_id) { + base::FilePath path = GetCacheDirectory(); + return path.Append(base::IntToString(tab_id)); +} + bool ThumbnailCache::CheckAndUpdateThumbnailMetaData(TabId tab_id, const GURL& url) { base::Time current_time = base::Time::Now(); @@ -309,8 +318,6 @@ void ThumbnailCache::DecompressThumbnailFromFile( TabId tab_id, const base::Callback<void(bool, SkBitmap)>& post_decompress_callback) { - base::FilePath file_path = GetFilePath(tab_id); - base::Callback<void(skia::RefPtr<SkPixelRef>, float, const gfx::Size&)> decompress_task = base::Bind( &ThumbnailCache::DecompressionTask, post_decompress_callback); @@ -318,25 +325,24 @@ void ThumbnailCache::DecompressThumbnailFromFile( content::BrowserThread::PostTask( content::BrowserThread::FILE, FROM_HERE, - base::Bind(&ThumbnailCache::ReadTask, true, file_path, decompress_task)); + base::Bind(&ThumbnailCache::ReadTask, true, tab_id, decompress_task)); } void ThumbnailCache::RemoveFromDisk(TabId tab_id) { - base::FilePath file_path = GetFilePath(tab_id); base::Closure task = - base::Bind(&ThumbnailCache::RemoveFromDiskTask, file_path); + base::Bind(&ThumbnailCache::RemoveFromDiskTask, tab_id); content::BrowserThread::PostTask( content::BrowserThread::FILE, FROM_HERE, task); } -void ThumbnailCache::RemoveFromDiskTask(const base::FilePath& file_path) { +void ThumbnailCache::RemoveFromDiskTask(TabId tab_id) { + base::FilePath file_path = GetFilePath(tab_id); if (base::PathExists(file_path)) base::DeleteFile(file_path, false); } -void ThumbnailCache::RemoveFromDiskAtAndAboveIdTask( - const base::FilePath& dir_path, - TabId min_id) { +void ThumbnailCache::RemoveFromDiskAtAndAboveIdTask(TabId min_id) { + base::FilePath dir_path = GetCacheDirectory(); base::FileEnumerator enumerator(dir_path, false, base::FileEnumerator::FILES); while (true) { base::FilePath path = enumerator.Next(); @@ -365,7 +371,7 @@ void ThumbnailCache::WriteThumbnailIfNecessary( content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE, base::Bind(&ThumbnailCache::WriteTask, - GetFilePath(tab_id), + tab_id, compressed_data, scale, content_size, @@ -410,8 +416,6 @@ void ThumbnailCache::ReadNextThumbnail() { TabId tab_id = read_queue_.front(); read_in_progress_ = true; - base::FilePath file_path = GetFilePath(tab_id); - base::Callback<void(skia::RefPtr<SkPixelRef>, float, const gfx::Size&)> post_read_task = base::Bind( &ThumbnailCache::PostReadTask, weak_factory_.GetWeakPtr(), tab_id); @@ -419,7 +423,7 @@ void ThumbnailCache::ReadNextThumbnail() { content::BrowserThread::PostTask( content::BrowserThread::FILE, FROM_HERE, - base::Bind(&ThumbnailCache::ReadTask, false, file_path, post_read_task)); + base::Bind(&ThumbnailCache::ReadTask, false, tab_id, post_read_task)); } void ThumbnailCache::MakeSpaceForNewItemIfNecessary(TabId tab_id) { @@ -483,10 +487,6 @@ void ThumbnailCache::InvalidateCachedThumbnail(Thumbnail* thumbnail) { approximation_cache_.Remove(tab_id); } -base::FilePath ThumbnailCache::GetFilePath(TabId tab_id) const { - return disk_cache_path_.Append(base::IntToString(tab_id)); -} - namespace { bool WriteToFile(base::File& file, @@ -540,13 +540,15 @@ bool WriteToFile(base::File& file, } // anonymous namespace -void ThumbnailCache::WriteTask(const base::FilePath& file_path, +void ThumbnailCache::WriteTask(TabId tab_id, skia::RefPtr<SkPixelRef> compressed_data, float scale, const gfx::Size& content_size, const base::Callback<void()>& post_write_task) { DCHECK(compressed_data); + base::FilePath file_path = GetFilePath(tab_id); + base::File file(file_path, base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE); @@ -746,13 +748,14 @@ bool ReadFromFile(base::File& file, void ThumbnailCache::ReadTask( bool decompress, - const base::FilePath& file_path, + TabId tab_id, const base::Callback< void(skia::RefPtr<SkPixelRef>, float, const gfx::Size&)>& post_read_task) { gfx::Size content_size; float scale = 0.f; skia::RefPtr<SkPixelRef> compressed_data; + base::FilePath file_path = GetFilePath(tab_id); if (base::PathExists(file_path)) { base::File file(file_path, base::File::FLAG_OPEN | base::File::FLAG_READ); diff --git a/chrome/browser/android/thumbnail/thumbnail_cache.h b/chrome/browser/android/thumbnail/thumbnail_cache.h index cf1f21b..0ab16b4 100644 --- a/chrome/browser/android/thumbnail/thumbnail_cache.h +++ b/chrome/browser/android/thumbnail/thumbnail_cache.h @@ -43,8 +43,7 @@ class ThumbnailCacheObserver { class ThumbnailCache : ThumbnailDelegate { public: - ThumbnailCache(const std::string& disk_cache_path_str, - size_t default_cache_size, + ThumbnailCache(size_t default_cache_size, size_t approximation_cache_size, size_t compression_queue_max_size, size_t write_queue_max_size, @@ -73,6 +72,8 @@ class ThumbnailCache : ThumbnailDelegate { // ThumbnailDelegate implementation void InvalidateCachedThumbnail(Thumbnail* thumbnail) override; + static base::FilePath GetCacheDirectory(); + static base::FilePath GetFilePath(TabId tab_id); private: class ThumbnailMetaData { @@ -91,9 +92,8 @@ class ThumbnailCache : ThumbnailDelegate { typedef base::hash_map<TabId, ThumbnailMetaData> ThumbnailMetaDataMap; void RemoveFromDisk(TabId tab_id); - static void RemoveFromDiskTask(const base::FilePath& file_path); - static void RemoveFromDiskAtAndAboveIdTask(const base::FilePath& dir_path, - TabId min_id); + static void RemoveFromDiskTask(TabId tab_id); + static void RemoveFromDiskAtAndAboveIdTask(TabId min_id); void WriteThumbnailIfNecessary(TabId tab_id, skia::RefPtr<SkPixelRef> compressed_data, float scale, @@ -105,8 +105,7 @@ class ThumbnailCache : ThumbnailDelegate { void ReadNextThumbnail(); void MakeSpaceForNewItemIfNecessary(TabId tab_id); void RemoveFromReadQueue(TabId tab_id); - base::FilePath GetFilePath(TabId tab_id) const; - static void WriteTask(const base::FilePath& file_path, + static void WriteTask(TabId tab_id, skia::RefPtr<SkPixelRef> compressed_data, float scale, const gfx::Size& content_size, @@ -130,7 +129,7 @@ class ThumbnailCache : ThumbnailDelegate { const gfx::Size& encoded_size); static void ReadTask( bool decompress, - const base::FilePath& file_path, + TabId tab_id, const base::Callback< void(skia::RefPtr<SkPixelRef>, float, const gfx::Size&)>& post_read_task); @@ -143,7 +142,6 @@ class ThumbnailCache : ThumbnailDelegate { static std::pair<SkBitmap, float> CreateApproximation(const SkBitmap& bitmap, float scale); - const base::FilePath disk_cache_path_; const size_t compression_queue_max_size_; const size_t write_queue_max_size_; const bool use_approximation_thumbnail_; |
