diff options
Diffstat (limited to 'dom/presentation/tests/mochitest/PresentationSessionChromeScript1UA.js')
-rw-r--r-- | dom/presentation/tests/mochitest/PresentationSessionChromeScript1UA.js | 366 |
1 files changed, 366 insertions, 0 deletions
diff --git a/dom/presentation/tests/mochitest/PresentationSessionChromeScript1UA.js b/dom/presentation/tests/mochitest/PresentationSessionChromeScript1UA.js new file mode 100644 index 000000000..82d7362b2 --- /dev/null +++ b/dom/presentation/tests/mochitest/PresentationSessionChromeScript1UA.js @@ -0,0 +1,366 @@ +/* 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'; + +const { classes: Cc, interfaces: Ci, manager: Cm, utils: Cu, results: Cr } = Components; + +Cu.import('resource://gre/modules/XPCOMUtils.jsm'); +Cu.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: XPCOMUtils.generateQI([Ci.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: function() { + // send offer after notifyConnected immediately + this._listener + .QueryInterface(Ci.nsIPresentationControlChannelListener) + .notifyConnected(); + }, + notifyReconnected: function() { + // send offer after notifyOpened immediately + this._listener + .QueryInterface(Ci.nsIPresentationControlChannelListener) + .notifyReconnected(); + }, + sendOffer: function(offer) { + Services.tm.mainThread.dispatch(() => { + mockControlChannelOfReceiver.onOffer(offer); + }, Ci.nsIThread.DISPATCH_NORMAL); + }, + onAnswer: function(answer) { + this._listener + .QueryInterface(Ci.nsIPresentationControlChannelListener) + .onAnswer(answer); + }, + launch: function(presentationId, url) { + sessionId = presentationId; + sendAsyncMessage('sender-launch', url); + }, + disconnect: function(reason) { + if (!this._listener) { + return; + } + this._listener + .QueryInterface(Ci.nsIPresentationControlChannelListener) + .notifyDisconnected(reason); + mockControlChannelOfReceiver.disconnect(); + }, + terminate: function(presentationId) { + sendAsyncMessage('sender-terminate'); + }, + reconnect: function(presentationId, url) { + sendAsyncMessage('start-reconnect', url); + }, + sendIceCandidate: function(candidate) { + mockControlChannelOfReceiver.notifyIceCandidate(candidate); + }, + notifyIceCandidate: function(candidate) { + if (!this._listener) { + return; + } + + this._listener + .QueryInterface(Ci.nsIPresentationControlChannelListener) + .onIceCandidate(candidate); + }, +}; + +// control channel of receiver +const mockControlChannelOfReceiver = { + QueryInterface: XPCOMUtils.generateQI([Ci.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: function() { + // do nothing + if (!this._listener) { + this._pendingOpened = true; + return; + } + this._listener + .QueryInterface(Ci.nsIPresentationControlChannelListener) + .notifyConnected(); + }, + onOffer: function(offer) { + this._listener + .QueryInterface(Ci.nsIPresentationControlChannelListener) + .onOffer(offer); + }, + sendAnswer: function(answer) { + Services.tm.mainThread.dispatch(() => { + mockControlChannelOfSender.onAnswer(answer); + }, Ci.nsIThread.DISPATCH_NORMAL); + }, + disconnect: function(reason) { + if (!this._listener) { + return; + } + + this._listener + .QueryInterface(Ci.nsIPresentationControlChannelListener) + .notifyDisconnected(reason); + sendAsyncMessage('control-channel-receiver-closed', reason); + }, + terminate: function(presentaionId) { + }, + sendIceCandidate: function(candidate) { + mockControlChannelOfReceiver.notifyIceCandidate(candidate); + }, + notifyIceCandidate: function(candidate) { + if (!this._listener) { + return; + } + + this._listener + .QueryInterface(Ci.nsIPresentationControlChannelListener) + .onIceCandidate(candidate); + }, +}; + +const mockDevice = { + QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDevice]), + id: 'id', + name: 'name', + type: 'type', + establishControlChannel: function(url, presentationId) { + if (triggerControlChannelError) { + throw Cr.NS_ERROR_FAILURE; + } + sendAsyncMessage('control-channel-established'); + return mockControlChannelOfSender; + }, + disconnect: function() { + sendAsyncMessage('device-disconnected'); + }, + isRequestedUrlSupported: function(requestedUrl) { + return true; + }, +}; + +const mockDevicePrompt = { + QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDevicePrompt, + Ci.nsIFactory]), + createInstance: function(aOuter, aIID) { + if (aOuter) { + throw Components.results.NS_ERROR_NO_AGGREGATION; + } + return this.QueryInterface(aIID); + }, + set request(request) { + this._request = request; + }, + get request() { + return this._request; + }, + promptDeviceSelection: function(request) { + this._request = request; + sendAsyncMessage('device-prompt'); + }, + simulateSelect: function() { + this._request.select(mockDevice); + }, + simulateCancel: function() { + this._request.cancel(); + } +}; + +const mockRequestUIGlue = { + QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationRequestUIGlue, + Ci.nsIFactory]), + set promise(aPromise) { + this._promise = aPromise + }, + get promise() { + return this._promise; + }, + createInstance: function(aOuter, aIID) { + if (aOuter) { + throw Components.results.NS_ERROR_NO_AGGREGATION; + } + return this.QueryInterface(aIID); + }, + sendRequest: function(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: contractId, + mockClassId: mockClassId, + mockFactory: mockFactory, + originalClassId: originalClassId, + originalFactory: originalFactory }; + } + // Register mock factories. + const uuidGenerator = Cc["@mozilla.org/uuid-generator;1"] + .getService(Ci.nsIUUIDGenerator); + 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); + + var obs = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService); + obs.addObserver(function setupRequestPromiseHandler(aSubject, aTopic, aData) { + debug('Got observer: setup-request-promise'); + obs.removeObserver(setupRequestPromiseHandler, aTopic); + mockRequestUIGlue.promise = aSubject; + sendAsyncMessage('promise-setup-ready'); + }, 'setup-request-promise', false); +} + +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(); |