forked from mirrors/gecko-dev
MozReview-Commit-ID: 8UGertZYKk --HG-- extra : rebase_source : ca00ad17ef23739d62e8e9e1336cb0fe07a7c379
265 lines
8.3 KiB
JavaScript
265 lines
8.3 KiB
JavaScript
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
|
/* Any copyright is dedicated to the Public Domain.
|
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
|
|
/* eslint-env mozilla/frame-script */
|
|
|
|
function loadPrivilegedScriptTest() {
|
|
/**
|
|
* The script is loaded as
|
|
* (a) a privileged script in content process for dc_sender.html
|
|
* (b) a frame script in the remote iframe process for dc_receiver_oop.html
|
|
* |type port == "undefined"| indicates the script is load by
|
|
* |loadPrivilegedScript| which is the first case.
|
|
*/
|
|
function sendMessage(type, data) {
|
|
if (typeof port == "undefined") {
|
|
sendAsyncMessage(type, {"data": data});
|
|
} else {
|
|
port.postMessage({"type": type,
|
|
"data": data
|
|
});
|
|
}
|
|
}
|
|
|
|
if (typeof port != "undefined") {
|
|
/**
|
|
* When the script is loaded by |loadPrivilegedScript|, these APIs
|
|
* are exposed to this script.
|
|
*/
|
|
port.onmessage = (e) => {
|
|
var type = e.data.type;
|
|
if (!handlers.hasOwnProperty(type)) {
|
|
return;
|
|
}
|
|
var args = [e];
|
|
handlers[type].forEach(handler => handler.apply(null, args));
|
|
};
|
|
var handlers = {};
|
|
/* eslint-disable-next-line no-native-reassign */
|
|
addMessageListener = function(message, handler) {
|
|
if (handlers.hasOwnProperty(message)) {
|
|
handlers[message].push(handler);
|
|
} else {
|
|
handlers[message] = [handler];
|
|
}
|
|
};
|
|
/* eslint-disable-next-line no-native-reassign */
|
|
removeMessageListener = function(message, handler) {
|
|
if (!handler || !handlers.hasOwnProperty(message)) {
|
|
return;
|
|
}
|
|
var index = handlers[message].indexOf(handler);
|
|
if (index != -1) {
|
|
handlers[message].splice(index, 1);
|
|
}
|
|
};
|
|
}
|
|
|
|
const Cm = Components.manager;
|
|
|
|
const mockedChannelDescription = {
|
|
/* eslint-disable-next-line mozilla/use-chromeutils-generateqi */
|
|
QueryInterface(iid) {
|
|
const interfaces = [Ci.nsIPresentationChannelDescription];
|
|
|
|
if (!interfaces.some(v => iid.equals(v))) {
|
|
throw Cr.NS_ERROR_NO_INTERFACE;
|
|
}
|
|
return this;
|
|
},
|
|
get type() {
|
|
/* global Services */
|
|
if (Services.prefs.getBoolPref("dom.presentation.session_transport.data_channel.enable")) {
|
|
return Ci.nsIPresentationChannelDescription.TYPE_DATACHANNEL;
|
|
}
|
|
return Ci.nsIPresentationChannelDescription.TYPE_TCP;
|
|
},
|
|
get dataChannelSDP() {
|
|
return "test-sdp";
|
|
}
|
|
};
|
|
|
|
function setTimeout(callback, delay) {
|
|
let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
|
timer.initWithCallback({ notify: callback },
|
|
delay,
|
|
Ci.nsITimer.TYPE_ONE_SHOT);
|
|
return timer;
|
|
}
|
|
|
|
const mockedSessionTransport = {
|
|
/* eslint-disable-next-line mozilla/use-chromeutils-generateqi */
|
|
QueryInterface(iid) {
|
|
const interfaces = [Ci.nsIPresentationSessionTransport,
|
|
Ci.nsIPresentationDataChannelSessionTransportBuilder,
|
|
Ci.nsIFactory];
|
|
|
|
if (!interfaces.some(v => iid.equals(v))) {
|
|
throw Cr.NS_ERROR_NO_INTERFACE;
|
|
}
|
|
return this;
|
|
},
|
|
createInstance(aOuter, aIID) {
|
|
if (aOuter) {
|
|
throw Cr.NS_ERROR_NO_AGGREGATION;
|
|
}
|
|
return this.QueryInterface(aIID);
|
|
},
|
|
set callback(callback) {
|
|
this._callback = callback;
|
|
},
|
|
get callback() {
|
|
return this._callback;
|
|
},
|
|
/* OOP case */
|
|
buildDataChannelTransport(role, window, listener) {
|
|
dump("PresentationSessionFrameScript: build data channel transport\n");
|
|
this._listener = listener;
|
|
this._role = role;
|
|
|
|
var hasNavigator = window ? (typeof window.navigator != "undefined") : false;
|
|
sendMessage("check-navigator", hasNavigator);
|
|
|
|
if (this._role == Ci.nsIPresentationService.ROLE_CONTROLLER) {
|
|
this._listener.sendOffer(mockedChannelDescription);
|
|
}
|
|
},
|
|
|
|
enableDataNotification() {
|
|
sendMessage("data-transport-notification-enabled");
|
|
},
|
|
send(data) {
|
|
sendMessage("message-sent", data);
|
|
},
|
|
close(reason) {
|
|
sendMessage("data-transport-closed", reason);
|
|
this._callback.QueryInterface(Ci.nsIPresentationSessionTransportCallback).notifyTransportClosed(reason);
|
|
this._callback = null;
|
|
},
|
|
simulateTransportReady() {
|
|
this._callback.QueryInterface(Ci.nsIPresentationSessionTransportCallback).notifyTransportReady();
|
|
},
|
|
simulateIncomingMessage(message) {
|
|
this._callback.QueryInterface(Ci.nsIPresentationSessionTransportCallback).notifyData(message, false);
|
|
},
|
|
onOffer(aOffer) {
|
|
this._listener.sendAnswer(mockedChannelDescription);
|
|
this._onSessionTransport();
|
|
},
|
|
onAnswer(aAnswer) {
|
|
this._onSessionTransport();
|
|
},
|
|
_onSessionTransport() {
|
|
setTimeout(() => {
|
|
this._listener.onSessionTransport(this);
|
|
this.simulateTransportReady();
|
|
this._listener = null;
|
|
}, 0);
|
|
}
|
|
};
|
|
|
|
|
|
function tearDown() {
|
|
mockedSessionTransport.callback = null;
|
|
|
|
/* Register original factories. */
|
|
for (var data of originalFactoryData) {
|
|
registerOriginalFactory(data.contractId, data.mockedClassId,
|
|
data.mockedFactory, data.originalClassId,
|
|
data.originalFactory);
|
|
}
|
|
sendMessage("teardown-complete");
|
|
}
|
|
|
|
|
|
function registerMockedFactory(contractId, mockedClassId, mockedFactory) {
|
|
var originalClassId, originalFactory;
|
|
var registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
|
|
|
|
if (!registrar.isCIDRegistered(mockedClassId)) {
|
|
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(mockedClassId, "", contractId, mockedFactory);
|
|
}
|
|
|
|
return { contractId,
|
|
mockedClassId,
|
|
mockedFactory,
|
|
originalClassId,
|
|
originalFactory };
|
|
}
|
|
|
|
function registerOriginalFactory(contractId, mockedClassId, mockedFactory, originalClassId, originalFactory) {
|
|
if (originalFactory) {
|
|
var registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
|
|
registrar.unregisterFactory(mockedClassId, mockedFactory);
|
|
registrar.registerFactory(originalClassId, "", contractId, originalFactory);
|
|
}
|
|
}
|
|
|
|
/* Register mocked factories. */
|
|
const originalFactoryData = [];
|
|
const uuidGenerator = Cc["@mozilla.org/uuid-generator;1"]
|
|
.getService(Ci.nsIUUIDGenerator);
|
|
originalFactoryData.push(registerMockedFactory("@mozilla.org/presentation/datachanneltransportbuilder;1",
|
|
uuidGenerator.generateUUID(),
|
|
mockedSessionTransport));
|
|
|
|
addMessageListener("trigger-incoming-message", function(event) {
|
|
mockedSessionTransport.simulateIncomingMessage(event.data.data);
|
|
});
|
|
addMessageListener("teardown", () => tearDown());
|
|
}
|
|
|
|
// Exposed to the caller of |loadPrivilegedScript|
|
|
var contentScript = {
|
|
handlers: {},
|
|
addMessageListener(message, handler) {
|
|
if (this.handlers.hasOwnProperty(message)) {
|
|
this.handlers[message].push(handler);
|
|
} else {
|
|
this.handlers[message] = [handler];
|
|
}
|
|
},
|
|
removeMessageListener(message, handler) {
|
|
if (!handler || !this.handlers.hasOwnProperty(message)) {
|
|
return;
|
|
}
|
|
var index = this.handlers[message].indexOf(handler);
|
|
if (index != -1) {
|
|
this.handlers[message].splice(index, 1);
|
|
}
|
|
},
|
|
sendAsyncMessage(message, data) {
|
|
port.postMessage({"type": message,
|
|
"data": data
|
|
});
|
|
}
|
|
};
|
|
|
|
if (!SpecialPowers.isMainProcess()) {
|
|
var port;
|
|
try {
|
|
port = SpecialPowers.loadPrivilegedScript(loadPrivilegedScriptTest.toSource());
|
|
} catch (e) {
|
|
ok(false, "loadPrivilegedScript shoulde not throw" + e);
|
|
}
|
|
|
|
port.onmessage = (e) => {
|
|
var type = e.data.type;
|
|
if (!contentScript.handlers.hasOwnProperty(type)) {
|
|
return;
|
|
}
|
|
var args = [e.data.data];
|
|
contentScript.handlers[type].forEach(handler => handler.apply(null, args));
|
|
};
|
|
}
|