Index: chrome/browser/chromeos/login/user_image_loader.cc |
diff --git a/chrome/browser/chromeos/login/user_image_loader.cc b/chrome/browser/chromeos/login/user_image_loader.cc |
index 4ea3c1c75d4276fa2077befef4d08b45fc049148..084f9ef67c4095e0604a6cf9cfbf0020168f3061 100644 |
--- a/chrome/browser/chromeos/login/user_image_loader.cc |
+++ b/chrome/browser/chromeos/login/user_image_loader.cc |
@@ -1,4 +1,4 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Copyright (c) 2013 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. |
@@ -9,6 +9,7 @@ |
#include "base/file_util.h" |
#include "base/memory/scoped_ptr.h" |
#include "base/message_loop.h" |
+#include "base/threading/worker_pool.h" |
#include "chrome/browser/chromeos/login/helper.h" |
#include "chrome/browser/chromeos/login/user_image.h" |
#include "content/public/browser/browser_thread.h" |
@@ -21,6 +22,8 @@ using content::BrowserThread; |
namespace chromeos { |
+typedef base::SequencedWorkerPool::SequenceToken SequenceToken; |
+ |
UserImageLoader::ImageInfo::ImageInfo(int size, |
const LoadedCallback& loaded_cb) |
: size(size), |
@@ -44,51 +47,67 @@ void UserImageLoader::Start(const std::string& filepath, |
target_message_loop_ = MessageLoop::current(); |
ImageInfo image_info(size, loaded_cb); |
- BrowserThread::PostTask( |
- BrowserThread::FILE, FROM_HERE, |
- base::Bind(&UserImageLoader::LoadImage, this, filepath, image_info)); |
+ base::SequencedWorkerPool* pool = BrowserThread::GetBlockingPool(); |
+ SequenceToken sequence_token = pool->GetSequenceToken(); |
+ scoped_refptr<base::SequencedTaskRunner> task_runner = pool-> |
+ GetSequencedTaskRunnerWithShutdownBehavior(sequence_token, |
+ base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN); |
+ task_runner->PostTask( |
+ FROM_HERE, |
+ base::Bind(&UserImageLoader::LoadImage, this, filepath, image_info, |
+ task_runner)); |
} |
-void UserImageLoader::LoadImage(const std::string& filepath, |
- const ImageInfo& image_info) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
+void UserImageLoader::LoadImage( |
+ const std::string& filepath, |
+ const ImageInfo& image_info, |
+ scoped_refptr<base::SequencedTaskRunner> task_runner) { |
+ DCHECK(task_runner->RunsTasksOnCurrentThread()); |
std::string image_data; |
file_util::ReadFileToString(FilePath(filepath), &image_data); |
scoped_refptr<ImageDecoder> image_decoder = |
new ImageDecoder(this, image_data, image_codec_); |
- image_info_map_.insert(std::make_pair(image_decoder.get(), image_info)); |
- image_decoder->Start(); |
+ { |
+ base::AutoLock lock(lock_); |
+ image_info_map_.insert(std::make_pair(image_decoder.get(), image_info)); |
+ } |
+ image_decoder->Start(task_runner); |
} |
void UserImageLoader::OnImageDecoded(const ImageDecoder* decoder, |
const SkBitmap& decoded_image) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
- |
- ImageInfoMap::iterator info_it = image_info_map_.find(decoder); |
- if (info_it == image_info_map_.end()) { |
- NOTREACHED(); |
- return; |
+ ImageInfoMap::iterator info_it; |
+ scoped_ptr<ImageInfo> image_info; |
+ { |
+ base::AutoLock lock(lock_); |
+ info_it = image_info_map_.find(decoder); |
+ if (info_it == image_info_map_.end()) { |
+ NOTREACHED(); |
+ return; |
+ } |
+ image_info.reset( |
+ new ImageInfo(info_it->second.size, info_it->second.loaded_cb)); |
+ image_info_map_.erase(info_it); |
} |
- const ImageInfo& image_info = info_it->second; |
SkBitmap final_image = decoded_image; |
- if (image_info.size > 0) { |
+ if (image_info->size > 0) { |
// Auto crop the image, taking the largest square in the center. |
int size = std::min(decoded_image.width(), decoded_image.height()); |
int x = (decoded_image.width() - size) / 2; |
int y = (decoded_image.height() - size) / 2; |
SkBitmap cropped_image = |
SkBitmapOperations::CreateTiledBitmap(decoded_image, x, y, size, size); |
- if (size > image_info.size) { |
+ if (size > image_info->size) { |
// Also downsize the image to save space and memory. |
final_image = |
skia::ImageOperations::Resize(cropped_image, |
skia::ImageOperations::RESIZE_LANCZOS3, |
- image_info.size, |
- image_info.size); |
+ image_info->size, |
+ image_info->size); |
} else { |
final_image = cropped_image; |
} |
@@ -101,25 +120,27 @@ void UserImageLoader::OnImageDecoded(const ImageDecoder* decoder, |
user_image.MarkAsSafe(); |
target_message_loop_->PostTask( |
FROM_HERE, |
- base::Bind(image_info.loaded_cb, user_image)); |
- |
- image_info_map_.erase(info_it); |
+ base::Bind(image_info->loaded_cb, user_image)); |
} |
void UserImageLoader::OnDecodeImageFailed(const ImageDecoder* decoder) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
- |
- ImageInfoMap::iterator info_it = image_info_map_.find(decoder); |
- if (info_it == image_info_map_.end()) { |
- NOTREACHED(); |
- return; |
+ ImageInfoMap::iterator info_it; |
+ scoped_ptr<ImageInfo> image_info; |
+ { |
+ base::AutoLock lock(lock_); |
+ info_it = image_info_map_.find(decoder); |
+ if (info_it == image_info_map_.end()) { |
+ NOTREACHED(); |
+ return; |
+ } |
+ image_info.reset( |
+ new ImageInfo(info_it->second.size, info_it->second.loaded_cb)); |
+ image_info_map_.erase(decoder); |
} |
- const ImageInfo& image_info = info_it->second; |
target_message_loop_->PostTask( |
FROM_HERE, |
- base::Bind(image_info.loaded_cb, UserImage())); |
- image_info_map_.erase(decoder); |
+ base::Bind(image_info->loaded_cb, UserImage())); |
} |
} // namespace chromeos |