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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
46 #include "content/child/web_url_loader_impl.h" | 46 #include "content/child/web_url_loader_impl.h" |
47 #include "content/child/web_url_request_util.h" | 47 #include "content/child/web_url_request_util.h" |
48 #include "content/child/webmessageportchannel_impl.h" | 48 #include "content/child/webmessageportchannel_impl.h" |
49 #include "content/child/weburlresponse_extradata_impl.h" | 49 #include "content/child/weburlresponse_extradata_impl.h" |
50 #include "content/common/accessibility_messages.h" | 50 #include "content/common/accessibility_messages.h" |
51 #include "content/common/associated_interface_provider_impl.h" | 51 #include "content/common/associated_interface_provider_impl.h" |
52 #include "content/common/associated_interfaces.mojom.h" | 52 #include "content/common/associated_interfaces.mojom.h" |
53 #include "content/common/clipboard_messages.h" | 53 #include "content/common/clipboard_messages.h" |
54 #include "content/common/content_constants_internal.h" | 54 #include "content/common/content_constants_internal.h" |
55 #include "content/common/content_security_policy_header.h" | 55 #include "content/common/content_security_policy_header.h" |
| 56 #include "content/common/download/mhtml_save_status.h" |
56 #include "content/common/edit_command.h" | 57 #include "content/common/edit_command.h" |
57 #include "content/common/frame_messages.h" | 58 #include "content/common/frame_messages.h" |
58 #include "content/common/frame_owner_properties.h" | 59 #include "content/common/frame_owner_properties.h" |
59 #include "content/common/frame_replication_state.h" | 60 #include "content/common/frame_replication_state.h" |
60 #include "content/common/gpu/client/context_provider_command_buffer.h" | 61 #include "content/common/gpu/client/context_provider_command_buffer.h" |
61 #include "content/common/input_messages.h" | 62 #include "content/common/input_messages.h" |
62 #include "content/common/navigation_params.h" | 63 #include "content/common/navigation_params.h" |
63 #include "content/common/page_messages.h" | 64 #include "content/common/page_messages.h" |
64 #include "content/common/savable_subframe.h" | 65 #include "content/common/savable_subframe.h" |
65 #include "content/common/service_worker/service_worker_types.h" | 66 #include "content/common/service_worker/service_worker_types.h" |
(...skipping 730 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
796 | 797 |
797 DISALLOW_COPY_AND_ASSIGN(MHTMLPartsGenerationDelegate); | 798 DISALLOW_COPY_AND_ASSIGN(MHTMLPartsGenerationDelegate); |
798 }; | 799 }; |
799 | 800 |
800 bool IsHttpPost(const blink::WebURLRequest& request) { | 801 bool IsHttpPost(const blink::WebURLRequest& request) { |
801 return request.httpMethod().utf8() == "POST"; | 802 return request.httpMethod().utf8() == "POST"; |
802 } | 803 } |
803 | 804 |
804 // Writes to file the serialized and encoded MHTML data from WebThreadSafeData | 805 // Writes to file the serialized and encoded MHTML data from WebThreadSafeData |
805 // instances. | 806 // instances. |
806 bool WriteMHTMLToDisk(std::vector<WebThreadSafeData> mhtml_contents, | 807 MhtmlSaveStatus WriteMHTMLToDisk(std::vector<WebThreadSafeData> mhtml_contents, |
807 base::File file) { | 808 base::File file) { |
808 TRACE_EVENT0("page-serialization", "WriteMHTMLToDisk (RenderFrameImpl)"); | 809 TRACE_EVENT0("page-serialization", "WriteMHTMLToDisk (RenderFrameImpl)"); |
809 SCOPED_UMA_HISTOGRAM_TIMER( | 810 SCOPED_UMA_HISTOGRAM_TIMER( |
810 "PageSerialization.MhtmlGeneration.WriteToDiskTime.SingleFrame"); | 811 "PageSerialization.MhtmlGeneration.WriteToDiskTime.SingleFrame"); |
811 DCHECK(!RenderThread::Get()) << "Should not run in the main renderer thread"; | 812 DCHECK(!RenderThread::Get()) << "Should not run in the main renderer thread"; |
812 bool success = true; | 813 MhtmlSaveStatus save_status = MhtmlSaveStatus::SUCCESS; |
813 for (const WebThreadSafeData& data : mhtml_contents) { | 814 for (const WebThreadSafeData& data : mhtml_contents) { |
814 if (!data.isEmpty() && | 815 if (!data.isEmpty() && |
815 file.WriteAtCurrentPos(data.data(), data.size()) < 0) { | 816 file.WriteAtCurrentPos(data.data(), data.size()) < 0) { |
816 success = false; | 817 save_status = MhtmlSaveStatus::FILE_WRITTING_ERROR; |
817 break; | 818 break; |
818 } | 819 } |
819 } | 820 } |
820 // Explicitly close |file| here to make sure to include any flush operations | 821 // Explicitly close |file| here to make sure to include any flush operations |
821 // in the UMA metric. | 822 // in the UMA metric. |
822 file.Close(); | 823 file.Close(); |
823 return success; | 824 return save_status; |
824 } | 825 } |
825 | 826 |
826 #if defined(OS_ANDROID) | 827 #if defined(OS_ANDROID) |
827 // Returns true if WMPI should be used for playback, false otherwise. | 828 // Returns true if WMPI should be used for playback, false otherwise. |
828 // | 829 // |
829 // Note that HLS and MP4 detection are pre-redirect and path-based. It is | 830 // Note that HLS and MP4 detection are pre-redirect and path-based. It is |
830 // possible to load such a URL and find different content. | 831 // possible to load such a URL and find different content. |
831 bool UseWebMediaPlayerImpl(const GURL& url) { | 832 bool UseWebMediaPlayerImpl(const GURL& url) { |
832 // Always use WMPI for playing blob URLs since WMPA could never play them very | 833 // Always use WMPI for playing blob URLs since WMPA could never play them very |
833 // well and no longer has support for MSE based playbacks. | 834 // well and no longer has support for MSE based playbacks. |
(...skipping 4511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5345 WebString::fromUTF8(params.mhtml_boundary_marker); | 5346 WebString::fromUTF8(params.mhtml_boundary_marker); |
5346 DCHECK(!mhtml_boundary.isEmpty()); | 5347 DCHECK(!mhtml_boundary.isEmpty()); |
5347 | 5348 |
5348 // Holds WebThreadSafeData instances for some or all of header, contents and | 5349 // Holds WebThreadSafeData instances for some or all of header, contents and |
5349 // footer. | 5350 // footer. |
5350 std::vector<WebThreadSafeData> mhtml_contents; | 5351 std::vector<WebThreadSafeData> mhtml_contents; |
5351 std::set<std::string> serialized_resources_uri_digests; | 5352 std::set<std::string> serialized_resources_uri_digests; |
5352 MHTMLPartsGenerationDelegate delegate(params, | 5353 MHTMLPartsGenerationDelegate delegate(params, |
5353 &serialized_resources_uri_digests); | 5354 &serialized_resources_uri_digests); |
5354 | 5355 |
5355 bool success = true; | 5356 MhtmlSaveStatus save_status = MhtmlSaveStatus::SUCCESS; |
5356 bool has_some_data = false; | 5357 bool has_some_data = false; |
5357 | 5358 |
5358 // Generate MHTML header if needed. | 5359 // Generate MHTML header if needed. |
5359 if (IsMainFrame()) { | 5360 if (IsMainFrame()) { |
5360 TRACE_EVENT0("page-serialization", | 5361 TRACE_EVENT0("page-serialization", |
5361 "RenderFrameImpl::OnSerializeAsMHTML header"); | 5362 "RenderFrameImpl::OnSerializeAsMHTML header"); |
5362 // The returned data can be empty if the main frame should be skipped. If | 5363 // The returned data can be empty if the main frame should be skipped. If |
5363 // the main frame is skipped, then the whole archive is bad. | 5364 // the main frame is skipped, then the whole archive is bad. |
5364 mhtml_contents.emplace_back(WebFrameSerializer::generateMHTMLHeader( | 5365 mhtml_contents.emplace_back(WebFrameSerializer::generateMHTMLHeader( |
5365 mhtml_boundary, GetWebFrame(), &delegate)); | 5366 mhtml_boundary, GetWebFrame(), &delegate)); |
5366 has_some_data = !mhtml_contents.back().isEmpty(); | 5367 if (mhtml_contents.back().isEmpty()) |
5367 success = has_some_data; | 5368 save_status = MhtmlSaveStatus::FRAME_SERIALIZATION_FORBIDDEN; |
| 5369 else |
| 5370 has_some_data = true; |
5368 } | 5371 } |
5369 | 5372 |
5370 // Generate MHTML parts. Note that if this is not the main frame, then even | 5373 // Generate MHTML parts. Note that if this is not the main frame, then even |
5371 // skipping the whole parts generation step is not an error - it simply | 5374 // skipping the whole parts generation step is not an error - it simply |
5372 // results in an omitted resource in the final file. | 5375 // results in an omitted resource in the final file. |
5373 if (success) { | 5376 if (save_status == MhtmlSaveStatus::SUCCESS) { |
5374 TRACE_EVENT0("page-serialization", | 5377 TRACE_EVENT0("page-serialization", |
5375 "RenderFrameImpl::OnSerializeAsMHTML parts serialization"); | 5378 "RenderFrameImpl::OnSerializeAsMHTML parts serialization"); |
5376 // The returned data can be empty if the frame should be skipped, but this | 5379 // The returned data can be empty if the frame should be skipped, but this |
5377 // is OK. | 5380 // is OK. |
5378 mhtml_contents.emplace_back(WebFrameSerializer::generateMHTMLParts( | 5381 mhtml_contents.emplace_back(WebFrameSerializer::generateMHTMLParts( |
5379 mhtml_boundary, GetWebFrame(), &delegate)); | 5382 mhtml_boundary, GetWebFrame(), &delegate)); |
5380 has_some_data |= !mhtml_contents.back().isEmpty(); | 5383 has_some_data |= !mhtml_contents.back().isEmpty(); |
5381 } | 5384 } |
5382 | 5385 |
5383 // Generate MHTML footer if needed. | 5386 // Generate MHTML footer if needed. |
5384 if (success && params.is_last_frame) { | 5387 if (save_status == MhtmlSaveStatus::SUCCESS && params.is_last_frame) { |
5385 TRACE_EVENT0("page-serialization", | 5388 TRACE_EVENT0("page-serialization", |
5386 "RenderFrameImpl::OnSerializeAsMHTML footer"); | 5389 "RenderFrameImpl::OnSerializeAsMHTML footer"); |
5387 mhtml_contents.emplace_back( | 5390 mhtml_contents.emplace_back( |
5388 WebFrameSerializer::generateMHTMLFooter(mhtml_boundary)); | 5391 WebFrameSerializer::generateMHTMLFooter(mhtml_boundary)); |
5389 has_some_data |= !mhtml_contents.back().isEmpty(); | 5392 has_some_data |= !mhtml_contents.back().isEmpty(); |
5390 } | 5393 } |
5391 | 5394 |
5392 // Note: we assume RenderFrameImpl::OnWriteMHTMLToDiskComplete and the rest of | 5395 // Note: we assume RenderFrameImpl::OnWriteMHTMLToDiskComplete and the rest of |
5393 // this function will be fast enough to not need to be accounted for in this | 5396 // this function will be fast enough to not need to be accounted for in this |
5394 // metric. | 5397 // metric. |
5395 base::TimeDelta main_thread_use_time = base::TimeTicks::Now() - start_time; | 5398 base::TimeDelta main_thread_use_time = base::TimeTicks::Now() - start_time; |
5396 UMA_HISTOGRAM_TIMES( | 5399 UMA_HISTOGRAM_TIMES( |
5397 "PageSerialization.MhtmlGeneration.RendererMainThreadTime.SingleFrame", | 5400 "PageSerialization.MhtmlGeneration.RendererMainThreadTime.SingleFrame", |
5398 main_thread_use_time); | 5401 main_thread_use_time); |
5399 | 5402 |
5400 if (success && has_some_data) { | 5403 if (save_status == MhtmlSaveStatus::SUCCESS && has_some_data) { |
5401 base::PostTaskAndReplyWithResult( | 5404 base::PostTaskAndReplyWithResult( |
5402 RenderThreadImpl::current()->GetFileThreadTaskRunner().get(), FROM_HERE, | 5405 RenderThreadImpl::current()->GetFileThreadTaskRunner().get(), FROM_HERE, |
5403 base::Bind(&WriteMHTMLToDisk, base::Passed(&mhtml_contents), | 5406 base::Bind(&WriteMHTMLToDisk, base::Passed(&mhtml_contents), |
5404 base::Passed(&file)), | 5407 base::Passed(&file)), |
5405 base::Bind(&RenderFrameImpl::OnWriteMHTMLToDiskComplete, | 5408 base::Bind(&RenderFrameImpl::OnWriteMHTMLToDiskComplete, |
5406 weak_factory_.GetWeakPtr(), params.job_id, | 5409 weak_factory_.GetWeakPtr(), params.job_id, |
5407 base::Passed(&serialized_resources_uri_digests), | 5410 base::Passed(&serialized_resources_uri_digests), |
5408 main_thread_use_time)); | 5411 main_thread_use_time)); |
5409 } else { | 5412 } else { |
5410 file.Close(); | 5413 file.Close(); |
5411 OnWriteMHTMLToDiskComplete(params.job_id, serialized_resources_uri_digests, | 5414 OnWriteMHTMLToDiskComplete(params.job_id, serialized_resources_uri_digests, |
5412 main_thread_use_time, success); | 5415 main_thread_use_time, save_status); |
5413 } | 5416 } |
5414 } | 5417 } |
5415 | 5418 |
5416 void RenderFrameImpl::OnWriteMHTMLToDiskComplete( | 5419 void RenderFrameImpl::OnWriteMHTMLToDiskComplete( |
5417 int job_id, | 5420 int job_id, |
5418 std::set<std::string> serialized_resources_uri_digests, | 5421 std::set<std::string> serialized_resources_uri_digests, |
5419 base::TimeDelta main_thread_use_time, | 5422 base::TimeDelta main_thread_use_time, |
5420 bool success) { | 5423 MhtmlSaveStatus save_status) { |
5421 TRACE_EVENT1("page-serialization", | 5424 TRACE_EVENT1("page-serialization", |
5422 "RenderFrameImpl::OnWriteMHTMLToDiskComplete", | 5425 "RenderFrameImpl::OnWriteMHTMLToDiskComplete", |
5423 "frame serialization was successful", success); | 5426 "frame save status", GetMhtmlSaveStatusLabel(save_status)); |
5424 DCHECK(RenderThread::Get()) << "Must run in the main renderer thread"; | 5427 DCHECK(RenderThread::Get()) << "Must run in the main renderer thread"; |
5425 // Notify the browser process about completion. | 5428 // Notify the browser process about completion. |
5426 // Note: we assume this method is fast enough to not need to be accounted for | 5429 // Note: we assume this method is fast enough to not need to be accounted for |
5427 // in PageSerialization.MhtmlGeneration.RendererMainThreadTime.SingleFrame. | 5430 // in PageSerialization.MhtmlGeneration.RendererMainThreadTime.SingleFrame. |
5428 Send(new FrameHostMsg_SerializeAsMHTMLResponse( | 5431 Send(new FrameHostMsg_SerializeAsMHTMLResponse( |
5429 routing_id_, job_id, success, serialized_resources_uri_digests, | 5432 routing_id_, job_id, save_status, serialized_resources_uri_digests, |
5430 main_thread_use_time)); | 5433 main_thread_use_time)); |
5431 } | 5434 } |
5432 | 5435 |
5433 void RenderFrameImpl::OnFind(int request_id, | 5436 void RenderFrameImpl::OnFind(int request_id, |
5434 const base::string16& search_text, | 5437 const base::string16& search_text, |
5435 const WebFindOptions& options) { | 5438 const WebFindOptions& options) { |
5436 DCHECK(!search_text.empty()); | 5439 DCHECK(!search_text.empty()); |
5437 | 5440 |
5438 blink::WebPlugin* plugin = GetWebPluginForFind(); | 5441 blink::WebPlugin* plugin = GetWebPluginForFind(); |
5439 // Check if the plugin still exists in the document. | 5442 // Check if the plugin still exists in the document. |
(...skipping 1199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6639 // event target. Potentially a Pepper plugin will receive the event. | 6642 // event target. Potentially a Pepper plugin will receive the event. |
6640 // In order to tell whether a plugin gets the last mouse event and which it | 6643 // In order to tell whether a plugin gets the last mouse event and which it |
6641 // is, we set |pepper_last_mouse_event_target_| to null here. If a plugin gets | 6644 // is, we set |pepper_last_mouse_event_target_| to null here. If a plugin gets |
6642 // the event, it will notify us via DidReceiveMouseEvent() and set itself as | 6645 // the event, it will notify us via DidReceiveMouseEvent() and set itself as |
6643 // |pepper_last_mouse_event_target_|. | 6646 // |pepper_last_mouse_event_target_|. |
6644 pepper_last_mouse_event_target_ = nullptr; | 6647 pepper_last_mouse_event_target_ = nullptr; |
6645 #endif | 6648 #endif |
6646 } | 6649 } |
6647 | 6650 |
6648 } // namespace content | 6651 } // namespace content |
OLD | NEW |