dom/apps/src/OperatorApps.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 file,
     3  * You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 "use strict";
     7 const Cu = Components.utils;
     8 const Cc = Components.classes;
     9 const Ci = Components.interfaces;
    11 this.EXPORTED_SYMBOLS = ["OperatorAppsRegistry"];
    13 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
    14 Cu.import("resource://gre/modules/FileUtils.jsm");
    15 Cu.import("resource://gre/modules/Webapps.jsm");
    16 Cu.import("resource://gre/modules/Services.jsm");
    17 Cu.import("resource://gre/modules/osfile.jsm");
    18 Cu.import("resource://gre/modules/AppsUtils.jsm");
    19 Cu.import("resource://gre/modules/Task.jsm");
    21 let Path = OS.Path;
    23 #ifdef MOZ_B2G_RIL
    24 XPCOMUtils.defineLazyServiceGetter(this, "iccProvider",
    25                                    "@mozilla.org/ril/content-helper;1",
    26                                    "nsIIccProvider");
    27 #endif
    29 function debug(aMsg) {
    30   //dump("-*-*- OperatorApps.jsm : " + aMsg + "\n");
    31 }
    33 // Single Variant source dir will be set in PREF_SINGLE_VARIANT_DIR
    34 // preference.
    35 // if PREF_SINGLE_VARIANT_DIR does not exist or has not value, it will use (as
    36 // single variant source) the value of
    37 // DIRECTORY_NAME + "/" + SINGLE_VARIANT_SOURCE_DIR value instead.
    38 // SINGLE_VARIANT_CONF_FILE will be stored on Single Variant Source.
    39 // Apps will be stored on an app per directory basis, hanging from
    40 // SINGLE_VARIANT_SOURCE_DIR
    41 const DIRECTORY_NAME = "webappsDir";
    42 const SINGLE_VARIANT_SOURCE_DIR = "svoperapps";
    43 const SINGLE_VARIANT_CONF_FILE  = "singlevariantconf.json";
    44 const PREF_FIRST_RUN_WITH_SIM   = "dom.webapps.firstRunWithSIM";
    45 const PREF_SINGLE_VARIANT_DIR   = "dom.mozApps.single_variant_sourcedir";
    46 const METADATA                  = "metadata.json";
    47 const UPDATEMANIFEST            = "update.webapp";
    48 const MANIFEST                  = "manifest.webapp";
    49 const APPLICATION_ZIP           = "application.zip";
    51 function isFirstRunWithSIM() {
    52   try {
    53     if (Services.prefs.prefHasUserValue(PREF_FIRST_RUN_WITH_SIM)) {
    54       return Services.prefs.getBoolPref(PREF_FIRST_RUN_WITH_SIM);
    55     }
    56   } catch(e) {
    57     debug ("Error getting pref. " + e);
    58   }
    59   return true;
    60 }
    62 #ifdef MOZ_B2G_RIL
    63 let iccListener = {
    64   notifyStkCommand: function() {},
    66   notifyStkSessionEnd: function() {},
    68   notifyCardStateChanged: function() {},
    70   notifyIccInfoChanged: function() {
    71     // TODO: Bug 927709 - OperatorApps for multi-sim
    72     // In Multi-sim, there is more than one client in iccProvider. Each
    73     // client represents a icc service. To maintain the backward compatibility
    74     // with single sim, we always use client 0 for now. Adding support for
    75     // multiple sim will be addressed in bug 927709, if needed.
    76     let clientId = 0;
    77     let iccInfo = iccProvider.getIccInfo(clientId);
    78     if (iccInfo && iccInfo.mcc && iccInfo.mnc) {
    79       let mcc = iccInfo.mcc;
    80       let mnc = iccInfo.mnc;
    81       debug("******* iccListener cardIccInfo MCC-MNC: " + mcc + "-" + mnc);
    82       iccProvider.unregisterIccMsg(clientId, this);
    83       OperatorAppsRegistry._installOperatorApps(mcc, mnc);
    85       debug("Broadcast message first-run-with-sim");
    86       let messenger = Cc["@mozilla.org/system-message-internal;1"]
    87                         .getService(Ci.nsISystemMessagesInternal);
    88       messenger.broadcastMessage("first-run-with-sim", { mcc: mcc,
    89                                                          mnc: mnc });
    90     }
    91   }
    92 };
    93 #endif
    95 this.OperatorAppsRegistry = {
    97   _baseDirectory: null,
    99   init: function() {
   100     debug("init");
   101 #ifdef MOZ_B2G_RIL
   102     if (isFirstRunWithSIM()) {
   103       debug("First Run with SIM");
   104       Task.spawn(function() {
   105         try {
   106           yield this._initializeSourceDir();
   107           // TODO: Bug 927709 - OperatorApps for multi-sim
   108           // In Multi-sim, there is more than one client in iccProvider. Each
   109           // client represents a icc service. To maintain the backward
   110           // compatibility with single sim, we always use client 0 for now.
   111           // Adding support for multiple sim will be addressed in bug 927709, if
   112           // needed.
   113           let clientId = 0;
   114           let iccInfo = iccProvider.getIccInfo(clientId);
   115           let mcc = 0;
   116           let mnc = 0;
   117           if (iccInfo && iccInfo.mcc) {
   118             mcc = iccInfo.mcc;
   119           }
   120           if (iccInfo && iccInfo.mnc) {
   121             mnc = iccInfo.mnc;
   122           }
   123           if (mcc && mnc) {
   124             this._installOperatorApps(mcc, mnc);
   125           } else {
   126             iccProvider.registerIccMsg(clientId, iccListener);
   127           }
   128         } catch (e) {
   129           debug("Error Initializing OperatorApps. " + e);
   130         }
   131       }.bind(this));
   132     } else {
   133       debug("No First Run with SIM");
   134     }
   135 #endif
   136   },
   138   _copyDirectory: function(aOrg, aDst) {
   139     debug("copying " + aOrg + " to " + aDst);
   140     return aDst && Task.spawn(function() {
   141       try {
   142         let orgDir = Cc["@mozilla.org/file/local;1"]
   143                        .createInstance(Ci.nsIFile);
   144         orgDir.initWithPath(aOrg);
   145         if (!orgDir.exists() || !orgDir.isDirectory()) {
   146           debug(aOrg + " does not exist or is not a directory");
   147           return;
   148         }
   150         let dstDir = Cc["@mozilla.org/file/local;1"]
   151                        .createInstance(Ci.nsIFile);
   152         dstDir.initWithPath(aDst);
   153         if (!dstDir.exists()) {
   154           dstDir.create(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
   155         }
   157         let entries = orgDir.directoryEntries;
   158         while (entries.hasMoreElements()) {
   159           let entry = entries.getNext().QueryInterface(Ci.nsIFile);
   161           if (!entry.isDirectory()) {
   162             // Remove the file, because copyTo doesn't overwrite files.
   163             let dstFile = dstDir.clone();
   164             dstFile.append(entry.leafName);
   165             if(dstFile.exists()) {
   166               dstFile.remove(false);
   167             }
   169             entry.copyTo(dstDir, entry.leafName);
   170           } else {
   171             yield this._copyDirectory(entry.path,
   172                                       Path.join(aDst, entry.leafName));
   173           }
   174         }
   175       } catch (e) {
   176         debug("Error copying " + aOrg + " to " + aDst + ". " + e);
   177       }
   178     }.bind(this));
   179   },
   181   _initializeSourceDir: function() {
   182     return Task.spawn(function() {
   183       let svFinalDirName;
   184       try {
   185         svFinalDirName = Services.prefs.getCharPref(PREF_SINGLE_VARIANT_DIR);
   186       } catch(e) {
   187         debug ("Error getting pref. " + e);
   188         this.appsDir = FileUtils.getFile(DIRECTORY_NAME,
   189                                          [SINGLE_VARIANT_SOURCE_DIR]).path;
   190         return;
   191       }
   192       // If SINGLE_VARIANT_CONF_FILE is in PREF_SINGLE_VARIANT_DIR return
   193       // PREF_SINGLE_VARIANT_DIR as sourceDir, else go to
   194       // DIRECTORY_NAME + SINGLE_VARIANT_SOURCE_DIR and move all apps (and
   195       // configuration file) to PREF_SINGLE_VARIANT_DIR and return
   196       // PREF_SINGLE_VARIANT_DIR as sourceDir.
   197       let svFinalDir = Cc["@mozilla.org/file/local;1"]
   198                          .createInstance(Ci.nsIFile);
   199       svFinalDir.initWithPath(svFinalDirName);
   200       if (!svFinalDir.exists()) {
   201         svFinalDir.create(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
   202       }
   204       let svIndex = svFinalDir.clone();
   205       svIndex.append(SINGLE_VARIANT_CONF_FILE);
   206       if (!svIndex.exists()) {
   207         let svSourceDir = FileUtils.getFile(DIRECTORY_NAME,
   208                                             [SINGLE_VARIANT_SOURCE_DIR]);
   210         yield this._copyDirectory(svSourceDir.path, svFinalDirName);
   212         debug("removing directory:" + svSourceDir.path);
   213         try {
   214           svSourceDir.remove(true);
   215         } catch(ex) { }
   216       }
   218       this.appsDir = svFinalDirName;
   219     }.bind(this));
   220   },
   222   set appsDir(aDir) {
   223     debug("appsDir SET: " + aDir);
   224     if (aDir) {
   225       this._baseDirectory = Cc["@mozilla.org/file/local;1"]
   226           .createInstance(Ci.nsILocalFile);
   227       this._baseDirectory.initWithPath(aDir);
   228     } else {
   229       this._baseDirectory = null;
   230     }
   231   },
   233   get appsDir() {
   234     return this._baseDirectory;
   235   },
   237   eraseVariantAppsNotInList: function(aIdsApp) {
   238     if (!aIdsApp || !Array.isArray(aIdsApp)) {
   239       aIdsApp = [ ];
   240     }
   242     let svDir;
   243     try {
   244       svDir = this.appsDir.clone();
   245     } catch (e) {
   246       debug("eraseVariantAppsNotInList --> Error getting Dir "+
   247              svDir.path + ". " + e);
   248       return;
   249     }
   251     if (!svDir || !svDir.exists()) {
   252       return;
   253     }
   255     let entries = svDir.directoryEntries;
   256     while (entries.hasMoreElements()) {
   257       let entry = entries.getNext().QueryInterface(Ci.nsIFile);
   258       if (entry.isDirectory() && aIdsApp.indexOf(entry.leafName) < 0) {
   259         try{
   260           entry.remove(true);
   261         } catch(e) {
   262           debug("Error removing [" + entry.path + "]." + e);
   263         }
   264       }
   265     }
   266   },
   268   _launchInstall: function(isPackage, aId, aMetadata, aManifest) {
   269     if (!aManifest) {
   270       debug("Error: The application " + aId + " does not have a manifest");
   271       return;
   272     }
   274     let appData = {
   275       app: {
   276         installOrigin: aMetadata.installOrigin,
   277         origin: aMetadata.origin,
   278         manifestURL: aMetadata.manifestURL,
   279         manifestHash: AppsUtils.computeHash(JSON.stringify(aManifest))
   280       },
   281       appId: undefined,
   282       isBrowser: false,
   283       isPackage: isPackage,
   284       forceSuccessAck: true
   285     };
   287     if (isPackage) {
   288       debug("aId:" + aId + ". Installing as packaged app.");
   289       let installPack = this.appsDir.clone();
   290       installPack.append(aId);
   291       installPack.append(APPLICATION_ZIP);
   293       if (!installPack.exists()) {
   294         debug("SV " + installPack.path + " file do not exists for app " + aId);
   295         return;
   296       }
   298       appData.app.localInstallPath = installPack.path;
   299       appData.app.updateManifest = aManifest;
   300       DOMApplicationRegistry.confirmInstall(appData);
   301     } else {
   302       debug("aId:" + aId + ". Installing as hosted app.");
   303       appData.app.manifest = aManifest;
   304       DOMApplicationRegistry.confirmInstall(appData);
   305     }
   306   },
   308   _installOperatorApps: function(aMcc, aMnc) {
   309     Task.spawn(function() {
   310       debug("Install operator apps ---> mcc:"+ aMcc + ", mnc:" + aMnc);
   311       if (!isFirstRunWithSIM()) {
   312         debug("Operator apps already installed.");
   313         return;
   314       }
   316       let aIdsApp = yield this._getSingleVariantApps(aMcc, aMnc);
   317       debug("installOperatorApps --> aIdsApp:" + JSON.stringify(aIdsApp));
   318       for (let i = 0; i < aIdsApp.length; i++) {
   319         let aId = aIdsApp[i];
   320         let aMetadata = yield AppsUtils.loadJSONAsync(
   321                            Path.join(this.appsDir.path, aId, METADATA));
   322         if (!aMetadata) {
   323           debug("Error reading metadata file");
   324           return;
   325         }
   327         debug("metadata:" + JSON.stringify(aMetadata));
   328         let isPackage = true;
   329         let manifest;
   330         let manifests = [UPDATEMANIFEST, MANIFEST];
   331         for (let j = 0; j < manifests.length; j++) {
   332           manifest = yield AppsUtils.loadJSONAsync(
   333                         Path.join(this.appsDir.path, aId, manifests[j]));
   335           if (!manifest) {
   336             isPackage = false;
   337           } else {
   338             break;
   339           }
   340         }
   341         if (manifest) {
   342           this._launchInstall(isPackage, aId, aMetadata, manifest);
   343         } else {
   344           debug ("Error. Neither " + UPDATEMANIFEST + " file nor " + MANIFEST +
   345                  " file for " + aId + " app.");
   346         }
   347       }
   348       this.eraseVariantAppsNotInList(aIdsApp);
   349       Services.prefs.setBoolPref(PREF_FIRST_RUN_WITH_SIM, false);
   350       Services.prefs.savePrefFile(null);
   351     }.bind(this)).then(null, function(aError) {
   352         debug("Error: " + aError);
   353     });
   354   },
   356   _getSingleVariantApps: function(aMcc, aMnc) {
   358     function normalizeCode(aCode) {
   359       let ncode = "" + aCode;
   360       while (ncode.length < 3) {
   361         ncode = "0" + ncode;
   362       }
   363       return ncode;
   364     }
   366     return Task.spawn(function*() {
   367       let key = normalizeCode(aMcc) + "-" + normalizeCode(aMnc);
   368       let file = Path.join(this.appsDir.path, SINGLE_VARIANT_CONF_FILE);
   369       let aData = yield AppsUtils.loadJSONAsync(file);
   371       if (!aData || !(key in aData)) {
   372         return [];
   373       }
   375       return aData[key];
   376     }.bind(this));
   377   }
   378 };
   380 OperatorAppsRegistry.init();

mercurial