| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/favicon_service.h" | 5 #include "components/favicon/core/favicon_service.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| 11 #include "base/hash.h" | 11 #include "base/hash.h" |
| 12 #include "base/single_thread_task_runner.h" | 12 #include "base/single_thread_task_runner.h" |
| 13 #include "base/threading/thread_task_runner_handle.h" | 13 #include "base/threading/thread_task_runner_handle.h" |
| 14 #include "base/trace_event/trace_event.h" |
| 14 #include "components/favicon/core/favicon_client.h" | 15 #include "components/favicon/core/favicon_client.h" |
| 15 #include "components/favicon_base/favicon_util.h" | 16 #include "components/favicon_base/favicon_util.h" |
| 16 #include "components/favicon_base/select_favicon_frames.h" | 17 #include "components/favicon_base/select_favicon_frames.h" |
| 17 #include "components/history/core/browser/history_service.h" | 18 #include "components/history/core/browser/history_service.h" |
| 18 #include "third_party/skia/include/core/SkBitmap.h" | 19 #include "third_party/skia/include/core/SkBitmap.h" |
| 19 #include "ui/gfx/codec/png_codec.h" | 20 #include "ui/gfx/codec/png_codec.h" |
| 20 #include "ui/gfx/favicon_size.h" | 21 #include "ui/gfx/favicon_size.h" |
| 21 #include "ui/gfx/image/image_skia.h" | 22 #include "ui/gfx/image/image_skia.h" |
| 22 #include "url/gurl.h" | 23 #include "url/gurl.h" |
| 23 | 24 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 62 void FaviconService::FaviconResultsCallbackRunner( | 63 void FaviconService::FaviconResultsCallbackRunner( |
| 63 const favicon_base::FaviconResultsCallback& callback, | 64 const favicon_base::FaviconResultsCallback& callback, |
| 64 const std::vector<favicon_base::FaviconRawBitmapResult>* results) { | 65 const std::vector<favicon_base::FaviconRawBitmapResult>* results) { |
| 65 callback.Run(*results); | 66 callback.Run(*results); |
| 66 } | 67 } |
| 67 | 68 |
| 68 base::CancelableTaskTracker::TaskId FaviconService::GetFaviconImage( | 69 base::CancelableTaskTracker::TaskId FaviconService::GetFaviconImage( |
| 69 const GURL& icon_url, | 70 const GURL& icon_url, |
| 70 const favicon_base::FaviconImageCallback& callback, | 71 const favicon_base::FaviconImageCallback& callback, |
| 71 base::CancelableTaskTracker* tracker) { | 72 base::CancelableTaskTracker* tracker) { |
| 73 TRACE_EVENT0("browser", "FaviconService::GetFaviconImage"); |
| 72 favicon_base::FaviconResultsCallback callback_runner = | 74 favicon_base::FaviconResultsCallback callback_runner = |
| 73 base::Bind(&FaviconService::RunFaviconImageCallbackWithBitmapResults, | 75 base::Bind(&FaviconService::RunFaviconImageCallbackWithBitmapResults, |
| 74 base::Unretained(this), callback, gfx::kFaviconSize); | 76 base::Unretained(this), callback, gfx::kFaviconSize); |
| 75 if (history_service_) { | 77 if (history_service_) { |
| 76 std::vector<GURL> icon_urls; | 78 std::vector<GURL> icon_urls; |
| 77 icon_urls.push_back(icon_url); | 79 icon_urls.push_back(icon_url); |
| 78 return history_service_->GetFavicons( | 80 return history_service_->GetFavicons( |
| 79 icon_urls, | 81 icon_urls, |
| 80 favicon_base::FAVICON, | 82 favicon_base::FAVICON, |
| 81 GetPixelSizesForFaviconScales(gfx::kFaviconSize), | 83 GetPixelSizesForFaviconScales(gfx::kFaviconSize), |
| 82 callback_runner, | 84 callback_runner, |
| 83 tracker); | 85 tracker); |
| 84 } | 86 } |
| 85 return RunWithEmptyResultAsync(callback_runner, tracker); | 87 return RunWithEmptyResultAsync(callback_runner, tracker); |
| 86 } | 88 } |
| 87 | 89 |
| 88 base::CancelableTaskTracker::TaskId FaviconService::GetRawFavicon( | 90 base::CancelableTaskTracker::TaskId FaviconService::GetRawFavicon( |
| 89 const GURL& icon_url, | 91 const GURL& icon_url, |
| 90 favicon_base::IconType icon_type, | 92 favicon_base::IconType icon_type, |
| 91 int desired_size_in_pixel, | 93 int desired_size_in_pixel, |
| 92 const favicon_base::FaviconRawBitmapCallback& callback, | 94 const favicon_base::FaviconRawBitmapCallback& callback, |
| 93 base::CancelableTaskTracker* tracker) { | 95 base::CancelableTaskTracker* tracker) { |
| 96 TRACE_EVENT0("browser", "FaviconService::GetRawFavicon"); |
| 94 favicon_base::FaviconResultsCallback callback_runner = | 97 favicon_base::FaviconResultsCallback callback_runner = |
| 95 base::Bind(&FaviconService::RunFaviconRawBitmapCallbackWithBitmapResults, | 98 base::Bind(&FaviconService::RunFaviconRawBitmapCallbackWithBitmapResults, |
| 96 base::Unretained(this), callback, desired_size_in_pixel); | 99 base::Unretained(this), callback, desired_size_in_pixel); |
| 97 | 100 |
| 98 if (history_service_) { | 101 if (history_service_) { |
| 99 std::vector<GURL> icon_urls; | 102 std::vector<GURL> icon_urls; |
| 100 icon_urls.push_back(icon_url); | 103 icon_urls.push_back(icon_url); |
| 101 std::vector<int> desired_sizes_in_pixel; | 104 std::vector<int> desired_sizes_in_pixel; |
| 102 desired_sizes_in_pixel.push_back(desired_size_in_pixel); | 105 desired_sizes_in_pixel.push_back(desired_size_in_pixel); |
| 103 | 106 |
| 104 return history_service_->GetFavicons( | 107 return history_service_->GetFavicons( |
| 105 icon_urls, icon_type, desired_sizes_in_pixel, callback_runner, tracker); | 108 icon_urls, icon_type, desired_sizes_in_pixel, callback_runner, tracker); |
| 106 } | 109 } |
| 107 return RunWithEmptyResultAsync(callback_runner, tracker); | 110 return RunWithEmptyResultAsync(callback_runner, tracker); |
| 108 } | 111 } |
| 109 | 112 |
| 110 base::CancelableTaskTracker::TaskId FaviconService::GetFavicon( | 113 base::CancelableTaskTracker::TaskId FaviconService::GetFavicon( |
| 111 const GURL& icon_url, | 114 const GURL& icon_url, |
| 112 favicon_base::IconType icon_type, | 115 favicon_base::IconType icon_type, |
| 113 int desired_size_in_dip, | 116 int desired_size_in_dip, |
| 114 const favicon_base::FaviconResultsCallback& callback, | 117 const favicon_base::FaviconResultsCallback& callback, |
| 115 base::CancelableTaskTracker* tracker) { | 118 base::CancelableTaskTracker* tracker) { |
| 119 TRACE_EVENT0("browser", "FaviconService::GetFavicon"); |
| 116 if (history_service_) { | 120 if (history_service_) { |
| 117 std::vector<GURL> icon_urls; | 121 std::vector<GURL> icon_urls; |
| 118 icon_urls.push_back(icon_url); | 122 icon_urls.push_back(icon_url); |
| 119 return history_service_->GetFavicons( | 123 return history_service_->GetFavicons( |
| 120 icon_urls, | 124 icon_urls, |
| 121 icon_type, | 125 icon_type, |
| 122 GetPixelSizesForFaviconScales(desired_size_in_dip), | 126 GetPixelSizesForFaviconScales(desired_size_in_dip), |
| 123 callback, | 127 callback, |
| 124 tracker); | 128 tracker); |
| 125 } | 129 } |
| 126 return RunWithEmptyResultAsync(callback, tracker); | 130 return RunWithEmptyResultAsync(callback, tracker); |
| 127 } | 131 } |
| 128 | 132 |
| 129 base::CancelableTaskTracker::TaskId FaviconService::GetFaviconImageForPageURL( | 133 base::CancelableTaskTracker::TaskId FaviconService::GetFaviconImageForPageURL( |
| 130 const GURL& page_url, | 134 const GURL& page_url, |
| 131 const favicon_base::FaviconImageCallback& callback, | 135 const favicon_base::FaviconImageCallback& callback, |
| 132 base::CancelableTaskTracker* tracker) { | 136 base::CancelableTaskTracker* tracker) { |
| 137 TRACE_EVENT0("browser", "FaviconService::GetFaviconImageForPageURL"); |
| 133 return GetFaviconForPageURLImpl( | 138 return GetFaviconForPageURLImpl( |
| 134 page_url, favicon_base::FAVICON, | 139 page_url, favicon_base::FAVICON, |
| 135 GetPixelSizesForFaviconScales(gfx::kFaviconSize), | 140 GetPixelSizesForFaviconScales(gfx::kFaviconSize), |
| 136 base::Bind(&FaviconService::RunFaviconImageCallbackWithBitmapResults, | 141 base::Bind(&FaviconService::RunFaviconImageCallbackWithBitmapResults, |
| 137 base::Unretained(this), callback, gfx::kFaviconSize), | 142 base::Unretained(this), callback, gfx::kFaviconSize), |
| 138 tracker); | 143 tracker); |
| 139 } | 144 } |
| 140 | 145 |
| 141 base::CancelableTaskTracker::TaskId FaviconService::GetRawFaviconForPageURL( | 146 base::CancelableTaskTracker::TaskId FaviconService::GetRawFaviconForPageURL( |
| 142 const GURL& page_url, | 147 const GURL& page_url, |
| 143 int icon_types, | 148 int icon_types, |
| 144 int desired_size_in_pixel, | 149 int desired_size_in_pixel, |
| 145 const favicon_base::FaviconRawBitmapCallback& callback, | 150 const favicon_base::FaviconRawBitmapCallback& callback, |
| 146 base::CancelableTaskTracker* tracker) { | 151 base::CancelableTaskTracker* tracker) { |
| 152 TRACE_EVENT0("browser", "FaviconService::GetRawFaviconForPageURL"); |
| 147 std::vector<int> desired_sizes_in_pixel; | 153 std::vector<int> desired_sizes_in_pixel; |
| 148 desired_sizes_in_pixel.push_back(desired_size_in_pixel); | 154 desired_sizes_in_pixel.push_back(desired_size_in_pixel); |
| 149 return GetFaviconForPageURLImpl( | 155 return GetFaviconForPageURLImpl( |
| 150 page_url, icon_types, desired_sizes_in_pixel, | 156 page_url, icon_types, desired_sizes_in_pixel, |
| 151 base::Bind(&FaviconService::RunFaviconRawBitmapCallbackWithBitmapResults, | 157 base::Bind(&FaviconService::RunFaviconRawBitmapCallbackWithBitmapResults, |
| 152 base::Unretained(this), callback, desired_size_in_pixel), | 158 base::Unretained(this), callback, desired_size_in_pixel), |
| 153 tracker); | 159 tracker); |
| 154 } | 160 } |
| 155 | 161 |
| 156 base::CancelableTaskTracker::TaskId | 162 base::CancelableTaskTracker::TaskId |
| 157 FaviconService::GetLargestRawFaviconForPageURL( | 163 FaviconService::GetLargestRawFaviconForPageURL( |
| 158 const GURL& page_url, | 164 const GURL& page_url, |
| 159 const std::vector<int>& icon_types, | 165 const std::vector<int>& icon_types, |
| 160 int minimum_size_in_pixels, | 166 int minimum_size_in_pixels, |
| 161 const favicon_base::FaviconRawBitmapCallback& callback, | 167 const favicon_base::FaviconRawBitmapCallback& callback, |
| 162 base::CancelableTaskTracker* tracker) { | 168 base::CancelableTaskTracker* tracker) { |
| 169 TRACE_EVENT0("browser", "FaviconService::GetLargestRawFaviconForPageURL"); |
| 163 favicon_base::FaviconResultsCallback favicon_results_callback = | 170 favicon_base::FaviconResultsCallback favicon_results_callback = |
| 164 base::Bind(&FaviconService::RunFaviconRawBitmapCallbackWithBitmapResults, | 171 base::Bind(&FaviconService::RunFaviconRawBitmapCallbackWithBitmapResults, |
| 165 base::Unretained(this), callback, 0); | 172 base::Unretained(this), callback, 0); |
| 166 if (favicon_client_ && favicon_client_->IsNativeApplicationURL(page_url)) { | 173 if (favicon_client_ && favicon_client_->IsNativeApplicationURL(page_url)) { |
| 167 std::vector<int> desired_sizes_in_pixel; | 174 std::vector<int> desired_sizes_in_pixel; |
| 168 desired_sizes_in_pixel.push_back(0); | 175 desired_sizes_in_pixel.push_back(0); |
| 169 return favicon_client_->GetFaviconForNativeApplicationURL( | 176 return favicon_client_->GetFaviconForNativeApplicationURL( |
| 170 page_url, desired_sizes_in_pixel, favicon_results_callback, tracker); | 177 page_url, desired_sizes_in_pixel, favicon_results_callback, tracker); |
| 171 } | 178 } |
| 172 if (history_service_) { | 179 if (history_service_) { |
| 173 return history_service_->GetLargestFaviconForURL(page_url, icon_types, | 180 return history_service_->GetLargestFaviconForURL(page_url, icon_types, |
| 174 minimum_size_in_pixels, callback, tracker); | 181 minimum_size_in_pixels, callback, tracker); |
| 175 } | 182 } |
| 176 return RunWithEmptyResultAsync(favicon_results_callback, tracker); | 183 return RunWithEmptyResultAsync(favicon_results_callback, tracker); |
| 177 } | 184 } |
| 178 | 185 |
| 179 base::CancelableTaskTracker::TaskId FaviconService::GetFaviconForPageURL( | 186 base::CancelableTaskTracker::TaskId FaviconService::GetFaviconForPageURL( |
| 180 const GURL& page_url, | 187 const GURL& page_url, |
| 181 int icon_types, | 188 int icon_types, |
| 182 int desired_size_in_dip, | 189 int desired_size_in_dip, |
| 183 const favicon_base::FaviconResultsCallback& callback, | 190 const favicon_base::FaviconResultsCallback& callback, |
| 184 base::CancelableTaskTracker* tracker) { | 191 base::CancelableTaskTracker* tracker) { |
| 192 TRACE_EVENT0("browser", "FaviconService::GetFaviconForPageURL"); |
| 185 return GetFaviconForPageURLImpl( | 193 return GetFaviconForPageURLImpl( |
| 186 page_url, | 194 page_url, |
| 187 icon_types, | 195 icon_types, |
| 188 GetPixelSizesForFaviconScales(desired_size_in_dip), | 196 GetPixelSizesForFaviconScales(desired_size_in_dip), |
| 189 callback, | 197 callback, |
| 190 tracker); | 198 tracker); |
| 191 } | 199 } |
| 192 | 200 |
| 193 base::CancelableTaskTracker::TaskId | 201 base::CancelableTaskTracker::TaskId |
| 194 FaviconService::UpdateFaviconMappingsAndFetch( | 202 FaviconService::UpdateFaviconMappingsAndFetch( |
| (...skipping 12 matching lines...) Expand all Loading... |
| 207 callback, | 215 callback, |
| 208 tracker); | 216 tracker); |
| 209 } | 217 } |
| 210 return RunWithEmptyResultAsync(callback, tracker); | 218 return RunWithEmptyResultAsync(callback, tracker); |
| 211 } | 219 } |
| 212 | 220 |
| 213 base::CancelableTaskTracker::TaskId FaviconService::GetLargestRawFaviconForID( | 221 base::CancelableTaskTracker::TaskId FaviconService::GetLargestRawFaviconForID( |
| 214 favicon_base::FaviconID favicon_id, | 222 favicon_base::FaviconID favicon_id, |
| 215 const favicon_base::FaviconRawBitmapCallback& callback, | 223 const favicon_base::FaviconRawBitmapCallback& callback, |
| 216 base::CancelableTaskTracker* tracker) { | 224 base::CancelableTaskTracker* tracker) { |
| 225 TRACE_EVENT0("browser", "FaviconService::GetLargestRawFaviconForID"); |
| 217 // Use 0 as |desired_size| to get the largest bitmap for |favicon_id| without | 226 // Use 0 as |desired_size| to get the largest bitmap for |favicon_id| without |
| 218 // any resizing. | 227 // any resizing. |
| 219 int desired_size = 0; | 228 int desired_size = 0; |
| 220 favicon_base::FaviconResultsCallback callback_runner = | 229 favicon_base::FaviconResultsCallback callback_runner = |
| 221 base::Bind(&FaviconService::RunFaviconRawBitmapCallbackWithBitmapResults, | 230 base::Bind(&FaviconService::RunFaviconRawBitmapCallbackWithBitmapResults, |
| 222 base::Unretained(this), callback, desired_size); | 231 base::Unretained(this), callback, desired_size); |
| 223 | 232 |
| 224 if (history_service_) { | 233 if (history_service_) { |
| 225 return history_service_->GetFaviconForID( | 234 return history_service_->GetFaviconForID( |
| 226 favicon_id, desired_size, callback_runner, tracker); | 235 favicon_id, desired_size, callback_runner, tracker); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 307 tracker); | 316 tracker); |
| 308 } | 317 } |
| 309 return RunWithEmptyResultAsync(callback, tracker); | 318 return RunWithEmptyResultAsync(callback, tracker); |
| 310 } | 319 } |
| 311 | 320 |
| 312 void FaviconService::RunFaviconImageCallbackWithBitmapResults( | 321 void FaviconService::RunFaviconImageCallbackWithBitmapResults( |
| 313 const favicon_base::FaviconImageCallback& callback, | 322 const favicon_base::FaviconImageCallback& callback, |
| 314 int desired_size_in_dip, | 323 int desired_size_in_dip, |
| 315 const std::vector<favicon_base::FaviconRawBitmapResult>& | 324 const std::vector<favicon_base::FaviconRawBitmapResult>& |
| 316 favicon_bitmap_results) { | 325 favicon_bitmap_results) { |
| 326 TRACE_EVENT0("browser", |
| 327 "FaviconService::RunFaviconImageCallbackWithBitmapResults"); |
| 317 favicon_base::FaviconImageResult image_result; | 328 favicon_base::FaviconImageResult image_result; |
| 318 image_result.image = favicon_base::SelectFaviconFramesFromPNGs( | 329 image_result.image = favicon_base::SelectFaviconFramesFromPNGs( |
| 319 favicon_bitmap_results, | 330 favicon_bitmap_results, |
| 320 favicon_base::GetFaviconScales(), | 331 favicon_base::GetFaviconScales(), |
| 321 desired_size_in_dip); | 332 desired_size_in_dip); |
| 322 favicon_base::SetFaviconColorSpace(&image_result.image); | 333 favicon_base::SetFaviconColorSpace(&image_result.image); |
| 323 | 334 |
| 324 image_result.icon_url = image_result.image.IsEmpty() ? | 335 image_result.icon_url = image_result.image.IsEmpty() ? |
| 325 GURL() : favicon_bitmap_results[0].icon_url; | 336 GURL() : favicon_bitmap_results[0].icon_url; |
| 326 callback.Run(image_result); | 337 callback.Run(image_result); |
| 327 } | 338 } |
| 328 | 339 |
| 329 void FaviconService::RunFaviconRawBitmapCallbackWithBitmapResults( | 340 void FaviconService::RunFaviconRawBitmapCallbackWithBitmapResults( |
| 330 const favicon_base::FaviconRawBitmapCallback& callback, | 341 const favicon_base::FaviconRawBitmapCallback& callback, |
| 331 int desired_size_in_pixel, | 342 int desired_size_in_pixel, |
| 332 const std::vector<favicon_base::FaviconRawBitmapResult>& | 343 const std::vector<favicon_base::FaviconRawBitmapResult>& |
| 333 favicon_bitmap_results) { | 344 favicon_bitmap_results) { |
| 334 if (favicon_bitmap_results.empty() || !favicon_bitmap_results[0].is_valid()) { | 345 TRACE_EVENT0("browser", |
| 335 callback.Run(favicon_base::FaviconRawBitmapResult()); | 346 "FaviconService::RunFaviconRawBitmapCallbackWithBitmapResults"); |
| 336 return; | 347 callback.Run( |
| 337 } | 348 ResizeFaviconBitmapResult(favicon_bitmap_results, desired_size_in_pixel)); |
| 338 | |
| 339 favicon_base::FaviconRawBitmapResult bitmap_result = | |
| 340 favicon_bitmap_results[0]; | |
| 341 | |
| 342 // If the desired size is 0, SelectFaviconFrames() will return the largest | |
| 343 // bitmap without doing any resizing. As |favicon_bitmap_results| has bitmap | |
| 344 // data for a single bitmap, return it and avoid an unnecessary decode. | |
| 345 if (desired_size_in_pixel == 0) { | |
| 346 callback.Run(bitmap_result); | |
| 347 return; | |
| 348 } | |
| 349 | |
| 350 // If history bitmap is already desired pixel size, return early. | |
| 351 if (bitmap_result.pixel_size.width() == desired_size_in_pixel && | |
| 352 bitmap_result.pixel_size.height() == desired_size_in_pixel) { | |
| 353 callback.Run(bitmap_result); | |
| 354 return; | |
| 355 } | |
| 356 | |
| 357 // Convert raw bytes to SkBitmap, resize via SelectFaviconFrames(), then | |
| 358 // convert back. | |
| 359 std::vector<float> desired_favicon_scales; | |
| 360 desired_favicon_scales.push_back(1.0f); | |
| 361 gfx::Image resized_image = favicon_base::SelectFaviconFramesFromPNGs( | |
| 362 favicon_bitmap_results, desired_favicon_scales, desired_size_in_pixel); | |
| 363 | |
| 364 std::vector<unsigned char> resized_bitmap_data; | |
| 365 if (!gfx::PNGCodec::EncodeBGRASkBitmap(resized_image.AsBitmap(), false, | |
| 366 &resized_bitmap_data)) { | |
| 367 callback.Run(favicon_base::FaviconRawBitmapResult()); | |
| 368 return; | |
| 369 } | |
| 370 | |
| 371 bitmap_result.bitmap_data = base::RefCountedBytes::TakeVector( | |
| 372 &resized_bitmap_data); | |
| 373 callback.Run(bitmap_result); | |
| 374 } | 349 } |
| 375 | 350 |
| 376 } // namespace favicon | 351 } // namespace favicon |
| OLD | NEW |