(FFOS Gecko & Gaia) OTA - 进入Gecko层

  代码位置:gecko/b2g/components/UpdatePrompt.js

  SystemApp发出'force-update-check'事件,也就从gaia进入到了gecko层。

 

1. 首先大概介绍一下UpdatePrompt.js。

  (a) UpdatePrompt.js里包含了2个对象,分别是UpdatePrompt和UpdateCheckListener。

  (b) UpdatePrompt实现了“@mozilla.org/updates/update-prompt;1”这个XPCOM组件。在gecko/b2g/components/B2GComponents.manifest中有注册:

#ifdef MOZ_UPDATER
# UpdatePrompt.js
component {88b3eb21-d072-4e3b-886d-f89d8c49fe59} UpdatePrompt.js
contract @mozilla.org/updates/update-prompt;1 {88b3eb21-d072-4e3b-886d-f89d8c49fe59}
category system-update-provider MozillaProvider @mozilla.org/updates/update-prompt;1,{88b3eb21-d072-4e3b-886d-f89d8c49fe59}
#endif

  (c) UpdatePrompt还实现了5个interface,分别是nsISystemUpdateProvider、nsIUpdatePrompt、nsIObserver、nsIRequestObserver和nsIProgressEventSink。

  (d) UpdateCheckListener实现了nsIUpdateCheckListener。

 

2. “@mozilla.org/updates/update-prompt;1”在B2G启动后会自动被加载,代码在gecko/b2g/chrome/content/shell.js中:

window.addEventListener('ContentStart', function update_onContentStart() {
  Cu.import('resource://gre/modules/WebappsUpdater.jsm');
  WebappsUpdater.handleContentStart(shell);

  let promptCc = Cc["@mozilla.org/updates/update-prompt;1"];
  if (!promptCc) {
    return;
  }

  let updatePrompt = promptCc.createInstance(Ci.nsIUpdatePrompt);
  if (!updatePrompt) {
    return;
  }

  updatePrompt.wrappedJSObject.handleContentStart(shell);
});

 

3. handleContentStart:

  通过SystemAppProxy注册event listener来监听‘mozContentEvent’。

handleContentStart: function UP_handleContentStart() {
  SystemAppProxy.addEventListener("mozContentEvent", this);
},

 

4. SystemAppProxy的代码位置在:gecko/b2g/components/SystemAppProxy.jsm

// Listen for dom events on the system app
addEventListener: function systemApp_addEventListener() {
  let content = this._frame ? this._frame.contentWindow : null;
  if (!content) {
    this._pendingListeners.push(arguments);
    return false;
  }

  content.addEventListener.apply(content, arguments);
  return true;
},

 

5. UpdatePrompt.handleEvent

  上一步注册了mozContentEvent的监听,handleEvent是回调函数,主要对4种消息进行处理。其中‘force-update-check’正是上一篇分析的从SystemApp发送过来的event。此时OTA流程从gaia走到了gecko中。

handleEvent: function UP_handleEvent(evt) {
  if (evt.type !== "mozContentEvent") {
    return;
  }

  let detail = evt.detail;
  if (!detail) {
    return;
  }

  switch (detail.type) {
    case "force-update-check":
      this.forceUpdateCheck();
      break;
    case "update-available-result":
      this.handleAvailableResult(detail);
      // If we started the apply prompt timer, this means that we're waiting
      // for the user to press Later or Install Now. In this situation we
      // don't want to clear this._update, becuase handleApplyPromptResult
      // needs it.
      if (this._applyPromptTimer == null && !this._waitingForIdle) {
        this._update = null;
      }
      break;
    case "update-download-cancel":
      this.handleDownloadCancel();
      break;
    case "update-prompt-apply-result":
      this.handleApplyPromptResult(detail);
      break;
  }
},

 

6. UpdatePrompt.forceUpdateCheck函数

  check的工作交给了另外一个XPCOM组件"@mozilla.org/updates/update-checker;1",调用它的checkForUpdates函数,并传递一个UpdateCheckListener进去,这个UpdateCheckListener是UpdatePrompt对象初始化时,内部new出来的,用于接收checker的事件回调。

forceUpdateCheck: function UP_forceUpdateCheck() {
  log("Forcing update check");

  let checker = Cc["@mozilla.org/updates/update-checker;1"]
                  .createInstance(Ci.nsIUpdateChecker);
  checker.checkForUpdates(this._updateCheckListener, true);
},

 

posted @ 2015-08-05 09:31  coding4范儿  阅读(311)  评论(0编辑  收藏  举报