summaryrefslogtreecommitdiffstats
path: root/dom/presentation/tests/mochitest/PresentationSessionChromeScript1UA.js
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /dom/presentation/tests/mochitest/PresentationSessionChromeScript1UA.js
parentInitial commit. (diff)
downloadfirefox-upstream.tar.xz
firefox-upstream.zip
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/presentation/tests/mochitest/PresentationSessionChromeScript1UA.js')
-rw-r--r--dom/presentation/tests/mochitest/PresentationSessionChromeScript1UA.js412
1 files changed, 412 insertions, 0 deletions
diff --git a/dom/presentation/tests/mochitest/PresentationSessionChromeScript1UA.js b/dom/presentation/tests/mochitest/PresentationSessionChromeScript1UA.js
new file mode 100644
index 0000000000..fe5bb6d6be
--- /dev/null
+++ b/dom/presentation/tests/mochitest/PresentationSessionChromeScript1UA.js
@@ -0,0 +1,412 @@
+/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
+/* 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";
+
+/* eslint-env mozilla/frame-script */
+
+const Cm = Components.manager;
+
+const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
+
+const uuidGenerator = Cc["@mozilla.org/uuid-generator;1"].getService(
+ Ci.nsIUUIDGenerator
+);
+
+function debug(str) {
+ // dump('DEBUG -*- PresentationSessionChromeScript1UA -*-: ' + str + '\n');
+}
+
+const originalFactoryData = [];
+var sessionId; // Store the uuid generated by PresentationRequest.
+var triggerControlChannelError = false; // For simulating error during control channel establishment.
+
+// control channel of sender
+const mockControlChannelOfSender = {
+ QueryInterface: ChromeUtils.generateQI(["nsIPresentationControlChannel"]),
+ set listener(listener) {
+ // PresentationControllingInfo::SetControlChannel
+ if (listener) {
+ debug("set listener for mockControlChannelOfSender without null");
+ } else {
+ debug("set listener for mockControlChannelOfSender with null");
+ }
+ this._listener = listener;
+ },
+ get listener() {
+ return this._listener;
+ },
+ notifyConnected() {
+ // send offer after notifyConnected immediately
+ this._listener
+ .QueryInterface(Ci.nsIPresentationControlChannelListener)
+ .notifyConnected();
+ },
+ notifyReconnected() {
+ // send offer after notifyOpened immediately
+ this._listener
+ .QueryInterface(Ci.nsIPresentationControlChannelListener)
+ .notifyReconnected();
+ },
+ sendOffer(offer) {
+ Services.tm.dispatchToMainThread(() => {
+ mockControlChannelOfReceiver.onOffer(offer);
+ });
+ },
+ onAnswer(answer) {
+ this._listener
+ .QueryInterface(Ci.nsIPresentationControlChannelListener)
+ .onAnswer(answer);
+ },
+ launch(presentationId, url) {
+ sessionId = presentationId;
+ sendAsyncMessage("sender-launch", url);
+ },
+ disconnect(reason) {
+ if (!this._listener) {
+ return;
+ }
+ this._listener
+ .QueryInterface(Ci.nsIPresentationControlChannelListener)
+ .notifyDisconnected(reason);
+ mockControlChannelOfReceiver.disconnect();
+ },
+ terminate(presentationId) {
+ sendAsyncMessage("sender-terminate");
+ },
+ reconnect(presentationId, url) {
+ sendAsyncMessage("start-reconnect", url);
+ },
+ sendIceCandidate(candidate) {
+ mockControlChannelOfReceiver.notifyIceCandidate(candidate);
+ },
+ notifyIceCandidate(candidate) {
+ if (!this._listener) {
+ return;
+ }
+
+ this._listener
+ .QueryInterface(Ci.nsIPresentationControlChannelListener)
+ .onIceCandidate(candidate);
+ },
+};
+
+// control channel of receiver
+const mockControlChannelOfReceiver = {
+ QueryInterface: ChromeUtils.generateQI(["nsIPresentationControlChannel"]),
+ set listener(listener) {
+ // PresentationPresentingInfo::SetControlChannel
+ if (listener) {
+ debug("set listener for mockControlChannelOfReceiver without null");
+ } else {
+ debug("set listener for mockControlChannelOfReceiver with null");
+ }
+ this._listener = listener;
+
+ if (this._pendingOpened) {
+ this._pendingOpened = false;
+ this.notifyConnected();
+ }
+ },
+ get listener() {
+ return this._listener;
+ },
+ notifyConnected() {
+ // do nothing
+ if (!this._listener) {
+ this._pendingOpened = true;
+ return;
+ }
+ this._listener
+ .QueryInterface(Ci.nsIPresentationControlChannelListener)
+ .notifyConnected();
+ },
+ onOffer(offer) {
+ this._listener
+ .QueryInterface(Ci.nsIPresentationControlChannelListener)
+ .onOffer(offer);
+ },
+ sendAnswer(answer) {
+ Services.tm.dispatchToMainThread(() => {
+ mockControlChannelOfSender.onAnswer(answer);
+ });
+ },
+ disconnect(reason) {
+ if (!this._listener) {
+ return;
+ }
+
+ this._listener
+ .QueryInterface(Ci.nsIPresentationControlChannelListener)
+ .notifyDisconnected(reason);
+ sendAsyncMessage("control-channel-receiver-closed", reason);
+ },
+ terminate(presentaionId) {},
+ sendIceCandidate(candidate) {
+ mockControlChannelOfSender.notifyIceCandidate(candidate);
+ },
+ notifyIceCandidate(candidate) {
+ if (!this._listener) {
+ return;
+ }
+
+ this._listener
+ .QueryInterface(Ci.nsIPresentationControlChannelListener)
+ .onIceCandidate(candidate);
+ },
+};
+
+const mockDevice = {
+ QueryInterface: ChromeUtils.generateQI(["nsIPresentationDevice"]),
+ id: "id",
+ name: "name",
+ type: "type",
+ establishControlChannel(url, presentationId) {
+ if (triggerControlChannelError) {
+ throw Components.Exception("", Cr.NS_ERROR_FAILURE);
+ }
+ sendAsyncMessage("control-channel-established");
+ return mockControlChannelOfSender;
+ },
+ disconnect() {
+ sendAsyncMessage("device-disconnected");
+ },
+ isRequestedUrlSupported(requestedUrl) {
+ return true;
+ },
+};
+
+const mockDevicePrompt = {
+ QueryInterface: ChromeUtils.generateQI([
+ "nsIPresentationDevicePrompt",
+ "nsIFactory",
+ ]),
+ createInstance(aOuter, aIID) {
+ if (aOuter) {
+ throw Components.Exception("", Cr.NS_ERROR_NO_AGGREGATION);
+ }
+ return this.QueryInterface(aIID);
+ },
+ set request(request) {
+ this._request = request;
+ },
+ get request() {
+ return this._request;
+ },
+ promptDeviceSelection(request) {
+ this._request = request;
+ sendAsyncMessage("device-prompt");
+ },
+ simulateSelect() {
+ this._request.select(mockDevice);
+ },
+ simulateCancel() {
+ this._request.cancel();
+ },
+};
+
+const mockRequestUIGlue = {
+ QueryInterface: ChromeUtils.generateQI([
+ "nsIPresentationRequestUIGlue",
+ "nsIFactory",
+ ]),
+ set promise(aPromise) {
+ this._promise = aPromise;
+ },
+ get promise() {
+ return this._promise;
+ },
+ createInstance(aOuter, aIID) {
+ if (aOuter) {
+ throw Components.Exception("", Cr.NS_ERROR_NO_AGGREGATION);
+ }
+ return this.QueryInterface(aIID);
+ },
+ sendRequest(aUrl, aSessionId) {
+ return this.promise;
+ },
+};
+
+function initMockAndListener() {
+ function registerMockFactory(contractId, mockClassId, mockFactory) {
+ var originalClassId, originalFactory;
+
+ var registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
+ if (!registrar.isCIDRegistered(mockClassId)) {
+ try {
+ originalClassId = registrar.contractIDToCID(contractId);
+ originalFactory = Cm.getClassObject(Cc[contractId], Ci.nsIFactory);
+ } catch (ex) {
+ originalClassId = "";
+ originalFactory = null;
+ }
+ if (originalFactory) {
+ registrar.unregisterFactory(originalClassId, originalFactory);
+ }
+ registrar.registerFactory(mockClassId, "", contractId, mockFactory);
+ }
+
+ return {
+ contractId,
+ mockClassId,
+ mockFactory,
+ originalClassId,
+ originalFactory,
+ };
+ }
+ // Register mock factories.
+ originalFactoryData.push(
+ registerMockFactory(
+ "@mozilla.org/presentation-device/prompt;1",
+ uuidGenerator.generateUUID(),
+ mockDevicePrompt
+ )
+ );
+ originalFactoryData.push(
+ registerMockFactory(
+ "@mozilla.org/presentation/requestuiglue;1",
+ uuidGenerator.generateUUID(),
+ mockRequestUIGlue
+ )
+ );
+
+ addMessageListener("trigger-device-add", function() {
+ debug("Got message: trigger-device-add");
+ var deviceManager = Cc[
+ "@mozilla.org/presentation-device/manager;1"
+ ].getService(Ci.nsIPresentationDeviceManager);
+ deviceManager
+ .QueryInterface(Ci.nsIPresentationDeviceListener)
+ .addDevice(mockDevice);
+ });
+
+ addMessageListener("trigger-device-prompt-select", function() {
+ debug("Got message: trigger-device-prompt-select");
+ mockDevicePrompt.simulateSelect();
+ });
+
+ addMessageListener("trigger-on-session-request", function(url) {
+ debug("Got message: trigger-on-session-request");
+ var deviceManager = Cc[
+ "@mozilla.org/presentation-device/manager;1"
+ ].getService(Ci.nsIPresentationDeviceManager);
+ deviceManager
+ .QueryInterface(Ci.nsIPresentationDeviceListener)
+ .onSessionRequest(
+ mockDevice,
+ url,
+ sessionId,
+ mockControlChannelOfReceiver
+ );
+ });
+
+ addMessageListener("trigger-on-terminate-request", function() {
+ debug("Got message: trigger-on-terminate-request");
+ var deviceManager = Cc[
+ "@mozilla.org/presentation-device/manager;1"
+ ].getService(Ci.nsIPresentationDeviceManager);
+ deviceManager
+ .QueryInterface(Ci.nsIPresentationDeviceListener)
+ .onTerminateRequest(
+ mockDevice,
+ sessionId,
+ mockControlChannelOfReceiver,
+ false
+ );
+ });
+
+ addMessageListener("trigger-control-channel-open", function(reason) {
+ debug("Got message: trigger-control-channel-open");
+ mockControlChannelOfSender.notifyConnected();
+ mockControlChannelOfReceiver.notifyConnected();
+ });
+
+ addMessageListener("trigger-control-channel-error", function(reason) {
+ debug("Got message: trigger-control-channel-open");
+ triggerControlChannelError = true;
+ });
+
+ addMessageListener("trigger-reconnected-acked", function(url) {
+ debug("Got message: trigger-reconnected-acked");
+ mockControlChannelOfSender.notifyReconnected();
+ var deviceManager = Cc[
+ "@mozilla.org/presentation-device/manager;1"
+ ].getService(Ci.nsIPresentationDeviceManager);
+ deviceManager
+ .QueryInterface(Ci.nsIPresentationDeviceListener)
+ .onReconnectRequest(
+ mockDevice,
+ url,
+ sessionId,
+ mockControlChannelOfReceiver
+ );
+ });
+
+ // Used to call sendAsyncMessage in chrome script from receiver.
+ addMessageListener("forward-command", function(command_data) {
+ let command = JSON.parse(command_data);
+ sendAsyncMessage(command.name, command.data);
+ });
+
+ addMessageListener("teardown", teardown);
+
+ Services.obs.addObserver(function setupRequestPromiseHandler(
+ aSubject,
+ aTopic,
+ aData
+ ) {
+ debug("Got observer: setup-request-promise");
+ Services.obs.removeObserver(setupRequestPromiseHandler, aTopic);
+ mockRequestUIGlue.promise = aSubject;
+ sendAsyncMessage("promise-setup-ready");
+ },
+ "setup-request-promise");
+}
+
+function teardown() {
+ function registerOriginalFactory(
+ contractId,
+ mockedClassId,
+ mockedFactory,
+ originalClassId,
+ originalFactory
+ ) {
+ if (originalFactory) {
+ var registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
+ registrar.unregisterFactory(mockedClassId, mockedFactory);
+ registrar.registerFactory(
+ originalClassId,
+ "",
+ contractId,
+ originalFactory
+ );
+ }
+ }
+
+ mockRequestUIGlue.promise = null;
+ mockControlChannelOfSender.listener = null;
+ mockControlChannelOfReceiver.listener = null;
+ mockDevicePrompt.request = null;
+
+ var deviceManager = Cc[
+ "@mozilla.org/presentation-device/manager;1"
+ ].getService(Ci.nsIPresentationDeviceManager);
+ deviceManager
+ .QueryInterface(Ci.nsIPresentationDeviceListener)
+ .removeDevice(mockDevice);
+ // Register original factories.
+ for (var data of originalFactoryData) {
+ registerOriginalFactory(
+ data.contractId,
+ data.mockClassId,
+ data.mockFactory,
+ data.originalClassId,
+ data.originalFactory
+ );
+ }
+ sendAsyncMessage("teardown-complete");
+}
+
+initMockAndListener();