• (FFOS Gecko & Gaia) OTA


      前面分析了这么多,还没有真正的走到download流程。这篇就去了解真正的downloader。

    1. UpdateService.downloadUpdate

      看来这正的worker就是最后new出来的Downloader。

    downloadUpdate: function AUS_downloadUpdate(update, background) {
      if (!update)
        throw Cr.NS_ERROR_NULL_POINTER;
    
      // Don't download the update if the update's version is less than the
      // current application's version or the update's version is the same as the
      // application's version and the build ID is the same as the application's
      // build ID.
      if (update.appVersion &&
          (Services.vc.compare(update.appVersion, Services.appinfo.version) < 0 ||
           update.buildID && update.buildID == Services.appinfo.appBuildID &&
           update.appVersion == Services.appinfo.version)) {
        LOG("UpdateService:downloadUpdate - canceling download of update since " +
            "it is for an earlier or same application version and build ID.
    " +
            "current application version: " + Services.appinfo.version + "
    " +
            "update application version : " + update.appVersion + "
    " +
            "current build ID: " + Services.appinfo.appBuildID + "
    " +
            "update build ID : " + update.buildID);
        cleanupActiveUpdate();
        return STATE_NONE;
      }
    
      // If a download request is in progress vs. a download ready to resume
      if (this.isDownloading) {
        if (update.isCompleteUpdate == this._downloader.isCompleteUpdate &&
            background == this._downloader.background) {
          LOG("UpdateService:downloadUpdate - no support for downloading more " +
              "than one update at a time");
          return readStatusFile(getUpdatesDir());
        }
        this._downloader.cancel();
      }
      if (AppConstants.platform == "gonk") {
        let um = Cc["@mozilla.org/updates/update-manager;1"].
                 getService(Ci.nsIUpdateManager);
        let activeUpdate = um.activeUpdate;
        if (activeUpdate &&
            (activeUpdate.appVersion != update.appVersion ||
             activeUpdate.buildID != update.buildID)) {
          // We have an activeUpdate (which presumably was interrupted), and are
          // about start downloading a new one. Make sure we remove all traces
          // of the active one (otherwise we'll start appending the new update.mar
          // the the one that's been partially downloaded).
          LOG("UpdateService:downloadUpdate - removing stale active update.");
          cleanupActiveUpdate();
        }
      }
      // Set the previous application version prior to downloading the update.
      update.previousAppVersion = Services.appinfo.version;
      this._downloader = new Downloader(background, this);
      return this._downloader.downloadUpdate(update);
    },

    2. Downloader.downloadUpdate

      由于downloadUpdate函数比较长,这里只贴出部分代码

    /**
     * Download and stage the given update.
     * @param   update
     *          A nsIUpdate object to download a patch for. Cannot be null.
     */
    downloadUpdate: function Downloader_downloadUpdate(update) {
      ...
      // 获取update保存位置
      var updateDir = getUpdatesDir();
      ...
      //根据预设的policy,返回Update中的一个UpdatePatch以下载
      this._patch = this._selectPatch(update, updateDir);
      ...

       // Only used by gonk
        let status = STATE_NONE;
        if (AppConstants.platform == "gonk") {

        ...

        // 检测之前是否有interrupted update

      }
      ...
      // 获取patch的URL
      
    var uri = Services.io.newURI(this._patch.URL, null, null);
      // 创建一个nsIIncrementalDownload组件去下载
      this._request = Cc["@mozilla.org/network/incremental-download;1"].createInstance(Ci.nsIIncrementalDownload);
    
    

       LOG("Downloader:downloadUpdate - downloading from " + uri.spec + " to " + patchFile.path);
       var interval = this.background ? getPref("getIntPref",
       PREF_APP_UPDATE_BACKGROUND_INTERVAL, DOWNLOAD_BACKGROUND_INTERVAL) : DOWNLOAD_FOREGROUND_INTERVAL;
       this._request.init(uri, patchFile, DOWNLOAD_CHUNK_SIZE, interval);

       //传递了this,因为Downloader实现了nsIRequest和nsIProcessEventSink接口,实现下载完成、下载进度等的回调
       this._request.start(this, null);

    
    

       writeStatusFile(updateDir, STATE_DOWNLOADING);
       this._patch.QueryInterface(Ci.nsIWritablePropertyBag);

       this._patch.state = STATE_DOWNLOADING;

       // 通过UpdateManager保存当前的下载update

       var um = Cc["@mozilla.org/updates/update-manager;1"].getService(Ci.nsIUpdateManager);
       um.saveUpdates();

       return STATE_DOWNLOADING;

    }

    3. Downloader.onStopRequest 下载完成

      代码很长,贴关键部分

    /**
       * When data transfer ceases
       * @param   request
       *          The nsIRequest object for the transfer
       * @param   context
       *          Additional data
       * @param   status
       *          Status code containing the reason for the cessation.
       */
      onStopRequest: function  Downloader_onStopRequest(request, context, status) {
        // 判断是否下载成功
        if (Components.isSuccessCode(status)) {
          // 验证update package
          if (this._verifyDownload()) {
            ...
          }
        } else {
            ...
        }
        ...
        this._patch.state = state;
        // UpdateManager保存状态
        var um = Cc["@mozilla.org/updates/update-manager;1"].
                 getService(Ci.nsIUpdateManager);
        if (deleteActiveUpdate) {
          this._update.installDate = (new Date()).getTime();
          um.activeUpdate = null;
        }
        else {
          if (um.activeUpdate) {
            um.activeUpdate.state = state;
          }
        }
        um.saveUpdates();
        ...
        if (shouldShowPrompt) {
          // Notify the user that an update has been downloaded and is ready for
          // installation (i.e. that they should restart the application). We do
          // not notify on failed update attempts.
          let prompter = Cc["@mozilla.org/updates/update-prompt;1"].
                         createInstance(Ci.nsIUpdatePrompt);
          // 通知UpdatePrompt,update下载完成
          prompter.showUpdateDownloaded(this._update, true);
        }
      }
  • 相关阅读:
    基础设施公募REITs介绍
    《苔》袁枚
    南京大学 静态软件分析(static program analyzes) Pointer Analysis 学习笔记
    南京大学 静态软件分析(static program analyzes) Data Flow Analysis:Applications 学习笔记
    南京大学 静态软件分析(static program analyzes) Static Analysis for Security 学习笔记
    tp5,把耗时操作转为队列,queue + redis + supervisor消息推送(队列的执行异步不异步不知道,workman,swoole可以异步)
    ThinkPHP 使用 thinkqueue 实现 redis 消息队列
    JAVA中“LIST泛型MAP根据某一个KEY去重
    nodejs搭建一个webscoket服务器【转】
    windows下安装node.js及环境配置、部署项目【转】
  • 原文地址:https://www.cnblogs.com/code-4-fun/p/4705388.html
Copyright © 2020-2023  润新知