// Copyright (c) 2010 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 CHROME_BROWSER_RENDERER_HOST_RENDER_PROCESS_HOST_H_ #define CHROME_BROWSER_RENDERER_HOST_RENDER_PROCESS_HOST_H_ #pragma once #include #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::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_DOMUI, // Renderer with DOMUI 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::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 channel_; // The registered listeners. When this list is empty or all NULL, we should // delete ourselves IDMap 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 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 // CHROME_BROWSER_RENDERER_HOST_RENDER_PROCESS_HOST_H_