summaryrefslogtreecommitdiffstats
path: root/chrome/browser/renderer_host/render_process_host.h
blob: 5b1bfc77fc349993e72f52183acf7ba2117ebfc9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
// Copyright (c) 2009 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_

#include <set>
#include <string>

#include "base/id_map.h"
#include "base/process.h"
#include "base/scoped_ptr.h"
#include "base/time.h"
#include "chrome/common/transport_dib.h"
#include "chrome/common/visitedlink_common.h"
#include "ipc/ipc_sync_channel.h"

class Profile;
struct ViewMsg_ClosePage_Params;

// 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_DOMUI,      // Renderer with DOMUI privileges, like New Tab.
    TYPE_EXTENSION,  // Renderer with extension privileges.
  };

  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_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 PaintRect message for the
  // specified render widget.  Returns true if successful, and the msg out-
  // param will contain a copy of the received PaintRect message.
  virtual bool WaitForPaintMsg(int render_widget_id,
                               const base::TimeDelta& max_delay,
                               IPC::Message* msg) = 0;

  // Called when a received message cannot be decoded.
  virtual void ReceivedBadMessage(uint16 msg_type) = 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;

  // Add a word in the spellchecker.
  virtual void AddWord(const string16& word) = 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 valid after calling Init, as it 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);

 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_;

 private:
  // The globally-uniqe 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  // CHROME_BROWSER_RENDERER_HOST_RENDER_PROCESS_HOST_H_