| 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 "chrome/browser/ui/ash/launcher/launcher_favicon_loader.h" | 5 #include "chrome/browser/ui/ash/launcher/launcher_favicon_loader.h" |
| 6 | 6 |
| 7 #include "ash/shelf/shelf_constants.h" | 7 #include "ash/shelf/shelf_constants.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/memory/weak_ptr.h" | 9 #include "base/memory/weak_ptr.h" |
| 10 #include "content/public/browser/render_view_host.h" | 10 #include "content/public/browser/render_view_host.h" |
| 11 #include "content/public/browser/web_contents.h" | 11 #include "content/public/browser/web_contents.h" |
| 12 #include "content/public/browser/web_contents_observer.h" | 12 #include "content/public/browser/web_contents_observer.h" |
| 13 #include "third_party/skia/include/core/SkBitmap.h" | 13 #include "third_party/skia/include/core/SkBitmap.h" |
| 14 #include "url/gurl.h" | 14 #include "url/gurl.h" |
| 15 | 15 |
| 16 namespace internal { | 16 namespace internal { |
| 17 | 17 |
| 18 const int kMaxBitmapSize = 256; | 18 const int kMaxBitmapSize = 256; |
| 19 | 19 |
| 20 //////////////////////////////////////////////////////////////////////////////// | 20 //////////////////////////////////////////////////////////////////////////////// |
| 21 // FaviconBitmapHandler fetchs all bitmaps with the 'icon' (or 'shortcut icon') | 21 // FaviconRawBitmapHandler fetchs all bitmaps with the 'icon' (or 'shortcut |
| 22 // icon') |
| 22 // link tag, storing the one that best matches ash::kShelfSize. | 23 // link tag, storing the one that best matches ash::kShelfSize. |
| 23 // These icon bitmaps are not resized and are not cached beyond the lifetime | 24 // These icon bitmaps are not resized and are not cached beyond the lifetime |
| 24 // of the class. Bitmaps larger than kMaxBitmapSize are ignored. | 25 // of the class. Bitmaps larger than kMaxBitmapSize are ignored. |
| 25 | 26 |
| 26 class FaviconBitmapHandler : public content::WebContentsObserver { | 27 class FaviconRawBitmapHandler : public content::WebContentsObserver { |
| 27 public: | 28 public: |
| 28 FaviconBitmapHandler(content::WebContents* web_contents, | 29 FaviconRawBitmapHandler(content::WebContents* web_contents, |
| 29 LauncherFaviconLoader::Delegate* delegate) | 30 LauncherFaviconLoader::Delegate* delegate) |
| 30 : content::WebContentsObserver(web_contents), | 31 : content::WebContentsObserver(web_contents), |
| 31 delegate_(delegate), | 32 delegate_(delegate), |
| 32 web_contents_(web_contents), | 33 web_contents_(web_contents), |
| 33 weak_ptr_factory_(this) { | 34 weak_ptr_factory_(this) {} |
| 34 } | |
| 35 | 35 |
| 36 virtual ~FaviconBitmapHandler() {} | 36 virtual ~FaviconRawBitmapHandler() {} |
| 37 | 37 |
| 38 const SkBitmap& bitmap() const { return bitmap_; } | 38 const SkBitmap& bitmap() const { return bitmap_; } |
| 39 | 39 |
| 40 bool HasPendingDownloads() const; | 40 bool HasPendingDownloads() const; |
| 41 | 41 |
| 42 // content::WebContentObserver implementation. | 42 // content::WebContentObserver implementation. |
| 43 virtual void DidUpdateFaviconURL( | 43 virtual void DidUpdateFaviconURL( |
| 44 const std::vector<content::FaviconURL>& candidates) OVERRIDE; | 44 const std::vector<content::FaviconURL>& candidates) OVERRIDE; |
| 45 | 45 |
| 46 private: | 46 private: |
| (...skipping 12 matching lines...) Expand all Loading... |
| 59 | 59 |
| 60 typedef std::set<GURL> UrlSet; | 60 typedef std::set<GURL> UrlSet; |
| 61 // Map of pending download urls. | 61 // Map of pending download urls. |
| 62 UrlSet pending_requests_; | 62 UrlSet pending_requests_; |
| 63 // Map of processed urls. | 63 // Map of processed urls. |
| 64 UrlSet processed_requests_; | 64 UrlSet processed_requests_; |
| 65 // Current bitmap and source url. | 65 // Current bitmap and source url. |
| 66 SkBitmap bitmap_; | 66 SkBitmap bitmap_; |
| 67 GURL bitmap_url_; | 67 GURL bitmap_url_; |
| 68 | 68 |
| 69 base::WeakPtrFactory<FaviconBitmapHandler> weak_ptr_factory_; | 69 base::WeakPtrFactory<FaviconRawBitmapHandler> weak_ptr_factory_; |
| 70 | 70 |
| 71 DISALLOW_COPY_AND_ASSIGN(FaviconBitmapHandler); | 71 DISALLOW_COPY_AND_ASSIGN(FaviconRawBitmapHandler); |
| 72 }; | 72 }; |
| 73 | 73 |
| 74 void FaviconBitmapHandler::DidUpdateFaviconURL( | 74 void FaviconRawBitmapHandler::DidUpdateFaviconURL( |
| 75 const std::vector<content::FaviconURL>& candidates) { | 75 const std::vector<content::FaviconURL>& candidates) { |
| 76 // This function receives a complete list of faviocn urls for the page. | 76 // This function receives a complete list of faviocn urls for the page. |
| 77 // It may get called multiple times with the same list, and will also get | 77 // It may get called multiple times with the same list, and will also get |
| 78 // called any time an item is added or removed. As such, we track processed | 78 // called any time an item is added or removed. As such, we track processed |
| 79 // and pending urls, but only until they are removed from the list. | 79 // and pending urls, but only until they are removed from the list. |
| 80 UrlSet new_pending, new_processed; | 80 UrlSet new_pending, new_processed; |
| 81 // Create a map of valid favicon urls. | 81 // Create a map of valid favicon urls. |
| 82 std::set<GURL> urls; | 82 std::set<GURL> urls; |
| 83 std::vector<content::FaviconURL>::const_iterator iter; | 83 std::vector<content::FaviconURL>::const_iterator iter; |
| 84 for (iter = candidates.begin(); iter != candidates.end(); ++iter) { | 84 for (iter = candidates.begin(); iter != candidates.end(); ++iter) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 105 iter != urls.end(); ++iter) { | 105 iter != urls.end(); ++iter) { |
| 106 if (processed_requests_.find(*iter) != processed_requests_.end()) | 106 if (processed_requests_.find(*iter) != processed_requests_.end()) |
| 107 continue; // Skip already processed downloads. | 107 continue; // Skip already processed downloads. |
| 108 if (pending_requests_.find(*iter) != pending_requests_.end()) | 108 if (pending_requests_.find(*iter) != pending_requests_.end()) |
| 109 continue; // Skip already pending downloads. | 109 continue; // Skip already pending downloads. |
| 110 pending_requests_.insert(*iter); | 110 pending_requests_.insert(*iter); |
| 111 web_contents_->DownloadImage( | 111 web_contents_->DownloadImage( |
| 112 *iter, | 112 *iter, |
| 113 true, // is a favicon | 113 true, // is a favicon |
| 114 0, // no maximum size | 114 0, // no maximum size |
| 115 base::Bind(&FaviconBitmapHandler::DidDownloadFavicon, | 115 base::Bind(&FaviconRawBitmapHandler::DidDownloadFavicon, |
| 116 weak_ptr_factory_.GetWeakPtr())); | 116 weak_ptr_factory_.GetWeakPtr())); |
| 117 } | 117 } |
| 118 } | 118 } |
| 119 | 119 |
| 120 bool FaviconBitmapHandler::HasPendingDownloads() const { | 120 bool FaviconRawBitmapHandler::HasPendingDownloads() const { |
| 121 return !pending_requests_.empty(); | 121 return !pending_requests_.empty(); |
| 122 } | 122 } |
| 123 | 123 |
| 124 void FaviconBitmapHandler::DidDownloadFavicon( | 124 void FaviconRawBitmapHandler::DidDownloadFavicon( |
| 125 int id, | 125 int id, |
| 126 int http_status_code, | 126 int http_status_code, |
| 127 const GURL& image_url, | 127 const GURL& image_url, |
| 128 const std::vector<SkBitmap>& bitmaps, | 128 const std::vector<SkBitmap>& bitmaps, |
| 129 const std::vector<gfx::Size>& original_bitmap_sizes) { | 129 const std::vector<gfx::Size>& original_bitmap_sizes) { |
| 130 UrlSet::iterator iter = pending_requests_.find(image_url); | 130 UrlSet::iterator iter = pending_requests_.find(image_url); |
| 131 if (iter == pending_requests_.end()) { | 131 if (iter == pending_requests_.end()) { |
| 132 // Updates are received for all downloads; ignore unrequested urls. | 132 // Updates are received for all downloads; ignore unrequested urls. |
| 133 return; | 133 return; |
| 134 } | 134 } |
| 135 pending_requests_.erase(iter); | 135 pending_requests_.erase(iter); |
| 136 | 136 |
| 137 // Favicon bitmaps are ordered by decreasing width. | 137 // Favicon bitmaps are ordered by decreasing width. |
| 138 if (!bitmaps.empty()) | 138 if (!bitmaps.empty()) |
| 139 AddFavicon(image_url, bitmaps[0]); | 139 AddFavicon(image_url, bitmaps[0]); |
| 140 } | 140 } |
| 141 | 141 |
| 142 void FaviconBitmapHandler::AddFavicon(const GURL& image_url, | 142 void FaviconRawBitmapHandler::AddFavicon(const GURL& image_url, |
| 143 const SkBitmap& new_bitmap) { | 143 const SkBitmap& new_bitmap) { |
| 144 processed_requests_.insert(image_url); | 144 processed_requests_.insert(image_url); |
| 145 if (new_bitmap.height() > kMaxBitmapSize || | 145 if (new_bitmap.height() > kMaxBitmapSize || |
| 146 new_bitmap.width() > kMaxBitmapSize) | 146 new_bitmap.width() > kMaxBitmapSize) |
| 147 return; | 147 return; |
| 148 if (new_bitmap.height() < ash::kShelfSize) | 148 if (new_bitmap.height() < ash::kShelfSize) |
| 149 return; | 149 return; |
| 150 if (!bitmap_.isNull()) { | 150 if (!bitmap_.isNull()) { |
| 151 // We want the smallest icon that is large enough. | 151 // We want the smallest icon that is large enough. |
| 152 if (new_bitmap.height() > bitmap_.height()) | 152 if (new_bitmap.height() > bitmap_.height()) |
| 153 return; | 153 return; |
| 154 } | 154 } |
| 155 bitmap_url_ = image_url; | 155 bitmap_url_ = image_url; |
| 156 bitmap_ = new_bitmap; | 156 bitmap_ = new_bitmap; |
| 157 delegate_->FaviconUpdated(); | 157 delegate_->FaviconUpdated(); |
| 158 } | 158 } |
| 159 | 159 |
| 160 } // namespace internal | 160 } // namespace internal |
| 161 | 161 |
| 162 //////////////////////////////////////////////////////////////////////////////// | 162 //////////////////////////////////////////////////////////////////////////////// |
| 163 | 163 |
| 164 LauncherFaviconLoader::LauncherFaviconLoader(Delegate* delegate, | 164 LauncherFaviconLoader::LauncherFaviconLoader(Delegate* delegate, |
| 165 content::WebContents* web_contents) | 165 content::WebContents* web_contents) |
| 166 : web_contents_(web_contents) { | 166 : web_contents_(web_contents) { |
| 167 favicon_handler_.reset( | 167 favicon_handler_.reset( |
| 168 new internal::FaviconBitmapHandler(web_contents, delegate)); | 168 new internal::FaviconRawBitmapHandler(web_contents, delegate)); |
| 169 } | 169 } |
| 170 | 170 |
| 171 LauncherFaviconLoader::~LauncherFaviconLoader() { | 171 LauncherFaviconLoader::~LauncherFaviconLoader() { |
| 172 } | 172 } |
| 173 | 173 |
| 174 SkBitmap LauncherFaviconLoader::GetFavicon() const { | 174 SkBitmap LauncherFaviconLoader::GetFavicon() const { |
| 175 return favicon_handler_->bitmap(); | 175 return favicon_handler_->bitmap(); |
| 176 } | 176 } |
| 177 | 177 |
| 178 bool LauncherFaviconLoader::HasPendingDownloads() const { | 178 bool LauncherFaviconLoader::HasPendingDownloads() const { |
| 179 return favicon_handler_->HasPendingDownloads(); | 179 return favicon_handler_->HasPendingDownloads(); |
| 180 } | 180 } |
| OLD | NEW |