Bug 1305352 - (Part 2) Implement PresentationRequestUIGlue on Fennec. r=snorp,r?schien
MozReview-Commit-ID: ISG6HS7HcPn
--- a/mobile/android/chrome/content/PresentationView.js
+++ b/mobile/android/chrome/content/PresentationView.js
@@ -1,22 +1,63 @@
+/* -*- Mode: tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+const TOPIC_PRESENTATION_VIEW_READY = "presentation-view-ready";
+const TOPIC_PRESENTATION_RECEIVER_LAUNCH = "presentation-receiver:launch";
+const TOPIC_PRESENTATION_RECEIVER_LAUNCH_RESPONSE = "presentation-receiver:launch:response";
+
// globals Services
Cu.import("resource://gre/modules/Services.jsm");
function log(str) {
// dump("-*- PresentationView.js -*-: " + str + "\n");
}
let PresentationView = {
_id: null,
startup: function startup() {
// use hash as the ID of this top level window
this._id = window.location.hash.substr(1);
+
+ // Listen "presentation-receiver:launch" sent from
+ // PresentationRequestUIGlue.
+ Services.obs.addObserver(this,TOPIC_PRESENTATION_RECEIVER_LAUNCH, false);
+
+ // Notify PresentationView is ready.
+ Services.obs.notifyObservers(null, TOPIC_PRESENTATION_VIEW_READY, this._id);
},
+
+ stop: function stop() {
+ Services.obs.removeObserver(this, TOPIC_PRESENTATION_RECEIVER_LAUNCH);
+ },
+
+ observe: function observe(aSubject, aTopic, aData) {
+ log("Got observe: aTopic=" + aTopic);
+
+ let requestData = JSON.parse(aData);
+ if (this._id != requestData.windowId) {
+ return;
+ }
+
+ let browser = document.getElementById("content");
+ browser.setAttribute("mozpresentation", requestData.url);
+ try {
+ browser.loadURI(requestData.url);
+ Services.obs.notifyObservers(browser,
+ TOPIC_PRESENTATION_RECEIVER_LAUNCH_RESPONSE,
+ JSON.stringify({ result: "success",
+ requestId: requestData.requestId }));
+ } catch (e) {
+ Services.obs.notifyObservers(null,
+ TOPIC_PRESENTATION_RECEIVER_LAUNCH_RESPONSE,
+ JSON.stringify({ result: "error",
+ reason: e.message }));
+ }
+ }
};
--- a/mobile/android/chrome/content/PresentationView.xul
+++ b/mobile/android/chrome/content/PresentationView.xul
@@ -1,14 +1,15 @@
<?xml version="1.0"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<window id="presentation-window"
onload="PresentationView.startup();"
+ onunload="PresentationView.stop();"
windowtype="navigator:browser"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<browser id="content" type="content-targetable" src="about:blank" flex="1"/>
<script type="application/javascript" src="chrome://browser/content/PresentationView.js"/>
</window>
--- a/mobile/android/components/MobileComponents.manifest
+++ b/mobile/android/components/MobileComponents.manifest
@@ -41,16 +41,20 @@ contract @mozilla.org/prompter;1 {9a6114
contract @mozilla.org/embedcomp/prompt-service;1 {9a61149b-2276-4a0a-b79c-be994ad106cf}
component {80dae1e9-e0d2-4974-915f-f97050fa8068} PromptService.js
contract @mozilla.org/network/authprompt-adapter-factory;1 {80dae1e9-e0d2-4974-915f-f97050fa8068}
# PresentationDevicePrompt.js
component {388bd149-c919-4a43-b646-d7ec57877689} PresentationDevicePrompt.js
contract @mozilla.org/presentation-device/prompt;1 {388bd149-c919-4a43-b646-d7ec57877689}
+# PresentationRequestUIGlue.js
+component {9c550ef7-3ff6-4bd1-9ad1-5a3735b90d21} PresentationRequestUIGlue.js
+contract @mozilla.org/presentation/requestuiglue;1 {9c550ef7-3ff6-4bd1-9ad1-5a3735b90d21}
+
# ImageBlockingPolicy.js
component {f55f77f9-d33d-4759-82fc-60db3ee0bb91} ImageBlockingPolicy.js
contract @mozilla.org/browser/blockimages-policy;1 {f55f77f9-d33d-4759-82fc-60db3ee0bb91}
category content-policy ImageBlockingPolicy @mozilla.org/browser/blockimages-policy;1
# XPIDialogService.js
component {c1242012-27d8-477e-a0f1-0b098ffc329b} XPIDialogService.js
contract @mozilla.org/addons/web-install-prompt;1 {c1242012-27d8-477e-a0f1-0b098ffc329b}
new file mode 100644
--- /dev/null
+++ b/mobile/android/components/PresentationRequestUIGlue.js
@@ -0,0 +1,86 @@
+/* -*- Mode: tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict"
+
+const { interfaces: Ci, utils: Cu, classes: Cc } = Components;
+
+const TOPIC_PRESENTATION_RECEIVER_LAUNCH = "presentation-receiver:launch";
+const TOPIC_PRESENTATION_RECEIVER_LAUNCH_RESPONSE = "presentation-receiver:launch:response";
+
+// globals XPCOMUtils
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+// globals Services
+Cu.import("resource://gre/modules/Services.jsm");
+
+function log(str) {
+ // dump("-*- PresentationRequestUIGlue.js -*-: " + str + "\n");
+}
+
+function PresentationRequestUIGlue() { }
+
+PresentationRequestUIGlue.prototype = {
+ sendRequest: function sendRequest(aURL, aSessionId, aDevice) {
+ log("PresentationRequestUIGlue - sendRequest aURL=" + aURL +
+ " aSessionId=" + aSessionId);
+
+ let localDevice;
+ try {
+ localDevice = aDevice.QueryInterface(Ci.nsIPresentationLocalDevice);
+ } catch (e) {
+ /* XXX: Currently, Fennec only support 1-UA devices. Remove this
+ * Promise.reject() when it starts to support 2-UA devices.
+ */
+ log("Not an 1-UA device.")
+ return new Promise.reject();
+ }
+
+ return new Promise((aResolve, aReject) => {
+
+ let uuidGenerator = Cc["@mozilla.org/uuid-generator;1"]
+ .getService(Ci.nsIUUIDGenerator);
+ let requestId = uuidGenerator.generateUUID().toString();
+
+ let handleObserve = (aSubject, aTopic, aData) => {
+ log("Got observe: aTopic=" + aTopic);
+
+ let data = JSON.parse(aData);
+ if (data.requestId != requestId) {
+ return;
+ }
+
+ Services.obs.removeObserver(handleObserve,
+ TOPIC_PRESENTATION_RECEIVER_LAUNCH_RESPONSE);
+ switch(data.result) {
+ case "success":
+ aResolve(aSubject);
+ break;
+ case "error":
+ aReject();
+ break;
+ };
+ };
+
+ Services.obs.addObserver(handleObserve,
+ TOPIC_PRESENTATION_RECEIVER_LAUNCH_RESPONSE,
+ false);
+
+ let data = {
+ url: aURL,
+ windowId: localDevice.windowId,
+ requestId: requestId
+ };
+ Services.obs.notifyObservers(null,
+ TOPIC_PRESENTATION_RECEIVER_LAUNCH,
+ JSON.stringify(data));
+ })
+ },
+
+ classID: Components.ID("9c550ef7-3ff6-4bd1-9ad1-5a3735b90d21"),
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationRequestUIGlue])
+};
+
+this.NSGetFactory = XPCOMUtils.generateNSGetFactory([PresentationRequestUIGlue]);
--- a/mobile/android/components/moz.build
+++ b/mobile/android/components/moz.build
@@ -22,16 +22,17 @@ EXTRA_COMPONENTS += [
'FilePicker.js',
'FxAccountsPush.js',
'HelperAppDialog.js',
'ImageBlockingPolicy.js',
'LoginManagerPrompter.js',
'NSSDialogService.js',
'PersistentNotificationHandler.js',
'PresentationDevicePrompt.js',
+ 'PresentationRequestUIGlue.js',
'PromptService.js',
'SessionStore.js',
'SiteSpecificUserAgent.js',
'Snippets.js',
'TabSource.js',
'XPIDialogService.js',
]
--- a/mobile/android/installer/package-manifest.in
+++ b/mobile/android/installer/package-manifest.in
@@ -527,16 +527,17 @@
@BINPATH@/components/FxAccountsPush.js
@BINPATH@/components/HelperAppDialog.js
@BINPATH@/components/LoginManagerPrompter.js
@BINPATH@/components/MobileComponents.manifest
@BINPATH@/components/MobileComponents.xpt
@BINPATH@/components/NSSDialogService.js
@BINPATH@/components/PersistentNotificationHandler.js
@BINPATH@/components/PresentationDevicePrompt.js
+@BINPATH@/components/PresentationRequestUIGlue.js
@BINPATH@/components/PromptService.js
@BINPATH@/components/SessionStore.js
@BINPATH@/components/SiteSpecificUserAgent.js
@BINPATH@/components/Snippets.js
@BINPATH@/components/XPIDialogService.js
#ifdef ENABLE_MARIONETTE