Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(709)

Side by Side Diff: chrome/renderer/render_process_impl.cc

Issue 6864001: Move RenderProcess to content. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/renderer/render_process_impl.h ('k') | chrome/renderer/render_process_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 #include "build/build_config.h"
6
7 #if defined(OS_WIN)
8 #include <windows.h>
9 #include <objidl.h>
10 #include <mlang.h>
11 #endif
12
13 #include "chrome/renderer/render_process_impl.h"
14
15 #include "base/basictypes.h"
16 #include "base/command_line.h"
17 #include "base/compiler_specific.h"
18 #include "base/file_util.h"
19 #include "base/message_loop.h"
20 #include "base/metrics/histogram.h"
21 #include "base/path_service.h"
22 #include "base/sys_info.h"
23 #include "base/utf_string_conversions.h"
24 #include "crypto/nss_util.h"
25 #include "chrome/common/chrome_switches.h"
26 #include "chrome/common/chrome_paths.h"
27 #include "chrome/common/render_messages.h"
28 #include "content/common/view_messages.h"
29 #include "content/renderer/render_thread.h"
30 #include "content/renderer/render_view.h"
31 #include "ipc/ipc_channel.h"
32 #include "ipc/ipc_message_utils.h"
33 #include "media/base/media.h"
34 #include "media/base/media_switches.h"
35 #include "skia/ext/platform_canvas.h"
36 #include "ui/gfx/surface/transport_dib.h"
37 #include "webkit/plugins/npapi/plugin_instance.h"
38 #include "webkit/plugins/npapi/plugin_lib.h"
39 #include "webkit/glue/webkit_glue.h"
40
41 #if defined(OS_MACOSX)
42 #include "base/mac/mac_util.h"
43 #elif defined(OS_WIN)
44 #include "app/win/iat_patch_function.h"
45 #endif
46
47 #if defined(OS_LINUX)
48 #include "content/renderer/renderer_sandbox_support_linux.h"
49 #endif
50
51 #if defined(OS_WIN)
52
53 static app::win::IATPatchFunction g_iat_patch_createdca;
54 HDC WINAPI CreateDCAPatch(LPCSTR driver_name,
55 LPCSTR device_name,
56 LPCSTR output,
57 const void* init_data) {
58 DCHECK(std::string("DISPLAY") == std::string(driver_name));
59 DCHECK(!device_name);
60 DCHECK(!output);
61 DCHECK(!init_data);
62
63 // CreateDC fails behind the sandbox, but not CreateCompatibleDC.
64 return CreateCompatibleDC(NULL);
65 }
66
67 static app::win::IATPatchFunction g_iat_patch_get_font_data;
68 DWORD WINAPI GetFontDataPatch(HDC hdc,
69 DWORD table,
70 DWORD offset,
71 LPVOID buffer,
72 DWORD length) {
73 int rv = GetFontData(hdc, table, offset, buffer, length);
74 if (rv == GDI_ERROR && hdc) {
75 HFONT font = static_cast<HFONT>(GetCurrentObject(hdc, OBJ_FONT));
76
77 LOGFONT logfont;
78 if (GetObject(font, sizeof(LOGFONT), &logfont)) {
79 std::vector<char> font_data;
80 if (RenderThread::current()->Send(new ViewHostMsg_PreCacheFont(logfont)))
81 rv = GetFontData(hdc, table, offset, buffer, length);
82 }
83 }
84 return rv;
85 }
86
87 #endif
88
89 RenderProcessImpl::RenderProcessImpl()
90 : ALLOW_THIS_IN_INITIALIZER_LIST(shared_mem_cache_cleaner_(
91 base::TimeDelta::FromSeconds(5),
92 this, &RenderProcessImpl::ClearTransportDIBCache)),
93 transport_dib_next_sequence_number_(0) {
94 in_process_plugins_ = InProcessPlugins();
95 for (size_t i = 0; i < arraysize(shared_mem_cache_); ++i)
96 shared_mem_cache_[i] = NULL;
97
98 #if defined(OS_WIN)
99 // HACK: See http://b/issue?id=1024307 for rationale.
100 if (GetModuleHandle(L"LPK.DLL") == NULL) {
101 // Makes sure lpk.dll is loaded by gdi32 to make sure ExtTextOut() works
102 // when buffering into a EMF buffer for printing.
103 typedef BOOL (__stdcall *GdiInitializeLanguagePack)(int LoadedShapingDLLs);
104 GdiInitializeLanguagePack gdi_init_lpk =
105 reinterpret_cast<GdiInitializeLanguagePack>(GetProcAddress(
106 GetModuleHandle(L"GDI32.DLL"),
107 "GdiInitializeLanguagePack"));
108 DCHECK(gdi_init_lpk);
109 if (gdi_init_lpk) {
110 gdi_init_lpk(0);
111 }
112 }
113 #endif
114
115 // Out of process dev tools rely upon auto break behavior.
116 webkit_glue::SetJavaScriptFlags(
117 "--debugger-auto-break"
118 // Enable lazy in-memory profiling.
119 " --prof --prof-lazy --logfile=*");
120
121 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
122 if (command_line.HasSwitch(switches::kJavaScriptFlags)) {
123 webkit_glue::SetJavaScriptFlags(
124 command_line.GetSwitchValueASCII(switches::kJavaScriptFlags));
125 }
126
127 if (command_line.HasSwitch(switches::kEnableWatchdog)) {
128 // TODO(JAR): Need to implement renderer IO msgloop watchdog.
129 }
130
131 if (command_line.HasSwitch(switches::kDumpHistogramsOnExit)) {
132 base::StatisticsRecorder::set_dump_on_exit(true);
133 }
134
135 // Note that under Linux, the media library will normally already have
136 // been initialized by the Zygote before this instance became a Renderer.
137 FilePath media_path;
138 if (PathService::Get(chrome::DIR_MEDIA_LIBS, &media_path))
139 media::InitializeMediaLibrary(media_path);
140
141 #if !defined(OS_MACOSX)
142 // TODO(hclam): Add more checks here. Currently this is not used.
143 if (media::IsMediaLibraryInitialized() &&
144 CommandLine::ForCurrentProcess()->HasSwitch(
145 switches::kEnableOpenMax)) {
146 media::InitializeOpenMaxLibrary(media_path);
147 }
148 #endif
149
150 #if defined(OS_WIN)
151 // Need to patch a few functions for font loading to work correctly.
152 FilePath pdf;
153 if (PathService::Get(chrome::FILE_PDF_PLUGIN, &pdf) &&
154 file_util::PathExists(pdf)) {
155 g_iat_patch_createdca.Patch(
156 pdf.value().c_str(), "gdi32.dll", "CreateDCA", CreateDCAPatch);
157 g_iat_patch_get_font_data.Patch(
158 pdf.value().c_str(), "gdi32.dll", "GetFontData", GetFontDataPatch);
159 }
160 #endif
161
162 #if defined(OS_LINUX)
163 // Remoting requires NSS to function properly.
164
165 if (!command_line.HasSwitch(switches::kSingleProcess) &&
166 command_line.HasSwitch(switches::kEnableRemoting)) {
167 #if defined(USE_NSS)
168 // We are going to fork to engage the sandbox and we have not loaded
169 // any security modules so it is safe to disable the fork check in NSS.
170 crypto::DisableNSSForkCheck();
171 crypto::ForceNSSNoDBInit();
172 crypto::EnsureNSSInit();
173 #else
174 // TODO(bulach): implement openssl support.
175 NOTREACHED() << "Remoting is not supported for openssl";
176 #endif
177 }
178 #endif
179 }
180
181 RenderProcessImpl::~RenderProcessImpl() {
182 // TODO(port): Try and limit what we pull in for our non-Win unit test bundle.
183 #ifndef NDEBUG
184 // log important leaked objects
185 webkit_glue::CheckForLeaks();
186 #endif
187
188 GetShutDownEvent()->Signal();
189 ClearTransportDIBCache();
190 }
191
192 bool RenderProcessImpl::InProcessPlugins() {
193 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
194 #if defined(OS_LINUX)
195 // Plugin processes require a UI message loop, and the Linux message loop
196 // implementation only allows one UI loop per process.
197 if (command_line.HasSwitch(switches::kInProcessPlugins))
198 NOTIMPLEMENTED() << ": in process plugins not supported on Linux";
199 return command_line.HasSwitch(switches::kInProcessPlugins);
200 #else
201 return command_line.HasSwitch(switches::kInProcessPlugins) ||
202 command_line.HasSwitch(switches::kSingleProcess);
203 #endif
204 }
205
206 // -----------------------------------------------------------------------------
207 // Platform specific code for dealing with bitmap transport...
208
209 TransportDIB* RenderProcessImpl::CreateTransportDIB(size_t size) {
210 #if defined(OS_WIN) || defined(OS_LINUX)
211 // Windows and Linux create transport DIBs inside the renderer
212 return TransportDIB::Create(size, transport_dib_next_sequence_number_++);
213 #elif defined(OS_MACOSX) // defined(OS_WIN) || defined(OS_LINUX)
214 // Mac creates transport DIBs in the browser, so we need to do a sync IPC to
215 // get one. The TransportDIB is cached in the browser.
216 TransportDIB::Handle handle;
217 IPC::Message* msg = new ViewHostMsg_AllocTransportDIB(size, true, &handle);
218 if (!main_thread()->Send(msg))
219 return NULL;
220 if (handle.fd < 0)
221 return NULL;
222 return TransportDIB::Map(handle);
223 #endif // defined(OS_MACOSX)
224 }
225
226 void RenderProcessImpl::FreeTransportDIB(TransportDIB* dib) {
227 if (!dib)
228 return;
229
230 #if defined(OS_MACOSX)
231 // On Mac we need to tell the browser that it can drop a reference to the
232 // shared memory.
233 IPC::Message* msg = new ViewHostMsg_FreeTransportDIB(dib->id());
234 main_thread()->Send(msg);
235 #endif
236
237 delete dib;
238 }
239
240 // -----------------------------------------------------------------------------
241
242
243 skia::PlatformCanvas* RenderProcessImpl::GetDrawingCanvas(
244 TransportDIB** memory, const gfx::Rect& rect) {
245 int width = rect.width();
246 int height = rect.height();
247 const size_t stride = skia::PlatformCanvas::StrideForWidth(rect.width());
248 #if defined(OS_LINUX)
249 const size_t max_size = base::SysInfo::MaxSharedMemorySize();
250 #else
251 const size_t max_size = 0;
252 #endif
253
254 // If the requested size is too big, reduce the height. Ideally we might like
255 // to reduce the width as well to make the size reduction more "balanced", but
256 // it rarely comes up in practice.
257 if ((max_size != 0) && (height * stride > max_size))
258 height = max_size / stride;
259
260 const size_t size = height * stride;
261
262 if (!GetTransportDIBFromCache(memory, size)) {
263 *memory = CreateTransportDIB(size);
264 if (!*memory)
265 return NULL;
266 }
267
268 return (*memory)->GetPlatformCanvas(width, height);
269 }
270
271 void RenderProcessImpl::ReleaseTransportDIB(TransportDIB* mem) {
272 if (PutSharedMemInCache(mem)) {
273 shared_mem_cache_cleaner_.Reset();
274 return;
275 }
276
277 FreeTransportDIB(mem);
278 }
279
280 bool RenderProcessImpl::UseInProcessPlugins() const {
281 return in_process_plugins_;
282 }
283
284 bool RenderProcessImpl::HasInitializedMediaLibrary() const {
285 return media::IsMediaLibraryInitialized();
286 }
287
288 bool RenderProcessImpl::GetTransportDIBFromCache(TransportDIB** mem,
289 size_t size) {
290 // look for a cached object that is suitable for the requested size.
291 for (size_t i = 0; i < arraysize(shared_mem_cache_); ++i) {
292 if (shared_mem_cache_[i] &&
293 size <= shared_mem_cache_[i]->size()) {
294 *mem = shared_mem_cache_[i];
295 shared_mem_cache_[i] = NULL;
296 return true;
297 }
298 }
299
300 return false;
301 }
302
303 int RenderProcessImpl::FindFreeCacheSlot(size_t size) {
304 // simple algorithm:
305 // - look for an empty slot to store mem, or
306 // - if full, then replace smallest entry which is smaller than |size|
307 for (size_t i = 0; i < arraysize(shared_mem_cache_); ++i) {
308 if (shared_mem_cache_[i] == NULL)
309 return i;
310 }
311
312 size_t smallest_size = size;
313 int smallest_index = -1;
314
315 for (size_t i = 1; i < arraysize(shared_mem_cache_); ++i) {
316 const size_t entry_size = shared_mem_cache_[i]->size();
317 if (entry_size < smallest_size) {
318 smallest_size = entry_size;
319 smallest_index = i;
320 }
321 }
322
323 if (smallest_index != -1) {
324 FreeTransportDIB(shared_mem_cache_[smallest_index]);
325 shared_mem_cache_[smallest_index] = NULL;
326 }
327
328 return smallest_index;
329 }
330
331 bool RenderProcessImpl::PutSharedMemInCache(TransportDIB* mem) {
332 const int slot = FindFreeCacheSlot(mem->size());
333 if (slot == -1)
334 return false;
335
336 shared_mem_cache_[slot] = mem;
337 return true;
338 }
339
340 void RenderProcessImpl::ClearTransportDIBCache() {
341 for (size_t i = 0; i < arraysize(shared_mem_cache_); ++i) {
342 if (shared_mem_cache_[i]) {
343 FreeTransportDIB(shared_mem_cache_[i]);
344 shared_mem_cache_[i] = NULL;
345 }
346 }
347 }
OLDNEW
« no previous file with comments | « chrome/renderer/render_process_impl.h ('k') | chrome/renderer/render_process_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698