Bug 1317697: Update initial process data after permission changes. r?mixedpuppy draft
authorKris Maglione <maglione.k@gmail.com>
Sun, 09 Apr 2017 23:58:26 -0700
changeset 559882 1dd948a14b127fd305ac662a56a3ad036063fe2a
parent 559881 9d7955a4d49d8621882e5edc00f3ce8a7b3662f9
child 623542 2b43e508e719e9666ed324357d6db63944da54a0
push id53247
push usermaglione.k@gmail.com
push dateMon, 10 Apr 2017 18:27:46 +0000
reviewersmixedpuppy
bugs1317697
milestone55.0a1
Bug 1317697: Update initial process data after permission changes. r?mixedpuppy MozReview-Commit-ID: GlO8N8oURjm
toolkit/components/extensions/Extension.jsm
toolkit/components/extensions/extension-process-script.js
--- a/toolkit/components/extensions/Extension.jsm
+++ b/toolkit/components/extensions/Extension.jsm
@@ -726,30 +726,46 @@ this.Extension = class extends Extension
     this.on("add-permissions", (ignoreEvent, permissions) => {
       for (let perm of permissions.permissions) {
         this.permissions.add(perm);
       }
 
       if (permissions.origins.length > 0) {
         this.whiteListedHosts = new MatchPattern(this.whiteListedHosts.pat.concat(...permissions.origins));
       }
+
+      this.updateMetadata();
     });
 
     this.on("remove-permissions", (ignoreEvent, permissions) => {
       for (let perm of permissions.permissions) {
         this.permissions.delete(perm);
       }
 
       for (let origin of permissions.origins) {
         this.whiteListedHosts.removeOne(origin);
       }
+
+      this.updateMetadata();
     });
     /* eslint-enable mozilla/balanced-listeners */
   }
 
+  /**
+   * Updates the initial process data for this extension after metadata
+   * changes.
+   */
+  updateMetadata() {
+    // Update the original metadata object in place, since it's stored
+    // in a list in the initial process data.
+    Object.assign(this.metadata, this.serialize());
+
+    this.broadcast("Extension:Update", this.metadata);
+  }
+
   static set browserUpdated(updated) {
     _browserUpdated = updated;
   }
 
   static get browserUpdated() {
     return _browserUpdated;
   }
 
@@ -915,20 +931,20 @@ this.Extension = class extends Extension
         promises.push(Management.asyncEmitManifestEntry(this, directive));
       }
     }
 
     let data = Services.ppmm.initialProcessData;
     if (!data["Extension:Extensions"]) {
       data["Extension:Extensions"] = [];
     }
-    let serial = this.serialize();
-    data["Extension:Extensions"].push(serial);
+    this.metadata = this.serialize();
+    data["Extension:Extensions"].push(this.metadata);
 
-    return this.broadcast("Extension:Startup", serial).then(() => {
+    return this.broadcast("Extension:Startup", this.metadata).then(() => {
       return Promise.all(promises);
     });
   }
 
   callOnClose(obj) {
     this.onShutdown.add(obj);
   }
 
@@ -1040,17 +1056,19 @@ this.Extension = class extends Extension
     this.hasShutdown = true;
 
     if (this.cleanupFile ||
         ["ADDON_INSTALL", "ADDON_UNINSTALL", "ADDON_UPGRADE", "ADDON_DOWNGRADE"].includes(reason)) {
       StartupCache.clearAddonData(this.id);
     }
 
     let data = Services.ppmm.initialProcessData;
-    data["Extension:Extensions"] = data["Extension:Extensions"].filter(e => e.id !== this.id);
+    if (data["Extension:Extensions"]) {
+      data["Extension:Extensions"] = data["Extension:Extensions"].filter(e => e.id !== this.id);
+    }
 
     Services.ppmm.removeMessageListener(this.MESSAGE_EMIT_EVENT, this);
 
     if (!this.manifest) {
       ExtensionManagement.shutdownExtension(this.uuid);
 
       this.cleanupGeneratedFile();
       return;
--- a/toolkit/components/extensions/extension-process-script.js
+++ b/toolkit/components/extensions/extension-process-script.js
@@ -556,16 +556,17 @@ ExtensionManager = {
   // Map[extensionId -> StubExtension]
   extensions: new Map(),
 
   init() {
     MessageChannel.setupMessageManagers([Services.cpmm]);
 
     Services.cpmm.addMessageListener("Extension:Startup", this);
     Services.cpmm.addMessageListener("Extension:Shutdown", this);
+    Services.cpmm.addMessageListener("Extension:Update", this);
     Services.cpmm.addMessageListener("Extension:FlushJarCache", this);
 
     let procData = Services.cpmm.initialProcessData || {};
 
     for (let data of procData["Extension:Extensions"] || []) {
       let extension = new StubExtension(data);
       this.extensions.set(data.id, extension);
       DocumentManager.initExtension(extension);
@@ -594,23 +595,33 @@ ExtensionManager = {
         this.extensions.set(data.id, extension);
 
         DocumentManager.initExtension(extension);
 
         Services.cpmm.sendAsyncMessage("Extension:StartupComplete");
         break;
       }
 
+      case "Extension:Update": {
+        let extension = this.extensions.get(data.id);
+        if (extension) {
+          Object.assign(extension.data, data);
+        }
+        Services.cpmm.sendAsyncMessage("Extension:UpdateComplete");
+        break;
+      }
+
       case "Extension:Shutdown": {
         let extension = this.extensions.get(data.id);
         this.extensions.delete(data.id);
 
         extension.shutdown();
 
         DocumentManager.uninitExtension(extension);
+        Services.cpmm.sendAsyncMessage("Extension:ShutdownComplete");
         break;
       }
 
       case "Extension:FlushJarCache": {
         ExtensionUtils.flushJarCache(data.path);
         Services.cpmm.sendAsyncMessage("Extension:FlushJarCacheComplete");
         break;
       }