diff --git a/include/capi/cef_load_handler_capi.h b/include/capi/cef_load_handler_capi.h index cac300563..e707a8dd2 100644 --- a/include/capi/cef_load_handler_capi.h +++ b/include/capi/cef_load_handler_capi.h @@ -88,6 +88,21 @@ typedef struct _cef_load_handler_t { struct _cef_browser_t* browser, struct _cef_frame_t* frame, enum cef_errorcode_t errorCode, const cef_string_t* errorText, const cef_string_t* failedUrl); + + /// + // Called when the render process terminates unexpectedly. |status| indicates + // how the process terminated. + /// + void (CEF_CALLBACK *on_render_process_terminated)( + struct _cef_load_handler_t* self, struct _cef_browser_t* browser, + enum cef_termination_status_t status); + + /// + // Called when a plugin has crashed. |plugin_path| is the path of the plugin + // that crashed. + /// + void (CEF_CALLBACK *on_plugin_crashed)(struct _cef_load_handler_t* self, + struct _cef_browser_t* browser, const cef_string_t* plugin_path); } cef_load_handler_t; diff --git a/include/cef_load_handler.h b/include/cef_load_handler.h index 91cec742f..cc5cbf376 100644 --- a/include/cef_load_handler.h +++ b/include/cef_load_handler.h @@ -50,6 +50,7 @@ class CefLoadHandler : public virtual CefBase { public: typedef cef_errorcode_t ErrorCode; + typedef cef_termination_status_t TerminationStatus; /// // Called when the browser begins loading a frame. The |frame| value will @@ -88,6 +89,22 @@ class CefLoadHandler : public virtual CefBase { ErrorCode errorCode, const CefString& errorText, const CefString& failedUrl) {} + + /// + // Called when the render process terminates unexpectedly. |status| indicates + // how the process terminated. + /// + /*--cef()--*/ + virtual void OnRenderProcessTerminated(CefRefPtr browser, + TerminationStatus status) {} + + /// + // Called when a plugin has crashed. |plugin_path| is the path of the plugin + // that crashed. + /// + /*--cef()--*/ + virtual void OnPluginCrashed(CefRefPtr browser, + const CefString& plugin_path) {} }; #endif // CEF_INCLUDE_CEF_LOAD_HANDLER_H_ diff --git a/include/internal/cef_types.h b/include/internal/cef_types.h index a844cea9e..71bf20584 100644 --- a/include/internal/cef_types.h +++ b/include/internal/cef_types.h @@ -580,6 +580,26 @@ typedef struct _cef_cookie_t { cef_time_t expires; } cef_cookie_t; +/// +// Process termination status values. +/// +enum cef_termination_status_t { + /// + // Non-zero exit status. + /// + TS_ABNORMAL_TERMINATION, + + /// + // SIGKILL or task manager kill. + /// + TS_PROCESS_WAS_KILLED, + + /// + // Segmentation fault. + /// + TS_PROCESS_CRASHED, +}; + /// // Storage types. /// diff --git a/libcef/browser/browser_host_impl.cc b/libcef/browser/browser_host_impl.cc index 7ab7702bd..3530e49cc 100644 --- a/libcef/browser/browser_host_impl.cc +++ b/libcef/browser/browser_host_impl.cc @@ -1125,6 +1125,20 @@ void CefBrowserHostImpl::RenderViewReady() { void CefBrowserHostImpl::RenderViewGone(base::TerminationStatus status) { queue_messages_ = true; + + cef_termination_status_t ts = TS_ABNORMAL_TERMINATION; + if (status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED) + ts = TS_PROCESS_WAS_KILLED; + else if (status == base::TERMINATION_STATUS_PROCESS_CRASHED) + ts = TS_PROCESS_CRASHED; + else if (status != base::TERMINATION_STATUS_ABNORMAL_TERMINATION) + return; + + if (client_.get()) { + CefRefPtr handler = client_->GetLoadHandler(); + if (handler.get()) + handler->OnRenderProcessTerminated(this, ts); + } } void CefBrowserHostImpl::DidCommitProvisionalLoadForFrame( @@ -1179,6 +1193,14 @@ void CefBrowserHostImpl::DidFailLoad(int64 frame_id, OnLoadEnd(frame, validated_url); } +void CefBrowserHostImpl::PluginCrashed(const FilePath& plugin_path) { + if (client_.get()) { + CefRefPtr handler = client_->GetLoadHandler(); + if (handler.get()) + handler->OnPluginCrashed(this, plugin_path.value()); + } +} + bool CefBrowserHostImpl::OnMessageReceived(const IPC::Message& message) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(CefBrowserHostImpl, message) diff --git a/libcef/browser/browser_host_impl.h b/libcef/browser/browser_host_impl.h index 3ff0fca52..9619066ee 100644 --- a/libcef/browser/browser_host_impl.h +++ b/libcef/browser/browser_host_impl.h @@ -262,6 +262,7 @@ class CefBrowserHostImpl : public CefBrowserHost, bool is_main_frame, int error_code, const string16& error_description) OVERRIDE; + virtual void PluginCrashed(const FilePath& plugin_path) OVERRIDE; virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; // Override to provide a thread safe implementation. virtual bool Send(IPC::Message* message) OVERRIDE; diff --git a/libcef_dll/cpptoc/load_handler_cpptoc.cc b/libcef_dll/cpptoc/load_handler_cpptoc.cc index f7da851a8..c68f442cd 100644 --- a/libcef_dll/cpptoc/load_handler_cpptoc.cc +++ b/libcef_dll/cpptoc/load_handler_cpptoc.cc @@ -93,6 +93,48 @@ void CEF_CALLBACK load_handler_on_load_error(struct _cef_load_handler_t* self, CefString(failedUrl)); } +void CEF_CALLBACK load_handler_on_render_process_terminated( + struct _cef_load_handler_t* self, cef_browser_t* browser, + enum cef_termination_status_t status) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return; + // Verify param: browser; type: refptr_diff + DCHECK(browser); + if (!browser) + return; + + // Execute + CefLoadHandlerCppToC::Get(self)->OnRenderProcessTerminated( + CefBrowserCToCpp::Wrap(browser), + status); +} + +void CEF_CALLBACK load_handler_on_plugin_crashed( + struct _cef_load_handler_t* self, cef_browser_t* browser, + const cef_string_t* plugin_path) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return; + // Verify param: browser; type: refptr_diff + DCHECK(browser); + if (!browser) + return; + // Verify param: plugin_path; type: string_byref_const + DCHECK(plugin_path); + if (!plugin_path) + return; + + // Execute + CefLoadHandlerCppToC::Get(self)->OnPluginCrashed( + CefBrowserCToCpp::Wrap(browser), + CefString(plugin_path)); +} + // CONSTRUCTOR - Do not edit by hand. @@ -101,6 +143,9 @@ CefLoadHandlerCppToC::CefLoadHandlerCppToC(CefLoadHandler* cls) struct_.struct_.on_load_start = load_handler_on_load_start; struct_.struct_.on_load_end = load_handler_on_load_end; struct_.struct_.on_load_error = load_handler_on_load_error; + struct_.struct_.on_render_process_terminated = + load_handler_on_render_process_terminated; + struct_.struct_.on_plugin_crashed = load_handler_on_plugin_crashed; } #ifndef NDEBUG diff --git a/libcef_dll/ctocpp/load_handler_ctocpp.cc b/libcef_dll/ctocpp/load_handler_ctocpp.cc index 83b061874..c853f0cd3 100644 --- a/libcef_dll/ctocpp/load_handler_ctocpp.cc +++ b/libcef_dll/ctocpp/load_handler_ctocpp.cc @@ -93,6 +93,46 @@ void CefLoadHandlerCToCpp::OnLoadError(CefRefPtr browser, failedUrl.GetStruct()); } +void CefLoadHandlerCToCpp::OnRenderProcessTerminated( + CefRefPtr browser, TerminationStatus status) { + if (CEF_MEMBER_MISSING(struct_, on_render_process_terminated)) + return; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Verify param: browser; type: refptr_diff + DCHECK(browser.get()); + if (!browser.get()) + return; + + // Execute + struct_->on_render_process_terminated(struct_, + CefBrowserCppToC::Wrap(browser), + status); +} + +void CefLoadHandlerCToCpp::OnPluginCrashed(CefRefPtr browser, + const CefString& plugin_path) { + if (CEF_MEMBER_MISSING(struct_, on_plugin_crashed)) + return; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Verify param: browser; type: refptr_diff + DCHECK(browser.get()); + if (!browser.get()) + return; + // Verify param: plugin_path; type: string_byref_const + DCHECK(!plugin_path.empty()); + if (plugin_path.empty()) + return; + + // Execute + struct_->on_plugin_crashed(struct_, + CefBrowserCppToC::Wrap(browser), + plugin_path.GetStruct()); +} + #ifndef NDEBUG template<> long CefCToCpp browser, CefRefPtr frame, ErrorCode errorCode, const CefString& errorText, const CefString& failedUrl) OVERRIDE; + virtual void OnRenderProcessTerminated(CefRefPtr browser, + TerminationStatus status) OVERRIDE; + virtual void OnPluginCrashed(CefRefPtr browser, + const CefString& plugin_path) OVERRIDE; }; #endif // BUILDING_CEF_SHARED diff --git a/tests/cefclient/client_handler.cpp b/tests/cefclient/client_handler.cpp index ba68935b0..7c5b15a3a 100644 --- a/tests/cefclient/client_handler.cpp +++ b/tests/cefclient/client_handler.cpp @@ -3,6 +3,7 @@ // can be found in the LICENSE file. #include "cefclient/client_handler.h" +#include #include #include #include @@ -282,6 +283,18 @@ void ClientHandler::OnLoadError(CefRefPtr browser, frame->LoadString(ss.str(), failedUrl); } +void ClientHandler::OnRenderProcessTerminated(CefRefPtr browser, + TerminationStatus status) { + // Load google.com if that's not the website that we terminated on. + CefRefPtr frame = browser->GetMainFrame(); + std::string url = frame->GetURL(); + std::transform(url.begin(), url.end(), url.begin(), tolower); + + const char kLoadURL[] = "http://www.google.com"; + if (url.find(kLoadURL) != 0) + frame->LoadURL(kLoadURL); +} + CefRefPtr ClientHandler::GetResourceHandler( CefRefPtr browser, CefRefPtr frame, diff --git a/tests/cefclient/client_handler.h b/tests/cefclient/client_handler.h index 15c5385cf..39b226045 100644 --- a/tests/cefclient/client_handler.h +++ b/tests/cefclient/client_handler.h @@ -149,6 +149,8 @@ class ClientHandler : public CefClient, ErrorCode errorCode, const CefString& errorText, const CefString& failedUrl) OVERRIDE; + virtual void OnRenderProcessTerminated(CefRefPtr browser, + TerminationStatus status) OVERRIDE; // CefRequestHandler methods virtual CefRefPtr GetResourceHandler(