|
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/. */ |
|
4 |
|
5 "use strict"; |
|
6 |
|
7 const Cc = Components.classes; |
|
8 const Ci = Components.interfaces; |
|
9 const Cu = Components.utils; |
|
10 |
|
11 Cu.import("resource://gre/modules/XPCOMUtils.jsm"); |
|
12 Cu.import("resource://gre/modules/Services.jsm"); |
|
13 |
|
14 XPCOMUtils.defineLazyServiceGetter(this, "cpmm", |
|
15 "@mozilla.org/childprocessmessagemanager;1", |
|
16 "nsISyncMessageSender"); |
|
17 |
|
18 function debug(aMsg) { |
|
19 //dump("-- ActivityProxy " + Date.now() + " : " + aMsg + "\n"); |
|
20 } |
|
21 |
|
22 /** |
|
23 * nsIActivityProxy implementation |
|
24 * We keep a reference to the C++ Activity object, and |
|
25 * communicate with the Message Manager to know when to |
|
26 * fire events on it. |
|
27 */ |
|
28 function ActivityProxy() { |
|
29 debug("ActivityProxy"); |
|
30 this.activity = null; |
|
31 let inParent = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime) |
|
32 .processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT; |
|
33 debug("inParent: " + inParent); |
|
34 Cu.import(inParent ? "resource://gre/modules/Webapps.jsm" |
|
35 : "resource://gre/modules/AppsServiceChild.jsm"); |
|
36 } |
|
37 |
|
38 ActivityProxy.prototype = { |
|
39 startActivity: function actProxy_startActivity(aActivity, aOptions, aWindow) { |
|
40 debug("startActivity"); |
|
41 |
|
42 this.window = aWindow; |
|
43 this.activity = aActivity; |
|
44 this.id = Cc["@mozilla.org/uuid-generator;1"] |
|
45 .getService(Ci.nsIUUIDGenerator) |
|
46 .generateUUID().toString(); |
|
47 // Retrieve the app's manifest url from the principal, so that we can |
|
48 // later notify when the activity handler called postResult or postError |
|
49 let principal = aWindow.document.nodePrincipal; |
|
50 let appId = principal.appId; |
|
51 let manifestURL = (appId != Ci.nsIScriptSecurityManager.NO_APP_ID && |
|
52 appId != Ci.nsIScriptSecurityManager.UNKNOWN_APP_ID) |
|
53 ? DOMApplicationRegistry.getManifestURLByLocalId(appId) |
|
54 : null; |
|
55 cpmm.sendAsyncMessage("Activity:Start", { id: this.id, |
|
56 options: { |
|
57 name: aOptions.name, |
|
58 data: aOptions.data |
|
59 }, |
|
60 manifestURL: manifestURL, |
|
61 pageURL: aWindow.document.location.href }); |
|
62 |
|
63 cpmm.addMessageListener("Activity:FireSuccess", this); |
|
64 cpmm.addMessageListener("Activity:FireError", this); |
|
65 }, |
|
66 |
|
67 receiveMessage: function actProxy_receiveMessage(aMessage) { |
|
68 debug("Got message: " + aMessage.name); |
|
69 let msg = aMessage.json; |
|
70 if (msg.id != this.id) |
|
71 return; |
|
72 debug("msg=" + JSON.stringify(msg)); |
|
73 |
|
74 switch(aMessage.name) { |
|
75 case "Activity:FireSuccess": |
|
76 debug("FireSuccess"); |
|
77 Services.DOMRequest.fireSuccess(this.activity, |
|
78 Cu.cloneInto(msg.result, this.window)); |
|
79 Services.obs.notifyObservers(null, "Activity:Success", null); |
|
80 break; |
|
81 case "Activity:FireError": |
|
82 debug("FireError"); |
|
83 Services.DOMRequest.fireError(this.activity, msg.error); |
|
84 Services.obs.notifyObservers(null, "Activity:Error", null); |
|
85 break; |
|
86 } |
|
87 // We can only get one FireSuccess / FireError message, so cleanup as soon as possible. |
|
88 this.cleanup(); |
|
89 }, |
|
90 |
|
91 cleanup: function actProxy_cleanup() { |
|
92 debug("cleanup"); |
|
93 if (cpmm && !this.cleanedUp) { |
|
94 cpmm.removeMessageListener("Activity:FireSuccess", this); |
|
95 cpmm.removeMessageListener("Activity:FireError", this); |
|
96 } |
|
97 this.cleanedUp = true; |
|
98 }, |
|
99 |
|
100 classID: Components.ID("{ba9bd5cb-76a0-4ecf-a7b3-d2f7c43c5949}"), |
|
101 QueryInterface: XPCOMUtils.generateQI([Ci.nsIActivityProxy]) |
|
102 } |
|
103 |
|
104 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ActivityProxy]); |