toolkit/modules/RemoteAddonsParent.jsm

branch
TOR_BUG_3246
changeset 7
129ffea94266
equal deleted inserted replaced
-1:000000000000 0:cc07f67180b2
1 // -*- Mode: javascript; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // This Source Code Form is subject to the terms of the Mozilla Public
3 // License, v. 2.0. If a copy of the MPL was not distributed with this
4 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
6 this.EXPORTED_SYMBOLS = ["RemoteAddonsParent"];
7
8 const Ci = Components.interfaces;
9 const Cc = Components.classes;
10 const Cu = Components.utils;
11
12 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
13 Cu.import('resource://gre/modules/Services.jsm');
14
15 /**
16 * This code listens for nsIContentPolicy hooks firing in child
17 * processes. It then fires all hooks in the parent process and
18 * returns the result to the child.
19 */
20 let ContentPolicyParent = {
21 /**
22 * Some builtin policies will have already run in the child, and
23 * there's no reason to run them in the parent. This is a list of
24 * those policies. We assume that all child processes have the same
25 * set of built-in policies.
26 */
27 _policiesToIgnore: [],
28
29 init: function() {
30 let ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"]
31 .getService(Ci.nsIMessageBroadcaster);
32 ppmm.addMessageListener("Addons:ContentPolicy:IgnorePolicies", this);
33 ppmm.addMessageListener("Addons:ContentPolicy:Run", this);
34
35 Services.obs.addObserver(this, "xpcom-category-entry-added", true);
36 Services.obs.addObserver(this, "xpcom-category-entry-removed", true);
37 },
38
39 observe: function(aSubject, aTopic, aData) {
40 switch (aTopic) {
41 case "xpcom-category-entry-added":
42 case "xpcom-category-entry-removed":
43 if (aData == "content-policy")
44 this.updatePolicies();
45 break;
46 }
47 },
48
49 /**
50 * There's no need for the child process to inform us about the
51 * shouldLoad hook if we don't have any policies in the parent to
52 * run. This code iterates over the parent's policies, looking for
53 * ones that should not be ignored. Based on that, it tells the
54 * children whether it needs to be informed about the shouldLoad
55 * hook.
56 */
57 updatePolicies: function() {
58 let needHook = false;
59
60 let services = Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager)
61 .enumerateCategory("content-policy");
62 while (services.hasMoreElements()) {
63 let item = services.getNext();
64 let name = item.QueryInterface(Components.interfaces.nsISupportsCString).toString();
65
66 if (this._policiesToIgnore.indexOf(name) == -1) {
67 needHook = true;
68 break;
69 }
70 }
71
72 let ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"]
73 .getService(Ci.nsIMessageBroadcaster);
74 ppmm.broadcastAsyncMessage("Addons:ContentPolicy:NeedHook", { needed: needHook });
75 },
76
77 receiveMessage: function (aMessage) {
78 switch (aMessage.name) {
79 case "Addons:ContentPolicy:IgnorePolicies":
80 this._policiesToIgnore = aMessage.data.policies;
81 this.updatePolicies();
82 break;
83
84 case "Addons:ContentPolicy:Run":
85 return this.shouldLoad(aMessage.data, aMessage.objects);
86 break;
87 }
88 },
89
90 shouldLoad: function(aData, aObjects) {
91 let services = Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager)
92 .enumerateCategory("content-policy");
93 while (services.hasMoreElements()) {
94 let item = services.getNext();
95 let name = item.QueryInterface(Components.interfaces.nsISupportsCString).toString();
96 if (this._policiesToIgnore.indexOf(name) != -1)
97 continue;
98
99 let policy = Cc[name].getService(Ci.nsIContentPolicy);
100 try {
101 let result = policy.shouldLoad(aData.contentType,
102 aObjects.contentLocation,
103 aObjects.requestOrigin,
104 aObjects.node,
105 aData.mimeTypeGuess,
106 null);
107 if (result != Ci.nsIContentPolicy.ACCEPT && result != 0)
108 return result;
109 } catch (e) {}
110 }
111
112 return Ci.nsIContentPolicy.ACCEPT;
113 },
114
115 QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
116 };
117
118 let RemoteAddonsParent = {
119 initialized: false,
120
121 init: function() {
122 if (this.initialized)
123 return;
124
125 this.initialized = true;
126
127 ContentPolicyParent.init();
128 },
129 };

mercurial