Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "content/renderer/render_frame_impl.h" | 5 #include "content/renderer/render_frame_impl.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <utility> | 9 #include <utility> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 21 #include "base/logging.h" | 21 #include "base/logging.h" |
| 22 #include "base/macros.h" | 22 #include "base/macros.h" |
| 23 #include "base/memory/ptr_util.h" | 23 #include "base/memory/ptr_util.h" |
| 24 #include "base/memory/shared_memory.h" | 24 #include "base/memory/shared_memory.h" |
| 25 #include "base/memory/weak_ptr.h" | 25 #include "base/memory/weak_ptr.h" |
| 26 #include "base/metrics/field_trial.h" | 26 #include "base/metrics/field_trial.h" |
| 27 #include "base/metrics/histogram_macros.h" | 27 #include "base/metrics/histogram_macros.h" |
| 28 #include "base/process/process.h" | 28 #include "base/process/process.h" |
| 29 #include "base/stl_util.h" | 29 #include "base/stl_util.h" |
| 30 #include "base/strings/string16.h" | 30 #include "base/strings/string16.h" |
| 31 #include "base/strings/stringprintf.h" | |
| 31 #include "base/strings/utf_string_conversions.h" | 32 #include "base/strings/utf_string_conversions.h" |
| 32 #include "base/task_runner_util.h" | 33 #include "base/task_runner_util.h" |
| 33 #include "base/threading/thread_task_runner_handle.h" | 34 #include "base/threading/thread_task_runner_handle.h" |
| 34 #include "base/time/time.h" | 35 #include "base/time/time.h" |
| 35 #include "base/trace_event/trace_event.h" | 36 #include "base/trace_event/trace_event.h" |
| 36 #include "build/build_config.h" | 37 #include "build/build_config.h" |
| 37 #include "cc/base/switches.h" | 38 #include "cc/base/switches.h" |
| 38 #include "content/child/appcache/appcache_dispatcher.h" | 39 #include "content/child/appcache/appcache_dispatcher.h" |
| 39 #include "content/child/quota_dispatcher.h" | 40 #include "content/child/quota_dispatcher.h" |
| 40 #include "content/child/request_extra_data.h" | 41 #include "content/child/request_extra_data.h" |
| (...skipping 753 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 794 | 795 |
| 795 DISALLOW_COPY_AND_ASSIGN(MHTMLPartsGenerationDelegate); | 796 DISALLOW_COPY_AND_ASSIGN(MHTMLPartsGenerationDelegate); |
| 796 }; | 797 }; |
| 797 | 798 |
| 798 bool IsHttpPost(const blink::WebURLRequest& request) { | 799 bool IsHttpPost(const blink::WebURLRequest& request) { |
| 799 return request.httpMethod().utf8() == "POST"; | 800 return request.httpMethod().utf8() == "POST"; |
| 800 } | 801 } |
| 801 | 802 |
| 802 // Writes to file the serialized and encoded MHTML data from WebThreadSafeData | 803 // Writes to file the serialized and encoded MHTML data from WebThreadSafeData |
| 803 // instances. | 804 // instances. |
| 804 bool WriteMHTMLToDisk(std::vector<WebThreadSafeData> mhtml_contents, | 805 MhtmlSaveStatus WriteMHTMLToDisk(std::vector<WebThreadSafeData> mhtml_contents, |
| 805 base::File file) { | 806 base::File file) { |
| 806 TRACE_EVENT0("page-serialization", "WriteMHTMLToDisk (RenderFrameImpl)"); | 807 TRACE_EVENT0("page-serialization", "WriteMHTMLToDisk (RenderFrameImpl)"); |
| 807 SCOPED_UMA_HISTOGRAM_TIMER( | 808 SCOPED_UMA_HISTOGRAM_TIMER( |
| 808 "PageSerialization.MhtmlGeneration.WriteToDiskTime.SingleFrame"); | 809 "PageSerialization.MhtmlGeneration.WriteToDiskTime.SingleFrame"); |
| 809 DCHECK(!RenderThread::Get()) << "Should not run in the main renderer thread"; | 810 DCHECK(!RenderThread::Get()) << "Should not run in the main renderer thread"; |
| 810 bool success = true; | 811 MhtmlSaveStatus save_status = MhtmlSaveStatus::SUCCESS; |
| 811 for (const WebThreadSafeData& data : mhtml_contents) { | 812 for (const WebThreadSafeData& data : mhtml_contents) { |
| 812 if (!data.isEmpty() && | 813 if (!data.isEmpty() && |
| 813 file.WriteAtCurrentPos(data.data(), data.size()) < 0) { | 814 file.WriteAtCurrentPos(data.data(), data.size()) < 0) { |
| 814 success = false; | 815 save_status = MhtmlSaveStatus::FILE_WRITTING_ERROR; |
| 815 break; | 816 break; |
| 816 } | 817 } |
| 817 } | 818 } |
| 818 // Explicitly close |file| here to make sure to include any flush operations | 819 // Explicitly close |file| here to make sure to include any flush operations |
| 819 // in the UMA metric. | 820 // in the UMA metric. |
| 820 file.Close(); | 821 file.Close(); |
| 821 return success; | 822 return save_status; |
| 822 } | 823 } |
| 823 | 824 |
| 824 #if defined(OS_ANDROID) | 825 #if defined(OS_ANDROID) |
| 825 // Returns true if WMPI should be used for playback, false otherwise. | 826 // Returns true if WMPI should be used for playback, false otherwise. |
| 826 // | 827 // |
| 827 // Note that HLS and MP4 detection are pre-redirect and path-based. It is | 828 // Note that HLS and MP4 detection are pre-redirect and path-based. It is |
| 828 // possible to load such a URL and find different content. | 829 // possible to load such a URL and find different content. |
| 829 bool UseWebMediaPlayerImpl(const GURL& url) { | 830 bool UseWebMediaPlayerImpl(const GURL& url) { |
| 830 // Always use WMPI for playing blob URLs since WMPA could never play them very | 831 // Always use WMPI for playing blob URLs since WMPA could never play them very |
| 831 // well and no longer has support for MSE based playbacks. | 832 // well and no longer has support for MSE based playbacks. |
| (...skipping 4542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5374 WebString::fromUTF8(params.mhtml_boundary_marker); | 5375 WebString::fromUTF8(params.mhtml_boundary_marker); |
| 5375 DCHECK(!mhtml_boundary.isEmpty()); | 5376 DCHECK(!mhtml_boundary.isEmpty()); |
| 5376 | 5377 |
| 5377 // Holds WebThreadSafeData instances for some or all of header, contents and | 5378 // Holds WebThreadSafeData instances for some or all of header, contents and |
| 5378 // footer. | 5379 // footer. |
| 5379 std::vector<WebThreadSafeData> mhtml_contents; | 5380 std::vector<WebThreadSafeData> mhtml_contents; |
| 5380 std::set<std::string> serialized_resources_uri_digests; | 5381 std::set<std::string> serialized_resources_uri_digests; |
| 5381 MHTMLPartsGenerationDelegate delegate(params, | 5382 MHTMLPartsGenerationDelegate delegate(params, |
| 5382 &serialized_resources_uri_digests); | 5383 &serialized_resources_uri_digests); |
| 5383 | 5384 |
| 5384 bool success = true; | 5385 MhtmlSaveStatus save_status = MhtmlSaveStatus::SUCCESS; |
| 5385 bool has_some_data = false; | 5386 bool has_some_data = false; |
| 5386 | 5387 |
| 5387 // Generate MHTML header if needed. | 5388 // Generate MHTML header if needed. |
| 5388 if (IsMainFrame()) { | 5389 if (IsMainFrame()) { |
| 5389 TRACE_EVENT0("page-serialization", | 5390 TRACE_EVENT0("page-serialization", |
| 5390 "RenderFrameImpl::OnSerializeAsMHTML header"); | 5391 "RenderFrameImpl::OnSerializeAsMHTML header"); |
| 5391 // The returned data can be empty if the main frame should be skipped. If | 5392 // The returned data can be empty if the main frame should be skipped. If |
| 5392 // the main frame is skipped, then the whole archive is bad. | 5393 // the main frame is skipped, then the whole archive is bad. |
| 5393 mhtml_contents.emplace_back(WebFrameSerializer::generateMHTMLHeader( | 5394 mhtml_contents.emplace_back(WebFrameSerializer::generateMHTMLHeader( |
| 5394 mhtml_boundary, GetWebFrame(), &delegate)); | 5395 mhtml_boundary, GetWebFrame(), &delegate)); |
| 5395 has_some_data = !mhtml_contents.back().isEmpty(); | 5396 if (mhtml_contents.back().isEmpty()) |
| 5396 success = has_some_data; | 5397 save_status = MhtmlSaveStatus::FRAME_SERIALIZATION_FORBIDDEN; |
| 5398 else | |
| 5399 has_some_data = true; | |
| 5397 } | 5400 } |
| 5398 | 5401 |
| 5399 // Generate MHTML parts. Note that if this is not the main frame, then even | 5402 // Generate MHTML parts. Note that if this is not the main frame, then even |
| 5400 // skipping the whole parts generation step is not an error - it simply | 5403 // skipping the whole parts generation step is not an error - it simply |
| 5401 // results in an omitted resource in the final file. | 5404 // results in an omitted resource in the final file. |
| 5402 if (success) { | 5405 if (save_status == MhtmlSaveStatus::SUCCESS) { |
| 5403 TRACE_EVENT0("page-serialization", | 5406 TRACE_EVENT0("page-serialization", |
| 5404 "RenderFrameImpl::OnSerializeAsMHTML parts serialization"); | 5407 "RenderFrameImpl::OnSerializeAsMHTML parts serialization"); |
| 5405 // The returned data can be empty if the frame should be skipped, but this | 5408 // The returned data can be empty if the frame should be skipped, but this |
| 5406 // is OK. | 5409 // is OK. |
| 5407 mhtml_contents.emplace_back(WebFrameSerializer::generateMHTMLParts( | 5410 mhtml_contents.emplace_back(WebFrameSerializer::generateMHTMLParts( |
| 5408 mhtml_boundary, GetWebFrame(), &delegate)); | 5411 mhtml_boundary, GetWebFrame(), &delegate)); |
| 5409 has_some_data |= !mhtml_contents.back().isEmpty(); | 5412 has_some_data |= !mhtml_contents.back().isEmpty(); |
| 5410 } | 5413 } |
| 5411 | 5414 |
| 5412 // Generate MHTML footer if needed. | 5415 // Generate MHTML footer if needed. |
| 5413 if (success && params.is_last_frame) { | 5416 if (save_status == MhtmlSaveStatus::SUCCESS && params.is_last_frame) { |
| 5414 TRACE_EVENT0("page-serialization", | 5417 TRACE_EVENT0("page-serialization", |
| 5415 "RenderFrameImpl::OnSerializeAsMHTML footer"); | 5418 "RenderFrameImpl::OnSerializeAsMHTML footer"); |
| 5416 mhtml_contents.emplace_back( | 5419 mhtml_contents.emplace_back( |
| 5417 WebFrameSerializer::generateMHTMLFooter(mhtml_boundary)); | 5420 WebFrameSerializer::generateMHTMLFooter(mhtml_boundary)); |
| 5418 has_some_data |= !mhtml_contents.back().isEmpty(); | 5421 has_some_data |= !mhtml_contents.back().isEmpty(); |
| 5419 } | 5422 } |
| 5420 | 5423 |
| 5421 // Note: we assume RenderFrameImpl::OnWriteMHTMLToDiskComplete and the rest of | 5424 // Note: we assume RenderFrameImpl::OnWriteMHTMLToDiskComplete and the rest of |
| 5422 // this function will be fast enough to not need to be accounted for in this | 5425 // this function will be fast enough to not need to be accounted for in this |
| 5423 // metric. | 5426 // metric. |
| 5424 base::TimeDelta main_thread_use_time = base::TimeTicks::Now() - start_time; | 5427 base::TimeDelta main_thread_use_time = base::TimeTicks::Now() - start_time; |
| 5425 UMA_HISTOGRAM_TIMES( | 5428 UMA_HISTOGRAM_TIMES( |
| 5426 "PageSerialization.MhtmlGeneration.RendererMainThreadTime.SingleFrame", | 5429 "PageSerialization.MhtmlGeneration.RendererMainThreadTime.SingleFrame", |
| 5427 main_thread_use_time); | 5430 main_thread_use_time); |
| 5428 | 5431 |
| 5429 if (success && has_some_data) { | 5432 if (save_status == MhtmlSaveStatus::SUCCESS && has_some_data) { |
| 5430 base::PostTaskAndReplyWithResult( | 5433 base::PostTaskAndReplyWithResult( |
| 5431 RenderThreadImpl::current()->GetFileThreadTaskRunner().get(), FROM_HERE, | 5434 RenderThreadImpl::current()->GetFileThreadTaskRunner().get(), FROM_HERE, |
| 5432 base::Bind(&WriteMHTMLToDisk, base::Passed(&mhtml_contents), | 5435 base::Bind(&WriteMHTMLToDisk, base::Passed(&mhtml_contents), |
| 5433 base::Passed(&file)), | 5436 base::Passed(&file)), |
| 5434 base::Bind(&RenderFrameImpl::OnWriteMHTMLToDiskComplete, | 5437 base::Bind(&RenderFrameImpl::OnWriteMHTMLToDiskComplete, |
| 5435 weak_factory_.GetWeakPtr(), params.job_id, | 5438 weak_factory_.GetWeakPtr(), params.job_id, |
| 5436 base::Passed(&serialized_resources_uri_digests), | 5439 base::Passed(&serialized_resources_uri_digests), |
| 5437 main_thread_use_time)); | 5440 main_thread_use_time)); |
| 5438 } else { | 5441 } else { |
| 5439 file.Close(); | 5442 file.Close(); |
| 5440 OnWriteMHTMLToDiskComplete(params.job_id, serialized_resources_uri_digests, | 5443 OnWriteMHTMLToDiskComplete(params.job_id, serialized_resources_uri_digests, |
| 5441 main_thread_use_time, success); | 5444 main_thread_use_time, save_status); |
| 5442 } | 5445 } |
| 5443 } | 5446 } |
| 5444 | 5447 |
| 5445 void RenderFrameImpl::OnWriteMHTMLToDiskComplete( | 5448 void RenderFrameImpl::OnWriteMHTMLToDiskComplete( |
| 5446 int job_id, | 5449 int job_id, |
| 5447 std::set<std::string> serialized_resources_uri_digests, | 5450 std::set<std::string> serialized_resources_uri_digests, |
| 5448 base::TimeDelta main_thread_use_time, | 5451 base::TimeDelta main_thread_use_time, |
| 5449 bool success) { | 5452 MhtmlSaveStatus save_status) { |
| 5450 TRACE_EVENT1("page-serialization", | 5453 TRACE_EVENT1( |
| 5451 "RenderFrameImpl::OnWriteMHTMLToDiskComplete", | 5454 "page-serialization", "RenderFrameImpl::OnWriteMHTMLToDiskComplete", |
| 5452 "frame serialization was successful", success); | 5455 "frame save status", |
| 5456 save_status == MhtmlSaveStatus::SUCCESS | |
| 5457 ? "success" | |
| 5458 : base::StringPrintf("failure (%d)", static_cast<int>(save_status))); | |
|
Łukasz Anforowicz
2016/11/22 19:22:13
I wonder if it would make sense to introduce a hel
carlosk
2016/11/22 23:26:24
Done.
| |
| 5453 DCHECK(RenderThread::Get()) << "Must run in the main renderer thread"; | 5459 DCHECK(RenderThread::Get()) << "Must run in the main renderer thread"; |
| 5454 // Notify the browser process about completion. | 5460 // Notify the browser process about completion. |
| 5455 // Note: we assume this method is fast enough to not need to be accounted for | 5461 // Note: we assume this method is fast enough to not need to be accounted for |
| 5456 // in PageSerialization.MhtmlGeneration.RendererMainThreadTime.SingleFrame. | 5462 // in PageSerialization.MhtmlGeneration.RendererMainThreadTime.SingleFrame. |
| 5457 Send(new FrameHostMsg_SerializeAsMHTMLResponse( | 5463 Send(new FrameHostMsg_SerializeAsMHTMLResponse( |
| 5458 routing_id_, job_id, success, serialized_resources_uri_digests, | 5464 routing_id_, job_id, save_status, serialized_resources_uri_digests, |
| 5459 main_thread_use_time)); | 5465 main_thread_use_time)); |
| 5460 } | 5466 } |
| 5461 | 5467 |
| 5462 void RenderFrameImpl::OnFind(int request_id, | 5468 void RenderFrameImpl::OnFind(int request_id, |
| 5463 const base::string16& search_text, | 5469 const base::string16& search_text, |
| 5464 const WebFindOptions& options) { | 5470 const WebFindOptions& options) { |
| 5465 DCHECK(!search_text.empty()); | 5471 DCHECK(!search_text.empty()); |
| 5466 | 5472 |
| 5467 blink::WebPlugin* plugin = GetWebPluginForFind(); | 5473 blink::WebPlugin* plugin = GetWebPluginForFind(); |
| 5468 // Check if the plugin still exists in the document. | 5474 // Check if the plugin still exists in the document. |
| (...skipping 1162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6631 // event target. Potentially a Pepper plugin will receive the event. | 6637 // event target. Potentially a Pepper plugin will receive the event. |
| 6632 // In order to tell whether a plugin gets the last mouse event and which it | 6638 // In order to tell whether a plugin gets the last mouse event and which it |
| 6633 // is, we set |pepper_last_mouse_event_target_| to null here. If a plugin gets | 6639 // is, we set |pepper_last_mouse_event_target_| to null here. If a plugin gets |
| 6634 // the event, it will notify us via DidReceiveMouseEvent() and set itself as | 6640 // the event, it will notify us via DidReceiveMouseEvent() and set itself as |
| 6635 // |pepper_last_mouse_event_target_|. | 6641 // |pepper_last_mouse_event_target_|. |
| 6636 pepper_last_mouse_event_target_ = nullptr; | 6642 pepper_last_mouse_event_target_ = nullptr; |
| 6637 #endif | 6643 #endif |
| 6638 } | 6644 } |
| 6639 | 6645 |
| 6640 } // namespace content | 6646 } // namespace content |
| OLD | NEW |