diff options
author | tommi@chromium.org <tommi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-10 14:09:37 +0000 |
---|---|---|
committer | tommi@chromium.org <tommi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-10 14:09:37 +0000 |
commit | bbfa9a15797ba107dcae0f7fff85a7f12ffd26b9 (patch) | |
tree | ee15898939e4989b96c6419217696f63d7a5585b /chrome_frame/chrome_frame_automation.h | |
parent | e721ebe885b159f9b18047392be9a0f5834998fb (diff) | |
download | chromium_src-bbfa9a15797ba107dcae0f7fff85a7f12ffd26b9.zip chromium_src-bbfa9a15797ba107dcae0f7fff85a7f12ffd26b9.tar.gz chromium_src-bbfa9a15797ba107dcae0f7fff85a7f12ffd26b9.tar.bz2 |
Handle automation server crashes. When Chrome crashes, we now handle the case and support document refresh or reload.
When chrome crashes, we draw a poor man's sad tab (":-("), so that can clearly be improved.
Another thing is that if the chrome instance that crashed held several navigational entries, then that history is lost.
TEST=There are a couple of tests included, so run those (*TabCrash*) and also verify that when the chrome automation server is killed that we do the right thing. Also check info in bug report.
BUG=25839
Review URL: http://codereview.chromium.org/3061036
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@55565 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_frame/chrome_frame_automation.h')
-rw-r--r-- | chrome_frame/chrome_frame_automation.h | 251 |
1 files changed, 197 insertions, 54 deletions
diff --git a/chrome_frame/chrome_frame_automation.h b/chrome_frame/chrome_frame_automation.h index 60fdcd4..4a3fcc5 100644 --- a/chrome_frame/chrome_frame_automation.h +++ b/chrome_frame/chrome_frame_automation.h @@ -51,19 +51,27 @@ struct DECLSPEC_NOVTABLE ChromeFrameAutomationProxy { // NOLINT virtual ~ChromeFrameAutomationProxy() {} }; +// Forward declarations. +class ProxyFactory; + // We extend the AutomationProxy class to handle our custom // IPC messages -class ChromeFrameAutomationProxyImpl : public ChromeFrameAutomationProxy, - // We have to derive from automationproxy since we want access to some members - // (tracker_ & channel_) - simple aggregation wont work; - // .. and non-public inheritance is verboten. - public AutomationProxy { +class ChromeFrameAutomationProxyImpl + : public ChromeFrameAutomationProxy, + // We have to derive from automationproxy since we want access to some + // members (tracker_ & channel_) - simple aggregation wont work; + // .. and non-public inheritance is verboten. + public AutomationProxy { public: + ~ChromeFrameAutomationProxyImpl(); virtual void SendAsAsync( IPC::SyncMessage* msg, SyncMessageReplyDispatcher::SyncMessageCallContext* context, void* key); + // Called on the worker thread. + virtual void OnChannelError(); + virtual void CancelAsync(void* key); virtual scoped_refptr<TabProxy> CreateTabProxy(int handle); @@ -81,73 +89,201 @@ class ChromeFrameAutomationProxyImpl : public ChromeFrameAutomationProxy, } protected: - explicit ChromeFrameAutomationProxyImpl(int launch_timeout); - ~ChromeFrameAutomationProxyImpl(); + friend class AutomationProxyCacheEntry; + ChromeFrameAutomationProxyImpl(AutomationProxyCacheEntry* entry, + int launch_timeout); + class CFMsgDispatcher; - scoped_refptr<CFMsgDispatcher> sync_; class TabProxyNotificationMessageFilter; + + scoped_refptr<CFMsgDispatcher> sync_; scoped_refptr<TabProxyNotificationMessageFilter> message_filter_; - friend class ProxyFactory; + AutomationProxyCacheEntry* proxy_entry_; }; -// This structure contains information used for launching chrome. -struct ChromeFrameLaunchParams { - int automation_server_launch_timeout; - GURL url; - GURL referrer; - FilePath profile_path; +// This class contains information used for launching chrome. +class ChromeFrameLaunchParams : // NOLINT + public base::RefCounted<ChromeFrameLaunchParams> { + public: + ChromeFrameLaunchParams(const GURL& url, const GURL& referrer, + const FilePath& profile_path, + const std::wstring& profile_name, + const std::wstring& extra_arguments, + bool incognito, bool widget_mode) + : launch_timeout_(kCommandExecutionTimeout), url_(url), + referrer_(referrer), profile_path_(profile_path), + profile_name_(profile_name), extra_arguments_(extra_arguments), + version_check_(true), incognito_mode_(incognito), + is_widget_mode_(widget_mode) { + } + + ~ChromeFrameLaunchParams() { + } + + void set_launch_timeout(int timeout) { + launch_timeout_ = timeout; + } + + int launch_timeout() const { + return launch_timeout_; + } + + const GURL& url() const { + return url_; + } + + void set_url(const GURL& url) { + url_ = url; + } + + const GURL& referrer() const { + return referrer_; + } + + void set_referrer(const GURL& referrer) { + referrer_ = referrer; + } + + const FilePath& profile_path() const { + return profile_path_; + } + + const std::wstring& profile_name() const { + return profile_name_; + } + + const std::wstring& extra_arguments() const { + return extra_arguments_; + } + + bool version_check() const { + return version_check_; + } + + void set_version_check(bool check) { + version_check_ = check; + } + + bool incognito() const { + return incognito_mode_; + } + + bool widget_mode() const { + return is_widget_mode_; + } + + protected: + int launch_timeout_; + GURL url_; + GURL referrer_; + FilePath profile_path_; + std::wstring profile_name_; + std::wstring extra_arguments_; + bool version_check_; + bool incognito_mode_; + bool is_widget_mode_; + + private: + DISALLOW_COPY_AND_ASSIGN(ChromeFrameLaunchParams); +}; + +// Callback when chrome process launch is complete and automation handshake +// (Hello message) is established. +struct DECLSPEC_NOVTABLE LaunchDelegate { // NOLINT + virtual void LaunchComplete(ChromeFrameAutomationProxy* proxy, + AutomationLaunchResult result) = 0; + virtual void AutomationServerDied() = 0; +}; // NOLINT + +// Manages a cached ChromeFrameAutomationProxyImpl entry and holds +// reference-less pointers to LaunchDelegate(s) to be notified in case +// of automation server process changes. +class AutomationProxyCacheEntry + : public base::RefCounted<AutomationProxyCacheEntry> { + public: + AutomationProxyCacheEntry(ChromeFrameLaunchParams* params, + LaunchDelegate* delegate); + + ~AutomationProxyCacheEntry(); + + void AddDelegate(LaunchDelegate* delegate); + void RemoveDelegate(LaunchDelegate* delegate, base::WaitableEvent* done, + bool* was_last_delegate); + + void StartSendUmaInterval(ChromeFrameHistogramSnapshots* snapshots, + int send_interval); + + DWORD WaitForThread(DWORD timeout) { // NOLINT + DCHECK(thread_.get()); + return ::WaitForSingleObject(thread_->thread_handle(), timeout); + } + + bool IsSameProfile(const std::wstring& name) const { + return lstrcmpiW(name.c_str(), profile_name.c_str()) == 0; + } + + base::Thread* thread() const { + return thread_.get(); + } + + MessageLoop* message_loop() const { + return thread_->message_loop(); + } + + bool IsSameThread(PlatformThreadId id) const { + return thread_->thread_id() == id; + } + + ChromeFrameAutomationProxyImpl* proxy() const { + DCHECK(IsSameThread(PlatformThread::CurrentId())); + return proxy_.get(); + } + + // Called by the proxy when the automation server has unexpectedly gone away. + void OnChannelError(); + + protected: + void CreateProxy(ChromeFrameLaunchParams* params, + LaunchDelegate* delegate); + void SendUMAData(); + + protected: std::wstring profile_name; - std::wstring extra_chrome_arguments; - bool perform_version_check; - bool incognito_mode; - bool is_widget_mode; + scoped_ptr<base::Thread> thread_; + scoped_ptr<ChromeFrameAutomationProxyImpl> proxy_; + AutomationLaunchResult launch_result_; + typedef std::vector<LaunchDelegate*> LaunchDelegates; + LaunchDelegates launch_delegates_; + // Used for UMA histogram logging to measure the time for the chrome + // automation server to start; + base::TimeTicks automation_server_launch_start_time_; + ChromeFrameHistogramSnapshots* snapshots_; + int uma_send_interval_; }; // We must create and destroy automation proxy in a thread with a message loop. // Hence thread cannot be a member of the proxy. class ProxyFactory { public: - // Callback when chrome process launch is complete and automation handshake - // (Hello message) is established. - struct DECLSPEC_NOVTABLE LaunchDelegate { // NOLINT - virtual void LaunchComplete(ChromeFrameAutomationProxy* proxy, - AutomationLaunchResult result) = 0; - }; // NOLINT - ProxyFactory(); virtual ~ProxyFactory(); + // Fetches or creates a new automation server instance. + // delegate may be NULL. If non-null, a pointer to the delegate will + // be stored for the lifetime of the automation process or until + // ReleaseAutomationServer is called. virtual void GetAutomationServer(LaunchDelegate* delegate, - const ChromeFrameLaunchParams& params, + ChromeFrameLaunchParams* params, void** automation_server_id); - virtual bool ReleaseAutomationServer(void* server_id); + virtual bool ReleaseAutomationServer(void* server_id, + LaunchDelegate* delegate); private: - struct ProxyCacheEntry { - std::wstring profile_name; - int ref_count; - scoped_ptr<base::Thread> thread; - ChromeFrameAutomationProxyImpl* proxy; - AutomationLaunchResult launch_result; - explicit ProxyCacheEntry(const std::wstring& profile); - }; - - void CreateProxy(ProxyCacheEntry* entry, - const ChromeFrameLaunchParams& params, - LaunchDelegate* delegate); - void ReleaseProxy(ProxyCacheEntry* entry, base::WaitableEvent* done); - - void SendUMAData(ProxyCacheEntry* proxy_entry); - - typedef StackVector<ProxyCacheEntry*, 4> Vector; + typedef StackVector<scoped_refptr<AutomationProxyCacheEntry>, 4> Vector; Vector proxies_; // Lock if we are going to call GetAutomationServer from more than one thread. Lock lock_; - // Used for UMA histogram logging to measure the time for the chrome - // automation server to start; - base::TimeTicks automation_server_launch_start_time_; - // Gathers histograms to be sent to Chrome. ChromeFrameHistogramSnapshots chrome_frame_histograms_; @@ -164,15 +300,16 @@ class ChromeFrameAutomationClient public base::RefCountedThreadSafe<ChromeFrameAutomationClient>, public PluginUrlRequestDelegate, public TabProxy::TabProxyDelegate, - public ProxyFactory::LaunchDelegate { + public LaunchDelegate { public: ChromeFrameAutomationClient(); ~ChromeFrameAutomationClient(); // Called from UI thread. virtual bool Initialize(ChromeFrameDelegate* chrome_frame_delegate, - const ChromeFrameLaunchParams& chrome_launch_params); + ChromeFrameLaunchParams* chrome_launch_params); void Uninitialize(); + void NotifyAndUninitialize(); virtual bool InitiateNavigation(const std::string& url, const std::string& referrer, @@ -284,7 +421,9 @@ class ChromeFrameAutomationClient protected: // ChromeFrameAutomationProxy::LaunchDelegate implementation. virtual void LaunchComplete(ChromeFrameAutomationProxy* proxy, - AutomationLaunchResult result); + AutomationLaunchResult result); + virtual void AutomationServerDied(); + // TabProxyDelegate implementation virtual void OnMessageReceived(TabProxy* tab, const IPC::Message& msg); virtual void OnChannelError(TabProxy* tab); @@ -301,12 +440,16 @@ class ChromeFrameAutomationClient Release(); } + scoped_refptr<ChromeFrameLaunchParams> launch_params() { + return chrome_launch_params_; + } + private: void OnMessageReceivedUIThread(const IPC::Message& msg); void OnChannelErrorUIThread(); HWND chrome_window() const { return chrome_window_; } - void BeginNavigate(const GURL& url, const GURL& referrer); + void BeginNavigate(); void BeginNavigateCompleted(AutomationMsg_NavigationResponseValues result); // Helpers @@ -352,7 +495,7 @@ class ChromeFrameAutomationClient // server being initialized. bool navigate_after_initialization_; - ChromeFrameLaunchParams chrome_launch_params_; + scoped_refptr<ChromeFrameLaunchParams> chrome_launch_params_; // When host network stack is used, this object is in charge of // handling network requests. |