| 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 784 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 795 | 795 |
| 796 DISALLOW_COPY_AND_ASSIGN(MHTMLPartsGenerationDelegate); | 796 DISALLOW_COPY_AND_ASSIGN(MHTMLPartsGenerationDelegate); |
| 797 }; | 797 }; |
| 798 | 798 |
| 799 bool IsHttpPost(const blink::WebURLRequest& request) { | 799 bool IsHttpPost(const blink::WebURLRequest& request) { |
| 800 return request.httpMethod().utf8() == "POST"; | 800 return request.httpMethod().utf8() == "POST"; |
| 801 } | 801 } |
| 802 | 802 |
| 803 // Writes to file the serialized and encoded MHTML data from WebThreadSafeData | 803 // Writes to file the serialized and encoded MHTML data from WebThreadSafeData |
| 804 // instances. | 804 // instances. |
| 805 bool WriteMHTMLToDisk(bool success, | 805 bool WriteMHTMLToDisk(std::vector<WebThreadSafeData> mhtml_contents, |
| 806 std::vector<WebThreadSafeData> mhtml_contents, | |
| 807 base::File file) { | 806 base::File file) { |
| 808 TRACE_EVENT_BEGIN0("page-serialization", | 807 TRACE_EVENT0("page-serialization", "WriteMHTMLToDisk (RenderFrameImpl)"); |
| 809 "WriteMHTMLToDisk (RenderFrameImpl)"); | 808 SCOPED_UMA_HISTOGRAM_TIMER( |
| 809 "PageSerialization.MhtmlGeneration.WriteToDiskTime.SingleFrame"); |
| 810 DCHECK(!RenderThread::Get()) << "Should not run in the main renderer thread"; | 810 DCHECK(!RenderThread::Get()) << "Should not run in the main renderer thread"; |
| 811 if (success) { | 811 bool success = true; |
| 812 SCOPED_UMA_HISTOGRAM_TIMER( | 812 for (const WebThreadSafeData& data : mhtml_contents) { |
| 813 "PageSerialization.MhtmlGeneration.WriteToDiskTime.SingleFrame"); | 813 if (!data.isEmpty() && |
| 814 for (const WebThreadSafeData& data : mhtml_contents) { | 814 file.WriteAtCurrentPos(data.data(), data.size()) < 0) { |
| 815 if (!data.isEmpty() && | 815 success = false; |
| 816 file.WriteAtCurrentPos(data.data(), data.size()) < 0) { | 816 break; |
| 817 success = false; | |
| 818 break; | |
| 819 } | |
| 820 } | 817 } |
| 821 // Explicitly close the file here to include any flush operations in the UMA | |
| 822 // metric. If this block is not executed close will be called upon |file| | |
| 823 // destruction at the end of this method's scope, which is still | |
| 824 // before any IPC is sent. | |
| 825 file.Close(); | |
| 826 } | 818 } |
| 827 | 819 // Explicitly close |file| here to make sure to include any flush operations |
| 828 TRACE_EVENT_END1("page-serialization", "WriteMHTMLToDisk (RenderFrameImpl)", | 820 // in the UMA metric. |
| 829 "success", success); | 821 file.Close(); |
| 830 return success; | 822 return success; |
| 831 } | 823 } |
| 832 | 824 |
| 833 #if defined(OS_ANDROID) | 825 #if defined(OS_ANDROID) |
| 834 // Returns true if WMPI should be used for playback, false otherwise. | 826 // Returns true if WMPI should be used for playback, false otherwise. |
| 835 // | 827 // |
| 836 // 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 |
| 837 // possible to load such a URL and find different content. | 829 // possible to load such a URL and find different content. |
| 838 bool UseWebMediaPlayerImpl(const GURL& url) { | 830 bool UseWebMediaPlayerImpl(const GURL& url) { |
| 839 // 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 |
| (...skipping 4534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5374 DCHECK(!mhtml_boundary.isEmpty()); | 5366 DCHECK(!mhtml_boundary.isEmpty()); |
| 5375 | 5367 |
| 5376 // Holds WebThreadSafeData instances for some or all of header, contents and | 5368 // Holds WebThreadSafeData instances for some or all of header, contents and |
| 5377 // footer. | 5369 // footer. |
| 5378 std::vector<WebThreadSafeData> mhtml_contents; | 5370 std::vector<WebThreadSafeData> mhtml_contents; |
| 5379 std::set<std::string> serialized_resources_uri_digests; | 5371 std::set<std::string> serialized_resources_uri_digests; |
| 5380 MHTMLPartsGenerationDelegate delegate(params, | 5372 MHTMLPartsGenerationDelegate delegate(params, |
| 5381 &serialized_resources_uri_digests); | 5373 &serialized_resources_uri_digests); |
| 5382 | 5374 |
| 5383 bool success = true; | 5375 bool success = true; |
| 5376 bool has_some_data = false; |
| 5384 | 5377 |
| 5385 // Generate MHTML header if needed. | 5378 // Generate MHTML header if needed. |
| 5386 if (IsMainFrame()) { | 5379 if (IsMainFrame()) { |
| 5387 TRACE_EVENT0("page-serialization", | 5380 TRACE_EVENT0("page-serialization", |
| 5388 "RenderFrameImpl::OnSerializeAsMHTML header"); | 5381 "RenderFrameImpl::OnSerializeAsMHTML header"); |
| 5389 // |data| can be empty if the main frame should be skipped. If the main | 5382 // The returned data can be empty if the main frame should be skipped. If |
| 5390 // frame is skipped, then the whole archive is bad, so bail to the error | 5383 // the main frame is skipped, then the whole archive is bad. |
| 5391 // condition. | |
| 5392 mhtml_contents.emplace_back(WebFrameSerializer::generateMHTMLHeader( | 5384 mhtml_contents.emplace_back(WebFrameSerializer::generateMHTMLHeader( |
| 5393 mhtml_boundary, GetWebFrame(), &delegate)); | 5385 mhtml_boundary, GetWebFrame(), &delegate)); |
| 5394 success = !mhtml_contents.back().isEmpty(); | 5386 has_some_data = !mhtml_contents.back().isEmpty(); |
| 5387 success = has_some_data; |
| 5395 } | 5388 } |
| 5396 | 5389 |
| 5397 // Generate MHTML parts. Note that if this is not the main frame, then even | 5390 // Generate MHTML parts. Note that if this is not the main frame, then even |
| 5398 // skipping the whole parts generation step is not an error - it simply | 5391 // skipping the whole parts generation step is not an error - it simply |
| 5399 // results in an omitted resource in the final file. | 5392 // results in an omitted resource in the final file. |
| 5400 if (success) { | 5393 if (success) { |
| 5401 TRACE_EVENT0("page-serialization", | 5394 TRACE_EVENT0("page-serialization", |
| 5402 "RenderFrameImpl::OnSerializeAsMHTML parts serialization"); | 5395 "RenderFrameImpl::OnSerializeAsMHTML parts serialization"); |
| 5403 // |data| can be empty if the frame should be skipped, but this is OK. | 5396 // The returned data can be empty if the frame should be skipped, but this |
| 5397 // is OK. |
| 5404 mhtml_contents.emplace_back(WebFrameSerializer::generateMHTMLParts( | 5398 mhtml_contents.emplace_back(WebFrameSerializer::generateMHTMLParts( |
| 5405 mhtml_boundary, GetWebFrame(), &delegate)); | 5399 mhtml_boundary, GetWebFrame(), &delegate)); |
| 5400 has_some_data |= !mhtml_contents.back().isEmpty(); |
| 5406 } | 5401 } |
| 5407 | 5402 |
| 5408 // Generate MHTML footer if needed. | 5403 // Generate MHTML footer if needed. |
| 5409 if (success && params.is_last_frame) { | 5404 if (success && params.is_last_frame) { |
| 5410 TRACE_EVENT0("page-serialization", | 5405 TRACE_EVENT0("page-serialization", |
| 5411 "RenderFrameImpl::OnSerializeAsMHTML footer"); | 5406 "RenderFrameImpl::OnSerializeAsMHTML footer"); |
| 5412 mhtml_contents.emplace_back( | 5407 mhtml_contents.emplace_back( |
| 5413 WebFrameSerializer::generateMHTMLFooter(mhtml_boundary)); | 5408 WebFrameSerializer::generateMHTMLFooter(mhtml_boundary)); |
| 5409 has_some_data |= !mhtml_contents.back().isEmpty(); |
| 5414 } | 5410 } |
| 5415 | 5411 |
| 5416 // Note: we assume RenderFrameImpl::OnWriteMHTMLToDiskComplete and the rest of | 5412 // Note: we assume RenderFrameImpl::OnWriteMHTMLToDiskComplete and the rest of |
| 5417 // this function will be fast enough to not need to be accounted for in this | 5413 // this function will be fast enough to not need to be accounted for in this |
| 5418 // metric. | 5414 // metric. |
| 5419 base::TimeDelta main_thread_use_time = base::TimeTicks::Now() - start_time; | 5415 base::TimeDelta main_thread_use_time = base::TimeTicks::Now() - start_time; |
| 5420 UMA_HISTOGRAM_TIMES( | 5416 UMA_HISTOGRAM_TIMES( |
| 5421 "PageSerialization.MhtmlGeneration.RendererMainThreadTime.SingleFrame", | 5417 "PageSerialization.MhtmlGeneration.RendererMainThreadTime.SingleFrame", |
| 5422 main_thread_use_time); | 5418 main_thread_use_time); |
| 5423 | 5419 |
| 5424 base::PostTaskAndReplyWithResult( | 5420 if (success && has_some_data) { |
| 5425 RenderThreadImpl::current()->GetFileThreadTaskRunner().get(), FROM_HERE, | 5421 base::PostTaskAndReplyWithResult( |
| 5426 base::Bind(&WriteMHTMLToDisk, success, base::Passed(&mhtml_contents), | 5422 RenderThreadImpl::current()->GetFileThreadTaskRunner().get(), FROM_HERE, |
| 5427 base::Passed(&file)), | 5423 base::Bind(&WriteMHTMLToDisk, base::Passed(&mhtml_contents), |
| 5428 base::Bind(&RenderFrameImpl::OnWriteMHTMLToDiskComplete, | 5424 base::Passed(&file)), |
| 5429 weak_factory_.GetWeakPtr(), params.job_id, | 5425 base::Bind(&RenderFrameImpl::OnWriteMHTMLToDiskComplete, |
| 5430 base::Passed(&serialized_resources_uri_digests), | 5426 weak_factory_.GetWeakPtr(), params.job_id, |
| 5431 main_thread_use_time)); | 5427 base::Passed(&serialized_resources_uri_digests), |
| 5428 main_thread_use_time)); |
| 5429 } else { |
| 5430 file.Close(); |
| 5431 OnWriteMHTMLToDiskComplete(params.job_id, serialized_resources_uri_digests, |
| 5432 main_thread_use_time, success); |
| 5433 } |
| 5432 } | 5434 } |
| 5433 | 5435 |
| 5434 void RenderFrameImpl::OnWriteMHTMLToDiskComplete( | 5436 void RenderFrameImpl::OnWriteMHTMLToDiskComplete( |
| 5435 int job_id, | 5437 int job_id, |
| 5436 std::set<std::string> serialized_resources_uri_digests, | 5438 std::set<std::string> serialized_resources_uri_digests, |
| 5437 base::TimeDelta main_thread_use_time, | 5439 base::TimeDelta main_thread_use_time, |
| 5438 bool success) { | 5440 bool success) { |
| 5441 TRACE_EVENT1("page-serialization", |
| 5442 "RenderFrameImpl::OnWriteMHTMLToDiskComplete", |
| 5443 "frame serialization was successful", success); |
| 5439 DCHECK(RenderThread::Get()) << "Must run in the main renderer thread"; | 5444 DCHECK(RenderThread::Get()) << "Must run in the main renderer thread"; |
| 5440 // Notify the browser process about completion. | 5445 // Notify the browser process about completion. |
| 5441 // Note: we assume this method is fast enough to not need to be accounted for | 5446 // Note: we assume this method is fast enough to not need to be accounted for |
| 5442 // in PageSerialization.MhtmlGeneration.RendererMainThreadTime.SingleFrame. | 5447 // in PageSerialization.MhtmlGeneration.RendererMainThreadTime.SingleFrame. |
| 5443 Send(new FrameHostMsg_SerializeAsMHTMLResponse( | 5448 Send(new FrameHostMsg_SerializeAsMHTMLResponse( |
| 5444 routing_id_, job_id, success, serialized_resources_uri_digests, | 5449 routing_id_, job_id, success, serialized_resources_uri_digests, |
| 5445 main_thread_use_time)); | 5450 main_thread_use_time)); |
| 5446 } | 5451 } |
| 5447 | 5452 |
| 5448 void RenderFrameImpl::OnFind(int request_id, | 5453 void RenderFrameImpl::OnFind(int request_id, |
| (...skipping 1159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6608 // event target. Potentially a Pepper plugin will receive the event. | 6613 // event target. Potentially a Pepper plugin will receive the event. |
| 6609 // In order to tell whether a plugin gets the last mouse event and which it | 6614 // In order to tell whether a plugin gets the last mouse event and which it |
| 6610 // is, we set |pepper_last_mouse_event_target_| to null here. If a plugin gets | 6615 // is, we set |pepper_last_mouse_event_target_| to null here. If a plugin gets |
| 6611 // the event, it will notify us via DidReceiveMouseEvent() and set itself as | 6616 // the event, it will notify us via DidReceiveMouseEvent() and set itself as |
| 6612 // |pepper_last_mouse_event_target_|. | 6617 // |pepper_last_mouse_event_target_|. |
| 6613 pepper_last_mouse_event_target_ = nullptr; | 6618 pepper_last_mouse_event_target_ = nullptr; |
| 6614 #endif | 6619 #endif |
| 6615 } | 6620 } |
| 6616 | 6621 |
| 6617 } // namespace content | 6622 } // namespace content |
| OLD | NEW |