|
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("-- ActivityWrapper.js " + Date.now() + " : " + aMsg + "\n"); |
|
20 } |
|
21 |
|
22 /** |
|
23 * nsISystemMessagesWrapper implementation. Will return a |
|
24 * nsIDOMMozActivityRequestHandler |
|
25 */ |
|
26 function ActivityWrapper() { |
|
27 debug("ActivityWrapper"); |
|
28 } |
|
29 |
|
30 ActivityWrapper.prototype = { |
|
31 wrapMessage: function wrapMessage(aMessage, aWindow) { |
|
32 debug("Wrapping " + JSON.stringify(aMessage)); |
|
33 |
|
34 // This message is useful to communicate that the activity message has been |
|
35 // properly received by the app. If the app will be killed, the |
|
36 // ActivitiesService will be able to fire an error and complete the |
|
37 // Activity workflow. |
|
38 cpmm.sendAsyncMessage("Activity:Ready", { id: aMessage.id }); |
|
39 |
|
40 let handler = new aWindow.ActivityRequestHandler(aMessage.id, aMessage.payload); |
|
41 |
|
42 // When the activity window is closed, fire an error to notify the activity |
|
43 // caller of the situation. |
|
44 // We don't need to check whether the activity itself already sent |
|
45 // back something since ActivitiesService.jsm takes care of that. |
|
46 let util = aWindow.QueryInterface(Ci.nsIInterfaceRequestor) |
|
47 .getInterface(Ci.nsIDOMWindowUtils); |
|
48 let innerWindowID = util.currentInnerWindowID; |
|
49 |
|
50 let observer = { |
|
51 observe: function(aSubject, aTopic, aData) { |
|
52 |
|
53 switch (aTopic) { |
|
54 case 'inner-window-destroyed': |
|
55 let wId = aSubject.QueryInterface(Ci.nsISupportsPRUint64).data; |
|
56 if (wId == innerWindowID) { |
|
57 debug("Closing activity window " + innerWindowID); |
|
58 Services.obs.removeObserver(observer, "inner-window-destroyed"); |
|
59 cpmm.sendAsyncMessage("Activity:PostError", |
|
60 { id: aMessage.id, |
|
61 error: "ActivityCanceled" |
|
62 }); |
|
63 } |
|
64 break; |
|
65 case 'activity-error': |
|
66 case 'activity-success': |
|
67 if (aData !== aMessage.id) { |
|
68 return; |
|
69 } |
|
70 Services.obs.removeObserver(observer, "activity-error"); |
|
71 Services.obs.removeObserver(observer, "activity-success"); |
|
72 let docshell = aWindow.QueryInterface(Ci.nsIInterfaceRequestor) |
|
73 .getInterface(Ci.nsIWebNavigation); |
|
74 Services.obs.notifyObservers(docshell, "activity-done", aTopic); |
|
75 break; |
|
76 } |
|
77 } |
|
78 } |
|
79 |
|
80 Services.obs.addObserver(observer, "activity-error", false); |
|
81 Services.obs.addObserver(observer, "activity-success", false); |
|
82 Services.obs.addObserver(observer, "inner-window-destroyed", false); |
|
83 return handler; |
|
84 }, |
|
85 |
|
86 classID: Components.ID("{5430d6f9-32d6-4924-ba39-6b6d1b093cd6}"), |
|
87 QueryInterface: XPCOMUtils.generateQI([Ci.nsISystemMessagesWrapper]) |
|
88 } |
|
89 |
|
90 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ActivityWrapper]); |
|
91 |