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

Side by Side Diff: components/favicon/content/content_favicon_driver.cc

Issue 2799273002: Add support to process favicons from Web Manifests (Closed)
Patch Set: Add hacks for demoing (DONOTSUBMIT) Created 3 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/content/content_favicon_driver.h" 5 #include "components/favicon/content/content_favicon_driver.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "components/favicon/content/favicon_url_util.h" 8 #include "components/favicon/content/favicon_url_util.h"
9 #include "components/favicon/core/favicon_service.h" 9 #include "components/favicon/core/favicon_service.h"
10 #include "components/favicon/core/favicon_url.h" 10 #include "components/favicon/core/favicon_url.h"
11 #include "components/history/core/browser/history_service.h" 11 #include "components/history/core/browser/history_service.h"
12 #include "content/public/browser/browser_context.h" 12 #include "content/public/browser/browser_context.h"
13 #include "content/public/browser/favicon_status.h" 13 #include "content/public/browser/favicon_status.h"
14 #include "content/public/browser/navigation_controller.h" 14 #include "content/public/browser/navigation_controller.h"
15 #include "content/public/browser/navigation_details.h" 15 #include "content/public/browser/navigation_details.h"
16 #include "content/public/browser/navigation_entry.h" 16 #include "content/public/browser/navigation_entry.h"
17 #include "content/public/browser/navigation_handle.h" 17 #include "content/public/browser/navigation_handle.h"
18 #include "content/public/common/favicon_url.h" 18 #include "content/public/common/favicon_url.h"
19 #include "content/public/common/manifest.h"
19 #include "ui/gfx/image/image.h" 20 #include "ui/gfx/image/image.h"
20 21
21 DEFINE_WEB_CONTENTS_USER_DATA_KEY(favicon::ContentFaviconDriver); 22 DEFINE_WEB_CONTENTS_USER_DATA_KEY(favicon::ContentFaviconDriver);
22 23
23 namespace favicon { 24 namespace favicon {
25 namespace {
26
27 // TODO / DONOTSUBMIT: Only for prototyping purposes.
28 void ExtractManifestURL(
29 const base::Callback<void(const base::Optional<GURL>&)>& callback,
30 const GURL& manifest_url,
31 const content::Manifest& manifest) {
32 if (manifest_url.is_empty())
33 callback.Run(base::nullopt);
34 else
35 callback.Run(manifest_url);
36 }
37
38 void ExtractManifestIcons(
39 ContentFaviconDriver::ManifestDownloadCallback callback,
40 const GURL& manifest_url,
41 const content::Manifest& manifest) {
42 // TODO/DONOTSUBMIT(mastiz): This should distinguish 404s from other status
43 // codes.
44 std::vector<FaviconURL> candidates;
45 for (const content::Manifest::Icon& icon : manifest.icons) {
46 candidates.emplace_back(icon.src, favicon_base::FAVICON, icon.sizes);
47 }
48 callback.Run(/*status_code=*/200, candidates);
49 }
50
51 } // namespace
24 52
25 // static 53 // static
26 void ContentFaviconDriver::CreateForWebContents( 54 void ContentFaviconDriver::CreateForWebContents(
27 content::WebContents* web_contents, 55 content::WebContents* web_contents,
28 FaviconService* favicon_service, 56 FaviconService* favicon_service,
29 history::HistoryService* history_service, 57 history::HistoryService* history_service,
30 bookmarks::BookmarkModel* bookmark_model) { 58 bookmarks::BookmarkModel* bookmark_model) {
31 if (FromWebContents(web_contents)) 59 if (FromWebContents(web_contents))
32 return; 60 return;
33 61
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 133
106 ContentFaviconDriver::~ContentFaviconDriver() { 134 ContentFaviconDriver::~ContentFaviconDriver() {
107 } 135 }
108 136
109 int ContentFaviconDriver::DownloadImage(const GURL& url, 137 int ContentFaviconDriver::DownloadImage(const GURL& url,
110 int max_image_size, 138 int max_image_size,
111 ImageDownloadCallback callback) { 139 ImageDownloadCallback callback) {
112 bool bypass_cache = (bypass_cache_page_url_ == GetActiveURL()); 140 bool bypass_cache = (bypass_cache_page_url_ == GetActiveURL());
113 bypass_cache_page_url_ = GURL(); 141 bypass_cache_page_url_ = GURL();
114 142
143 LOG(INFO) << "MIKEL Downloading image " << url;
144
115 return web_contents()->DownloadImage(url, true, max_image_size, bypass_cache, 145 return web_contents()->DownloadImage(url, true, max_image_size, bypass_cache,
116 callback); 146 callback);
117 } 147 }
118 148
149 void ContentFaviconDriver::DownloadManifest(const GURL& url,
150 ManifestDownloadCallback callback) {
151 web_contents()->GetManifest(base::Bind(&ExtractManifestIcons, callback));
152 }
153
119 bool ContentFaviconDriver::IsOffTheRecord() { 154 bool ContentFaviconDriver::IsOffTheRecord() {
120 DCHECK(web_contents()); 155 DCHECK(web_contents());
121 return web_contents()->GetBrowserContext()->IsOffTheRecord(); 156 return web_contents()->GetBrowserContext()->IsOffTheRecord();
122 } 157 }
123 158
124 void ContentFaviconDriver::OnFaviconUpdated( 159 void ContentFaviconDriver::OnFaviconUpdated(
125 const GURL& page_url, 160 const GURL& page_url,
126 FaviconDriverObserver::NotificationIconType notification_icon_type, 161 FaviconDriverObserver::NotificationIconType notification_icon_type,
127 const GURL& icon_url, 162 const GURL& icon_url,
128 bool icon_url_changed, 163 bool icon_url_changed,
129 const gfx::Image& image) { 164 const gfx::Image& image) {
130 content::NavigationEntry* entry = 165 content::NavigationEntry* entry =
131 web_contents()->GetController().GetLastCommittedEntry(); 166 web_contents()->GetController().GetLastCommittedEntry();
132 DCHECK(entry && entry->GetURL() == page_url); 167 DCHECK(entry && entry->GetURL() == page_url);
133 168
134 if (notification_icon_type == FaviconDriverObserver::NON_TOUCH_16_DIP) { 169 if (notification_icon_type == FaviconDriverObserver::NON_TOUCH_16_DIP) {
135 entry->GetFavicon().valid = true; 170 entry->GetFavicon().valid = true;
136 entry->GetFavicon().url = icon_url; 171 entry->GetFavicon().url = icon_url;
137 entry->GetFavicon().image = image; 172 entry->GetFavicon().image = image;
138 web_contents()->NotifyNavigationStateChanged(content::INVALIDATE_TYPE_TAB); 173 web_contents()->NotifyNavigationStateChanged(content::INVALIDATE_TYPE_TAB);
139 } 174 }
140 175
141 NotifyFaviconUpdatedObservers(notification_icon_type, icon_url, 176 NotifyFaviconUpdatedObservers(notification_icon_type, icon_url,
142 icon_url_changed, image); 177 icon_url_changed, image);
143 } 178 }
144 179
145 void ContentFaviconDriver::DidUpdateFaviconURL( 180 void ContentFaviconDriver::DidUpdateFaviconURL(
146 const std::vector<content::FaviconURL>& candidates) { 181 const std::vector<content::FaviconURL>& candidates) {
182 LOG(INFO) << "MIKEL DidUpdateFaviconURL() " << candidates.size();
147 DCHECK(!candidates.empty()); 183 DCHECK(!candidates.empty());
148 184
149 // Ignore the update if there is no last committed navigation entry. This can 185 // Ignore the update if there is no last committed navigation entry. This can
150 // occur when loading an initially blank page. 186 // occur when loading an initially blank page.
151 content::NavigationEntry* entry = 187 content::NavigationEntry* entry =
152 web_contents()->GetController().GetLastCommittedEntry(); 188 web_contents()->GetController().GetLastCommittedEntry();
153 if (!entry) 189 if (!entry)
154 return; 190 return;
155 191
156 favicon_urls_ = candidates; 192 favicon_urls_ = candidates;
157 OnUpdateFaviconURL(entry->GetURL(), 193
158 FaviconURLsFromContentFaviconURLs(candidates)); 194 // On regular page loads, DidUpdateManifestURL() is guaranteed to be called
195 // after DidUpdateFaviconURL(). However, a page can update the favicons via
196 // javascript.
197 if (received_manifest_url_) {
198 OnUpdateCandidates(entry->GetURL(),
199 FaviconURLsFromContentFaviconURLs(favicon_urls_),
200 manifest_url_);
201 }
202 }
203
204 void ContentFaviconDriver::DidUpdateManifestURL(
205 const base::Optional<GURL>& manifest_url) {
206 LOG(INFO) << "MIKEL DidUpdateManifestURL() " << manifest_url.value_or(GURL());
207 // Ignore the update if there is no last committed navigation entry. This can
208 // occur when loading an initially blank page.
209 content::NavigationEntry* entry =
210 web_contents()->GetController().GetLastCommittedEntry();
211 if (!entry)
212 return;
213
214 received_manifest_url_ = true;
215 manifest_url_ = manifest_url;
216
217 OnUpdateCandidates(entry->GetURL(),
218 FaviconURLsFromContentFaviconURLs(favicon_urls_),
219 manifest_url);
159 } 220 }
160 221
161 void ContentFaviconDriver::DidStartNavigation( 222 void ContentFaviconDriver::DidStartNavigation(
162 content::NavigationHandle* navigation_handle) { 223 content::NavigationHandle* navigation_handle) {
163 if (!navigation_handle->IsInMainFrame()) 224 if (!navigation_handle->IsInMainFrame())
164 return; 225 return;
165 226
227 favicon_urls_.clear();
228 received_manifest_url_ = false;
229 manifest_url_.reset();
230
166 content::ReloadType reload_type = navigation_handle->GetReloadType(); 231 content::ReloadType reload_type = navigation_handle->GetReloadType();
167 if (reload_type == content::ReloadType::NONE || IsOffTheRecord()) 232 if (reload_type == content::ReloadType::NONE || IsOffTheRecord())
168 return; 233 return;
169 234
170 bypass_cache_page_url_ = navigation_handle->GetURL(); 235 bypass_cache_page_url_ = navigation_handle->GetURL();
171 SetFaviconOutOfDateForPage( 236 SetFaviconOutOfDateForPage(
172 navigation_handle->GetURL(), 237 navigation_handle->GetURL(),
173 reload_type == content::ReloadType::BYPASSING_CACHE); 238 reload_type == content::ReloadType::BYPASSING_CACHE);
174 } 239 }
175 240
176 void ContentFaviconDriver::DidFinishNavigation( 241 void ContentFaviconDriver::DidFinishNavigation(
177 content::NavigationHandle* navigation_handle) { 242 content::NavigationHandle* navigation_handle) {
178 if (!navigation_handle->IsInMainFrame() || 243 if (!navigation_handle->IsInMainFrame() ||
179 !navigation_handle->HasCommitted() || 244 !navigation_handle->HasCommitted() ||
180 navigation_handle->IsErrorPage()) { 245 navigation_handle->IsErrorPage()) {
181 return; 246 return;
182 } 247 }
183 248
184 favicon_urls_.clear(); 249 /////////////////////////////
250 // DONOTSUBMIT / TODO: This hack is here to make the prototype work.
251 base::Callback<void(const base::Optional<GURL>&)> cb =
252 base::Bind(&ContentFaviconDriver::DidUpdateManifestURL,
253 base::Unretained(this));
254 web_contents()->GetManifest(base::Bind(&ExtractManifestURL, cb));
255 /////////////////////////////
185 256
186 // Wait till the user navigates to a new URL to start checking the cache 257 // Wait till the user navigates to a new URL to start checking the cache
187 // again. The cache may be ignored for non-reload navigations (e.g. 258 // again. The cache may be ignored for non-reload navigations (e.g.
188 // history.replace() in-page navigation). This is allowed to increase the 259 // history.replace() in-page navigation). This is allowed to increase the
189 // likelihood that "reloading a page ignoring the cache" redownloads the 260 // likelihood that "reloading a page ignoring the cache" redownloads the
190 // favicon. In particular, a page may do an in-page navigation before 261 // favicon. In particular, a page may do an in-page navigation before
191 // FaviconHandler has the time to determine that the favicon needs to be 262 // FaviconHandler has the time to determine that the favicon needs to be
192 // redownloaded. 263 // redownloaded.
193 GURL url = navigation_handle->GetURL(); 264 GURL url = navigation_handle->GetURL();
194 if (url != bypass_cache_page_url_) 265 if (url != bypass_cache_page_url_)
195 bypass_cache_page_url_ = GURL(); 266 bypass_cache_page_url_ = GURL();
196 267
197 // Get the favicon, either from history or request it from the net. 268 // Get the favicon, either from history or request it from the net.
198 FetchFavicon(url); 269 FetchFavicon(url);
199 } 270 }
200 271
201 } // namespace favicon 272 } // namespace favicon
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698