Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(598)

Side by Side Diff: components/printing/renderer/print_web_view_helper.cc

Issue 2522313003: Check for PrintWebViewHelper validity when running nested message loops. (Closed)
Patch Set: Simplify, fix build Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « components/printing/renderer/print_web_view_helper.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "components/printing/renderer/print_web_view_helper.h" 5 #include "components/printing/renderer/print_web_view_helper.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
(...skipping 952 matching lines...) Expand 10 before | Expand all | Expand 10 after
963 if (g_is_preview_enabled) { 963 if (g_is_preview_enabled) {
964 #if BUILDFLAG(ENABLE_PRINT_PREVIEW) 964 #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
965 print_preview_context_.InitWithFrame(web_frame); 965 print_preview_context_.InitWithFrame(web_frame);
966 RequestPrintPreview(PRINT_PREVIEW_SCRIPTED); 966 RequestPrintPreview(PRINT_PREVIEW_SCRIPTED);
967 #endif 967 #endif
968 } else { 968 } else {
969 #if BUILDFLAG(ENABLE_BASIC_PRINTING) 969 #if BUILDFLAG(ENABLE_BASIC_PRINTING)
970 Print(web_frame, blink::WebNode(), true /* is_scripted? */); 970 Print(web_frame, blink::WebNode(), true /* is_scripted? */);
971 #endif 971 #endif
972 } 972 }
973 // WARNING: |this| may be gone at this point. Do not do any more work here and
974 // just return.
973 } 975 }
974 976
975 bool PrintWebViewHelper::OnMessageReceived(const IPC::Message& message) { 977 bool PrintWebViewHelper::OnMessageReceived(const IPC::Message& message) {
976 // The class is not designed to handle recursive messages. This is not 978 // The class is not designed to handle recursive messages. This is not
977 // expected during regular flow. However, during rendering of content for 979 // expected during regular flow. However, during rendering of content for
978 // printing, lower level code may run nested message loop. E.g. PDF may has 980 // printing, lower level code may run nested message loop. E.g. PDF may has
979 // script to show message box http://crbug.com/502562. In that moment browser 981 // script to show message box http://crbug.com/502562. In that moment browser
980 // may receive updated printer capabilities and decide to restart print 982 // may receive updated printer capabilities and decide to restart print
981 // preview generation. When this happened message handling function may 983 // preview generation. When this happened message handling function may
982 // choose to ignore message or safely crash process. 984 // choose to ignore message or safely crash process.
(...skipping 29 matching lines...) Expand all
1012 void PrintWebViewHelper::OnPrintPages() { 1014 void PrintWebViewHelper::OnPrintPages() {
1013 if (ipc_nesting_level_> 1) 1015 if (ipc_nesting_level_> 1)
1014 return; 1016 return;
1015 1017
1016 blink::WebLocalFrame* frame = render_frame()->GetWebFrame(); 1018 blink::WebLocalFrame* frame = render_frame()->GetWebFrame();
1017 1019
1018 // If we are printing a PDF extension frame, find the plugin node and print 1020 // If we are printing a PDF extension frame, find the plugin node and print
1019 // that instead. 1021 // that instead.
1020 auto plugin = delegate_->GetPdfElement(frame); 1022 auto plugin = delegate_->GetPdfElement(frame);
1021 Print(frame, plugin, false /* is_scripted? */); 1023 Print(frame, plugin, false /* is_scripted? */);
1024 // WARNING: |this| may be gone at this point. Do not do any more work here and
1025 // just return.
1022 } 1026 }
1023 1027
1024 void PrintWebViewHelper::OnPrintForSystemDialog() { 1028 void PrintWebViewHelper::OnPrintForSystemDialog() {
1025 if (ipc_nesting_level_> 1) 1029 if (ipc_nesting_level_> 1)
1026 return; 1030 return;
1027 blink::WebLocalFrame* frame = print_preview_context_.source_frame(); 1031 blink::WebLocalFrame* frame = print_preview_context_.source_frame();
1028 if (!frame) { 1032 if (!frame) {
1029 NOTREACHED(); 1033 NOTREACHED();
1030 return; 1034 return;
1031 } 1035 }
1032 Print(frame, print_preview_context_.source_node(), false); 1036 Print(frame, print_preview_context_.source_node(), false);
1037 // WARNING: |this| may be gone at this point. Do not do any more work here and
1038 // just return.
1033 } 1039 }
1034 #endif // BUILDFLAG(ENABLE_BASIC_PRINTING) 1040 #endif // BUILDFLAG(ENABLE_BASIC_PRINTING)
1035 1041
1036 #if BUILDFLAG(ENABLE_BASIC_PRINTING) && BUILDFLAG(ENABLE_PRINT_PREVIEW) 1042 #if BUILDFLAG(ENABLE_BASIC_PRINTING) && BUILDFLAG(ENABLE_PRINT_PREVIEW)
1037 void PrintWebViewHelper::OnPrintForPrintPreview( 1043 void PrintWebViewHelper::OnPrintForPrintPreview(
1038 const base::DictionaryValue& job_settings) { 1044 const base::DictionaryValue& job_settings) {
1039 CHECK_LE(ipc_nesting_level_, 1); 1045 CHECK_LE(ipc_nesting_level_, 1);
1040 // If still not finished with earlier print request simply ignore. 1046 // If still not finished with earlier print request simply ignore.
1041 if (prep_frame_view_) 1047 if (prep_frame_view_)
1042 return; 1048 return;
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after
1411 1417
1412 if (print_node_in_progress_) { 1418 if (print_node_in_progress_) {
1413 // This can happen as a result of processing sync messages when printing 1419 // This can happen as a result of processing sync messages when printing
1414 // from ppapi plugins. It's a rare case, so its OK to just fail here. 1420 // from ppapi plugins. It's a rare case, so its OK to just fail here.
1415 // See http://crbug.com/159165. 1421 // See http://crbug.com/159165.
1416 return; 1422 return;
1417 } 1423 }
1418 1424
1419 print_node_in_progress_ = true; 1425 print_node_in_progress_ = true;
1420 1426
1421 // Make a copy of the node, in case RenderView::OnContextMenuClosed resets
1422 // its |context_menu_node_|.
1423 if (g_is_preview_enabled) { 1427 if (g_is_preview_enabled) {
1424 #if BUILDFLAG(ENABLE_PRINT_PREVIEW) 1428 #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
1425 print_preview_context_.InitWithNode(node); 1429 print_preview_context_.InitWithNode(node);
1426 RequestPrintPreview(PRINT_PREVIEW_USER_INITIATED_CONTEXT_NODE); 1430 RequestPrintPreview(PRINT_PREVIEW_USER_INITIATED_CONTEXT_NODE);
1427 #endif 1431 #endif
1428 } else { 1432 } else {
1429 #if BUILDFLAG(ENABLE_BASIC_PRINTING) 1433 #if BUILDFLAG(ENABLE_BASIC_PRINTING)
1434 // Make a copy of the node, in case RenderView::OnContextMenuClosed() resets
1435 // its |context_menu_node_|.
1430 blink::WebNode duplicate_node(node); 1436 blink::WebNode duplicate_node(node);
1431 Print(duplicate_node.document().frame(), duplicate_node, false); 1437
1438 auto self = weak_ptr_factory_.GetWeakPtr();
1439 Print(duplicate_node.document().frame(), duplicate_node,
1440 false /* is_scripted? */);
1441 // Check if |this| is still valid.
1442 if (!self)
1443 return;
1432 #endif 1444 #endif
1433 } 1445 }
1434 1446
1435 print_node_in_progress_ = false; 1447 print_node_in_progress_ = false;
1436 } 1448 }
1437 1449
1438 #if BUILDFLAG(ENABLE_BASIC_PRINTING) 1450 #if BUILDFLAG(ENABLE_BASIC_PRINTING)
1439 void PrintWebViewHelper::Print(blink::WebLocalFrame* frame, 1451 void PrintWebViewHelper::Print(blink::WebLocalFrame* frame,
1440 const blink::WebNode& node, 1452 const blink::WebNode& node,
1441 bool is_scripted) { 1453 bool is_scripted) {
1442 // If still not finished with earlier print request simply ignore. 1454 // If still not finished with earlier print request simply ignore.
1443 if (prep_frame_view_) 1455 if (prep_frame_view_)
1444 return; 1456 return;
1445 1457
1446 FrameReference frame_ref(frame); 1458 FrameReference frame_ref(frame);
1447 1459
1448 int expected_page_count = 0; 1460 int expected_page_count = 0;
1449 if (!CalculateNumberOfPages(frame, node, &expected_page_count)) { 1461 if (!CalculateNumberOfPages(frame, node, &expected_page_count)) {
1450 DidFinishPrinting(FAIL_PRINT_INIT); 1462 DidFinishPrinting(FAIL_PRINT_INIT);
1451 return; // Failed to init print page settings. 1463 return; // Failed to init print page settings.
1452 } 1464 }
1453 1465
1454 // Some full screen plugins can say they don't want to print. 1466 // Some full screen plugins can say they don't want to print.
1455 if (!expected_page_count) { 1467 if (!expected_page_count) {
1456 DidFinishPrinting(FAIL_PRINT); 1468 DidFinishPrinting(FAIL_PRINT);
1457 return; 1469 return;
1458 } 1470 }
1459 1471
1460 // Ask the browser to show UI to retrieve the final print settings. 1472 // Ask the browser to show UI to retrieve the final print settings.
1461 if (delegate_->IsAskPrintSettingsEnabled() && 1473 if (delegate_->IsAskPrintSettingsEnabled()) {
1462 !GetPrintSettingsFromUser(frame_ref.GetFrame(), node, expected_page_count, 1474 // PrintHostMsg_ScriptedPrint in GetPrintSettingsFromUser() will reset
1463 is_scripted)) { 1475 // |print_scaling_option|, so save the value here and restore it afterwards.
1464 DidFinishPrinting(OK); // Release resources and fail silently. 1476 blink::WebPrintScalingOption scaling_option =
1465 return; 1477 print_pages_params_->params.print_scaling_option;
1478
1479 PrintMsg_PrintPages_Params print_settings;
1480 auto self = weak_ptr_factory_.GetWeakPtr();
1481 GetPrintSettingsFromUser(frame_ref.GetFrame(), node, expected_page_count,
1482 is_scripted, &print_settings);
1483 // Check if |this| is still valid.
1484 if (!self)
1485 return;
1486
1487 print_settings.params.print_scaling_option = scaling_option;
1488 SetPrintPagesParams(print_settings);
1489 if (!print_settings.params.dpi || !print_settings.params.document_cookie) {
1490 DidFinishPrinting(OK); // Release resources and fail silently on failure.
1491 return;
1492 }
1466 } 1493 }
1467 1494
1468 // Render Pages for printing. 1495 // Render Pages for printing.
1469 if (!RenderPagesForPrint(frame_ref.GetFrame(), node)) { 1496 if (!RenderPagesForPrint(frame_ref.GetFrame(), node)) {
1470 LOG(ERROR) << "RenderPagesForPrint failed"; 1497 LOG(ERROR) << "RenderPagesForPrint failed";
1471 DidFinishPrinting(FAIL_PRINT); 1498 DidFinishPrinting(FAIL_PRINT);
1472 } 1499 }
1473 scripting_throttler_.Reset(); 1500 scripting_throttler_.Reset();
1474 } 1501 }
1475 #endif // BUILDFLAG(ENABLE_BASIC_PRINTING) 1502 #endif // BUILDFLAG(ENABLE_BASIC_PRINTING)
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
1725 } 1752 }
1726 1753
1727 settings.params.print_to_pdf = IsPrintToPdfRequested(*job_settings); 1754 settings.params.print_to_pdf = IsPrintToPdfRequested(*job_settings);
1728 UpdateFrameMarginsCssInfo(*job_settings); 1755 UpdateFrameMarginsCssInfo(*job_settings);
1729 settings.params.print_scaling_option = GetPrintScalingOption( 1756 settings.params.print_scaling_option = GetPrintScalingOption(
1730 frame, node, source_is_html, *job_settings, settings.params); 1757 frame, node, source_is_html, *job_settings, settings.params);
1731 } 1758 }
1732 1759
1733 SetPrintPagesParams(settings); 1760 SetPrintPagesParams(settings);
1734 1761
1735 if (!PrintMsg_Print_Params_IsValid(settings.params)) { 1762 if (PrintMsg_Print_Params_IsValid(settings.params))
1736 if (!print_for_preview_) 1763 return true;
1737 print_preview_context_.set_error(PREVIEW_ERROR_INVALID_PRINTER_SETTINGS);
1738 else
1739 Send(new PrintHostMsg_ShowInvalidPrinterSettingsError(routing_id()));
1740 1764
1741 return false; 1765 if (print_for_preview_)
1742 } 1766 Send(new PrintHostMsg_ShowInvalidPrinterSettingsError(routing_id()));
1743 1767 else
1744 return true; 1768 print_preview_context_.set_error(PREVIEW_ERROR_INVALID_PRINTER_SETTINGS);
1769 return false;
1745 } 1770 }
1746 #endif // BUILDFLAG(ENABLE_PRINT_PREVIEW) 1771 #endif // BUILDFLAG(ENABLE_PRINT_PREVIEW)
1747 1772
1748 #if BUILDFLAG(ENABLE_BASIC_PRINTING) 1773 #if BUILDFLAG(ENABLE_BASIC_PRINTING)
1749 bool PrintWebViewHelper::GetPrintSettingsFromUser(blink::WebLocalFrame* frame, 1774 void PrintWebViewHelper::GetPrintSettingsFromUser(
1750 const blink::WebNode& node, 1775 blink::WebLocalFrame* frame,
1751 int expected_pages_count, 1776 const blink::WebNode& node,
1752 bool is_scripted) { 1777 int expected_pages_count,
1778 bool is_scripted,
1779 PrintMsg_PrintPages_Params* print_settings) {
1753 PrintHostMsg_ScriptedPrint_Params params; 1780 PrintHostMsg_ScriptedPrint_Params params;
1754 PrintMsg_PrintPages_Params print_settings;
1755
1756 params.cookie = print_pages_params_->params.document_cookie; 1781 params.cookie = print_pages_params_->params.document_cookie;
1757 params.has_selection = frame->hasSelection(); 1782 params.has_selection = frame->hasSelection();
1758 params.expected_pages_count = expected_pages_count; 1783 params.expected_pages_count = expected_pages_count;
1759 MarginType margin_type = DEFAULT_MARGINS; 1784 MarginType margin_type = DEFAULT_MARGINS;
1760 if (PrintingNodeOrPdfFrame(frame, node)) { 1785 if (PrintingNodeOrPdfFrame(frame, node))
1761 margin_type = 1786 margin_type = GetMarginsForPdf(frame, node, print_pages_params_->params);
1762 GetMarginsForPdf(frame, node, print_pages_params_->params);
1763 }
1764 params.margin_type = margin_type; 1787 params.margin_type = margin_type;
1765 params.is_scripted = is_scripted; 1788 params.is_scripted = is_scripted;
1766 params.is_modifiable = !PrintingNodeOrPdfFrame(frame, node); 1789 params.is_modifiable = !PrintingNodeOrPdfFrame(frame, node);
1767 1790
1768 Send(new PrintHostMsg_DidShowPrintDialog(routing_id())); 1791 Send(new PrintHostMsg_DidShowPrintDialog(routing_id()));
1769 1792
1770 // PrintHostMsg_ScriptedPrint will reset print_scaling_option, so we save the 1793 print_pages_params_.reset();
1771 // value before and restore it afterwards.
1772 blink::WebPrintScalingOption scaling_option =
1773 print_pages_params_->params.print_scaling_option;
1774 1794
1775 print_pages_params_.reset(); 1795 auto msg = base::MakeUnique<PrintHostMsg_ScriptedPrint>(
1776 IPC::SyncMessage* msg = 1796 routing_id(), params, print_settings);
1777 new PrintHostMsg_ScriptedPrint(routing_id(), params, &print_settings);
1778 msg->EnableMessagePumping(); 1797 msg->EnableMessagePumping();
1779 Send(msg); 1798 Send(msg.release());
1780 print_settings.params.print_scaling_option = scaling_option; 1799 // WARNING: |this| may be gone at this point. Do not do any more work here
1781 SetPrintPagesParams(print_settings); 1800 // and just return.
1782 return (print_settings.params.dpi && print_settings.params.document_cookie);
1783 } 1801 }
1784 1802
1785 bool PrintWebViewHelper::RenderPagesForPrint(blink::WebLocalFrame* frame, 1803 bool PrintWebViewHelper::RenderPagesForPrint(blink::WebLocalFrame* frame,
1786 const blink::WebNode& node) { 1804 const blink::WebNode& node) {
1787 if (!frame || prep_frame_view_) 1805 if (!frame || prep_frame_view_)
1788 return false; 1806 return false;
1789 1807
1790 const PrintMsg_PrintPages_Params& params = *print_pages_params_; 1808 const PrintMsg_PrintPages_Params& params = *print_pages_params_;
1791 const PrintMsg_Print_Params& print_params = params.params; 1809 const PrintMsg_Print_Params& print_params = params.params;
1792 prep_frame_view_.reset(new PrepareFrameAndViewForPrint( 1810 prep_frame_view_.reset(new PrepareFrameAndViewForPrint(
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
1936 // |is_modifiable| value until they are fully loaded, which occurs when 1954 // |is_modifiable| value until they are fully loaded, which occurs when
1937 // DidStopLoading() is called. Defer showing the preview until then. 1955 // DidStopLoading() is called. Defer showing the preview until then.
1938 on_stop_loading_closure_ = 1956 on_stop_loading_closure_ =
1939 base::Bind(&PrintWebViewHelper::ShowScriptedPrintPreview, 1957 base::Bind(&PrintWebViewHelper::ShowScriptedPrintPreview,
1940 base::Unretained(this)); 1958 base::Unretained(this));
1941 } else { 1959 } else {
1942 base::ThreadTaskRunnerHandle::Get()->PostTask( 1960 base::ThreadTaskRunnerHandle::Get()->PostTask(
1943 FROM_HERE, base::Bind(&PrintWebViewHelper::ShowScriptedPrintPreview, 1961 FROM_HERE, base::Bind(&PrintWebViewHelper::ShowScriptedPrintPreview,
1944 weak_ptr_factory_.GetWeakPtr())); 1962 weak_ptr_factory_.GetWeakPtr()));
1945 } 1963 }
1946 IPC::SyncMessage* msg = 1964 auto msg = base::MakeUnique<PrintHostMsg_SetupScriptedPrintPreview>(
1947 new PrintHostMsg_SetupScriptedPrintPreview(routing_id()); 1965 routing_id());
1948 msg->EnableMessagePumping(); 1966 msg->EnableMessagePumping();
1949 Send(msg); 1967 auto self = weak_ptr_factory_.GetWeakPtr();
1950 is_scripted_preview_delayed_ = false; 1968 Send(msg.release());
1969 // Check if |this| is still valid.
1970 if (self)
1971 is_scripted_preview_delayed_ = false;
1951 return; 1972 return;
1952 } 1973 }
1953 case PRINT_PREVIEW_USER_INITIATED_ENTIRE_FRAME: { 1974 case PRINT_PREVIEW_USER_INITIATED_ENTIRE_FRAME: {
1954 // Wait for DidStopLoading. Continuing with this function while 1975 // Wait for DidStopLoading. Continuing with this function while
1955 // |is_loading_| is true will cause print preview to hang when try to 1976 // |is_loading_| is true will cause print preview to hang when try to
1956 // print a PDF document. 1977 // print a PDF document.
1957 if (is_loading_ && GetPlugin(print_preview_context_.source_frame())) { 1978 if (is_loading_ && GetPlugin(print_preview_context_.source_frame())) {
1958 on_stop_loading_closure_ = 1979 on_stop_loading_closure_ =
1959 base::Bind(&PrintWebViewHelper::RequestPrintPreview, 1980 base::Bind(&PrintWebViewHelper::RequestPrintPreview,
1960 base::Unretained(this), type); 1981 base::Unretained(this), type);
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after
2317 blink::WebConsoleMessage::LevelWarning, message)); 2338 blink::WebConsoleMessage::LevelWarning, message));
2318 return false; 2339 return false;
2319 } 2340 }
2320 2341
2321 void PrintWebViewHelper::ScriptingThrottler::Reset() { 2342 void PrintWebViewHelper::ScriptingThrottler::Reset() {
2322 // Reset counter on successful print. 2343 // Reset counter on successful print.
2323 count_ = 0; 2344 count_ = 0;
2324 } 2345 }
2325 2346
2326 } // namespace printing 2347 } // namespace printing
OLDNEW
« no previous file with comments | « components/printing/renderer/print_web_view_helper.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698