summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-09 04:30:30 +0000
committerananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-09 04:30:30 +0000
commit1b9af295f86b846582f96277bdba05d98bc3d2f4 (patch)
tree1241b0a0dfbdac3d6b941198068b8c9f8d30c5d9 /chrome
parent3222e481e8bd6e542419d6d97ae26382f571e71d (diff)
downloadchromium_src-1b9af295f86b846582f96277bdba05d98bc3d2f4.zip
chromium_src-1b9af295f86b846582f96277bdba05d98bc3d2f4.tar.gz
chromium_src-1b9af295f86b846582f96277bdba05d98bc3d2f4.tar.bz2
Windowed plugins like Flash would cause the hung plugin dialog to show up when the print dialog was displayed.
The proposed fix is to signal the modal dialog event which would ensure that the renderer and plugins both pump messages when the print dialog is displayed. This fixes http://code.google.com/p/chromium/issues/detail?id=13804 Bug=13804 Review URL: http://codereview.chromium.org/155133 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@20243 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/renderer_host/render_view_host.cc31
-rw-r--r--chrome/browser/renderer_host/render_view_host.h3
-rw-r--r--chrome/browser/renderer_host/render_widget_helper.cc30
-rw-r--r--chrome/browser/renderer_host/render_widget_helper.h9
-rw-r--r--chrome/browser/renderer_host/resource_message_filter.cc22
-rw-r--r--chrome/browser/renderer_host/resource_message_filter.h8
-rw-r--r--chrome/common/render_messages.h44
-rw-r--r--chrome/common/render_messages_internal.h9
-rw-r--r--chrome/renderer/mock_render_thread.cc14
-rw-r--r--chrome/renderer/mock_render_thread.h6
-rw-r--r--chrome/renderer/print_web_view_helper.cc20
11 files changed, 146 insertions, 50 deletions
diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc
index 4445099..43de151 100644
--- a/chrome/browser/renderer_host/render_view_host.cc
+++ b/chrome/browser/renderer_host/render_view_host.cc
@@ -559,8 +559,7 @@ void RenderViewHost::JavaScriptMessageBoxClosed(IPC::Message* reply_msg,
}
void RenderViewHost::JavaScriptMessageBoxWindowDestroyed() {
- if (--modal_dialog_count_ == 0)
- modal_dialog_event_->Reset();
+ ResetModalDialogEvent();
}
void RenderViewHost::ModalHTMLDialogClosed(IPC::Message* reply_msg,
@@ -568,8 +567,7 @@ void RenderViewHost::ModalHTMLDialogClosed(IPC::Message* reply_msg,
if (is_waiting_for_unload_ack_)
StartHangMonitorTimeout(TimeDelta::FromMilliseconds(kUnloadTimeoutMS));
- if (--modal_dialog_count_ == 0)
- modal_dialog_event_->Reset();
+ ResetModalDialogEvent();
ViewHostMsg_ShowModalHTMLDialog::WriteReplyParams(reply_msg, json_retval);
Send(reply_msg);
@@ -812,8 +810,7 @@ void RenderViewHost::OnMessageReceived(const IPC::Message& msg) {
void RenderViewHost::Shutdown() {
// If we are being run modally (see RunModal), then we need to cleanup.
if (run_modal_reply_msg_) {
- if (--modal_dialog_count_ == 0)
- modal_dialog_event_->Reset();
+ ResetModalDialogEvent();
Send(run_modal_reply_msg_);
run_modal_reply_msg_ = NULL;
}
@@ -865,8 +862,7 @@ void RenderViewHost::OnMsgShowWidget(int route_id,
void RenderViewHost::OnMsgRunModal(IPC::Message* reply_msg) {
DCHECK(!run_modal_reply_msg_);
- if (modal_dialog_count_++ == 0)
- modal_dialog_event_->Signal();
+ SignalModalDialogEvent();
run_modal_reply_msg_ = reply_msg;
// TODO(darin): Bug 1107929: Need to inform our delegate to show this view in
@@ -1200,8 +1196,7 @@ void RenderViewHost::OnMsgRunJavaScriptMessage(
const int flags,
IPC::Message* reply_msg) {
StopHangMonitorTimeout();
- if (modal_dialog_count_++ == 0)
- modal_dialog_event_->Signal();
+ SignalModalDialogEvent();
delegate_->RunJavaScriptMessage(message, default_prompt, frame_url, flags,
reply_msg,
&are_javascript_messages_suppressed_);
@@ -1211,8 +1206,7 @@ void RenderViewHost::OnMsgRunBeforeUnloadConfirm(const GURL& frame_url,
const std::wstring& message,
IPC::Message* reply_msg) {
StopHangMonitorTimeout();
- if (modal_dialog_count_++ == 0)
- modal_dialog_event_->Signal();
+ SignalModalDialogEvent();
delegate_->RunBeforeUnloadConfirm(message, reply_msg);
}
@@ -1220,8 +1214,7 @@ void RenderViewHost::OnMsgShowModalHTMLDialog(
const GURL& url, int width, int height, const std::string& json_arguments,
IPC::Message* reply_msg) {
StopHangMonitorTimeout();
- if (modal_dialog_count_++ == 0)
- modal_dialog_event_->Signal();
+ SignalModalDialogEvent();
delegate_->ShowModalHTMLDialog(url, width, height, json_arguments, reply_msg);
}
@@ -1509,3 +1502,13 @@ void RenderViewHost::OnAccessibilityFocusChange(int acc_obj_id) {
void RenderViewHost::OnCSSInserted() {
delegate_->DidInsertCSS();
}
+
+void RenderViewHost::SignalModalDialogEvent() {
+ if (modal_dialog_count_++ == 0)
+ modal_dialog_event_->Signal();
+}
+
+void RenderViewHost::ResetModalDialogEvent() {
+ if (--modal_dialog_count_ == 0)
+ modal_dialog_event_->Reset();
+}
diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h
index 6d39844..210d74f 100644
--- a/chrome/browser/renderer_host/render_view_host.h
+++ b/chrome/browser/renderer_host/render_view_host.h
@@ -409,6 +409,9 @@ class RenderViewHost : public RenderWidgetHost,
const std::string& response,
const std::string& error);
+ void SignalModalDialogEvent();
+ void ResetModalDialogEvent();
+
protected:
// RenderWidgetHost protected overrides.
virtual void UnhandledKeyboardEvent(const NativeWebKeyboardEvent& event);
diff --git a/chrome/browser/renderer_host/render_widget_helper.cc b/chrome/browser/renderer_host/render_widget_helper.cc
index 7105f8c..9d898b8 100644
--- a/chrome/browser/renderer_host/render_widget_helper.cc
+++ b/chrome/browser/renderer_host/render_widget_helper.cc
@@ -265,6 +265,36 @@ void RenderWidgetHelper::OnCreateWidgetOnUI(
host->CreateNewWidget(route_id, activatable);
}
+void RenderWidgetHelper::SignalModalDialogEvent(int routing_id) {
+ ui_loop()->PostTask(FROM_HERE,
+ NewRunnableMethod(
+ this, &RenderWidgetHelper::SignalModalDialogEventOnUI,
+ routing_id));
+}
+
+void RenderWidgetHelper::SignalModalDialogEventOnUI(int routing_id) {
+ RenderViewHost* host = RenderViewHost::FromID(render_process_id_,
+ routing_id);
+ if (host) {
+ host->SignalModalDialogEvent();
+ }
+}
+
+void RenderWidgetHelper::ResetModalDialogEvent(int routing_id) {
+ ui_loop()->PostTask(FROM_HERE,
+ NewRunnableMethod(
+ this, &RenderWidgetHelper::ResetModalDialogEventOnUI,
+ routing_id));
+}
+
+void RenderWidgetHelper::ResetModalDialogEventOnUI(int routing_id) {
+ RenderViewHost* host = RenderViewHost::FromID(render_process_id_,
+ routing_id);
+ if (host) {
+ host->ResetModalDialogEvent();
+ }
+}
+
#if defined(OS_MACOSX)
TransportDIB* RenderWidgetHelper::MapTransportDIB(TransportDIB::Id dib_id) {
AutoLock locked(allocated_dibs_lock_);
diff --git a/chrome/browser/renderer_host/render_widget_helper.h b/chrome/browser/renderer_host/render_widget_helper.h
index 5392750..0ff672b 100644
--- a/chrome/browser/renderer_host/render_widget_helper.h
+++ b/chrome/browser/renderer_host/render_widget_helper.h
@@ -138,6 +138,12 @@ class RenderWidgetHelper :
void FreeTransportDIB(TransportDIB::Id dib_id);
#endif
+ // Helper functions to signal and reset the modal dialog event, used to
+ // signal the renderer that it needs to pump messages while waiting for
+ // sync calls to return. These functions proxy the request to the UI thread.
+ void SignalModalDialogEvent(int routing_id);
+ void ResetModalDialogEvent(int routing_id);
+
private:
// A class used to proxy a paint message. PaintMsgProxy objects are created
// on the IO thread and destroyed on the UI thread.
@@ -181,6 +187,9 @@ class RenderWidgetHelper :
std::map<TransportDIB::Id, int> allocated_dibs_;
#endif
+ void SignalModalDialogEventOnUI(int routing_id);
+ void ResetModalDialogEventOnUI(int routing_id);
+
// A map of live paint messages. Must hold pending_paints_lock_ to access.
// The PaintMsgProxy objects are not owned by this map. (See PaintMsgProxy
// for details about how the lifetime of instances are managed.)
diff --git a/chrome/browser/renderer_host/resource_message_filter.cc b/chrome/browser/renderer_host/resource_message_filter.cc
index fa3af6ec3..6858430 100644
--- a/chrome/browser/renderer_host/resource_message_filter.cc
+++ b/chrome/browser/renderer_host/resource_message_filter.cc
@@ -737,15 +737,13 @@ void ResourceMessageFilter::OnGetDefaultPrintSettingsReply(
#if defined(OS_WIN)
-void ResourceMessageFilter::OnScriptedPrint(gfx::NativeViewId host_window_id,
- int cookie,
- int expected_pages_count,
- bool has_selection,
- IPC::Message* reply_msg) {
- HWND host_window = gfx::NativeViewFromId(host_window_id);
+void ResourceMessageFilter::OnScriptedPrint(
+ const ViewHostMsg_ScriptedPrint_Params& params,
+ IPC::Message* reply_msg) {
+ HWND host_window = gfx::NativeViewFromId(params.host_window_id);
scoped_refptr<printing::PrinterQuery> printer_query;
- print_job_manager_->PopPrinterQuery(cookie, &printer_query);
+ print_job_manager_->PopPrinterQuery(params.cookie, &printer_query);
if (!printer_query.get()) {
printer_query = new printing::PrinterQuery;
}
@@ -754,6 +752,7 @@ void ResourceMessageFilter::OnScriptedPrint(gfx::NativeViewId host_window_id,
this,
&ResourceMessageFilter::OnScriptedPrintReply,
printer_query,
+ params.routing_id,
reply_msg);
// Shows the Print... dialog box. This is asynchronous, only the IPC message
// sender will hang until the Print dialog is dismissed.
@@ -764,15 +763,19 @@ void ResourceMessageFilter::OnScriptedPrint(gfx::NativeViewId host_window_id,
host_window = GetAncestor(host_window, GA_ROOTOWNER);
}
DCHECK(host_window);
+
+ render_widget_helper_->SignalModalDialogEvent(params.routing_id);
+
printer_query->GetSettings(printing::PrinterQuery::ASK_USER,
host_window,
- expected_pages_count,
- has_selection,
+ params.expected_pages_count,
+ params.has_selection,
task);
}
void ResourceMessageFilter::OnScriptedPrintReply(
scoped_refptr<printing::PrinterQuery> printer_query,
+ int routing_id,
IPC::Message* reply_msg) {
ViewMsg_PrintPages_Params params;
if (printer_query->last_status() != printing::PrintingContext::OK ||
@@ -791,6 +794,7 @@ void ResourceMessageFilter::OnScriptedPrintReply(
} else {
printer_query->StopWorker();
}
+ render_widget_helper_->ResetModalDialogEvent(routing_id);
}
#endif // OS_WIN
diff --git a/chrome/browser/renderer_host/resource_message_filter.h b/chrome/browser/renderer_host/resource_message_filter.h
index 91a20d8..70eeaf8 100644
--- a/chrome/browser/renderer_host/resource_message_filter.h
+++ b/chrome/browser/renderer_host/resource_message_filter.h
@@ -48,6 +48,8 @@ namespace WebKit {
struct WebScreenInfo;
}
+struct ViewHostMsg_ScriptedPrint_Params;
+
// This class filters out incoming IPC messages for network requests and
// processes them on the IPC thread. As a result, network requests are not
// delayed by costly UI processing that may be occuring on the main thread of
@@ -204,13 +206,11 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter,
// A javascript code requested to print the current page. The renderer host
// have to show to the user the print dialog and returns the selected print
// settings.
- void OnScriptedPrint(gfx::NativeViewId host_window,
- int cookie,
- int expected_pages_count,
- bool has_selection,
+ void OnScriptedPrint(const ViewHostMsg_ScriptedPrint_Params& params,
IPC::Message* reply_msg);
void OnScriptedPrintReply(
scoped_refptr<printing::PrinterQuery> printer_query,
+ int routing_id,
IPC::Message* reply_msg);
#endif
// Browser side transport DIB allocation
diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h
index 8cd4280..b2fd1f9 100644
--- a/chrome/common/render_messages.h
+++ b/chrome/common/render_messages.h
@@ -397,6 +397,15 @@ struct ViewHostMsg_ShowPopup_Params {
std::vector<WebMenuItem> popup_items;
};
+// Parameters for the IPC message ViewHostMsg_ScriptedPrint
+struct ViewHostMsg_ScriptedPrint_Params {
+ int routing_id;
+ gfx::NativeViewId host_window_id;
+ int cookie;
+ int expected_pages_count;
+ bool has_selection;
+};
+
namespace IPC {
template <>
@@ -1913,6 +1922,41 @@ struct ParamTraits<ViewHostMsg_ShowPopup_Params> {
}
};
+// Traits for ViewHostMsg_ScriptedPrint_Params.
+template <>
+struct ParamTraits<ViewHostMsg_ScriptedPrint_Params> {
+ typedef ViewHostMsg_ScriptedPrint_Params param_type;
+ static void Write(Message* m, const param_type& p) {
+ WriteParam(m, p.routing_id);
+ WriteParam(m, p.host_window_id);
+ WriteParam(m, p.cookie);
+ WriteParam(m, p.expected_pages_count);
+ WriteParam(m, p.has_selection);
+ }
+ static bool Read(const Message* m, void** iter, param_type* p) {
+ return
+ ReadParam(m, iter, &p->routing_id) &&
+ ReadParam(m, iter, &p->host_window_id) &&
+ ReadParam(m, iter, &p->cookie) &&
+ ReadParam(m, iter, &p->expected_pages_count) &&
+ ReadParam(m, iter, &p->has_selection);
+ }
+ static void Log(const param_type& p, std::wstring* l) {
+ l->append(L"(");
+ LogParam(p.routing_id, l);
+ l->append(L", ");
+ LogParam(p.host_window_id, l);
+ l->append(L", ");
+ LogParam(p.cookie, l);
+ l->append(L", ");
+ LogParam(p.expected_pages_count, l);
+ l->append(L", ");
+ LogParam(p.has_selection, l);
+ l->append(L")");
+ }
+};
+
+
} // namespace IPC
diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h
index a674ad2..5938bc1 100644
--- a/chrome/common/render_messages_internal.h
+++ b/chrome/common/render_messages_internal.h
@@ -1081,12 +1081,9 @@ IPC_BEGIN_MESSAGES(ViewHost)
// by javascript. This step is about showing UI to the user to select the
// final print settings. The output parameter is the same as
// ViewMsg_PrintPages which is executed implicitly.
- IPC_SYNC_MESSAGE_ROUTED4_1(ViewHostMsg_ScriptedPrint,
- gfx::NativeViewId /* host_window */,
- int /* cookie */,
- int /* expected_pages_count */,
- bool /* has_selection */,
- ViewMsg_PrintPages_Params /* settings choosen by
+ IPC_SYNC_MESSAGE_CONTROL1_1(ViewHostMsg_ScriptedPrint,
+ ViewHostMsg_ScriptedPrint_Params,
+ ViewMsg_PrintPages_Params /* settings choosen by
the user*/)
#endif // defined(OS_WIN)
diff --git a/chrome/renderer/mock_render_thread.cc b/chrome/renderer/mock_render_thread.cc
index a9df6fd..3494b12 100644
--- a/chrome/renderer/mock_render_thread.cc
+++ b/chrome/renderer/mock_render_thread.cc
@@ -114,15 +114,13 @@ void MockRenderThread::OnGetDefaultPrintSettings(ViewMsg_Print_Params* params) {
printer_->GetDefaultPrintSettings(params);
}
-void MockRenderThread::OnScriptedPrint(gfx::NativeViewId host_window,
- int cookie,
- int expected_pages_count,
- bool has_selection,
- ViewMsg_PrintPages_Params* settings) {
+void MockRenderThread::OnScriptedPrint(
+ const ViewHostMsg_ScriptedPrint_Params& params,
+ ViewMsg_PrintPages_Params* settings) {
if (printer_.get()) {
- printer_->ScriptedPrint(cookie,
- expected_pages_count,
- has_selection,
+ printer_->ScriptedPrint(params.cookie,
+ params.expected_pages_count,
+ params.has_selection,
settings);
}
}
diff --git a/chrome/renderer/mock_render_thread.h b/chrome/renderer/mock_render_thread.h
index 75ca5d3..1921fb1 100644
--- a/chrome/renderer/mock_render_thread.h
+++ b/chrome/renderer/mock_render_thread.h
@@ -14,6 +14,7 @@
struct ViewMsg_Print_Params;
struct ViewMsg_PrintPages_Params;
+struct ViewHostMsg_ScriptedPrint_Params;
// This class is very simple mock of RenderThread. It simulates an IPC channel
// which supports only two messages:
@@ -89,10 +90,7 @@ class MockRenderThread : public RenderThreadBase {
void OnGetDefaultPrintSettings(ViewMsg_Print_Params* setting);
// The RenderView expects final print settings from the user.
- void OnScriptedPrint(gfx::NativeViewId host_window,
- int cookie,
- int expected_pages_count,
- bool has_selection,
+ void OnScriptedPrint(const ViewHostMsg_ScriptedPrint_Params& params,
ViewMsg_PrintPages_Params* settings);
void OnDidGetPrintedPagesCount(int cookie, int number_pages);
diff --git a/chrome/renderer/print_web_view_helper.cc b/chrome/renderer/print_web_view_helper.cc
index 966a9e0..aac98ac 100644
--- a/chrome/renderer/print_web_view_helper.cc
+++ b/chrome/renderer/print_web_view_helper.cc
@@ -157,15 +157,25 @@ void PrintWebViewHelper::Print(WebFrame* frame, bool script_initiated) {
// Ask the browser to show UI to retrieve the final print settings.
ViewMsg_PrintPages_Params print_settings;
+
+ ViewHostMsg_ScriptedPrint_Params params;
+
+ // The routing id is sent across as it is needed to look up the
+ // corresponding RenderViewHost instance to signal and reset the
+ // pump messages event.
+ params.routing_id = routing_id();
// host_window_ may be NULL at this point if the current window is a popup
// and the print() command has been issued from the parent. The receiver
// of this message has to deal with this.
- msg = new ViewHostMsg_ScriptedPrint(routing_id(),
- render_view_->host_window(),
- default_settings.document_cookie,
- expected_pages_count,
- frame->HasSelection(),
+ params.host_window_id = render_view_->host_window();
+ params.cookie = default_settings.document_cookie;
+ params.has_selection = frame->HasSelection();
+ params.expected_pages_count = expected_pages_count;
+
+ msg = new ViewHostMsg_ScriptedPrint(params,
&print_settings);
+ msg->set_pump_messages_event(render_view_->modal_dialog_event());
+
if (Send(msg)) {
msg = NULL;