Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(37)

Side by Side Diff: components/favicon/core/large_icon_service.cc

Issue 1122103003: [Large Icon Service] Move icon resizing into worker thread. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Inject caller's task runner to Session; fix tests by mocking GetBackgroundTaskRunner(). Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/favicon/core/large_icon_service.h" 5 #include "components/favicon/core/large_icon_service.h"
6 6
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/task_runner.h"
11 #include "base/threading/sequenced_worker_pool.h"
7 #include "components/favicon/core/favicon_service.h" 12 #include "components/favicon/core/favicon_service.h"
8 #include "components/favicon_base/fallback_icon_style.h" 13 #include "components/favicon_base/fallback_icon_style.h"
9 #include "components/favicon_base/favicon_types.h" 14 #include "content/public/browser/browser_thread.h"
10 #include "skia/ext/image_operations.h" 15 #include "skia/ext/image_operations.h"
11 #include "ui/gfx/codec/png_codec.h" 16 #include "ui/gfx/codec/png_codec.h"
12 #include "ui/gfx/geometry/size.h" 17 #include "ui/gfx/geometry/size.h"
13 18
19 namespace {
20
21 } // namespace
22
14 namespace favicon { 23 namespace favicon {
15 24
16 LargeIconService::LargeIconService(FaviconService* favicon_service) 25 LargeIconService::Session::Session(
17 : favicon_service_(favicon_service) { 26 int min_source_size_in_pixel,
18 large_icon_types_.push_back(favicon_base::IconType::FAVICON); 27 int desired_size_in_pixel,
19 large_icon_types_.push_back(favicon_base::IconType::TOUCH_ICON); 28 favicon_base::LargeIconCallback callback,
20 large_icon_types_.push_back(favicon_base::IconType::TOUCH_PRECOMPOSED_ICON); 29 scoped_refptr<base::TaskRunner> background_task_runner,
30 base::CancelableTaskTracker* tracker)
31 : min_source_size_in_pixel_(min_source_size_in_pixel),
32 desired_size_in_pixel_(desired_size_in_pixel),
33 callback_(callback),
34 background_task_runner_(background_task_runner),
35 caller_task_runner_(base::MessageLoop::current()->task_runner()),
36 tracker_(tracker) {
21 } 37 }
22 38
23 LargeIconService::~LargeIconService() { 39 LargeIconService::Session::~Session() {
24 } 40 }
25 41
26 base::CancelableTaskTracker::TaskId 42 void LargeIconService::Session::OnIconLookupComplete(
27 LargeIconService::GetLargeIconOrFallbackStyle( 43 const favicon_base::FaviconRawBitmapResult& bitmap_result) {
28 const GURL& page_url, 44 bitmap_result_ = bitmap_result;
29 int min_source_size_in_pixel, 45 tracker_->PostTask(
30 int desired_size_in_pixel, 46 background_task_runner_.get(), FROM_HERE,
31 const favicon_base::LargeIconCallback& callback, 47 base::Bind(&LargeIconService::Session::ProcessIconOnBackgroundThread,
32 base::CancelableTaskTracker* tracker) { 48 this));
pkotwicz 2015/05/11 14:35:08 Shouldn't you use CancelableTaskTracker::PostTaskA
huangs 2015/05/11 15:20:39 Nice! Done.
33 DCHECK_LE(1, min_source_size_in_pixel);
34 DCHECK_LE(0, desired_size_in_pixel);
35
36 // TODO(beaudoin): For now this is just a wrapper around
37 // GetLargestRawFaviconForPageURL. Add the logic required to select the best
38 // possible large icon. Also add logic to fetch-on-demand when the URL of
39 // a large icon is known but its bitmap is not available.
40 return favicon_service_->GetLargestRawFaviconForPageURL(
41 page_url,
42 large_icon_types_,
43 std::max(min_source_size_in_pixel, desired_size_in_pixel),
44 base::Bind(&LargeIconService::RunLargeIconCallback,
45 base::Unretained(this), callback, min_source_size_in_pixel,
46 desired_size_in_pixel),
47 tracker);
48 } 49 }
49 50
50 bool LargeIconService::ResizeLargeIconIfValid( 51 void LargeIconService::Session::ProcessIconOnBackgroundThread() {
52 favicon_base::FaviconRawBitmapResult resized_bitmap_result;
53 if (ResizeLargeIconOnBackgroundThreadIfValid(min_source_size_in_pixel_,
54 desired_size_in_pixel_, bitmap_result_, &resized_bitmap_result)) {
55 result_.reset(
56 new favicon_base::LargeIconResult(resized_bitmap_result));
57 } else {
58 // Failed to resize |bitmap_result|, so compute fallback icon style.
59 scoped_ptr<favicon_base::FallbackIconStyle> fallback_icon_style(
60 new favicon_base::FallbackIconStyle());
61 if (bitmap_result_.is_valid()) {
62 favicon_base::SetDominantColorAsBackground(
63 bitmap_result_.bitmap_data, fallback_icon_style.get());
64 }
65 result_.reset(
66 new favicon_base::LargeIconResult(fallback_icon_style.release()));
67 }
68
69 // Should not use |tracker_|, which should only be used in the caller thread.
70 caller_task_runner_->PostTask(
71 FROM_HERE,
72 base::Bind(&LargeIconService::Session::OnIconProcessingComplete, this));
73 }
74
75 // static
76 bool LargeIconService::Session::ResizeLargeIconOnBackgroundThreadIfValid(
51 int min_source_size_in_pixel, 77 int min_source_size_in_pixel,
52 int desired_size_in_pixel, 78 int desired_size_in_pixel,
53 const favicon_base::FaviconRawBitmapResult& bitmap_result, 79 const favicon_base::FaviconRawBitmapResult& bitmap_result,
54 favicon_base::FaviconRawBitmapResult* resized_bitmap_result) { 80 favicon_base::FaviconRawBitmapResult* resized_bitmap_result) {
55 // Require bitmap to be valid and square. 81 // Require bitmap to be valid and square.
56 if (!bitmap_result.is_valid() || 82 if (!bitmap_result.is_valid() ||
57 bitmap_result.pixel_size.width() != bitmap_result.pixel_size.height()) 83 bitmap_result.pixel_size.width() != bitmap_result.pixel_size.height())
58 return false; 84 return false;
59 85
60 // Require bitmap to be large enough. It's square, so just check width. 86 // Require bitmap to be large enough. It's square, so just check width.
(...skipping 21 matching lines...) Expand all
82 if (!gfx::PNGCodec::EncodeBGRASkBitmap(resized_bitmap, false, &bitmap_data)) 108 if (!gfx::PNGCodec::EncodeBGRASkBitmap(resized_bitmap, false, &bitmap_data))
83 return false; 109 return false;
84 110
85 resized_bitmap_result->pixel_size = 111 resized_bitmap_result->pixel_size =
86 gfx::Size(desired_size_in_pixel, desired_size_in_pixel); 112 gfx::Size(desired_size_in_pixel, desired_size_in_pixel);
87 resized_bitmap_result->bitmap_data = 113 resized_bitmap_result->bitmap_data =
88 base::RefCountedBytes::TakeVector(&bitmap_data); 114 base::RefCountedBytes::TakeVector(&bitmap_data);
89 return true; 115 return true;
90 } 116 }
91 117
92 void LargeIconService::RunLargeIconCallback( 118 void LargeIconService::Session::OnIconProcessingComplete() {
93 const favicon_base::LargeIconCallback& callback, 119 callback_.Run(*result_);
94 int min_source_size_in_pixel, 120 }
95 int desired_size_in_pixel,
96 const favicon_base::FaviconRawBitmapResult& bitmap_result) {
97 favicon_base::FaviconRawBitmapResult resized_bitmap_result;
98 if (ResizeLargeIconIfValid(min_source_size_in_pixel, desired_size_in_pixel,
99 bitmap_result, &resized_bitmap_result)) {
100 callback.Run(favicon_base::LargeIconResult(resized_bitmap_result));
101 return;
102 }
103 121
104 // Failed to resize |bitmap_result|, so compute fallback icon style. 122 LargeIconService::LargeIconService(FaviconService* favicon_service)
105 favicon_base::LargeIconResult result(new favicon_base::FallbackIconStyle()); 123 : favicon_service_(favicon_service) {
106 if (bitmap_result.is_valid()) { 124 large_icon_types_.push_back(favicon_base::IconType::FAVICON);
107 favicon_base::SetDominantColorAsBackground( 125 large_icon_types_.push_back(favicon_base::IconType::TOUCH_ICON);
108 bitmap_result.bitmap_data, result.fallback_icon_style.get()); 126 large_icon_types_.push_back(favicon_base::IconType::TOUCH_PRECOMPOSED_ICON);
109 } 127 }
110 callback.Run(result); 128
129 LargeIconService::~LargeIconService() {
130 }
131
132 base::CancelableTaskTracker::TaskId
133 LargeIconService::GetLargeIconOrFallbackStyle(
134 const GURL& page_url,
135 int min_source_size_in_pixel,
136 int desired_size_in_pixel,
137 const favicon_base::LargeIconCallback& callback,
138 base::CancelableTaskTracker* tracker) {
139 DCHECK_LE(1, min_source_size_in_pixel);
140 DCHECK_LE(0, desired_size_in_pixel);
141
142 scoped_refptr<LargeIconService::Session> session =
143 new LargeIconService::Session(min_source_size_in_pixel,
144 desired_size_in_pixel, callback, GetBackgroundTaskRunner(), tracker);
145
146 // TODO(beaudoin): For now this is just a wrapper around
147 // GetLargestRawFaviconForPageURL. Add the logic required to select the best
148 // possible large icon. Also add logic to fetch-on-demand when the URL of
149 // a large icon is known but its bitmap is not available.
150 return favicon_service_->GetLargestRawFaviconForPageURL(
151 page_url, large_icon_types_, desired_size_in_pixel,
152 base::Bind(&LargeIconService::Session::OnIconLookupComplete, session),
153 tracker);
154 }
155
156 // Returns TaskRunner used to execute background task.
157 scoped_refptr<base::TaskRunner> LargeIconService::GetBackgroundTaskRunner() {
158 return content::BrowserThread::GetBlockingPool()
159 ->GetTaskRunnerWithShutdownBehavior(
160 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
111 } 161 }
112 162
113 } // namespace favicon 163 } // namespace favicon
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698