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 |