dom/downloads/src/DownloadsAPI.jsm

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 "use strict";
     7 const Cc = Components.classes;
     8 const Ci = Components.interfaces;
     9 const Cu = Components.utils;
    11 this.EXPORTED_SYMBOLS = [];
    13 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
    14 Cu.import("resource://gre/modules/Downloads.jsm");
    15 Cu.import("resource://gre/modules/Task.jsm");
    17 XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
    18                                    "@mozilla.org/parentprocessmessagemanager;1",
    19                                    "nsIMessageBroadcaster");
    21 function debug(aStr) {
    22 #ifdef MOZ_DEBUG
    23   dump("-*- DownloadsAPI.jsm : " + aStr + "\n");
    24 #endif
    25 }
    27 function sendPromiseMessage(aMm, aMessageName, aData, aError) {
    28   debug("sendPromiseMessage " + aMessageName);
    29   let msg = {
    30     id: aData.id,
    31     promiseId: aData.promiseId
    32   };
    34   if (aError) {
    35     msg.error = aError;
    36   }
    38   aMm.sendAsyncMessage(aMessageName, msg);
    39 }
    41 let DownloadsAPI = {
    42   init: function() {
    43     debug("init");
    45     this._ids = new WeakMap(); // Maps toolkit download objects to ids.
    46     this._index = {};          // Maps ids to downloads.
    48     ["Downloads:GetList",
    49      "Downloads:ClearAllDone",
    50      "Downloads:Remove",
    51      "Downloads:Pause",
    52      "Downloads:Resume"].forEach((msgName) => {
    53       ppmm.addMessageListener(msgName, this);
    54     });
    56     let self = this;
    57     Task.spawn(function () {
    58       let list = yield Downloads.getList(Downloads.ALL);
    59       yield list.addView(self);
    61       debug("view added to download list.");
    62     }).then(null, Components.utils.reportError);
    64     this._currentId = 0;
    65   },
    67   /**
    68     * Returns a unique id for each download, hashing the url and the path.
    69     */
    70   downloadId: function(aDownload) {
    71     let id = this._ids.get(aDownload, null);
    72     if (!id) {
    73       id = "download-" + this._currentId++;
    74       this._ids.set(aDownload, id);
    75       this._index[id] = aDownload;
    76     }
    77     return id;
    78   },
    80   getDownloadById: function(aId) {
    81     return this._index[aId];
    82   },
    84   /**
    85     * Converts a download object into a plain json object that we'll
    86     * send to the DOM side.
    87     */
    88   jsonDownload: function(aDownload) {
    89     let res = {
    90       totalBytes: aDownload.totalBytes,
    91       currentBytes: aDownload.currentBytes,
    92       url: aDownload.source.url,
    93       path: aDownload.target.path,
    94       contentType: aDownload.contentType,
    95       startTime: aDownload.startTime.getTime()
    96     };
    98     if (aDownload.error) {
    99       res.error = aDownload.error;
   100     }
   102     res.id = this.downloadId(aDownload);
   104     // The state of the download. Can be any of "downloading", "stopped",
   105     // "succeeded", finalized".
   107     // Default to "stopped"
   108     res.state = "stopped";
   109     if (!aDownload.stopped &&
   110         !aDownload.canceled &&
   111         !aDownload.succeeded &&
   112         !aDownload.DownloadError) {
   113       res.state = "downloading";
   114     } else if (aDownload.succeeded) {
   115       res.state = "succeeded";
   116     }
   117     return res;
   118   },
   120   /**
   121     * download view methods.
   122     */
   123   onDownloadAdded: function(aDownload) {
   124     let download = this.jsonDownload(aDownload);
   125     debug("onDownloadAdded " + uneval(download));
   126     ppmm.broadcastAsyncMessage("Downloads:Added", download);
   127   },
   129   onDownloadRemoved: function(aDownload) {
   130     let download = this.jsonDownload(aDownload);
   131     download.state = "finalized";
   132     debug("onDownloadRemoved " + uneval(download));
   133     ppmm.broadcastAsyncMessage("Downloads:Removed", download);
   134     this._index[this._ids.get(aDownload)] = null;
   135     this._ids.delete(aDownload);
   136   },
   138   onDownloadChanged: function(aDownload) {
   139     let download = this.jsonDownload(aDownload);
   140     debug("onDownloadChanged " + uneval(download));
   141     ppmm.broadcastAsyncMessage("Downloads:Changed", download);
   142   },
   144   receiveMessage: function(aMessage) {
   145     if (!aMessage.target.assertPermission("downloads")) {
   146       debug("No 'downloads' permission!");
   147       return;
   148     }
   150     debug("message: " + aMessage.name);
   152     switch (aMessage.name) {
   153     case "Downloads:GetList":
   154       this.getList(aMessage.data, aMessage.target);
   155       break;
   156     case "Downloads:ClearAllDone":
   157       this.clearAllDone(aMessage.data, aMessage.target);
   158       break;
   159     case "Downloads:Remove":
   160       this.remove(aMessage.data, aMessage.target);
   161       break;
   162     case "Downloads:Pause":
   163       this.pause(aMessage.data, aMessage.target);
   164       break;
   165     case "Downloads:Resume":
   166       this.resume(aMessage.data, aMessage.target);
   167       break;
   168     default:
   169       debug("Invalid message: " + aMessage.name);
   170     }
   171   },
   173   getList: function(aData, aMm) {
   174     debug("getList called!");
   175     let self = this;
   176     Task.spawn(function () {
   177       let list = yield Downloads.getList(Downloads.ALL);
   178       let downloads = yield list.getAll();
   179       let res = [];
   180       downloads.forEach((aDownload) => {
   181         res.push(self.jsonDownload(aDownload));
   182       });
   183       aMm.sendAsyncMessage("Downloads:GetList:Return", res);
   184     }).then(null, Components.utils.reportError);
   185   },
   187   clearAllDone: function(aData, aMm) {
   188     debug("clearAllDone called!");
   189     let self = this;
   190     Task.spawn(function () {
   191       let list = yield Downloads.getList(Downloads.ALL);
   192       yield list.removeFinished();
   193       list = yield Downloads.getList(Downloads.ALL);
   194       let downloads = yield list.getAll();
   195       let res = [];
   196       downloads.forEach((aDownload) => {
   197         res.push(self.jsonDownload(aDownload));
   198       });
   199       aMm.sendAsyncMessage("Downloads:ClearAllDone:Return", res);
   200     }).then(null, Components.utils.reportError);
   201   },
   203   remove: function(aData, aMm) {
   204     debug("remove id " + aData.id);
   205     let download = this.getDownloadById(aData.id);
   206     if (!download) {
   207       sendPromiseMessage(aMm, "Downloads:Remove:Return",
   208                          aData, "NoSuchDownload");
   209       return;
   210     }
   212     Task.spawn(function() {
   213       yield download.finalize(true);
   214       let list = yield Downloads.getList(Downloads.ALL);
   215       yield list.remove(download);
   216     }).then(
   217       function() {
   218         sendPromiseMessage(aMm, "Downloads:Remove:Return", aData);
   219       },
   220       function() {
   221         sendPromiseMessage(aMm, "Downloads:Remove:Return",
   222                            aData, "RemoveError");
   223       }
   224     );
   225   },
   227   pause: function(aData, aMm) {
   228     debug("pause id " + aData.id);
   229     let download = this.getDownloadById(aData.id);
   230     if (!download) {
   231       sendPromiseMessage(aMm, "Downloads:Pause:Return",
   232                          aData, "NoSuchDownload");
   233       return;
   234     }
   236     download.cancel().then(
   237       function() {
   238         sendPromiseMessage(aMm, "Downloads:Pause:Return", aData);
   239       },
   240       function() {
   241         sendPromiseMessage(aMm, "Downloads:Pause:Return",
   242                            aData, "PauseError");
   243       }
   244     );
   245   },
   247   resume: function(aData, aMm) {
   248     debug("resume id " + aData.id);
   249     let download = this.getDownloadById(aData.id);
   250     if (!download) {
   251       sendPromiseMessage(aMm, "Downloads:Resume:Return",
   252                          aData, "NoSuchDownload");
   253       return;
   254     }
   256     download.start().then(
   257       function() {
   258         sendPromiseMessage(aMm, "Downloads:Resume:Return", aData);
   259       },
   260       function() {
   261         sendPromiseMessage(aMm, "Downloads:Resume:Return",
   262                            aData, "ResumeError");
   263       }
   264     );
   265   }
   266 };
   268 DownloadsAPI.init();

mercurial