diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
commit | 2aa4a82499d4becd2284cdb482213d541b8804dd (patch) | |
tree | b80bf8bf13c3766139fbacc530efd0dd9d54394c /dom/presentation/tests/mochitest/PresentationSessionChromeScript1UA.js | |
parent | Initial commit. (diff) | |
download | firefox-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.js | 412 |
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(); |