OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/renderer/chrome_render_view_observer.h" | 5 #include "chrome/renderer/chrome_render_view_observer.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
10 #include "chrome/common/chrome_switches.h" | 10 #include "chrome/common/chrome_switches.h" |
11 #include "chrome/common/render_messages.h" | 11 #include "chrome/common/render_messages.h" |
12 #include "chrome/common/thumbnail_score.h" | 12 #include "chrome/common/thumbnail_score.h" |
| 13 #include "chrome/common/url_constants.h" |
13 #include "chrome/renderer/about_handler.h" | 14 #include "chrome/renderer/about_handler.h" |
| 15 #include "chrome/renderer/automation/dom_automation_controller.h" |
| 16 #include "chrome/renderer/external_host_bindings.h" |
14 #include "chrome/renderer/safe_browsing/phishing_classifier_delegate.h" | 17 #include "chrome/renderer/safe_browsing/phishing_classifier_delegate.h" |
15 #include "chrome/renderer/translate_helper.h" | 18 #include "chrome/renderer/translate_helper.h" |
| 19 #include "content/common/bindings_policy.h" |
16 #include "content/common/view_messages.h" | 20 #include "content/common/view_messages.h" |
17 #include "content/renderer/content_renderer_client.h" | 21 #include "content/renderer/content_renderer_client.h" |
18 #include "content/renderer/render_view.h" | 22 #include "googleurl/src/gurl.h" |
| 23 #include "net/base/data_url.h" |
19 #include "skia/ext/bitmap_platform_device.h" | 24 #include "skia/ext/bitmap_platform_device.h" |
20 #include "skia/ext/image_operations.h" | 25 #include "skia/ext/image_operations.h" |
21 #include "skia/ext/platform_canvas.h" | 26 #include "skia/ext/platform_canvas.h" |
| 27 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCString.h" |
22 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDataSource.h" | 28 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDataSource.h" |
23 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" | 29 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" |
| 30 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPageSerializer.h" |
24 #include "third_party/WebKit/Source/WebKit/chromium/public/WebRect.h" | 31 #include "third_party/WebKit/Source/WebKit/chromium/public/WebRect.h" |
25 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSize.h" | 32 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSize.h" |
| 33 #include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h" |
| 34 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLRequest.h" |
| 35 #include "third_party/WebKit/Source/WebKit/chromium/public/WebVector.h" |
26 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" | 36 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" |
27 #include "ui/gfx/color_utils.h" | 37 #include "ui/gfx/color_utils.h" |
| 38 #include "ui/gfx/favicon_size.h" |
28 #include "ui/gfx/skbitmap_operations.h" | 39 #include "ui/gfx/skbitmap_operations.h" |
| 40 #include "webkit/glue/dom_operations.h" |
| 41 #include "webkit/glue/image_decoder.h" |
| 42 #include "webkit/glue/image_resource_fetcher.h" |
29 #include "webkit/glue/webkit_glue.h" | 43 #include "webkit/glue/webkit_glue.h" |
| 44 #include "v8/include/v8-testing.h" |
30 | 45 |
| 46 using WebKit::WebCString; |
31 using WebKit::WebDataSource; | 47 using WebKit::WebDataSource; |
32 using WebKit::WebFrame; | 48 using WebKit::WebFrame; |
| 49 using WebKit::WebPageSerializer; |
| 50 using WebKit::WebPageSerializerClient; |
33 using WebKit::WebRect; | 51 using WebKit::WebRect; |
34 using WebKit::WebSize; | 52 using WebKit::WebSize; |
| 53 using WebKit::WebString; |
| 54 using WebKit::WebURL; |
| 55 using WebKit::WebURLRequest; |
35 using WebKit::WebView; | 56 using WebKit::WebView; |
| 57 using WebKit::WebVector; |
| 58 using webkit_glue::ImageResourceFetcher; |
36 | 59 |
37 // Delay in milliseconds that we'll wait before capturing the page contents | 60 // Delay in milliseconds that we'll wait before capturing the page contents |
38 // and thumbnail. | 61 // and thumbnail. |
39 static const int kDelayForCaptureMs = 500; | 62 static const int kDelayForCaptureMs = 500; |
40 | 63 |
41 // Typically, we capture the page data once the page is loaded. | 64 // Typically, we capture the page data once the page is loaded. |
42 // Sometimes, the page never finishes to load, preventing the page capture | 65 // Sometimes, the page never finishes to load, preventing the page capture |
43 // To workaround this problem, we always perform a capture after the following | 66 // To workaround this problem, we always perform a capture after the following |
44 // delay. | 67 // delay. |
45 static const int kDelayForForcedCaptureMs = 6000; | 68 static const int kDelayForForcedCaptureMs = 6000; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 | 110 |
88 ChromeRenderViewObserver::ChromeRenderViewObserver( | 111 ChromeRenderViewObserver::ChromeRenderViewObserver( |
89 RenderView* render_view, | 112 RenderView* render_view, |
90 TranslateHelper* translate_helper, | 113 TranslateHelper* translate_helper, |
91 safe_browsing::PhishingClassifierDelegate* phishing_classifier) | 114 safe_browsing::PhishingClassifierDelegate* phishing_classifier) |
92 : RenderViewObserver(render_view), | 115 : RenderViewObserver(render_view), |
93 translate_helper_(translate_helper), | 116 translate_helper_(translate_helper), |
94 phishing_classifier_(phishing_classifier), | 117 phishing_classifier_(phishing_classifier), |
95 last_indexed_page_id_(-1), | 118 last_indexed_page_id_(-1), |
96 ALLOW_THIS_IN_INITIALIZER_LIST(page_info_method_factory_(this)) { | 119 ALLOW_THIS_IN_INITIALIZER_LIST(page_info_method_factory_(this)) { |
| 120 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
| 121 if (command_line.HasSwitch(switches::kDomAutomationController)) { |
| 122 int old_bindings = render_view->enabled_bindings(); |
| 123 render_view->set_enabled_bindings( |
| 124 old_bindings |= BindingsPolicy::DOM_AUTOMATION); |
| 125 } |
97 } | 126 } |
98 | 127 |
99 ChromeRenderViewObserver::~ChromeRenderViewObserver() { | 128 ChromeRenderViewObserver::~ChromeRenderViewObserver() { |
100 } | 129 } |
101 | 130 |
102 bool ChromeRenderViewObserver::OnMessageReceived(const IPC::Message& message) { | 131 bool ChromeRenderViewObserver::OnMessageReceived(const IPC::Message& message) { |
103 bool handled = true; | 132 bool handled = true; |
104 IPC_BEGIN_MESSAGE_MAP(ChromeRenderViewObserver, message) | 133 IPC_BEGIN_MESSAGE_MAP(ChromeRenderViewObserver, message) |
105 IPC_MESSAGE_HANDLER(ViewMsg_CaptureSnapshot, OnCaptureSnapshot) | 134 IPC_MESSAGE_HANDLER(ViewMsg_CaptureSnapshot, OnCaptureSnapshot) |
| 135 IPC_MESSAGE_HANDLER(ViewMsg_HandleMessageFromExternalHost, |
| 136 OnHandleMessageFromExternalHost) |
| 137 IPC_MESSAGE_HANDLER(ViewMsg_JavaScriptStressTestControl, |
| 138 OnJavaScriptStressTestControl) |
| 139 IPC_MESSAGE_HANDLER(ViewMsg_GetAllSavableResourceLinksForCurrentPage, |
| 140 OnGetAllSavableResourceLinksForCurrentPage) |
| 141 IPC_MESSAGE_HANDLER( |
| 142 ViewMsg_GetSerializedHtmlDataForCurrentPageWithLocalLinks, |
| 143 OnGetSerializedHtmlDataForCurrentPageWithLocalLinks) |
| 144 IPC_MESSAGE_HANDLER(ViewMsg_DownloadFavicon, OnDownloadFavicon) |
| 145 IPC_MESSAGE_HANDLER(ViewMsg_EnableViewSourceMode, OnEnableViewSourceMode) |
106 IPC_MESSAGE_UNHANDLED(handled = false) | 146 IPC_MESSAGE_UNHANDLED(handled = false) |
107 IPC_END_MESSAGE_MAP() | 147 IPC_END_MESSAGE_MAP() |
108 | 148 |
109 // Filter only. | 149 // Filter only. |
110 IPC_BEGIN_MESSAGE_MAP(ChromeRenderViewObserver, message) | 150 IPC_BEGIN_MESSAGE_MAP(ChromeRenderViewObserver, message) |
111 IPC_MESSAGE_HANDLER(ViewMsg_Navigate, OnNavigate) | 151 IPC_MESSAGE_HANDLER(ViewMsg_Navigate, OnNavigate) |
112 IPC_END_MESSAGE_MAP() | 152 IPC_END_MESSAGE_MAP() |
113 | 153 |
114 return handled; | 154 return handled; |
115 } | 155 } |
116 | 156 |
117 void ChromeRenderViewObserver::OnCaptureSnapshot() { | 157 void ChromeRenderViewObserver::OnCaptureSnapshot() { |
118 SkBitmap snapshot; | 158 SkBitmap snapshot; |
119 bool error = false; | 159 bool error = false; |
120 | 160 |
121 WebFrame* main_frame = render_view()->webview()->mainFrame(); | 161 WebFrame* main_frame = render_view()->webview()->mainFrame(); |
122 if (!main_frame) | 162 if (!main_frame) |
123 error = true; | 163 error = true; |
124 | 164 |
125 if (!error && !CaptureSnapshot(render_view()->webview(), &snapshot)) | 165 if (!error && !CaptureSnapshot(render_view()->webview(), &snapshot)) |
126 error = true; | 166 error = true; |
127 | 167 |
128 DCHECK(error == snapshot.empty()) << | 168 DCHECK(error == snapshot.empty()) << |
129 "Snapshot should be empty on error, non-empty otherwise."; | 169 "Snapshot should be empty on error, non-empty otherwise."; |
130 | 170 |
131 // Send the snapshot to the browser process. | 171 // Send the snapshot to the browser process. |
132 Send(new ViewHostMsg_Snapshot(routing_id(), snapshot)); | 172 Send(new ViewHostMsg_Snapshot(routing_id(), snapshot)); |
133 } | 173 } |
134 | 174 |
| 175 void ChromeRenderViewObserver::OnHandleMessageFromExternalHost( |
| 176 const std::string& message, |
| 177 const std::string& origin, |
| 178 const std::string& target) { |
| 179 if (message.empty()) |
| 180 return; |
| 181 GetExternalHostBindings()->ForwardMessageFromExternalHost(message, origin, |
| 182 target); |
| 183 } |
| 184 |
| 185 void ChromeRenderViewObserver::OnJavaScriptStressTestControl(int cmd, |
| 186 int param) { |
| 187 if (cmd == kJavaScriptStressTestSetStressRunType) { |
| 188 v8::Testing::SetStressRunType(static_cast<v8::Testing::StressType>(param)); |
| 189 } else if (cmd == kJavaScriptStressTestPrepareStressRun) { |
| 190 v8::Testing::PrepareStressRun(param); |
| 191 } |
| 192 } |
| 193 |
| 194 void ChromeRenderViewObserver::OnGetAllSavableResourceLinksForCurrentPage( |
| 195 const GURL& page_url) { |
| 196 // Prepare list to storage all savable resource links. |
| 197 std::vector<GURL> resources_list; |
| 198 std::vector<GURL> referrers_list; |
| 199 std::vector<GURL> frames_list; |
| 200 webkit_glue::SavableResourcesResult result(&resources_list, |
| 201 &referrers_list, |
| 202 &frames_list); |
| 203 |
| 204 if (!webkit_glue::GetAllSavableResourceLinksForCurrentPage( |
| 205 render_view()->webview(), |
| 206 page_url, |
| 207 &result, |
| 208 chrome::kSavableSchemes)) { |
| 209 // If something is wrong when collecting all savable resource links, |
| 210 // send empty list to embedder(browser) to tell it failed. |
| 211 referrers_list.clear(); |
| 212 resources_list.clear(); |
| 213 frames_list.clear(); |
| 214 } |
| 215 |
| 216 // Send result of all savable resource links to embedder. |
| 217 Send(new ViewHostMsg_SendCurrentPageAllSavableResourceLinks(routing_id(), |
| 218 resources_list, |
| 219 referrers_list, |
| 220 frames_list)); |
| 221 } |
| 222 |
| 223 void |
| 224 ChromeRenderViewObserver::OnGetSerializedHtmlDataForCurrentPageWithLocalLinks( |
| 225 const std::vector<GURL>& links, |
| 226 const std::vector<FilePath>& local_paths, |
| 227 const FilePath& local_directory_name) { |
| 228 |
| 229 // Convert std::vector of GURLs to WebVector<WebURL> |
| 230 WebVector<WebURL> weburl_links(links); |
| 231 |
| 232 // Convert std::vector of std::strings to WebVector<WebString> |
| 233 WebVector<WebString> webstring_paths(local_paths.size()); |
| 234 for (size_t i = 0; i < local_paths.size(); i++) |
| 235 webstring_paths[i] = webkit_glue::FilePathToWebString(local_paths[i]); |
| 236 |
| 237 WebPageSerializer::serialize(render_view()->webview()->mainFrame(), |
| 238 true, this, weburl_links, webstring_paths, |
| 239 webkit_glue::FilePathToWebString( |
| 240 local_directory_name)); |
| 241 } |
| 242 |
| 243 void ChromeRenderViewObserver::OnDownloadFavicon(int id, |
| 244 const GURL& image_url, |
| 245 int image_size) { |
| 246 bool data_image_failed = false; |
| 247 if (image_url.SchemeIs("data")) { |
| 248 SkBitmap data_image = ImageFromDataUrl(image_url); |
| 249 data_image_failed = data_image.empty(); |
| 250 if (!data_image_failed) { |
| 251 Send(new ViewHostMsg_DidDownloadFavicon( |
| 252 routing_id(), id, image_url, false, data_image)); |
| 253 } |
| 254 } |
| 255 |
| 256 if (data_image_failed || |
| 257 !DownloadFavicon(id, image_url, image_size)) { |
| 258 Send(new ViewHostMsg_DidDownloadFavicon( |
| 259 routing_id(), id, image_url, true, SkBitmap())); |
| 260 } |
| 261 } |
| 262 |
| 263 void ChromeRenderViewObserver::OnEnableViewSourceMode() { |
| 264 if (!render_view()->webview()) |
| 265 return; |
| 266 WebFrame* main_frame = render_view()->webview()->mainFrame(); |
| 267 if (!main_frame) |
| 268 return; |
| 269 |
| 270 main_frame->enableViewSourceMode(true); |
| 271 } |
| 272 |
| 273 void ChromeRenderViewObserver::didSerializeDataForFrame( |
| 274 const WebURL& frame_url, |
| 275 const WebCString& data, |
| 276 WebPageSerializerClient::PageSerializationStatus status) { |
| 277 Send(new ViewHostMsg_SendSerializedHtmlData( |
| 278 routing_id(), |
| 279 frame_url, |
| 280 data.data(), |
| 281 static_cast<int32>(status))); |
| 282 } |
| 283 |
135 void ChromeRenderViewObserver::OnNavigate( | 284 void ChromeRenderViewObserver::OnNavigate( |
136 const ViewMsg_Navigate_Params& params) { | 285 const ViewMsg_Navigate_Params& params) { |
137 AboutHandler::MaybeHandle(params.url); | 286 AboutHandler::MaybeHandle(params.url); |
138 } | 287 } |
139 | 288 |
140 void ChromeRenderViewObserver::DidStopLoading() { | 289 void ChromeRenderViewObserver::DidStopLoading() { |
141 MessageLoop::current()->PostDelayedTask( | 290 MessageLoop::current()->PostDelayedTask( |
142 FROM_HERE, | 291 FROM_HERE, |
143 page_info_method_factory_.NewRunnableMethod( | 292 page_info_method_factory_.NewRunnableMethod( |
144 &ChromeRenderViewObserver::CapturePageInfo, render_view()->page_id(), | 293 &ChromeRenderViewObserver::CapturePageInfo, render_view()->page_id(), |
145 false), | 294 false), |
146 render_view()->content_state_immediately() ? 0 : kDelayForCaptureMs); | 295 render_view()->content_state_immediately() ? 0 : kDelayForCaptureMs); |
| 296 |
| 297 GURL osd_url = |
| 298 render_view()->webview()->mainFrame()->openSearchDescriptionURL(); |
| 299 if (!osd_url.is_empty()) { |
| 300 Send(new ViewHostMsg_PageHasOSDD( |
| 301 routing_id(), render_view()->page_id(), osd_url, |
| 302 search_provider::AUTODETECTED_PROVIDER)); |
| 303 } |
| 304 |
| 305 // TODO : Get both favicon and touch icon url, and send them to the browser. |
| 306 GURL favicon_url(render_view()->webview()->mainFrame()->favIconURL()); |
| 307 if (!favicon_url.is_empty()) { |
| 308 std::vector<FaviconURL> urls; |
| 309 urls.push_back(FaviconURL(favicon_url, FAVICON)); |
| 310 Send(new ViewHostMsg_UpdateFaviconURL( |
| 311 routing_id(), render_view()->page_id(), urls)); |
| 312 } |
| 313 } |
| 314 |
| 315 void ChromeRenderViewObserver::DidChangeIcons(WebFrame* frame) { |
| 316 if (frame->parent()) |
| 317 return; |
| 318 |
| 319 std::vector<FaviconURL> urls; |
| 320 urls.push_back(FaviconURL(frame->favIconURL(), FAVICON)); |
| 321 Send(new ViewHostMsg_UpdateFaviconURL( |
| 322 routing_id(), render_view()->page_id(), urls)); |
147 } | 323 } |
148 | 324 |
149 void ChromeRenderViewObserver::DidCommitProvisionalLoad( | 325 void ChromeRenderViewObserver::DidCommitProvisionalLoad( |
150 WebFrame* frame, bool is_new_navigation) { | 326 WebFrame* frame, bool is_new_navigation) { |
151 if (!is_new_navigation) | 327 if (!is_new_navigation) |
152 return; | 328 return; |
153 | 329 |
154 MessageLoop::current()->PostDelayedTask( | 330 MessageLoop::current()->PostDelayedTask( |
155 FROM_HERE, | 331 FROM_HERE, |
156 page_info_method_factory_.NewRunnableMethod( | 332 page_info_method_factory_.NewRunnableMethod( |
157 &ChromeRenderViewObserver::CapturePageInfo, render_view()->page_id(), | 333 &ChromeRenderViewObserver::CapturePageInfo, render_view()->page_id(), |
158 true), | 334 true), |
159 kDelayForForcedCaptureMs); | 335 kDelayForForcedCaptureMs); |
160 } | 336 } |
161 | 337 |
| 338 void ChromeRenderViewObserver::DidClearWindowObject(WebFrame* frame) { |
| 339 if (BindingsPolicy::is_dom_automation_enabled( |
| 340 render_view()->enabled_bindings())) { |
| 341 BindDOMAutomationController(frame); |
| 342 } |
| 343 |
| 344 if (BindingsPolicy::is_external_host_enabled( |
| 345 render_view()->enabled_bindings())) { |
| 346 GetExternalHostBindings()->set_message_sender(render_view()); |
| 347 GetExternalHostBindings()->set_routing_id(routing_id()); |
| 348 GetExternalHostBindings()->BindToJavascript(frame, "externalHost"); |
| 349 } |
| 350 } |
| 351 |
162 void ChromeRenderViewObserver::CapturePageInfo(int load_id, | 352 void ChromeRenderViewObserver::CapturePageInfo(int load_id, |
163 bool preliminary_capture) { | 353 bool preliminary_capture) { |
164 if (load_id != render_view()->page_id()) | 354 if (load_id != render_view()->page_id()) |
165 return; // This capture call is no longer relevant due to navigation. | 355 return; // This capture call is no longer relevant due to navigation. |
166 | 356 |
167 if (load_id == last_indexed_page_id_) | 357 if (load_id == last_indexed_page_id_) |
168 return; // we already indexed this page | 358 return; // we already indexed this page |
169 | 359 |
170 if (!render_view()->webview()) | 360 if (!render_view()->webview()) |
171 return; | 361 return; |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
352 static_cast<skia::BitmapPlatformDevice&>(canvas.getTopPlatformDevice()); | 542 static_cast<skia::BitmapPlatformDevice&>(canvas.getTopPlatformDevice()); |
353 | 543 |
354 const SkBitmap& bitmap = device.accessBitmap(false); | 544 const SkBitmap& bitmap = device.accessBitmap(false); |
355 if (!bitmap.copyTo(snapshot, SkBitmap::kARGB_8888_Config)) | 545 if (!bitmap.copyTo(snapshot, SkBitmap::kARGB_8888_Config)) |
356 return false; | 546 return false; |
357 | 547 |
358 HISTOGRAM_TIMES("Renderer4.Snapshot", | 548 HISTOGRAM_TIMES("Renderer4.Snapshot", |
359 base::TimeTicks::Now() - beginning_time); | 549 base::TimeTicks::Now() - beginning_time); |
360 return true; | 550 return true; |
361 } | 551 } |
| 552 |
| 553 void ChromeRenderViewObserver::BindDOMAutomationController(WebFrame* frame) { |
| 554 if (!dom_automation_controller_.get()) { |
| 555 dom_automation_controller_.reset(new DomAutomationController()); |
| 556 } |
| 557 dom_automation_controller_->set_message_sender(this); |
| 558 dom_automation_controller_->set_routing_id(routing_id()); |
| 559 dom_automation_controller_->BindToJavascript(frame, |
| 560 "domAutomationController"); |
| 561 } |
| 562 |
| 563 ExternalHostBindings* ChromeRenderViewObserver::GetExternalHostBindings() { |
| 564 if (!external_host_bindings_.get()) |
| 565 external_host_bindings_.reset(new ExternalHostBindings()); |
| 566 return external_host_bindings_.get(); |
| 567 } |
| 568 |
| 569 bool ChromeRenderViewObserver::DownloadFavicon(int id, |
| 570 const GURL& image_url, |
| 571 int image_size) { |
| 572 // Make sure webview was not shut down. |
| 573 if (!render_view()->webview()) |
| 574 return false; |
| 575 // Create an image resource fetcher and assign it with a call back object. |
| 576 image_fetchers_.push_back(linked_ptr<ImageResourceFetcher>( |
| 577 new ImageResourceFetcher( |
| 578 image_url, render_view()->webview()->mainFrame(), id, image_size, |
| 579 WebURLRequest::TargetIsFavicon, |
| 580 NewCallback(this, &ChromeRenderViewObserver::DidDownloadFavicon)))); |
| 581 return true; |
| 582 } |
| 583 |
| 584 void ChromeRenderViewObserver::DidDownloadFavicon( |
| 585 ImageResourceFetcher* fetcher, const SkBitmap& image) { |
| 586 // Notify requester of image download status. |
| 587 Send(new ViewHostMsg_DidDownloadFavicon(routing_id(), |
| 588 fetcher->id(), |
| 589 fetcher->image_url(), |
| 590 image.isNull(), |
| 591 image)); |
| 592 |
| 593 // Remove the image fetcher from our pending list. We're in the callback from |
| 594 // ImageResourceFetcher, best to delay deletion. |
| 595 RenderView::ImageResourceFetcherList::iterator iter; |
| 596 for (iter = image_fetchers_.begin(); iter != image_fetchers_.end(); ++iter) { |
| 597 if (iter->get() == fetcher) { |
| 598 iter->release(); |
| 599 image_fetchers_.erase(iter); |
| 600 break; |
| 601 } |
| 602 } |
| 603 MessageLoop::current()->DeleteSoon(FROM_HERE, fetcher); |
| 604 } |
| 605 |
| 606 SkBitmap ChromeRenderViewObserver::ImageFromDataUrl(const GURL& url) const { |
| 607 std::string mime_type, char_set, data; |
| 608 if (net::DataURL::Parse(url, &mime_type, &char_set, &data) && !data.empty()) { |
| 609 // Decode the favicon using WebKit's image decoder. |
| 610 webkit_glue::ImageDecoder decoder(gfx::Size(kFaviconSize, kFaviconSize)); |
| 611 const unsigned char* src_data = |
| 612 reinterpret_cast<const unsigned char*>(&data[0]); |
| 613 |
| 614 return decoder.Decode(src_data, data.size()); |
| 615 } |
| 616 return SkBitmap(); |
| 617 } |
OLD | NEW |