chromium---Browser进程启动流程

                           ubuntu 下chromium的brower进程启动流程

源文件:

src/chrome/app/chrome_exe_main_aura.cc

src/chrome/app/chrome_main.cc

src/content/app/content_main.cc

src/services/service_manager/embedder/main.cc

src/content/app/content_service_manager_main_delegate.cc

src/content/app/content_main_runner.cc

src/content/browser/browser_main.cc

src/content/browser/browser_main_runner.cc

src/content/browser/browser_main_loop.cc

src/chrome/browser/chrome_browser_main.cc

调用堆栈:

chromium---Browser进程启动流程_第1张图片

 

流程图:

 

chromium---Browser进程启动流程_第2张图片

 

源码:

int main(int argc, const char** argv) {
  return ChromeMain(argc, argv);
}

 

main()进来,调用了ChromeMain();这个接口是跨平台的实现,在不同平台的chrome进程都会进入到这里。接下来会调用到ContentMain(),如下是对应的实现。

namespace content {

int ContentMain(const ContentMainParams& params) {
  ContentServiceManagerMainDelegate delegate(params);
  service_manager::MainParams main_params(&delegate);
#if defined(OS_POSIX) && !defined(OS_ANDROID)
  main_params.argc = params.argc;
  main_params.argv = params.argv;
#endif
  return service_manager::Main(main_params);
}

}  // namespace content

content::ContentMain()进到 service_manager::Main(main_params),

int Main(const MainParams& params) {
  MainDelegate* delegate = params.delegate;
  DCHECK(delegate);

  ..........

  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
          ::switches::kTraceToConsole)) {
    base::trace_event::TraceConfig trace_config =
        tracing::GetConfigForTraceToConsole();
    base::trace_event::TraceLog::GetInstance()->SetEnabled(
        trace_config, base::trace_event::TraceLog::RECORDING_MODE);
  }

  switch (process_type) {
    case ProcessType::kDefault:
      NOTREACHED();
      break;

    case ProcessType::kServiceManager:
      exit_code = RunServiceManager(delegate);
      break;

    case ProcessType::kService:
      CommonSubprocessInit();
      exit_code = RunService(delegate);
      break;

    case ProcessType::kEmbedder:
      if (delegate->IsEmbedderSubprocess())
        CommonSubprocessInit();
      exit_code = delegate->RunEmbedderProcess();
      break;
  }

  .......

  return exit_code;
}

service_manager::Main(main_params), 会进到 delegate->RunEmbedderProcess();看看delegate是ContentServiceManagerMainDelegate继承了MainDelegate类

int ContentServiceManagerMainDelegate::RunEmbedderProcess() {
  return content_main_runner_->Run();
}

再进入一个Run()方法。这个 content_main_runner是什么?看下面:

ContentServiceManagerMainDelegate::ContentServiceManagerMainDelegate(
    const ContentMainParams& params)
    : content_main_params_(params),
      content_main_runner_(ContentMainRunner::Create()) {}

 

 content_main_runner就是ContentMainRunner::Create()返回的ContentMainRunner*也就是ContentMainRunnerImpl对象。

// static
ContentMainRunner* ContentMainRunner::Create() {
  return new ContentMainRunnerImpl();
}

 到Run()里面调用了RunNamedProcessTypeMain(),这个函数特别重要,所有进程的入口就在这里。

int Run() override {
    DCHECK(is_initialized_);
    DCHECK(!is_shutdown_);
    const base::CommandLine& command_line =
        *base::CommandLine::ForCurrentProcess();
    std::string process_type =
        command_line.GetSwitchValueASCII(switches::kProcessType);

    // Run this logic on all child processes. Zygotes will run this at a later
    // point in time when the command line has been updated.
    std::unique_ptr field_trial_list;
    if (!process_type.empty() && process_type != switches::kZygoteProcess)
      InitializeFieldTrialAndFeatureList(&field_trial_list);

    MainFunctionParams main_params(command_line);
    main_params.ui_task = ui_task_;
#if defined(OS_WIN)
    main_params.sandbox_info = &sandbox_info_;
#elif defined(OS_MACOSX)
    main_params.autorelease_pool = autorelease_pool_;
#endif
#if defined(USE_AURA)
    main_params.env_mode = env_mode_;
#endif
    main_params.create_discardable_memory = create_discardable_memory_;

    return RunNamedProcessTypeMain(process_type, main_params, delegate_);
  }

可以看到这里根据process_type来启动不同的主函数。

// Run the FooMain() for a given process type.
// If |process_type| is empty, runs BrowserMain().
// Returns the exit code for this process.
int RunNamedProcessTypeMain(
    const std::string& process_type,
    const MainFunctionParams& main_function_params,
    ContentMainDelegate* delegate) {
  static const MainFunction kMainFunctions[] = {
#if !defined(CHROME_MULTIPLE_DLL_CHILD)
    { "",                            BrowserMain },
#endif
#if !defined(CHROME_MULTIPLE_DLL_BROWSER)
#if BUILDFLAG(ENABLE_PLUGINS)
    { switches::kPpapiPluginProcess, PpapiPluginMain },
    { switches::kPpapiBrokerProcess, PpapiBrokerMain },
#endif  // ENABLE_PLUGINS
    { switches::kUtilityProcess,     UtilityMain },
    { switches::kRendererProcess,    RendererMain },
    { switches::kGpuProcess,         GpuMain },
#endif  // !CHROME_MULTIPLE_DLL_BROWSER
  };

  RegisterMainThreadFactories();

  for (size_t i = 0; i < arraysize(kMainFunctions); ++i) {
    if (process_type == kMainFunctions[i].name) {
      if (delegate) {
        int exit_code = delegate->RunProcess(process_type,
            main_function_params);
#if defined(OS_ANDROID)
        // In Android's browser process, the negative exit code doesn't mean the
        // default behavior should be used as the UI message loop is managed by
        // the Java and the browser process's default behavior is always
        // overridden.
        if (process_type.empty())
          return exit_code;
#endif
        if (exit_code >= 0)
          return exit_code;
      }
      return kMainFunctions[i].function(main_function_params);
    }
  }

#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) && \
    !defined(OS_FUCHSIA)
  // Zygote startup is special -- see RunZygote comments above
  // for why we don't use ZygoteMain directly.
  if (process_type == switches::kZygoteProcess)
    return RunZygote(main_function_params, delegate);
#endif

  // If it's a process we don't know about, the embedder should know.
  if (delegate)
    return delegate->RunProcess(process_type, main_function_params);

  NOTREACHED() << "Unknown process type: " << process_type;
  return 1;
}

第一个进程就是BrowserMain();是浏览器的Browser进程。

// Main routine for running as the Browser process.
int BrowserMain(const MainFunctionParams& parameters) {
  ScopedBrowserMainEvent scoped_browser_main_event;

  base::trace_event::TraceLog::GetInstance()->set_process_name("Browser");
  base::trace_event::TraceLog::GetInstance()->SetProcessSortIndex(
      kTraceEventBrowserProcessSortIndex);

  std::unique_ptr main_runner(BrowserMainRunner::Create());

  int exit_code = main_runner->Initialize(parameters);
  if (exit_code >= 0)
    return exit_code;

  exit_code = main_runner->Run();

  main_runner->Shutdown();

  return exit_code;
}

再看看 main_runner(BrowserMainRunner::Create())创造了BrowserMainRunner类型的智能指针。调用了BrowserMainRunner接口的实现类BrowserMainRunnerImpl()来创造对象。 main_runner->Initialize(parameters)具体内容如下:

int Initialize(const MainFunctionParams& parameters) override {

      .....

      main_loop_.reset(new BrowserMainLoop(parameters));

      main_loop_->Init();

      main_loop_->EarlyInitialization();

      // Must happen before we try to use a message loop or display any UI.
      if (!main_loop_->InitializeToolkit())
        return 1;

      main_loop_->PreMainMessageLoopStart();
      main_loop_->MainMessageLoopStart();
      main_loop_->PostMainMessageLoopStart();

// WARNING: If we get a WM_ENDSESSION, objects created on the stack here
// are NOT deleted. If you need something to run during WM_ENDSESSION add it
// to browser_shutdown::Shutdown or BrowserProcess::EndSession.

      ui::InitializeInputMethod();
      UMA_HISTOGRAM_TIMES("Startup.BrowserMainRunnerImplInitializeStep1Time",
                          base::TimeTicks::Now() - start_time_step1);
    }
    const base::TimeTicks start_time_step2 = base::TimeTicks::Now();
    main_loop_->CreateStartupTasks();
    int result_code = main_loop_->GetResultCode();
    if (result_code > 0)
      return result_code;

    UMA_HISTOGRAM_TIMES("Startup.BrowserMainRunnerImplInitializeStep2Time",
                        base::TimeTicks::Now() - start_time_step2);

    // Return -1 to indicate no early termination.
    return -1;
  }

到这里主要关注main_loop,即BrowserMainLoop对象,调用了Init(),EarlyInitialization(), MainMessageLoopStart(), ...  CreateStartupTasks() ,重点看看CreateStartupTasks()的内容。

void BrowserMainLoop::CreateStartupTasks() {
  TRACE_EVENT0("startup", "BrowserMainLoop::CreateStartupTasks");

  DCHECK(!startup_task_runner_);
#if defined(OS_ANDROID)
  startup_task_runner_ = std::make_unique(
      base::Bind(&BrowserStartupComplete), base::ThreadTaskRunnerHandle::Get());
#else
  startup_task_runner_ = std::make_unique(
      base::Callback(), base::ThreadTaskRunnerHandle::Get());
#endif
  StartupTask pre_create_threads =
      base::Bind(&BrowserMainLoop::PreCreateThreads, base::Unretained(this));
  startup_task_runner_->AddTask(pre_create_threads);

  StartupTask create_threads =
      base::Bind(&BrowserMainLoop::CreateThreads, base::Unretained(this));
  startup_task_runner_->AddTask(create_threads);

  StartupTask browser_thread_started = base::Bind(
      &BrowserMainLoop::BrowserThreadsStarted, base::Unretained(this));
  startup_task_runner_->AddTask(browser_thread_started);

  StartupTask pre_main_message_loop_run = base::Bind(
      &BrowserMainLoop::PreMainMessageLoopRun, base::Unretained(this));
  startup_task_runner_->AddTask(pre_main_message_loop_run);

#if defined(OS_ANDROID)
  if (parameters_.ui_task) {
    // Running inside browser tests, which relies on synchronous start.
    startup_task_runner_->RunAllTasksNow();
  } else {
    startup_task_runner_->StartRunningTasksAsync();
  }
#else
  startup_task_runner_->RunAllTasksNow();
#endif
}

CreateStartupTasks中把PreCreateThreads、CreateThreads、BrowserThreadsStarted、PreMainMessageLoopRun这几个函数包装成tasks,放到主线程的消息队列中运行。

可见, Initialize()创建了任务,然后开始Run。

你可能感兴趣的:(Browser,chromium,chromium,进程启动)