| // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CONTENT_BROWSER_RENDERER_HOST_RENDER_PROCESS_HOST_H_ |
| #define CONTENT_BROWSER_RENDERER_HOST_RENDER_PROCESS_HOST_H_ |
| #pragma once |
| |
| #include <set> |
| |
| #include "app/surface/transport_dib.h" |
| #include "base/id_map.h" |
| #include "base/process.h" |
| #include "base/process_util.h" |
| #include "base/scoped_ptr.h" |
| #include "base/time.h" |
| #include "chrome/common/visitedlink_common.h" |
| #include "ipc/ipc_sync_channel.h" |
| |
| class Profile; |
| class URLRequestContextGetter; |
| struct ViewMsg_ClosePage_Params; |
| |
| namespace base { |
| class SharedMemory; |
| } |
| |
| // Virtual interface that represents the browser side of the browser <-> |
| // renderer communication channel. There will generally be one |
| // RenderProcessHost per renderer process. |
| // |
| // The concrete implementation of this class for normal use is the |
| // BrowserRenderProcessHost. It may also be implemented by a testing interface |
| // for mocking purposes. |
| class RenderProcessHost : public IPC::Channel::Sender, |
| public IPC::Channel::Listener { |
| public: |
| typedef IDMap<RenderProcessHost>::iterator iterator; |
| |
| // We classify renderers according to their highest privilege, and try |
| // to group pages into renderers with similar privileges. |
| // Note: it may be possible for a renderer to have multiple privileges, |
| // in which case we call it an "extension" renderer. |
| enum Type { |
| TYPE_NORMAL, // Normal renderer, no extra privileges. |
| TYPE_WEBUI, // Renderer with WebUI privileges, like New Tab. |
| TYPE_EXTENSION, // Renderer with extension privileges. |
| }; |
| |
| // Details for RENDERER_PROCESS_CLOSED notifications. |
| struct RendererClosedDetails { |
| RendererClosedDetails(base::TerminationStatus status, |
| int exit_code, |
| bool was_extension_renderer) { |
| this->status = status; |
| this->exit_code = exit_code; |
| this->was_extension_renderer = was_extension_renderer; |
| } |
| base::TerminationStatus status; |
| int exit_code; |
| bool was_extension_renderer; |
| }; |
| |
| explicit RenderProcessHost(Profile* profile); |
| virtual ~RenderProcessHost(); |
| |
| // Returns the user profile associated with this renderer process. |
| Profile* profile() const { return profile_; } |
| |
| // Returns the unique ID for this child process. This can be used later in |
| // a call to FromID() to get back to this object (this is used to avoid |
| // sending non-threadsafe pointers to other threads). |
| // |
| // This ID will be unique for all child processes, including workers, plugins, |
| // etc. It is generated by ChildProcessInfo. |
| int id() const { return id_; } |
| |
| // Returns true iff channel_ has been set to non-NULL. Use this for checking |
| // if there is connection or not. |
| bool HasConnection() { return channel_.get() != NULL; } |
| |
| bool sudden_termination_allowed() const { |
| return sudden_termination_allowed_; |
| } |
| void set_sudden_termination_allowed(bool enabled) { |
| sudden_termination_allowed_ = enabled; |
| } |
| |
| // Used for refcounting, each holder of this object must Attach and Release |
| // just like it would for a COM object. This object should be allocated on |
| // the heap; when no listeners own it any more, it will delete itself. |
| void Attach(IPC::Channel::Listener* listener, int routing_id); |
| |
| // See Attach() |
| void Release(int listener_id); |
| |
| // Listeners should call this when they've sent a "Close" message and |
| // they're waiting for a "Close_ACK", so that if the renderer process |
| // goes away we'll know that it was intentional rather than a crash. |
| void ReportExpectingClose(int32 listener_id); |
| |
| // Allows iteration over this RenderProcessHost's RenderViewHost listeners. |
| // Use from UI thread only. |
| typedef IDMap<IPC::Channel::Listener>::const_iterator listeners_iterator; |
| |
| listeners_iterator ListenersIterator() { |
| return listeners_iterator(&listeners_); |
| } |
| |
| IPC::Channel::Listener* GetListenerByID(int routing_id) { |
| return listeners_.Lookup(routing_id); |
| } |
| |
| // Called to inform the render process host of a new "max page id" for a |
| // render view host. The render process host computes the largest page id |
| // across all render view hosts and uses the value when it needs to |
| // initialize a new renderer in place of the current one. |
| void UpdateMaxPageID(int32 page_id); |
| |
| void set_ignore_input_events(bool ignore_input_events) { |
| ignore_input_events_ = ignore_input_events; |
| } |
| bool ignore_input_events() { |
| return ignore_input_events_; |
| } |
| |
| // Returns how long the child has been idle. The definition of idle |
| // depends on when a derived class calls mark_child_process_activity_time(). |
| // This is a rough indicator and its resolution should not be better than |
| // 10 milliseconds. |
| base::TimeDelta get_child_process_idle_time() const { |
| return base::TimeTicks::Now() - child_process_activity_time_; |
| } |
| |
| // Call this function when it is evident that the child process is actively |
| // performing some operation, for example if we just received an IPC message. |
| void mark_child_process_activity_time() { |
| child_process_activity_time_ = base::TimeTicks::Now(); |
| } |
| |
| // Try to shutdown the associated render process as fast as possible, but |
| // only if |count| matches the number of render widgets that this process |
| // controls. |
| bool FastShutdownForPageCount(size_t count); |
| |
| bool fast_shutdown_started() { |
| return fast_shutdown_started_; |
| } |
| |
| // Virtual interface --------------------------------------------------------- |
| |
| // Initialize the new renderer process, returning true on success. This must |
| // be called once before the object can be used, but can be called after |
| // that with no effect. Therefore, if the caller isn't sure about whether |
| // the process has been created, it should just call Init(). |
| virtual bool Init( |
| bool is_accessibility_enabled, bool is_extensions_process) = 0; |
| |
| // Gets the next available routing id. |
| virtual int GetNextRoutingID() = 0; |
| |
| // Called on the UI thread to cancel any outstanding resource requests for |
| // the specified render widget. |
| virtual void CancelResourceRequests(int render_widget_id) = 0; |
| |
| // Called on the UI thread to simulate a ClosePage_ACK message to the |
| // ResourceDispatcherHost. Necessary for a cross-site request, in the case |
| // that the original RenderViewHost is not live and thus cannot run an |
| // onunload handler. |
| virtual void CrossSiteClosePageACK( |
| const ViewMsg_ClosePage_Params& params) = 0; |
| |
| // Called on the UI thread to wait for the next UpdateRect message for the |
| // specified render widget. Returns true if successful, and the msg out- |
| // param will contain a copy of the received UpdateRect message. |
| virtual bool WaitForUpdateMsg(int render_widget_id, |
| const base::TimeDelta& max_delay, |
| IPC::Message* msg) = 0; |
| |
| // Called when a received message cannot be decoded. |
| virtual void ReceivedBadMessage() = 0; |
| |
| // Track the count of visible widgets. Called by listeners to register and |
| // unregister visibility. |
| virtual void WidgetRestored() = 0; |
| virtual void WidgetHidden() = 0; |
| |
| // Called when RenderView is created by a listener. |
| virtual void ViewCreated() = 0; |
| |
| // Informs the renderer about a new visited link table. |
| virtual void SendVisitedLinkTable(base::SharedMemory* table_memory) = 0; |
| |
| // Notify the renderer that a link was visited. |
| virtual void AddVisitedLinks( |
| const VisitedLinkCommon::Fingerprints& links) = 0; |
| |
| // Clear internal visited links buffer and ask the renderer to update link |
| // coloring state for all of its links. |
| virtual void ResetVisitedLinks() = 0; |
| |
| // Try to shutdown the associated renderer process as fast as possible. |
| // If this renderer has any RenderViews with unload handlers, then this |
| // function does nothing. The current implementation uses TerminateProcess. |
| // Returns True if it was able to do fast shutdown. |
| virtual bool FastShutdownIfPossible() = 0; |
| |
| // Synchronously sends the message, waiting for the specified timeout. The |
| // implementor takes ownership of the given Message regardless of whether or |
| // not this method succeeds. Returns true on success. |
| virtual bool SendWithTimeout(IPC::Message* msg, int timeout_ms) = 0; |
| |
| // Returns the process object associated with the child process. In certain |
| // tests or single-process mode, this will actually represent the current |
| // process. |
| // |
| // NOTE: this is not necessarily valid immediately after calling Init, as |
| // Init starts the process asynchronously. It's guaranteed to be valid after |
| // the first IPC arrives. |
| virtual base::ProcessHandle GetHandle() = 0; |
| |
| // Transport DIB functions --------------------------------------------------- |
| |
| // Return the TransportDIB for the given id. On Linux, this can involve |
| // mapping shared memory. On Mac, the shared memory is created in the browser |
| // process and the cached metadata is returned. On Windows, this involves |
| // duplicating the handle from the remote process. The RenderProcessHost |
| // still owns the returned DIB. |
| virtual TransportDIB* GetTransportDIB(TransportDIB::Id dib_id) = 0; |
| |
| // Static management functions ----------------------------------------------- |
| |
| // Flag to run the renderer in process. This is primarily |
| // for debugging purposes. When running "in process", the |
| // browser maintains a single RenderProcessHost which communicates |
| // to a RenderProcess which is instantiated in the same process |
| // with the Browser. All IPC between the Browser and the |
| // Renderer is the same, it's just not crossing a process boundary. |
| static bool run_renderer_in_process() { |
| return run_renderer_in_process_; |
| } |
| static void set_run_renderer_in_process(bool value) { |
| run_renderer_in_process_ = value; |
| } |
| |
| // Allows iteration over all the RenderProcessHosts in the browser. Note |
| // that each host may not be active, and therefore may have NULL channels. |
| static iterator AllHostsIterator(); |
| |
| // Returns the RenderProcessHost given its ID. Returns NULL if the ID does |
| // not correspond to a live RenderProcessHost. |
| static RenderProcessHost* FromID(int render_process_id); |
| |
| // Returns true if the caller should attempt to use an existing |
| // RenderProcessHost rather than creating a new one. |
| static bool ShouldTryToUseExistingProcessHost(); |
| |
| // Get an existing RenderProcessHost associated with the given profile, if |
| // possible. The renderer process is chosen randomly from suitable renderers |
| // that share the same profile and type. |
| // Returns NULL if no suitable renderer process is available, in which case |
| // the caller is free to create a new renderer. |
| static RenderProcessHost* GetExistingProcessHost(Profile* profile, Type type); |
| |
| // Overrides the default heuristic for limiting the max renderer process |
| // count. This is useful for unit testing process limit behaviors. |
| // A value of zero means to use the default heuristic. |
| static void SetMaxRendererProcessCount(size_t count); |
| |
| protected: |
| // A proxy for our IPC::Channel that lives on the IO thread (see |
| // browser_process.h) |
| scoped_ptr<IPC::SyncChannel> channel_; |
| |
| // The registered listeners. When this list is empty or all NULL, we should |
| // delete ourselves |
| IDMap<IPC::Channel::Listener> listeners_; |
| |
| // The maximum page ID we've ever seen from the renderer process. |
| int32 max_page_id_; |
| |
| // True if fast shutdown has been performed on this RPH. |
| bool fast_shutdown_started_; |
| |
| // True if we've posted a DeleteTask and will be deleted soon. |
| bool deleting_soon_; |
| |
| private: |
| // The globally-unique identifier for this RPH. |
| int id_; |
| |
| Profile* profile_; |
| |
| // set of listeners that expect the renderer process to close |
| std::set<int> listeners_expecting_close_; |
| |
| // True if the process can be shut down suddenly. If this is true, then we're |
| // sure that all the RenderViews in the process can be shutdown suddenly. If |
| // it's false, then specific RenderViews might still be allowed to be shutdown |
| // suddenly by checking their SuddenTerminationAllowed() flag. This can occur |
| // if one tab has an unload event listener but another tab in the same process |
| // doesn't. |
| bool sudden_termination_allowed_; |
| |
| // Set to true if we shouldn't send input events. We actually do the |
| // filtering for this at the render widget level. |
| bool ignore_input_events_; |
| |
| // See getter above. |
| static bool run_renderer_in_process_; |
| |
| // Records the last time we regarded the child process active. |
| base::TimeTicks child_process_activity_time_; |
| |
| DISALLOW_COPY_AND_ASSIGN(RenderProcessHost); |
| }; |
| |
| // Factory object for RenderProcessHosts. Using this factory allows tests to |
| // swap out a different one to use a TestRenderProcessHost. |
| class RenderProcessHostFactory { |
| public: |
| virtual ~RenderProcessHostFactory() {} |
| virtual RenderProcessHost* CreateRenderProcessHost( |
| Profile* profile) const = 0; |
| }; |
| |
| #endif // CONTENT_BROWSER_RENDERER_HOST_RENDER_PROCESS_HOST_H_ |