Firefox OS启动过程分析-Shell入口
本节介绍Firefox OS 初始化Shell的过程。
在Firefox OS启动过程分析-b2g进程启动
一节中,b2g进程在初始化过程中就会在某点开始加载Shell入口(它是所有应用的container)
从b2g/app/b2g.js中,我们得知Shell的入口:
pref("toolkit.defaultChromeURI", "chrome://b2g/content/shell.html");
- 1
那么shell.html是何时加载的?
具体运行流程如下所示:
main
|
|-RunProcesses
|
|-b2g_main
|
|-do_main
|
|-XRE_main
|
|-XREMain::XRE_main
|
|-mScopedXPCOM->Initialize();
| |
| |-NS_InitXPCOM2
|
|-XREMain::XRE_mainRun()
|
|--mozilla::ipc::ProcLoaderClientGeckoInit();
|
|-cmdLine->Init(...)
|
|-cmdLine->Run(); ((toolkit/components/commandlines/nsCommandLine.cpp))
| |
| |-nsCommandLine::EnumerateValidators
| |
| |-nsCommandLine::EnumerateHandlers
| |
| |-EnumRun
| |
| **|-nsICommandLineHandler->Handle**
|
|
|-appStartup->Run()
|
|-mAppShell->Run();
|
|-MessageLoop::current()->Run();
即,Shell入口(chrome://b2g/content/shell.html)是在
cmdLine->Run();
中开始加载的。
在该函数中:
cmdLine->Run()
|
|-nsCommandLine::EnumerateValidators
|
|-nsCommandLine::EnumerateHandlers
|
|-EnumRun
|
|-nsICommandLineHandler->Handle
nsCommandLine::EnumerateHandlers(...)
- 1
会按照字母顺序(见nsICommandLineHandler.idl)枚举所有category是”command-line-handler”的xpcom组件,这些xpcom组件都基于nsICommandLineHandler。
将xpcom组件传入EnumRun中:
static nsresult
EnumRun(nsICommandLineHandler* aHandler, nsICommandLine* aThis, void*)
{
return aHandler->Handle(aThis);
}
开始执行nsICommandLineHandler->Handle。
看下nsICommandLineHandler.idl的说明
The entries in this category are read in alphabetical order, and each category value is treated as a service contractid implementing this interface.
- 1
说明,这些xpcom组件是按照category的字母排序的。
那么有哪些category是”command-line-handler”的xpcom组件呢?搜素下源码,包括:
category command-line-handler m-b2goop @mozilla.org/commandlinehandler/general-startup;1?type=b2goop
category command-line-handler m-b2gcmds @mozilla.org/commandlinehandler/general-startup;1?type=b2gcmds
category command-line-handler m-b2gbootstrap @mozilla.org/commandlinehandler/general-startup;1?type=b2gbootstrap
category command-line-handler a-webide @mozilla.org/browser/webide-clh;1
category command-line-handler m-setdefaultbrowser @mozilla.org/browser/default-browser-clh;1
category command-line-handler m-browser @mozilla.org/browser/clh;1 application={ec8030f7-c20a-464f-9b0e-13a3a9e97384}
category command-line-handler x-default @mozilla.org/browser/final-clh;1 application={ec8030f7-c20a-464f-9b0e-13a3a9e97384}
category command-line-handler m-recording @mozilla.org/commandlinehandler/general-startup;1?type=recording
category command-line-handler m-reftest @mozilla.org/commandlinehandler/general-startup;1?type=reftest
category command-line-handler x-browser @mozilla.org/browser/browser-clh;1
category command-line-handler m-browser @mozilla.org/browser/clh;
category command-line-handler m-tps @mozilla.org/commandlinehandler/general-startup;1?type=tps
category command-line-handler m-tp @mozilla.org/commandlinehandler/general-startup;1?type=tp
category command-line-handler b-marionette @mozilla.org/marionette;1
category command-line-handler y-default @mozilla.org/toolkit/default-clh;1
category command-line-handler b-jsconsole @mozilla.org/toolkit/console-clh;1
category command-line-handler x-default @mozilla.org/webapprt/clh;1
搜索下toolkit.defaultChromeURI,我们得知:Shell入口是在gecko/toolkit/components/nsDefaultCLH.js中开始加载的:
// if the pref is missing, ignore the exception
try {
var chromeURI = prefs.getCharPref("toolkit.defaultChromeURI");
var flags = "chrome,dialog=no,all";
try {
flags = prefs.getCharPref("toolkit.defaultChromeFeatures");
}
catch (e) { }
var wwatch = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
.getService(nsIWindowWatcher);
wwatch.openWindow(null, chromeURI, "_blank",
flags, cmdLine);
}
catch (e) { }
最后调用
wwatch.openWindow(null, chromeURI, "_blank",
flags, cmdLine);
- 1
- 2
开始加载Shell窗口。
其中,nsDefaultCLH.manifest:
component {6ebc941a-f2ff-4d56-b3b6-f7d0b9d73344} nsDefaultCLH.js
contract @mozilla.org/toolkit/default-clh;1 {6ebc941a-f2ff-4d56-b3b6-f7d0b9d73344}
category command-line-handler y-default @mozilla.org/toolkit/default-clh;1
加载:
chrome://b2g/content/shell.html
- 1
都干了点啥?下节再进行分析。