转:Firefox OS启动过程分析-Shell入口

时间:2021-11-01 04:23:37
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

都干了点啥?下节再进行分析。