| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/public/app/content_main_runner.h" | 5 #include "content/public/app/content_main_runner.h" |
| 6 | 6 |
| 7 #include "base/allocator/allocator_extension.h" | 7 #include "base/allocator/allocator_extension.h" |
| 8 #include "base/at_exit.h" | 8 #include "base/at_exit.h" |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/debug/debugger.h" | 10 #include "base/debug/debugger.h" |
| 11 #include "base/debug/trace_event.h" | 11 #include "base/debug/trace_event.h" |
| 12 #include "base/file_path.h" | 12 #include "base/file_path.h" |
| 13 #include "base/i18n/icu_util.h" | 13 #include "base/i18n/icu_util.h" |
| 14 #include "base/lazy_instance.h" |
| 14 #include "base/logging.h" | 15 #include "base/logging.h" |
| 15 #include "base/memory/scoped_ptr.h" | 16 #include "base/memory/scoped_ptr.h" |
| 16 #include "base/metrics/stats_table.h" | 17 #include "base/metrics/stats_table.h" |
| 17 #include "base/path_service.h" | 18 #include "base/path_service.h" |
| 18 #include "base/process_util.h" | 19 #include "base/process_util.h" |
| 19 #include "base/stringprintf.h" | 20 #include "base/stringprintf.h" |
| 20 #include "base/string_number_conversions.h" | 21 #include "base/string_number_conversions.h" |
| 21 #include "content/browser/browser_main.h" | 22 #include "content/browser/browser_main.h" |
| 22 #include "content/common/set_process_title.h" | 23 #include "content/common/set_process_title.h" |
| 23 #include "content/common/url_schemes.h" | 24 #include "content/common/url_schemes.h" |
| 24 #include "content/public/app/content_main_delegate.h" | 25 #include "content/public/app/content_main_delegate.h" |
| 25 #include "content/public/app/startup_helper_win.h" | 26 #include "content/public/app/startup_helper_win.h" |
| 27 #include "content/public/browser/content_browser_client.h" |
| 26 #include "content/public/common/content_client.h" | 28 #include "content/public/common/content_client.h" |
| 27 #include "content/public/common/content_constants.h" | 29 #include "content/public/common/content_constants.h" |
| 28 #include "content/public/common/content_paths.h" | 30 #include "content/public/common/content_paths.h" |
| 29 #include "content/public/common/content_switches.h" | 31 #include "content/public/common/content_switches.h" |
| 30 #include "content/public/common/main_function_params.h" | 32 #include "content/public/common/main_function_params.h" |
| 31 #include "content/public/common/sandbox_init.h" | 33 #include "content/public/common/sandbox_init.h" |
| 34 #include "content/public/plugin/content_plugin_client.h" |
| 35 #include "content/public/renderer/content_renderer_client.h" |
| 36 #include "content/public/utility/content_utility_client.h" |
| 32 #include "crypto/nss_util.h" | 37 #include "crypto/nss_util.h" |
| 33 #include "ipc/ipc_switches.h" | 38 #include "ipc/ipc_switches.h" |
| 34 #include "media/base/media.h" | 39 #include "media/base/media.h" |
| 35 #include "sandbox/src/sandbox_types.h" | 40 #include "sandbox/src/sandbox_types.h" |
| 36 #include "ui/base/ui_base_switches.h" | 41 #include "ui/base/ui_base_switches.h" |
| 37 #include "ui/base/ui_base_paths.h" | 42 #include "ui/base/ui_base_paths.h" |
| 38 #include "ui/base/win/dpi.h" | 43 #include "ui/base/win/dpi.h" |
| 39 #include "webkit/glue/webkit_glue.h" | 44 #include "webkit/glue/webkit_glue.h" |
| 40 | 45 |
| 41 #if defined(USE_TCMALLOC) | 46 #if defined(USE_TCMALLOC) |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 74 | 79 |
| 75 extern int GpuMain(const content::MainFunctionParams&); | 80 extern int GpuMain(const content::MainFunctionParams&); |
| 76 extern int PluginMain(const content::MainFunctionParams&); | 81 extern int PluginMain(const content::MainFunctionParams&); |
| 77 extern int PpapiPluginMain(const content::MainFunctionParams&); | 82 extern int PpapiPluginMain(const content::MainFunctionParams&); |
| 78 extern int PpapiBrokerMain(const content::MainFunctionParams&); | 83 extern int PpapiBrokerMain(const content::MainFunctionParams&); |
| 79 extern int RendererMain(const content::MainFunctionParams&); | 84 extern int RendererMain(const content::MainFunctionParams&); |
| 80 extern int WorkerMain(const content::MainFunctionParams&); | 85 extern int WorkerMain(const content::MainFunctionParams&); |
| 81 extern int UtilityMain(const content::MainFunctionParams&); | 86 extern int UtilityMain(const content::MainFunctionParams&); |
| 82 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) | 87 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) |
| 83 namespace content { | 88 namespace content { |
| 84 extern int ZygoteMain(const content::MainFunctionParams&, | 89 extern int ZygoteMain(const MainFunctionParams&, |
| 85 content::ZygoteForkDelegate* forkdelegate); | 90 ZygoteForkDelegate* forkdelegate); |
| 86 } // namespace content | 91 } // namespace content |
| 87 #endif | 92 #endif |
| 88 | 93 |
| 89 namespace { | 94 namespace content { |
| 95 |
| 96 base::LazyInstance<ContentBrowserClient> |
| 97 g_empty_content_browser_client = LAZY_INSTANCE_INITIALIZER; |
| 98 base::LazyInstance<ContentPluginClient> |
| 99 g_empty_content_plugin_client = LAZY_INSTANCE_INITIALIZER; |
| 100 base::LazyInstance<ContentRendererClient> |
| 101 g_empty_content_renderer_client = LAZY_INSTANCE_INITIALIZER; |
| 102 base::LazyInstance<ContentUtilityClient> |
| 103 g_empty_content_utility_client = LAZY_INSTANCE_INITIALIZER; |
| 90 | 104 |
| 91 #if defined(OS_WIN) | 105 #if defined(OS_WIN) |
| 92 | 106 |
| 93 static CAppModule _Module; | 107 static CAppModule _Module; |
| 94 | 108 |
| 95 #elif defined(OS_MACOSX) | 109 #elif defined(OS_MACOSX) |
| 96 | 110 |
| 97 // Completes the Mach IPC handshake by sending this process' task port to the | 111 // Completes the Mach IPC handshake by sending this process' task port to the |
| 98 // parent process. The parent is listening on the Mach port given by | 112 // parent process. The parent is listening on the Mach port given by |
| 99 // |GetMachPortName()|. The task port is used by the parent to get CPU/memory | 113 // |GetMachPortName()|. The task port is used by the parent to get CPU/memory |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 199 static void InitializeStatsTable(const CommandLine& command_line) { | 213 static void InitializeStatsTable(const CommandLine& command_line) { |
| 200 // Initialize the Stats Counters table. With this initialized, | 214 // Initialize the Stats Counters table. With this initialized, |
| 201 // the StatsViewer can be utilized to read counters outside of | 215 // the StatsViewer can be utilized to read counters outside of |
| 202 // Chrome. These lines can be commented out to effectively turn | 216 // Chrome. These lines can be commented out to effectively turn |
| 203 // counters 'off'. The table is created and exists for the life | 217 // counters 'off'. The table is created and exists for the life |
| 204 // of the process. It is not cleaned up. | 218 // of the process. It is not cleaned up. |
| 205 if (command_line.HasSwitch(switches::kEnableStatsTable)) { | 219 if (command_line.HasSwitch(switches::kEnableStatsTable)) { |
| 206 // NOTIMPLEMENTED: we probably need to shut this down correctly to avoid | 220 // NOTIMPLEMENTED: we probably need to shut this down correctly to avoid |
| 207 // leaking shared memory regions on posix platforms. | 221 // leaking shared memory regions on posix platforms. |
| 208 std::string statsfile = | 222 std::string statsfile = |
| 209 base::StringPrintf( | 223 base::StringPrintf("%s-%u", kStatsFilename, |
| 210 "%s-%u", content::kStatsFilename, | |
| 211 static_cast<unsigned int>(GetBrowserPid(command_line))); | 224 static_cast<unsigned int>(GetBrowserPid(command_line))); |
| 212 base::StatsTable* stats_table = new base::StatsTable(statsfile, | 225 base::StatsTable* stats_table = new base::StatsTable(statsfile, |
| 213 content::kStatsMaxThreads, content::kStatsMaxCounters); | 226 kStatsMaxThreads, kStatsMaxCounters); |
| 214 base::StatsTable::set_current(stats_table); | 227 base::StatsTable::set_current(stats_table); |
| 215 } | 228 } |
| 216 } | 229 } |
| 217 | 230 |
| 231 class ContentClientInitializer { |
| 232 public: |
| 233 static void Set(const std::string& process_type, |
| 234 ContentMainDelegate* delegate) { |
| 235 ContentClient* content_client = GetContentClient(); |
| 236 if (process_type.empty()) { |
| 237 if (delegate) |
| 238 content_client->browser_ = delegate->CreateContentBrowserClient(); |
| 239 if (!content_client->browser_) |
| 240 content_client->browser_ = &g_empty_content_browser_client.Get(); |
| 241 } |
| 242 |
| 243 if (process_type == switches::kPluginProcess) { |
| 244 if (delegate) |
| 245 content_client->plugin_ = delegate->CreateContentPluginClient(); |
| 246 if (!content_client->plugin_) |
| 247 content_client->plugin_ = &g_empty_content_plugin_client.Get(); |
| 248 } else if (process_type == switches::kRendererProcess) { |
| 249 if (delegate) |
| 250 content_client->renderer_ = delegate->CreateContentRendererClient(); |
| 251 if (!content_client->renderer_) |
| 252 content_client->renderer_ = &g_empty_content_renderer_client.Get(); |
| 253 } else if (process_type == switches::kUtilityProcess) { |
| 254 if (delegate) |
| 255 content_client->utility_ = delegate->CreateContentUtilityClient(); |
| 256 if (!content_client->utility_) |
| 257 content_client->utility_ = &g_empty_content_utility_client.Get(); |
| 258 } |
| 259 } |
| 260 }; |
| 261 |
| 218 // We dispatch to a process-type-specific FooMain() based on a command-line | 262 // We dispatch to a process-type-specific FooMain() based on a command-line |
| 219 // flag. This struct is used to build a table of (flag, main function) pairs. | 263 // flag. This struct is used to build a table of (flag, main function) pairs. |
| 220 struct MainFunction { | 264 struct MainFunction { |
| 221 const char* name; | 265 const char* name; |
| 222 int (*function)(const content::MainFunctionParams&); | 266 int (*function)(const MainFunctionParams&); |
| 223 }; | 267 }; |
| 224 | 268 |
| 225 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) | 269 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) |
| 226 // On platforms that use the zygote, we have a special subset of | 270 // On platforms that use the zygote, we have a special subset of |
| 227 // subprocesses that are launched via the zygote. This function | 271 // subprocesses that are launched via the zygote. This function |
| 228 // fills in some process-launching bits around ZygoteMain(). | 272 // fills in some process-launching bits around ZygoteMain(). |
| 229 // Returns the exit code of the subprocess. | 273 // Returns the exit code of the subprocess. |
| 230 int RunZygote(const content::MainFunctionParams& main_function_params, | 274 int RunZygote(const MainFunctionParams& main_function_params, |
| 231 content::ContentMainDelegate* delegate) { | 275 ContentMainDelegate* delegate) { |
| 232 static const MainFunction kMainFunctions[] = { | 276 static const MainFunction kMainFunctions[] = { |
| 233 { switches::kRendererProcess, RendererMain }, | 277 { switches::kRendererProcess, RendererMain }, |
| 234 { switches::kWorkerProcess, WorkerMain }, | 278 { switches::kWorkerProcess, WorkerMain }, |
| 235 { switches::kPpapiPluginProcess, PpapiPluginMain }, | 279 { switches::kPpapiPluginProcess, PpapiPluginMain }, |
| 236 { switches::kUtilityProcess, UtilityMain }, | 280 { switches::kUtilityProcess, UtilityMain }, |
| 237 }; | 281 }; |
| 238 | 282 |
| 239 scoped_ptr<content::ZygoteForkDelegate> zygote_fork_delegate; | 283 scoped_ptr<ZygoteForkDelegate> zygote_fork_delegate; |
| 240 if (delegate) { | 284 if (delegate) { |
| 241 zygote_fork_delegate.reset(delegate->ZygoteStarting()); | 285 zygote_fork_delegate.reset(delegate->ZygoteStarting()); |
| 242 // Each Renderer we spawn will re-attempt initialization of the media | 286 // Each Renderer we spawn will re-attempt initialization of the media |
| 243 // libraries, at which point failure will be detected and handled, so | 287 // libraries, at which point failure will be detected and handled, so |
| 244 // we do not need to cope with initialization failures here. | 288 // we do not need to cope with initialization failures here. |
| 245 FilePath media_path; | 289 FilePath media_path; |
| 246 if (PathService::Get(content::DIR_MEDIA_LIBS, &media_path)) | 290 if (PathService::Get(DIR_MEDIA_LIBS, &media_path)) |
| 247 media::InitializeMediaLibrary(media_path); | 291 media::InitializeMediaLibrary(media_path); |
| 248 } | 292 } |
| 249 | 293 |
| 250 // This function call can return multiple times, once per fork(). | 294 // This function call can return multiple times, once per fork(). |
| 251 if (!content::ZygoteMain(main_function_params, zygote_fork_delegate.get())) | 295 if (!ZygoteMain(main_function_params, zygote_fork_delegate.get())) |
| 252 return 1; | 296 return 1; |
| 253 | 297 |
| 254 if (delegate) delegate->ZygoteForked(); | 298 if (delegate) delegate->ZygoteForked(); |
| 255 | 299 |
| 256 // Zygote::HandleForkRequest may have reallocated the command | 300 // Zygote::HandleForkRequest may have reallocated the command |
| 257 // line so update it here with the new version. | 301 // line so update it here with the new version. |
| 258 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | 302 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
| 303 std::string process_type = |
| 304 command_line.GetSwitchValueASCII(switches::kProcessType); |
| 305 ContentClientInitializer::Set(process_type, delegate); |
| 259 | 306 |
| 260 // If a custom user agent was passed on the command line, we need | 307 // If a custom user agent was passed on the command line, we need |
| 261 // to (re)set it now, rather than using the default one the zygote | 308 // to (re)set it now, rather than using the default one the zygote |
| 262 // initialized. | 309 // initialized. |
| 263 if (command_line.HasSwitch(switches::kUserAgent)) { | 310 if (command_line.HasSwitch(switches::kUserAgent)) { |
| 264 webkit_glue::SetUserAgent( | 311 webkit_glue::SetUserAgent( |
| 265 command_line.GetSwitchValueASCII(switches::kUserAgent), true); | 312 command_line.GetSwitchValueASCII(switches::kUserAgent), true); |
| 266 } | 313 } |
| 267 | 314 |
| 268 // The StatsTable must be initialized in each process; we already | 315 // The StatsTable must be initialized in each process; we already |
| 269 // initialized for the browser process, now we need to initialize | 316 // initialized for the browser process, now we need to initialize |
| 270 // within the new processes as well. | 317 // within the new processes as well. |
| 271 InitializeStatsTable(command_line); | 318 InitializeStatsTable(command_line); |
| 272 | 319 |
| 273 content::MainFunctionParams main_params(command_line); | 320 MainFunctionParams main_params(command_line); |
| 274 | |
| 275 // Get the new process type from the new command line. | |
| 276 std::string process_type = | |
| 277 command_line.GetSwitchValueASCII(switches::kProcessType); | |
| 278 | 321 |
| 279 for (size_t i = 0; i < arraysize(kMainFunctions); ++i) { | 322 for (size_t i = 0; i < arraysize(kMainFunctions); ++i) { |
| 280 if (process_type == kMainFunctions[i].name) | 323 if (process_type == kMainFunctions[i].name) |
| 281 return kMainFunctions[i].function(main_params); | 324 return kMainFunctions[i].function(main_params); |
| 282 } | 325 } |
| 283 | 326 |
| 284 if (delegate) | 327 if (delegate) |
| 285 return delegate->RunProcess(process_type, main_params); | 328 return delegate->RunProcess(process_type, main_params); |
| 286 | 329 |
| 287 NOTREACHED() << "Unknown zygote process type: " << process_type; | 330 NOTREACHED() << "Unknown zygote process type: " << process_type; |
| 288 return 1; | 331 return 1; |
| 289 } | 332 } |
| 290 #endif // defined(OS_POSIX) && !defined(OS_MACOSX) | 333 #endif // defined(OS_POSIX) && !defined(OS_MACOSX) |
| 291 | 334 |
| 292 // Run the FooMain() for a given process type. | 335 // Run the FooMain() for a given process type. |
| 293 // If |process_type| is empty, runs BrowserMain(). | 336 // If |process_type| is empty, runs BrowserMain(). |
| 294 // Returns the exit code for this process. | 337 // Returns the exit code for this process. |
| 295 int RunNamedProcessTypeMain( | 338 int RunNamedProcessTypeMain( |
| 296 const std::string& process_type, | 339 const std::string& process_type, |
| 297 const content::MainFunctionParams& main_function_params, | 340 const MainFunctionParams& main_function_params, |
| 298 content::ContentMainDelegate* delegate) { | 341 ContentMainDelegate* delegate) { |
| 299 static const MainFunction kMainFunctions[] = { | 342 static const MainFunction kMainFunctions[] = { |
| 300 { "", BrowserMain }, | 343 { "", BrowserMain }, |
| 301 { switches::kRendererProcess, RendererMain }, | 344 { switches::kRendererProcess, RendererMain }, |
| 302 { switches::kPluginProcess, PluginMain }, | 345 { switches::kPluginProcess, PluginMain }, |
| 303 { switches::kWorkerProcess, WorkerMain }, | 346 { switches::kWorkerProcess, WorkerMain }, |
| 304 { switches::kPpapiPluginProcess, PpapiPluginMain }, | 347 { switches::kPpapiPluginProcess, PpapiPluginMain }, |
| 305 { switches::kPpapiBrokerProcess, PpapiBrokerMain }, | 348 { switches::kPpapiBrokerProcess, PpapiBrokerMain }, |
| 306 { switches::kUtilityProcess, UtilityMain }, | 349 { switches::kUtilityProcess, UtilityMain }, |
| 307 { switches::kGpuProcess, GpuMain }, | 350 { switches::kGpuProcess, GpuMain }, |
| 308 }; | 351 }; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 327 #endif | 370 #endif |
| 328 | 371 |
| 329 // If it's a process we don't know about, the embedder should know. | 372 // If it's a process we don't know about, the embedder should know. |
| 330 if (delegate) | 373 if (delegate) |
| 331 return delegate->RunProcess(process_type, main_function_params); | 374 return delegate->RunProcess(process_type, main_function_params); |
| 332 | 375 |
| 333 NOTREACHED() << "Unknown process type: " << process_type; | 376 NOTREACHED() << "Unknown process type: " << process_type; |
| 334 return 1; | 377 return 1; |
| 335 } | 378 } |
| 336 | 379 |
| 337 class ContentMainRunnerImpl : public content::ContentMainRunner { | 380 class ContentMainRunnerImpl : public ContentMainRunner { |
| 338 public: | 381 public: |
| 339 ContentMainRunnerImpl() | 382 ContentMainRunnerImpl() |
| 340 : is_initialized_(false), | 383 : is_initialized_(false), |
| 341 is_shutdown_(false), | 384 is_shutdown_(false), |
| 342 completed_basic_startup_(false) { | 385 completed_basic_startup_(false) { |
| 343 } | 386 } |
| 344 | 387 |
| 345 ~ContentMainRunnerImpl() { | 388 ~ContentMainRunnerImpl() { |
| 346 if (is_initialized_ && !is_shutdown_) | 389 if (is_initialized_ && !is_shutdown_) |
| 347 Shutdown(); | 390 Shutdown(); |
| 348 } | 391 } |
| 349 | 392 |
| 350 #if defined(USE_TCMALLOC) | 393 #if defined(USE_TCMALLOC) |
| 351 static void GetStatsThunk(char* buffer, int buffer_length) { | 394 static void GetStatsThunk(char* buffer, int buffer_length) { |
| 352 MallocExtension::instance()->GetStats(buffer, buffer_length); | 395 MallocExtension::instance()->GetStats(buffer, buffer_length); |
| 353 } | 396 } |
| 354 | 397 |
| 355 static void ReleaseFreeMemoryThunk() { | 398 static void ReleaseFreeMemoryThunk() { |
| 356 MallocExtension::instance()->ReleaseFreeMemory(); | 399 MallocExtension::instance()->ReleaseFreeMemory(); |
| 357 } | 400 } |
| 358 #endif | 401 #endif |
| 359 | 402 |
| 360 | 403 |
| 361 #if defined(OS_WIN) | 404 #if defined(OS_WIN) |
| 362 virtual int Initialize(HINSTANCE instance, | 405 virtual int Initialize(HINSTANCE instance, |
| 363 sandbox::SandboxInterfaceInfo* sandbox_info, | 406 sandbox::SandboxInterfaceInfo* sandbox_info, |
| 364 content::ContentMainDelegate* delegate) OVERRIDE { | 407 ContentMainDelegate* delegate) OVERRIDE { |
| 365 // argc/argv are ignored on Windows; see command_line.h for details. | 408 // argc/argv are ignored on Windows; see command_line.h for details. |
| 366 int argc = 0; | 409 int argc = 0; |
| 367 char** argv = NULL; | 410 char** argv = NULL; |
| 368 | 411 |
| 369 content::RegisterInvalidParamHandler(); | 412 RegisterInvalidParamHandler(); |
| 370 _Module.Init(NULL, static_cast<HINSTANCE>(instance)); | 413 _Module.Init(NULL, static_cast<HINSTANCE>(instance)); |
| 371 | 414 |
| 372 if (sandbox_info) | 415 if (sandbox_info) |
| 373 sandbox_info_ = *sandbox_info; | 416 sandbox_info_ = *sandbox_info; |
| 374 else | 417 else |
| 375 memset(&sandbox_info_, 0, sizeof(sandbox_info_)); | 418 memset(&sandbox_info_, 0, sizeof(sandbox_info_)); |
| 376 | 419 |
| 377 #else // !OS_WIN | 420 #else // !OS_WIN |
| 378 virtual int Initialize(int argc, | 421 virtual int Initialize(int argc, |
| 379 const char** argv, | 422 const char** argv, |
| 380 content::ContentMainDelegate* delegate) OVERRIDE { | 423 ContentMainDelegate* delegate) OVERRIDE { |
| 381 | 424 |
| 382 // NOTE(willchan): One might ask why this call is done here rather than in | 425 // NOTE(willchan): One might ask why this call is done here rather than in |
| 383 // process_util_linux.cc with the definition of | 426 // process_util_linux.cc with the definition of |
| 384 // EnableTerminationOnOutOfMemory(). That's because base shouldn't have a | 427 // EnableTerminationOnOutOfMemory(). That's because base shouldn't have a |
| 385 // dependency on TCMalloc. Really, we ought to have our allocator shim code | 428 // dependency on TCMalloc. Really, we ought to have our allocator shim code |
| 386 // implement this EnableTerminationOnOutOfMemory() function. Whateverz. | 429 // implement this EnableTerminationOnOutOfMemory() function. Whateverz. |
| 387 // This works for now. | 430 // This works for now. |
| 388 #if !defined(OS_MACOSX) && defined(USE_TCMALLOC) | 431 #if !defined(OS_MACOSX) && defined(USE_TCMALLOC) |
| 389 // For tcmalloc, we need to tell it to behave like new. | 432 // For tcmalloc, we need to tell it to behave like new. |
| 390 tc_set_new_mode(1); | 433 tc_set_new_mode(1); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 441 | 484 |
| 442 // On Android, the command line is initialized when library is loaded. | 485 // On Android, the command line is initialized when library is loaded. |
| 443 // (But *is* initialized here for content shell bringup) | 486 // (But *is* initialized here for content shell bringup) |
| 444 #if !defined(OS_ANDROID) || defined(ANDROID_UPSTREAM_BRINGUP) | 487 #if !defined(OS_ANDROID) || defined(ANDROID_UPSTREAM_BRINGUP) |
| 445 CommandLine::Init(argc, argv); | 488 CommandLine::Init(argc, argv); |
| 446 #endif | 489 #endif |
| 447 | 490 |
| 448 int exit_code; | 491 int exit_code; |
| 449 if (delegate && delegate->BasicStartupComplete(&exit_code)) | 492 if (delegate && delegate->BasicStartupComplete(&exit_code)) |
| 450 return exit_code; | 493 return exit_code; |
| 451 DCHECK(!delegate || content::GetContentClient()) << | |
| 452 "BasicStartupComplete didn't set the content client"; | |
| 453 | 494 |
| 454 completed_basic_startup_ = true; | 495 completed_basic_startup_ = true; |
| 455 | 496 |
| 456 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | 497 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
| 457 std::string process_type = | 498 std::string process_type = |
| 458 command_line.GetSwitchValueASCII(switches::kProcessType); | 499 command_line.GetSwitchValueASCII(switches::kProcessType); |
| 500 |
| 501 if (!GetContentClient()) |
| 502 SetContentClient(&empty_content_client_); |
| 503 ContentClientInitializer::Set(process_type, delegate_); |
| 459 | 504 |
| 460 // Enable startup tracing asap to avoid early TRACE_EVENT calls being | 505 // Enable startup tracing asap to avoid early TRACE_EVENT calls being |
| 461 // ignored. | 506 // ignored. |
| 462 if (command_line.HasSwitch(switches::kTraceStartup)) { | 507 if (command_line.HasSwitch(switches::kTraceStartup)) { |
| 463 base::debug::TraceLog::GetInstance()->SetEnabled( | 508 base::debug::TraceLog::GetInstance()->SetEnabled( |
| 464 command_line.GetSwitchValueASCII(switches::kTraceStartup)); | 509 command_line.GetSwitchValueASCII(switches::kTraceStartup)); |
| 465 } | 510 } |
| 466 | 511 |
| 467 #if defined(OS_MACOSX) | 512 #if defined(OS_MACOSX) |
| 468 // We need to allocate the IO Ports before the Sandbox is initialized or | 513 // We need to allocate the IO Ports before the Sandbox is initialized or |
| (...skipping 11 matching lines...) Expand all Loading... |
| 480 } | 525 } |
| 481 | 526 |
| 482 if (!process_type.empty() && | 527 if (!process_type.empty() && |
| 483 (!delegate || delegate->ShouldSendMachPort(process_type))) { | 528 (!delegate || delegate->ShouldSendMachPort(process_type))) { |
| 484 SendTaskPortToParentProcess(); | 529 SendTaskPortToParentProcess(); |
| 485 } | 530 } |
| 486 #elif defined(OS_WIN) | 531 #elif defined(OS_WIN) |
| 487 #if defined(ENABLE_HIDPI) | 532 #if defined(ENABLE_HIDPI) |
| 488 ui::EnableHighDPISupport(); | 533 ui::EnableHighDPISupport(); |
| 489 #endif | 534 #endif |
| 490 content::SetupCRT(command_line); | 535 SetupCRT(command_line); |
| 491 #endif | 536 #endif |
| 492 | 537 |
| 493 #if defined(OS_POSIX) | 538 #if defined(OS_POSIX) |
| 494 if (!process_type.empty()) { | 539 if (!process_type.empty()) { |
| 495 // When you hit Ctrl-C in a terminal running the browser | 540 // When you hit Ctrl-C in a terminal running the browser |
| 496 // process, a SIGINT is delivered to the entire process group. | 541 // process, a SIGINT is delivered to the entire process group. |
| 497 // When debugging the browser process via gdb, gdb catches the | 542 // When debugging the browser process via gdb, gdb catches the |
| 498 // SIGINT for the browser process (and dumps you back to the gdb | 543 // SIGINT for the browser process (and dumps you back to the gdb |
| 499 // console) but doesn't for the child processes, killing them. | 544 // console) but doesn't for the child processes, killing them. |
| 500 // The fix is to have child processes ignore SIGINT; they'll die | 545 // The fix is to have child processes ignore SIGINT; they'll die |
| 501 // on their own when the browser process goes away. | 546 // on their own when the browser process goes away. |
| 502 // | 547 // |
| 503 // Note that we *can't* rely on BeingDebugged to catch this case because | 548 // Note that we *can't* rely on BeingDebugged to catch this case because |
| 504 // we are the child process, which is not being debugged. | 549 // we are the child process, which is not being debugged. |
| 505 // TODO(evanm): move this to some shared subprocess-init function. | 550 // TODO(evanm): move this to some shared subprocess-init function. |
| 506 if (!base::debug::BeingDebugged()) | 551 if (!base::debug::BeingDebugged()) |
| 507 signal(SIGINT, SIG_IGN); | 552 signal(SIGINT, SIG_IGN); |
| 508 } | 553 } |
| 509 #endif | 554 #endif |
| 510 | 555 |
| 511 #if defined(USE_NSS) | 556 #if defined(USE_NSS) |
| 512 crypto::EarlySetupForNSSInit(); | 557 crypto::EarlySetupForNSSInit(); |
| 513 #endif | 558 #endif |
| 514 | 559 |
| 515 ui::RegisterPathProvider(); | 560 ui::RegisterPathProvider(); |
| 516 content::RegisterPathProvider(); | 561 RegisterPathProvider(); |
| 517 content::RegisterContentSchemes(true); | 562 RegisterContentSchemes(true); |
| 518 | 563 |
| 519 CHECK(icu_util::Initialize()); | 564 CHECK(icu_util::Initialize()); |
| 520 | 565 |
| 521 InitializeStatsTable(command_line); | 566 InitializeStatsTable(command_line); |
| 522 | 567 |
| 523 if (delegate) | 568 if (delegate) |
| 524 delegate->PreSandboxStartup(); | 569 delegate->PreSandboxStartup(); |
| 525 | 570 |
| 526 // Set any custom user agent passed on the command line now so the string | 571 // Set any custom user agent passed on the command line now so the string |
| 527 // doesn't change between calls to webkit_glue::GetUserAgent(), otherwise it | 572 // doesn't change between calls to webkit_glue::GetUserAgent(), otherwise it |
| 528 // defaults to the user agent set during SetContentClient(). | 573 // defaults to the user agent set during SetContentClient(). |
| 529 if (command_line.HasSwitch(switches::kUserAgent)) { | 574 if (command_line.HasSwitch(switches::kUserAgent)) { |
| 530 webkit_glue::SetUserAgent( | 575 webkit_glue::SetUserAgent( |
| 531 command_line.GetSwitchValueASCII(switches::kUserAgent), true); | 576 command_line.GetSwitchValueASCII(switches::kUserAgent), true); |
| 532 } | 577 } |
| 533 | 578 |
| 534 if (!process_type.empty()) | 579 if (!process_type.empty()) |
| 535 CommonSubprocessInit(process_type); | 580 CommonSubprocessInit(process_type); |
| 536 | 581 |
| 537 #if defined(OS_WIN) | 582 #if defined(OS_WIN) |
| 538 CHECK(content::InitializeSandbox(sandbox_info)); | 583 CHECK(InitializeSandbox(sandbox_info)); |
| 539 #elif defined(OS_MACOSX) | 584 #elif defined(OS_MACOSX) |
| 540 if (process_type == switches::kRendererProcess || | 585 if (process_type == switches::kRendererProcess || |
| 541 process_type == switches::kPpapiPluginProcess || | 586 process_type == switches::kPpapiPluginProcess || |
| 542 (delegate && delegate->DelaySandboxInitialization(process_type))) { | 587 (delegate && delegate->DelaySandboxInitialization(process_type))) { |
| 543 // On OS X the renderer sandbox needs to be initialized later in the | 588 // On OS X the renderer sandbox needs to be initialized later in the |
| 544 // startup sequence in RendererMainPlatformDelegate::EnableSandbox(). | 589 // startup sequence in RendererMainPlatformDelegate::EnableSandbox(). |
| 545 } else { | 590 } else { |
| 546 CHECK(content::InitializeSandbox()); | 591 CHECK(InitializeSandbox()); |
| 547 } | 592 } |
| 548 #endif | 593 #endif |
| 549 | 594 |
| 550 if (delegate) | 595 if (delegate) |
| 551 delegate->SandboxInitialized(process_type); | 596 delegate->SandboxInitialized(process_type); |
| 552 | 597 |
| 553 #if defined(OS_POSIX) | 598 #if defined(OS_POSIX) |
| 554 SetProcessTitleFromCommandLine(argv); | 599 SetProcessTitleFromCommandLine(argv); |
| 555 #endif | 600 #endif |
| 556 | 601 |
| 557 // Return -1 to indicate no early termination. | 602 // Return -1 to indicate no early termination. |
| 558 return -1; | 603 return -1; |
| 559 } | 604 } |
| 560 | 605 |
| 561 virtual int Run() OVERRIDE { | 606 virtual int Run() OVERRIDE { |
| 562 DCHECK(is_initialized_); | 607 DCHECK(is_initialized_); |
| 563 DCHECK(!is_shutdown_); | 608 DCHECK(!is_shutdown_); |
| 564 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | 609 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
| 565 std::string process_type = | 610 std::string process_type = |
| 566 command_line.GetSwitchValueASCII(switches::kProcessType); | 611 command_line.GetSwitchValueASCII(switches::kProcessType); |
| 567 | 612 |
| 568 content::MainFunctionParams main_params(command_line); | 613 MainFunctionParams main_params(command_line); |
| 569 #if defined(OS_WIN) | 614 #if defined(OS_WIN) |
| 570 main_params.sandbox_info = &sandbox_info_; | 615 main_params.sandbox_info = &sandbox_info_; |
| 571 #elif defined(OS_MACOSX) | 616 #elif defined(OS_MACOSX) |
| 572 main_params.autorelease_pool = autorelease_pool_.get(); | 617 main_params.autorelease_pool = autorelease_pool_.get(); |
| 573 #endif | 618 #endif |
| 574 | 619 |
| 575 return RunNamedProcessTypeMain(process_type, main_params, delegate_); | 620 return RunNamedProcessTypeMain(process_type, main_params, delegate_); |
| 576 } | 621 } |
| 577 | 622 |
| 578 virtual void Shutdown() OVERRIDE { | 623 virtual void Shutdown() OVERRIDE { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 598 #if defined(OS_MACOSX) | 643 #if defined(OS_MACOSX) |
| 599 autorelease_pool_.reset(NULL); | 644 autorelease_pool_.reset(NULL); |
| 600 #endif | 645 #endif |
| 601 | 646 |
| 602 exit_manager_.reset(NULL); | 647 exit_manager_.reset(NULL); |
| 603 | 648 |
| 604 delegate_ = NULL; | 649 delegate_ = NULL; |
| 605 is_shutdown_ = true; | 650 is_shutdown_ = true; |
| 606 } | 651 } |
| 607 | 652 |
| 608 protected: | 653 private: |
| 609 // True if the runner has been initialized. | 654 // True if the runner has been initialized. |
| 610 bool is_initialized_; | 655 bool is_initialized_; |
| 611 | 656 |
| 612 // True if the runner has been shut down. | 657 // True if the runner has been shut down. |
| 613 bool is_shutdown_; | 658 bool is_shutdown_; |
| 614 | 659 |
| 615 // True if basic startup was completed. | 660 // True if basic startup was completed. |
| 616 bool completed_basic_startup_; | 661 bool completed_basic_startup_; |
| 617 | 662 |
| 663 // Used if the embedder doesn't set one. |
| 664 ContentClient empty_content_client_; |
| 665 |
| 618 // The delegate will outlive this object. | 666 // The delegate will outlive this object. |
| 619 content::ContentMainDelegate* delegate_; | 667 ContentMainDelegate* delegate_; |
| 620 | 668 |
| 621 scoped_ptr<base::AtExitManager> exit_manager_; | 669 scoped_ptr<base::AtExitManager> exit_manager_; |
| 622 #if defined(OS_WIN) | 670 #if defined(OS_WIN) |
| 623 sandbox::SandboxInterfaceInfo sandbox_info_; | 671 sandbox::SandboxInterfaceInfo sandbox_info_; |
| 624 #elif defined(OS_MACOSX) | 672 #elif defined(OS_MACOSX) |
| 625 scoped_ptr<base::mac::ScopedNSAutoreleasePool> autorelease_pool_; | 673 scoped_ptr<base::mac::ScopedNSAutoreleasePool> autorelease_pool_; |
| 626 #endif | 674 #endif |
| 627 | 675 |
| 628 DISALLOW_COPY_AND_ASSIGN(ContentMainRunnerImpl); | 676 DISALLOW_COPY_AND_ASSIGN(ContentMainRunnerImpl); |
| 629 }; | 677 }; |
| 630 | 678 |
| 631 } // namespace | |
| 632 | |
| 633 namespace content { | |
| 634 | |
| 635 // static | 679 // static |
| 636 ContentMainRunner* ContentMainRunner::Create() { | 680 ContentMainRunner* ContentMainRunner::Create() { |
| 637 return new ContentMainRunnerImpl(); | 681 return new ContentMainRunnerImpl(); |
| 638 } | 682 } |
| 639 | 683 |
| 640 } // namespace content | 684 } // namespace content |
| OLD | NEW |