| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef CONTENT_BROWSER_RENDERER_HOST_RENDER_PROCESS_HOST_H_ | |
| 6 #define CONTENT_BROWSER_RENDERER_HOST_RENDER_PROCESS_HOST_H_ | |
| 7 #pragma once | |
| 8 | |
| 9 #include <set> | |
| 10 | |
| 11 #include "base/id_map.h" | |
| 12 #include "base/memory/scoped_ptr.h" | |
| 13 #include "base/process.h" | |
| 14 #include "base/process_util.h" | |
| 15 #include "base/time.h" | |
| 16 #include "content/common/content_export.h" | |
| 17 #include "ipc/ipc_channel_proxy.h" | |
| 18 #include "ui/gfx/native_widget_types.h" | |
| 19 #include "ui/gfx/surface/transport_dib.h" | |
| 20 | |
| 21 class GURL; | |
| 22 struct ViewMsg_SwapOut_Params; | |
| 23 | |
| 24 namespace content { | |
| 25 class BrowserContext; | |
| 26 } | |
| 27 | |
| 28 // Virtual interface that represents the browser side of the browser <-> | |
| 29 // renderer communication channel. There will generally be one | |
| 30 // RenderProcessHost per renderer process. | |
| 31 // | |
| 32 // The concrete implementation of this class for normal use is the | |
| 33 // BrowserRenderProcessHost. It may also be implemented by a testing interface | |
| 34 // for mocking purposes. | |
| 35 class CONTENT_EXPORT RenderProcessHost : public IPC::Channel::Sender, | |
| 36 public IPC::Channel::Listener { | |
| 37 public: | |
| 38 typedef IDMap<RenderProcessHost>::iterator iterator; | |
| 39 | |
| 40 // Details for RENDERER_PROCESS_CLOSED notifications. | |
| 41 struct RendererClosedDetails { | |
| 42 RendererClosedDetails(base::ProcessHandle handle, | |
| 43 base::TerminationStatus status, | |
| 44 int exit_code, | |
| 45 bool was_alive) { | |
| 46 this->handle = handle; | |
| 47 this->status = status; | |
| 48 this->exit_code = exit_code; | |
| 49 this->was_alive = was_alive; | |
| 50 } | |
| 51 base::ProcessHandle handle; | |
| 52 base::TerminationStatus status; | |
| 53 int exit_code; | |
| 54 bool was_alive; | |
| 55 }; | |
| 56 | |
| 57 explicit RenderProcessHost(content::BrowserContext* browser_context); | |
| 58 virtual ~RenderProcessHost(); | |
| 59 | |
| 60 // Returns the user browser context associated with this renderer process. | |
| 61 content::BrowserContext* browser_context() const { return browser_context_; } | |
| 62 | |
| 63 // Returns the unique ID for this child process. This can be used later in | |
| 64 // a call to FromID() to get back to this object (this is used to avoid | |
| 65 // sending non-threadsafe pointers to other threads). | |
| 66 // | |
| 67 // This ID will be unique for all child processes, including workers, plugins, | |
| 68 // etc. It is generated by ChildProcessInfo. | |
| 69 int id() const { return id_; } | |
| 70 | |
| 71 // Returns true iff channel_ has been set to non-NULL. Use this for checking | |
| 72 // if there is connection or not. Virtual for mocking out for tests. | |
| 73 virtual bool HasConnection() const; | |
| 74 | |
| 75 bool sudden_termination_allowed() const { | |
| 76 return sudden_termination_allowed_; | |
| 77 } | |
| 78 void set_sudden_termination_allowed(bool enabled) { | |
| 79 sudden_termination_allowed_ = enabled; | |
| 80 } | |
| 81 | |
| 82 // Used for refcounting, each holder of this object must Attach and Release | |
| 83 // just like it would for a COM object. This object should be allocated on | |
| 84 // the heap; when no listeners own it any more, it will delete itself. | |
| 85 void Attach(IPC::Channel::Listener* listener, int routing_id); | |
| 86 | |
| 87 // See Attach() | |
| 88 void Release(int listener_id); | |
| 89 | |
| 90 // Schedules the host for deletion and removes it from the all_hosts list. | |
| 91 void Cleanup(); | |
| 92 | |
| 93 // Listeners should call this when they've sent a "Close" message and | |
| 94 // they're waiting for a "Close_ACK", so that if the renderer process | |
| 95 // goes away we'll know that it was intentional rather than a crash. | |
| 96 void ReportExpectingClose(int32 listener_id); | |
| 97 | |
| 98 // Track the count of pending views that are being swapped back in. Called | |
| 99 // by listeners to register and unregister pending views to prevent the | |
| 100 // process from exiting. | |
| 101 void AddPendingView(); | |
| 102 void RemovePendingView(); | |
| 103 | |
| 104 // Allows iteration over this RenderProcessHost's RenderViewHost listeners. | |
| 105 // Use from UI thread only. | |
| 106 typedef IDMap<IPC::Channel::Listener>::const_iterator listeners_iterator; | |
| 107 | |
| 108 listeners_iterator ListenersIterator() { | |
| 109 return listeners_iterator(&listeners_); | |
| 110 } | |
| 111 | |
| 112 IPC::Channel::Listener* GetListenerByID(int routing_id) { | |
| 113 return listeners_.Lookup(routing_id); | |
| 114 } | |
| 115 | |
| 116 IPC::ChannelProxy* channel() { return channel_.get(); } | |
| 117 | |
| 118 // Called to inform the render process host of a new "max page id" for a | |
| 119 // render view host. The render process host computes the largest page id | |
| 120 // across all render view hosts and uses the value when it needs to | |
| 121 // initialize a new renderer in place of the current one. | |
| 122 void UpdateMaxPageID(int32 page_id); | |
| 123 | |
| 124 void set_ignore_input_events(bool ignore_input_events) { | |
| 125 ignore_input_events_ = ignore_input_events; | |
| 126 } | |
| 127 bool ignore_input_events() { | |
| 128 return ignore_input_events_; | |
| 129 } | |
| 130 | |
| 131 // Returns how long the child has been idle. The definition of idle | |
| 132 // depends on when a derived class calls mark_child_process_activity_time(). | |
| 133 // This is a rough indicator and its resolution should not be better than | |
| 134 // 10 milliseconds. | |
| 135 base::TimeDelta get_child_process_idle_time() const { | |
| 136 return base::TimeTicks::Now() - child_process_activity_time_; | |
| 137 } | |
| 138 | |
| 139 // Call this function when it is evident that the child process is actively | |
| 140 // performing some operation, for example if we just received an IPC message. | |
| 141 void mark_child_process_activity_time() { | |
| 142 child_process_activity_time_ = base::TimeTicks::Now(); | |
| 143 } | |
| 144 | |
| 145 // Try to shutdown the associated render process as fast as possible, but | |
| 146 // only if |count| matches the number of render widgets that this process | |
| 147 // controls. | |
| 148 bool FastShutdownForPageCount(size_t count); | |
| 149 | |
| 150 bool fast_shutdown_started() { | |
| 151 return fast_shutdown_started_; | |
| 152 } | |
| 153 | |
| 154 // Virtual interface --------------------------------------------------------- | |
| 155 | |
| 156 // Call this to allow queueing of IPC messages that are sent before the | |
| 157 // process is launched. | |
| 158 virtual void EnableSendQueue() = 0; | |
| 159 | |
| 160 // Initialize the new renderer process, returning true on success. This must | |
| 161 // be called once before the object can be used, but can be called after | |
| 162 // that with no effect. Therefore, if the caller isn't sure about whether | |
| 163 // the process has been created, it should just call Init(). | |
| 164 virtual bool Init(bool is_accessibility_enabled) = 0; | |
| 165 | |
| 166 // Gets the next available routing id. | |
| 167 virtual int GetNextRoutingID() = 0; | |
| 168 | |
| 169 // Update the max page ID and send the update to the renderer process as well. | |
| 170 virtual void UpdateAndSendMaxPageID(int32 page_id) = 0; | |
| 171 | |
| 172 // Called on the UI thread to cancel any outstanding resource requests for | |
| 173 // the specified render widget. | |
| 174 virtual void CancelResourceRequests(int render_widget_id) = 0; | |
| 175 | |
| 176 // Called on the UI thread to simulate a SwapOut_ACK message to the | |
| 177 // ResourceDispatcherHost. Necessary for a cross-site request, in the case | |
| 178 // that the original RenderViewHost is not live and thus cannot run an | |
| 179 // unload handler. | |
| 180 virtual void CrossSiteSwapOutACK( | |
| 181 const ViewMsg_SwapOut_Params& params) = 0; | |
| 182 | |
| 183 // Called on the UI thread to wait for the next UpdateRect message for the | |
| 184 // specified render widget. Returns true if successful, and the msg out- | |
| 185 // param will contain a copy of the received UpdateRect message. | |
| 186 virtual bool WaitForUpdateMsg(int render_widget_id, | |
| 187 const base::TimeDelta& max_delay, | |
| 188 IPC::Message* msg) = 0; | |
| 189 | |
| 190 // Called when a received message cannot be decoded. | |
| 191 virtual void ReceivedBadMessage() = 0; | |
| 192 | |
| 193 // Track the count of visible widgets. Called by listeners to register and | |
| 194 // unregister visibility. | |
| 195 virtual void WidgetRestored() = 0; | |
| 196 virtual void WidgetHidden() = 0; | |
| 197 virtual int VisibleWidgetCount() const = 0; | |
| 198 | |
| 199 // Try to shutdown the associated renderer process as fast as possible. | |
| 200 // If this renderer has any RenderViews with unload handlers, then this | |
| 201 // function does nothing. The current implementation uses TerminateProcess. | |
| 202 // Returns True if it was able to do fast shutdown. | |
| 203 virtual bool FastShutdownIfPossible() = 0; | |
| 204 | |
| 205 // Dump the child process' handle table before shutting down. | |
| 206 virtual void DumpHandles() = 0; | |
| 207 | |
| 208 // Returns the process object associated with the child process. In certain | |
| 209 // tests or single-process mode, this will actually represent the current | |
| 210 // process. | |
| 211 // | |
| 212 // NOTE: this is not necessarily valid immediately after calling Init, as | |
| 213 // Init starts the process asynchronously. It's guaranteed to be valid after | |
| 214 // the first IPC arrives. | |
| 215 virtual base::ProcessHandle GetHandle() = 0; | |
| 216 | |
| 217 // Transport DIB functions --------------------------------------------------- | |
| 218 | |
| 219 // Return the TransportDIB for the given id. On Linux, this can involve | |
| 220 // mapping shared memory. On Mac, the shared memory is created in the browser | |
| 221 // process and the cached metadata is returned. On Windows, this involves | |
| 222 // duplicating the handle from the remote process. The RenderProcessHost | |
| 223 // still owns the returned DIB. | |
| 224 virtual TransportDIB* GetTransportDIB(TransportDIB::Id dib_id) = 0; | |
| 225 | |
| 226 // RenderWidgetHost / compositing surface mapping functions ------------------ | |
| 227 | |
| 228 // Set a mapping from a RenderWidgetHost to a compositing surface. Pass a null | |
| 229 // handle to remove the mapping. | |
| 230 virtual void SetCompositingSurface( | |
| 231 int render_widget_id, | |
| 232 gfx::PluginWindowHandle compositing_surface) = 0; | |
| 233 | |
| 234 // Static management functions ----------------------------------------------- | |
| 235 | |
| 236 // Flag to run the renderer in process. This is primarily | |
| 237 // for debugging purposes. When running "in process", the | |
| 238 // browser maintains a single RenderProcessHost which communicates | |
| 239 // to a RenderProcess which is instantiated in the same process | |
| 240 // with the Browser. All IPC between the Browser and the | |
| 241 // Renderer is the same, it's just not crossing a process boundary. | |
| 242 static bool run_renderer_in_process() { | |
| 243 return run_renderer_in_process_; | |
| 244 } | |
| 245 static void set_run_renderer_in_process(bool value) { | |
| 246 run_renderer_in_process_ = value; | |
| 247 } | |
| 248 | |
| 249 // Allows iteration over all the RenderProcessHosts in the browser. Note | |
| 250 // that each host may not be active, and therefore may have NULL channels. | |
| 251 static iterator AllHostsIterator(); | |
| 252 | |
| 253 // Returns the RenderProcessHost given its ID. Returns NULL if the ID does | |
| 254 // not correspond to a live RenderProcessHost. | |
| 255 static RenderProcessHost* FromID(int render_process_id); | |
| 256 | |
| 257 // Returns true if the caller should attempt to use an existing | |
| 258 // RenderProcessHost rather than creating a new one. | |
| 259 static bool ShouldTryToUseExistingProcessHost(); | |
| 260 | |
| 261 // Get an existing RenderProcessHost associated with the given browser | |
| 262 // context, if possible. The renderer process is chosen randomly from | |
| 263 // suitable renderers that share the same context and type (determined by the | |
| 264 // site url). | |
| 265 // Returns NULL if no suitable renderer process is available, in which case | |
| 266 // the caller is free to create a new renderer. | |
| 267 static RenderProcessHost* GetExistingProcessHost( | |
| 268 content::BrowserContext* browser_context, const GURL& site_url); | |
| 269 | |
| 270 // Overrides the default heuristic for limiting the max renderer process | |
| 271 // count. This is useful for unit testing process limit behaviors. | |
| 272 // A value of zero means to use the default heuristic. | |
| 273 static void SetMaxRendererProcessCountForTest(size_t count); | |
| 274 | |
| 275 protected: | |
| 276 // A proxy for our IPC::Channel that lives on the IO thread (see | |
| 277 // browser_process.h) | |
| 278 scoped_ptr<IPC::ChannelProxy> channel_; | |
| 279 | |
| 280 // The registered listeners. When this list is empty or all NULL, we should | |
| 281 // delete ourselves | |
| 282 IDMap<IPC::Channel::Listener> listeners_; | |
| 283 | |
| 284 // The maximum page ID we've ever seen from the renderer process. | |
| 285 int32 max_page_id_; | |
| 286 | |
| 287 // True if fast shutdown has been performed on this RPH. | |
| 288 bool fast_shutdown_started_; | |
| 289 | |
| 290 // True if we've posted a DeleteTask and will be deleted soon. | |
| 291 bool deleting_soon_; | |
| 292 | |
| 293 // The count of currently swapped out but pending RenderViews. We have | |
| 294 // started to swap these in, so the renderer process should not exit if | |
| 295 // this count is non-zero. | |
| 296 int32 pending_views_; | |
| 297 | |
| 298 private: | |
| 299 // The globally-unique identifier for this RPH. | |
| 300 int id_; | |
| 301 | |
| 302 content::BrowserContext* browser_context_; | |
| 303 | |
| 304 // set of listeners that expect the renderer process to close | |
| 305 std::set<int> listeners_expecting_close_; | |
| 306 | |
| 307 // True if the process can be shut down suddenly. If this is true, then we're | |
| 308 // sure that all the RenderViews in the process can be shutdown suddenly. If | |
| 309 // it's false, then specific RenderViews might still be allowed to be shutdown | |
| 310 // suddenly by checking their SuddenTerminationAllowed() flag. This can occur | |
| 311 // if one tab has an unload event listener but another tab in the same process | |
| 312 // doesn't. | |
| 313 bool sudden_termination_allowed_; | |
| 314 | |
| 315 // Set to true if we shouldn't send input events. We actually do the | |
| 316 // filtering for this at the render widget level. | |
| 317 bool ignore_input_events_; | |
| 318 | |
| 319 // See getter above. | |
| 320 static bool run_renderer_in_process_; | |
| 321 | |
| 322 // Records the last time we regarded the child process active. | |
| 323 base::TimeTicks child_process_activity_time_; | |
| 324 | |
| 325 DISALLOW_COPY_AND_ASSIGN(RenderProcessHost); | |
| 326 }; | |
| 327 | |
| 328 // Factory object for RenderProcessHosts. Using this factory allows tests to | |
| 329 // swap out a different one to use a TestRenderProcessHost. | |
| 330 class RenderProcessHostFactory { | |
| 331 public: | |
| 332 virtual ~RenderProcessHostFactory() {} | |
| 333 virtual RenderProcessHost* CreateRenderProcessHost( | |
| 334 content::BrowserContext* browser_context) const = 0; | |
| 335 }; | |
| 336 | |
| 337 #endif // CONTENT_BROWSER_RENDERER_HOST_RENDER_PROCESS_HOST_H_ | |
| OLD | NEW |