(FFOS Gecko & Gaia) OTA - 重回Gaia层

  SystemApp中的UpdateManager作为gaia和gecko的通信桥梁,会接收gecko中UpdatePrompt发送的'update-available'事件。

 

1. UpdateManager.handleEvent

var detail = evt.detail;

if (detail.type && detail.type === 'update-available') {
// systemUpdatable是在UpdateManager初始化时new出来的,UpdateManager中只会存在一个SystemUpdatable。
this.systemUpdatable.size = detail.size; this.systemUpdatable.rememberKnownUpdate();
// 添加到UpdateManager中的updatesQueue队列。
this.addToUpdatesQueue(this
.systemUpdatable); }

 

2. UpdateManager.addToUpdatesQueue

  逻辑比较简单,做一些check之后,push到updatesQueue中,然后render UI。

    addToUpdatesQueue: function um_addToUpdatesQueue(updatable) {
      if (this._downloading) {
        return;
      }

      if (updatable.app &&
          updatable.app.installState !== 'installed') {
        return;
      }

      if (updatable.app &&
          this.updatableApps.indexOf(updatable) === -1) {
        return;
      }

      var alreadyThere = this.updatesQueue.some(function lookup(u) {
        return (u.app === updatable.app);
      });
      if (alreadyThere) {
        return;
      }

      this.updatesQueue.push(updatable);

      if (this._notificationTimeout === null) {
        this._notificationTimeout = setTimeout(
          this.displayNotificationAndToaster.bind(this),
          this.NOTIFICATION_BUFFERING_TIMEOUT);
      }
      this.render();
    },

 

3. 触发下载

  UpdateManager是gaia层的,在它初始化时会做一些UI相关的操作,比如download button的bind和listen。

this.downloadButton = document.getElementById('updates-download-button');
this.downloadButton.onclick = this.requestDownloads.bind(this);

  下载的启动又分为以下几个步骤:

  (1) UpdateManager.requestDownloads

requestDownloads: function um_requestDownloads(evt) {
  evt.preventDefault();
// 通过DataConnection去下载
if (evt.target == this.downloadViaDataConnectionButton) { this._startedDownloadUsingDataConnection = true; this.startDownloads(); } else { this.promptOrDownload(); } },

  (2) UpdateManager.promptOrDownload

    promptOrDownload: function um_promptOrDownload() {
      var self = this;

      if (self.downloadDialog.dataset.online == 'false') {
        self.showPromptNoConnection();
        return;
      }
      // check wifi
      if (self._wifiAvailable()) {
        self._startedDownloadUsingDataConnection = false;
        self.startDownloads();
        return;
      }
    ……
    }

  (3) UpdateManager.startDownloads

    startDownloads: function um_startDownloads() {
      this.downloadViaDataConnectionDialog.classList.remove('visible');
      this._closeDownloadDialog();
      Service.request('UtilityTray:show');

      var checkValues = {};
      var dialog = this.downloadDialogList;
      var checkboxes = dialog.querySelectorAll('input[type="checkbox"]');
      for (var i = 0; i < checkboxes.length; i++) {
        var checkbox = checkboxes[i];
        checkValues[checkbox.dataset.position] = checkbox.checked;
      }

// 遍历updatesQueue
this.updatesQueue.forEach(function(updatable, index) { // The user opted out of the download if (updatable.app && !checkValues[index]) { return; } updatable.download(); }); this._downloadedBytes = 0; this.render(); },

  (4) SystemUpdatable.download()

  代码位置:gaia/apps/system/js/updatable.js

  由走回了UpdateManager,添加到downloadsQueue,并且发送了一个'update-available-result'

SystemUpdatable.prototype.download = function() {
  if (this.downloading) {
    return;
  }

  this.downloading = true;
  this.paused = false;
  UpdateManager.addToDownloadsQueue(this);
  this.progress = 0;
  this._dispatchEvent('update-available-result', 'download');
};

  (5) UpdateManager.addToDownloadsQueue

    addToDownloadsQueue: function um_addToDownloadsQueue(updatable) {
      if (updatable.app &&
          this.updatableApps.indexOf(updatable) === -1) {
        return;
      }

      var alreadyThere = this.downloadsQueue.some(function lookup(u) {
        return (u.app === updatable.app);
      });
      if (alreadyThere) {
        return;
      }

      this.downloadsQueue.push(updatable);

      if (this.downloadsQueue.length === 1) {
        this._downloading = true;
        Service.request('incDownloads');
        this._wifiLock = navigator.requestWakeLock('wifi');

        this.displayNotificationIfHidden();
        this.render();
      }
    },

 

4. 触发下载2

  看完了‘3’的分析,调来调去的好像也没有触发什么下载。

  回头看看本文最开始的部分,是从接收到'update-available'开始的,最后也只是向UpdatePrompt返回了一个'update-available-result'。

  其实UpdateManager和UpdatePrompt都是通过这种event来通信的,UpdateManager会做一些UI相关的操作,实际动作还是会交给UpdatePrompt去转发和实现。

  (1) UpdatePrompt --- update-xxx ---> UpdateManager

  (2) UpdateManager --- update-xxx-result ---> UpdatePrompt

posted @ 2015-08-05 14:07  coding4范儿  阅读(626)  评论(0编辑  收藏  举报