toolkit/devtools/apps/app-actor-front.js

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 const {Ci, Cc, Cu, Cr} = require("chrome");
     2 Cu.import("resource://gre/modules/osfile.jsm");
     3 const {Services} = Cu.import("resource://gre/modules/Services.jsm");
     4 const {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm");
     5 const {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
     6 const {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
     8 // XXX: bug 912476 make this module a real protocol.js front
     9 // by converting webapps actor to protocol.js
    11 const PR_USEC_PER_MSEC = 1000;
    12 const PR_RDWR = 0x04;
    13 const PR_CREATE_FILE = 0x08;
    14 const PR_TRUNCATE = 0x20;
    16 const CHUNK_SIZE = 10000;
    18 const appTargets = new Map();
    20 function addDirToZip(writer, dir, basePath) {
    21   let files = dir.directoryEntries;
    23   while (files.hasMoreElements()) {
    24     let file = files.getNext().QueryInterface(Ci.nsIFile);
    26     if (file.isHidden() ||
    27         file.isSpecial() ||
    28         file.equals(writer.file))
    29     {
    30       continue;
    31     }
    33     if (file.isDirectory()) {
    34       writer.addEntryDirectory(basePath + file.leafName + "/",
    35                                file.lastModifiedTime * PR_USEC_PER_MSEC,
    36                                true);
    37       addDirToZip(writer, file, basePath + file.leafName + "/");
    38     } else {
    39       writer.addEntryFile(basePath + file.leafName,
    40                           Ci.nsIZipWriter.COMPRESSION_DEFAULT,
    41                           file,
    42                           true);
    43     }
    44   }
    45 }
    47 /**
    48  * Convert an XPConnect result code to its name and message.
    49  * We have to extract them from an exception per bug 637307 comment 5.
    50  */
    51 function getResultTest(code) {
    52   let regexp =
    53     /^\[Exception... "(.*)"  nsresult: "0x[0-9a-fA-F]* \((.*)\)"  location: ".*"  data: .*\]$/;
    54   let ex = Cc["@mozilla.org/js/xpc/Exception;1"].
    55            createInstance(Ci.nsIXPCException);
    56   ex.initialize(null, code, null, null, null, null);
    57   let [, message, name] = regexp.exec(ex.toString());
    58   return { name: name, message: message };
    59 }
    61 function zipDirectory(zipFile, dirToArchive) {
    62   let deferred = promise.defer();
    63   let writer = Cc["@mozilla.org/zipwriter;1"].createInstance(Ci.nsIZipWriter);
    64   writer.open(zipFile, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE);
    66   this.addDirToZip(writer, dirToArchive, "");
    68   writer.processQueue({
    69     onStartRequest: function onStartRequest(request, context) {},
    70     onStopRequest: (request, context, status) => {
    71       if (status == Cr.NS_OK) {
    72         writer.close();
    73         deferred.resolve(zipFile);
    74       }
    75       else {
    76         let { name, message } = getResultText(status);
    77         deferred.reject(name + ": " + message);
    78       }
    79     }
    80   }, null);
    82   return deferred.promise;
    83 }
    85 function uploadPackage(client, webappsActor, packageFile) {
    86   let deferred = promise.defer();
    88   let request = {
    89     to: webappsActor,
    90     type: "uploadPackage"
    91   };
    92   client.request(request, (res) => {
    93     openFile(res.actor);
    94   });
    96   function openFile(actor) {
    97     OS.File.open(packageFile.path)
    98       .then(function (file) {
    99         uploadChunk(actor, file);
   100       });
   101   }
   102   function uploadChunk(actor, file) {
   103     file.read(CHUNK_SIZE)
   104         .then(function (bytes) {
   105           // To work around the fact that JSON.stringify translates the typed
   106           // array to object, we are encoding the typed array here into a string
   107           let chunk = String.fromCharCode.apply(null, bytes);
   109           let request = {
   110             to: actor,
   111             type: "chunk",
   112             chunk: chunk
   113           };
   114           client.request(request, (res) => {
   115             if (bytes.length == CHUNK_SIZE) {
   116               uploadChunk(actor, file);
   117             } else {
   118               file.close().then(function () {
   119                 endsUpload(actor);
   120               });
   121             }
   122           });
   123         });
   124   }
   125   function endsUpload(actor) {
   126     let request = {
   127       to: actor,
   128       type: "done"
   129     };
   130     client.request(request, (res) => {
   131       deferred.resolve(actor);
   132     });
   133   }
   134   return deferred.promise;
   135 }
   137 function removeServerTemporaryFile(client, fileActor) {
   138   let request = {
   139     to: fileActor,
   140     type: "remove"
   141   };
   142   client.request(request);
   143 }
   145 function installPackaged(client, webappsActor, packagePath, appId) {
   146   let deferred = promise.defer();
   147   let file = FileUtils.File(packagePath);
   148   let packagePromise;
   149   if (file.isDirectory()) {
   150     let tmpZipFile = FileUtils.getDir("TmpD", [], true);
   151     tmpZipFile.append("application.zip");
   152     tmpZipFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, parseInt("666", 8));
   153     packagePromise = zipDirectory(tmpZipFile, file)
   154   } else {
   155     packagePromise = promise.resolve(file);
   156   }
   157   packagePromise.then((zipFile) => {
   158     uploadPackage(client, webappsActor, zipFile)
   159         .then((fileActor) => {
   160           let request = {
   161             to: webappsActor,
   162             type: "install",
   163             appId: appId,
   164             upload: fileActor
   165           };
   166           client.request(request, (res) => {
   167             // If the install method immediatly fails,
   168             // reject immediatly the installPackaged promise.
   169             // Otherwise, wait for webappsEvent for completion
   170             if (res.error) {
   171               deferred.reject(res);
   172             }
   173             if ("error" in res)
   174               deferred.reject({error: res.error, message: res.message});
   175             else
   176               deferred.resolve({appId: res.appId});
   177           });
   178           // Ensure deleting the temporary package file, but only if that a temporary
   179           // package created when we pass a directory as `packagePath`
   180           if (zipFile != file)
   181             zipFile.remove(false);
   182           // In case of success or error, ensure deleting the temporary package file
   183           // also created on the device, but only once install request is done
   184           deferred.promise.then(
   185             () => removeServerTemporaryFile(client, fileActor),
   186             () => removeServerTemporaryFile(client, fileActor));
   187         });
   188   });
   189   return deferred.promise;
   190 }
   191 exports.installPackaged = installPackaged;
   193 function installHosted(client, webappsActor, appId, metadata, manifest) {
   194   let deferred = promise.defer();
   195   let request = {
   196     to: webappsActor,
   197     type: "install",
   198     appId: appId,
   199     metadata: metadata,
   200     manifest: manifest
   201   };
   202   client.request(request, (res) => {
   203     if (res.error) {
   204       deferred.reject(res);
   205     }
   206     if ("error" in res)
   207       deferred.reject({error: res.error, message: res.message});
   208     else
   209       deferred.resolve({appId: res.appId});
   210   });
   211   return deferred.promise;
   212 }
   213 exports.installHosted = installHosted;
   215 function getTargetForApp(client, webappsActor, manifestURL) {
   216   // Ensure always returning the exact same JS object for a target
   217   // of the same app in order to show only one toolbox per app and
   218   // avoid re-creating lot of objects twice.
   219   let existingTarget = appTargets.get(manifestURL);
   220   if (existingTarget)
   221     return promise.resolve(existingTarget);
   223   let deferred = promise.defer();
   224   let request = {
   225     to: webappsActor,
   226     type: "getAppActor",
   227     manifestURL: manifestURL,
   228   }
   229   client.request(request, (res) => {
   230     if (res.error) {
   231       deferred.reject(res.error);
   232     } else {
   233       let options = {
   234         form: res.actor,
   235         client: client,
   236         chrome: false
   237       };
   239       devtools.TargetFactory.forRemoteTab(options).then((target) => {
   240         target.isApp = true;
   241         appTargets.set(manifestURL, target);
   242         target.on("close", () => {
   243           appTargets.delete(manifestURL);
   244         });
   245         deferred.resolve(target)
   246       }, (error) => {
   247         deferred.reject(error);
   248       });
   249     }
   250   });
   251   return deferred.promise;
   252 }
   253 exports.getTargetForApp = getTargetForApp;
   255 function reloadApp(client, webappsActor, manifestURL) {
   256   let deferred = promise.defer();
   257   getTargetForApp(client,
   258                   webappsActor,
   259                   manifestURL).
   260     then((target) => {
   261       // Request the ContentActor to reload the app
   262       let request = {
   263         to: target.form.actor,
   264         type: "reload",
   265         manifestURL: manifestURL
   266       };
   267       client.request(request, (res) => {
   268         deferred.resolve();
   269       });
   270     }, () => {
   271      deferred.reject("Not running");
   272     });
   273   return deferred.promise;
   274 }
   275 exports.reloadApp = reloadApp;
   277 function launchApp(client, webappsActor, manifestURL) {
   278   let deferred = promise.defer();
   279   let request = {
   280     to: webappsActor,
   281     type: "launch",
   282     manifestURL: manifestURL
   283   };
   284   client.request(request, (res) => {
   285     if (res.error) {
   286       deferred.reject(res.error);
   287     } else {
   288       deferred.resolve(res);
   289     }
   290   });
   291   return deferred.promise;
   292 }
   293 exports.launchApp = launchApp;
   295 function closeApp(client, webappsActor, manifestURL) {
   296   let deferred = promise.defer();
   297   let request = {
   298     to: webappsActor,
   299     type: "close",
   300     manifestURL: manifestURL
   301   };
   302   client.request(request, (res) => {
   303     if (res.error) {
   304       deferred.reject(res.error);
   305     } else {
   306       deferred.resolve(res);
   307     }
   308   });
   309   return deferred.promise;
   310 }
   311 exports.closeApp = closeApp;

mercurial