privatevoidensureProviderCreated(){checkThread();if(mProvider == null){// As this can get called during the base class constructor chain, pass the minimum// number of dependencies here; the rest are deferred to init().
mProvider =getFactory().createWebView(this,newPrivateAccess());}}privatestaticsynchronized WebViewFactoryProvider getFactory(){return WebViewFactory.getProvider();}
publicclassContentMain{/**
* Start the ContentMainRunner in native side.
**/publicstaticintstart(){// 看这里!!!returnnativeStart();}privatestaticnativeintnativeStart();}
intRun() 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<base::FieldTrialList> 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_;
main_params.created_main_parts_closure = created_main_parts_closure_;
#ifdefined(OS_WIN)
main_params.sandbox_info =&sandbox_info_;
#elif defined(OS_MACOSX)
main_params.autorelease_pool = autorelease_pool_;
#endif
// 看这里!!!returnRunNamedProcessTypeMain(process_type, main_params, delegate_);}// 看这里!!!RunNamedProcessTypeMain函数intRunNamedProcessTypeMain(const std::string& process_type,const MainFunctionParams& main_function_params,
ContentMainDelegate* delegate){staticconst MainFunction kMainFunctions[]={
#if!defined(CHROME_MULTIPLE_DLL_CHILD)// 看这里!!!这个会把启动函数,注册进去。{"", BrowserMain },
#endif
#if!defined(CHROME_MULTIPLE_DLL_BROWSER)
#ifBUILDFLAG(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);
#ifdefined(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);}}//省略}
int BrowserMainLoop::BrowserThreadsStarted(){TRACE_EVENT0("startup","BrowserMainLoop::BrowserThreadsStarted");
audio_service_runner_ =
base::MakeRefCounted<base::DeferredSequencedTaskRunner>();// Bring up Mojo IPC and the embedded Service Manager as early as possible.// Initializaing mojo requires the IO thread to have been initialized first,// so this cannot happen any earlier than now.InitializeMojo();
#ifBUILDFLAG(ENABLE_MUS)if(features::IsMusEnabled()){
base::CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableSurfaceSynchronization);}
#endif
HistogramSynchronizer::GetInstance();// 看这里!!!如果为Android平台,或定义了OS_CHROMEOS,就会将Browser Thread优先级设置为base::ThreadPriority::DISPLAY
#ifdefined(OS_ANDROID)||defined(OS_CHROMEOS)// Up the priority of the UI thread.
base::PlatformThread::SetCurrentThreadPriority(base::ThreadPriority::DISPLAY);
#endif
// 省略}
enumclassThreadPriority:int{// Suitable for threads that shouldn't disrupt high priority work.
BACKGROUND,// Default priority level.
NORMAL,// Suitable for threads which generate data for the display (at ~60Hz).
DISPLAY,// Suitable for low-latency, glitch-resistant audio.
REALTIME_AUDIO,};