mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 03:15:11 +00:00
Bug 1197690 - Part1: Support reconnect command, r=junior
--HG-- extra : rebase_source : 4ccac7c28201562848c18b60b18614f450bdd19f
This commit is contained in:
parent
2c0b817322
commit
165708a330
@ -262,6 +262,27 @@ PresentationDeviceManager::OnTerminateRequest(nsIPresentationDevice* aDevice,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresentationDeviceManager::OnReconnectRequest(nsIPresentationDevice* aDevice,
|
||||
const nsAString& aUrl,
|
||||
const nsAString& aPresentationId,
|
||||
nsIPresentationControlChannel* aControlChannel)
|
||||
{
|
||||
NS_ENSURE_ARG(aDevice);
|
||||
NS_ENSURE_ARG(aControlChannel);
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
||||
NS_ENSURE_TRUE(obs, NS_ERROR_FAILURE);
|
||||
|
||||
RefPtr<PresentationSessionRequest> request =
|
||||
new PresentationSessionRequest(aDevice, aUrl, aPresentationId, aControlChannel);
|
||||
obs->NotifyObservers(request,
|
||||
PRESENTATION_RECONNECT_REQUEST_TOPIC,
|
||||
nullptr);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIObserver
|
||||
NS_IMETHODIMP
|
||||
PresentationDeviceManager::Observe(nsISupports *aSubject,
|
||||
|
@ -64,6 +64,11 @@ interface nsIPresentationControlChannelListener: nsISupports
|
||||
* @param reason The reason of channel close, NS_OK represents normal close.
|
||||
*/
|
||||
void notifyDisconnected(in nsresult reason);
|
||||
|
||||
/*
|
||||
* The callback for notifying the reconnect command is acknowledged.
|
||||
*/
|
||||
void notifyReconnected();
|
||||
};
|
||||
|
||||
/*
|
||||
@ -122,4 +127,13 @@ interface nsIPresentationControlChannel: nsISupports
|
||||
* @param reason The reason of disconnecting channel; NS_OK represents normal.
|
||||
*/
|
||||
void disconnect(in nsresult reason);
|
||||
|
||||
/*
|
||||
* Reconnect a presentation on remote endpoint.
|
||||
* Note that only controller is allowed to reconnect a session.
|
||||
* @param presentationId The Id for representing this session.
|
||||
* @param url The URL requested to open by remote device.
|
||||
* @throws NS_ERROR_FAILURE on failure
|
||||
*/
|
||||
void reconnect(in DOMString presentationId, in DOMString url);
|
||||
};
|
||||
|
@ -57,6 +57,18 @@ interface nsIPresentationControlServerListener: nsISupports
|
||||
in DOMString aPresentationId,
|
||||
in nsIPresentationControlChannel aControlChannel,
|
||||
in boolean aIsFromReceiver);
|
||||
|
||||
/**
|
||||
* Callback while the remote host is requesting to reconnect a presentation session.
|
||||
* @param aDeviceInfo The device information related to the remote host.
|
||||
* @param aUrl The URL requested to open by remote device.
|
||||
* @param aPresentationId The Id for representing this session.
|
||||
* @param aControlChannel The control channel for this session.
|
||||
*/
|
||||
void onReconnectRequest(in nsITCPDeviceInfo aDeviceInfo,
|
||||
in DOMString url,
|
||||
in DOMString aPresentationId,
|
||||
in nsIPresentationControlChannel aControlChannel);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -44,6 +44,18 @@ interface nsIPresentationDeviceListener: nsISupports
|
||||
in DOMString presentationId,
|
||||
in nsIPresentationControlChannel controlChannel,
|
||||
in boolean aIsFromReceiver);
|
||||
|
||||
/*
|
||||
* Callback while the remote device is requesting to reconnect a presentation session.
|
||||
* @param device The remote device that sent session request.
|
||||
* @param aUrl The URL requested to open by remote device.
|
||||
* @param presentationId The Id for representing this session.
|
||||
* @param controlChannel The control channel for this session.
|
||||
*/
|
||||
void onReconnectRequest(in nsIPresentationDevice device,
|
||||
in DOMString url,
|
||||
in DOMString presentationId,
|
||||
in nsIPresentationControlChannel controlChannel);
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -12,8 +12,10 @@ interface nsIPresentationControlChannel;
|
||||
%}
|
||||
|
||||
/*
|
||||
* The event of a device requesting for a presentation session. User can
|
||||
* monitor the session request on every device by observing "presentation-sesion-request".
|
||||
* The event of a device requesting for starting or reconnecting
|
||||
* a presentation session. User can monitor the session request
|
||||
* on every device by observing "presentation-sesion-request" for a
|
||||
* new session and "presentation-reconnect-request" for reconnecting.
|
||||
*/
|
||||
[scriptable, uuid(d808a084-d0f8-455a-a8df-5879e05a755b)]
|
||||
interface nsIPresentationSessionRequest: nsISupports
|
||||
|
@ -60,6 +60,9 @@ var handlers = [
|
||||
case CommandType.ICE_CANDIDATE:
|
||||
stateMachine._notifyChannelDescriptor(command);
|
||||
break;
|
||||
case CommandType.RECONNECT_ACK:
|
||||
stateMachine._notifyReconnect(command.presentationId);
|
||||
break;
|
||||
default:
|
||||
debug("unexpected command: " + JSON.stringify(command));
|
||||
// ignore unexpected command.
|
||||
@ -111,6 +114,16 @@ ControllerStateMachine.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
reconnect: function _reconnect(presentationId, url) {
|
||||
if (this.state === State.CONNECTED) {
|
||||
this._sendCommand({
|
||||
type: CommandType.RECONNECT,
|
||||
presentationId: presentationId,
|
||||
url: url,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
sendOffer: function _sendOffer(offer) {
|
||||
if (this.state === State.CONNECTED) {
|
||||
this._sendCommand({
|
||||
@ -200,6 +213,10 @@ ControllerStateMachine.prototype = {
|
||||
this._channel.notifyTerminate(presentationId);
|
||||
},
|
||||
|
||||
_notifyReconnect: function _notifyReconnect(presentationId) {
|
||||
this._channel.notifyReconnect(presentationId);
|
||||
},
|
||||
|
||||
_notifyChannelDescriptor: function _notifyChannelDescriptor(command) {
|
||||
switch (command.type) {
|
||||
case CommandType.ANSWER:
|
||||
|
@ -436,6 +436,37 @@ DisplayDeviceProvider::OnTerminateRequest(nsITCPDeviceInfo* aDeviceInfo,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
DisplayDeviceProvider::OnReconnectRequest(nsITCPDeviceInfo* aDeviceInfo,
|
||||
const nsAString& aUrl,
|
||||
const nsAString& aPresentationId,
|
||||
nsIPresentationControlChannel* aControlChannel)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aDeviceInfo);
|
||||
MOZ_ASSERT(aControlChannel);
|
||||
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIPresentationDeviceListener> listener;
|
||||
rv = GetListener(getter_AddRefs(listener));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!listener);
|
||||
|
||||
rv = listener->OnReconnectRequest(mDevice,
|
||||
aUrl,
|
||||
aPresentationId,
|
||||
aControlChannel);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIObserver
|
||||
NS_IMETHODIMP
|
||||
DisplayDeviceProvider::Observe(nsISupports* aSubject,
|
||||
|
@ -474,6 +474,12 @@ LegacyTCPControlChannel.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
reconnect: function() {
|
||||
// Legacy protocol doesn't support extra reconnect protocol.
|
||||
// Trigger error handling for browser to shutdown all the resource locally.
|
||||
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
|
||||
},
|
||||
|
||||
classID: Components.ID("{4027ce3d-06e3-4d06-a235-df329cb0d411}"),
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationControlChannel,
|
||||
Ci.nsIStreamListener]),
|
||||
|
@ -873,63 +873,13 @@ MulticastDNSDeviceProvider::OnPortChange(uint16_t aPort)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MulticastDNSDeviceProvider::OnSessionRequest(nsITCPDeviceInfo* aDeviceInfo,
|
||||
const nsAString& aUrl,
|
||||
const nsAString& aPresentationId,
|
||||
nsIPresentationControlChannel* aControlChannel)
|
||||
// Create a new device if we were unable to find one with the address.
|
||||
already_AddRefed<MulticastDNSDeviceProvider::Device>
|
||||
MulticastDNSDeviceProvider::GetOrCreateDevice(nsITCPDeviceInfo* aDeviceInfo)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsAutoCString address;
|
||||
Unused << aDeviceInfo->GetAddress(address);
|
||||
|
||||
LOG_I("OnSessionRequest: %s", address.get());
|
||||
|
||||
RefPtr<Device> device;
|
||||
uint32_t index;
|
||||
if (FindDeviceByAddress(address, index)) {
|
||||
device = mDevices[index];
|
||||
} else {
|
||||
// create a one-time device object for non-discoverable controller
|
||||
// this device will not be listed in available device list and cannot
|
||||
// be used for requesting session.
|
||||
nsAutoCString id;
|
||||
Unused << aDeviceInfo->GetId(id);
|
||||
uint16_t port;
|
||||
Unused << aDeviceInfo->GetPort(&port);
|
||||
|
||||
device = new Device(id,
|
||||
/* aName = */ id,
|
||||
/* aType = */ EmptyCString(),
|
||||
address,
|
||||
port,
|
||||
DeviceState::eActive,
|
||||
/* aProvider = */ nullptr);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPresentationDeviceListener> listener;
|
||||
if (NS_SUCCEEDED(GetListener(getter_AddRefs(listener))) && listener) {
|
||||
Unused << listener->OnSessionRequest(device, aUrl, aPresentationId,
|
||||
aControlChannel);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MulticastDNSDeviceProvider::OnTerminateRequest(nsITCPDeviceInfo* aDeviceInfo,
|
||||
const nsAString& aPresentationId,
|
||||
nsIPresentationControlChannel* aControlChannel,
|
||||
bool aIsFromReceiver)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsAutoCString address;
|
||||
Unused << aDeviceInfo->GetAddress(address);
|
||||
|
||||
LOG_I("OnTerminateRequest: %s", address.get());
|
||||
|
||||
RefPtr<Device> device;
|
||||
uint32_t index;
|
||||
if (FindDeviceByAddress(address, index)) {
|
||||
@ -952,6 +902,46 @@ MulticastDNSDeviceProvider::OnTerminateRequest(nsITCPDeviceInfo* aDeviceInfo,
|
||||
/* aProvider = */ nullptr);
|
||||
}
|
||||
|
||||
return device.forget();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MulticastDNSDeviceProvider::OnSessionRequest(nsITCPDeviceInfo* aDeviceInfo,
|
||||
const nsAString& aUrl,
|
||||
const nsAString& aPresentationId,
|
||||
nsIPresentationControlChannel* aControlChannel)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsAutoCString address;
|
||||
Unused << aDeviceInfo->GetAddress(address);
|
||||
|
||||
LOG_I("OnSessionRequest: %s", address.get());
|
||||
|
||||
RefPtr<Device> device = GetOrCreateDevice(aDeviceInfo);
|
||||
nsCOMPtr<nsIPresentationDeviceListener> listener;
|
||||
if (NS_SUCCEEDED(GetListener(getter_AddRefs(listener))) && listener) {
|
||||
Unused << listener->OnSessionRequest(device, aUrl, aPresentationId,
|
||||
aControlChannel);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MulticastDNSDeviceProvider::OnTerminateRequest(nsITCPDeviceInfo* aDeviceInfo,
|
||||
const nsAString& aPresentationId,
|
||||
nsIPresentationControlChannel* aControlChannel,
|
||||
bool aIsFromReceiver)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsAutoCString address;
|
||||
Unused << aDeviceInfo->GetAddress(address);
|
||||
|
||||
LOG_I("OnTerminateRequest: %s", address.get());
|
||||
|
||||
RefPtr<Device> device = GetOrCreateDevice(aDeviceInfo);
|
||||
nsCOMPtr<nsIPresentationDeviceListener> listener;
|
||||
if (NS_SUCCEEDED(GetListener(getter_AddRefs(listener))) && listener) {
|
||||
Unused << listener->OnTerminateRequest(device, aPresentationId,
|
||||
@ -961,6 +951,29 @@ MulticastDNSDeviceProvider::OnTerminateRequest(nsITCPDeviceInfo* aDeviceInfo,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MulticastDNSDeviceProvider::OnReconnectRequest(nsITCPDeviceInfo* aDeviceInfo,
|
||||
const nsAString& aUrl,
|
||||
const nsAString& aPresentationId,
|
||||
nsIPresentationControlChannel* aControlChannel)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsAutoCString address;
|
||||
Unused << aDeviceInfo->GetAddress(address);
|
||||
|
||||
LOG_I("OnReconnectRequest: %s", address.get());
|
||||
|
||||
RefPtr<Device> device = GetOrCreateDevice(aDeviceInfo);
|
||||
nsCOMPtr<nsIPresentationDeviceListener> listener;
|
||||
if (NS_SUCCEEDED(GetListener(getter_AddRefs(listener))) && listener) {
|
||||
Unused << listener->OnReconnectRequest(device, aUrl, aPresentationId,
|
||||
aControlChannel);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIObserver
|
||||
NS_IMETHODIMP
|
||||
MulticastDNSDeviceProvider::Observe(nsISupports* aSubject,
|
||||
|
@ -19,6 +19,8 @@
|
||||
#include "nsTArray.h"
|
||||
#include "nsWeakPtr.h"
|
||||
|
||||
class nsITCPDeviceInfo;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace presentation {
|
||||
@ -162,6 +164,9 @@ private:
|
||||
bool FindDeviceByAddress(const nsACString& aAddress,
|
||||
uint32_t& aIndex);
|
||||
|
||||
already_AddRefed<Device>
|
||||
GetOrCreateDevice(nsITCPDeviceInfo* aDeviceInfo);
|
||||
|
||||
void MarkAllDevicesUnknown();
|
||||
void ClearUnknownDevices();
|
||||
void ClearDevices();
|
||||
|
@ -193,6 +193,21 @@ PresentationControlService.prototype = {
|
||||
this.releaseControlChannel(aControlChannel);
|
||||
},
|
||||
|
||||
onSessionReconnect: function(aDeviceInfo, aUrl, aPresentationId, aControlChannel) {
|
||||
DEBUG && log("TCPPresentationServer - onSessionReconnect: " +
|
||||
aDeviceInfo.address + ":" + aDeviceInfo.port); // jshint ignore:line
|
||||
if (!this.listener) {
|
||||
this.releaseControlChannel(aControlChannel);
|
||||
return;
|
||||
}
|
||||
|
||||
this.listener.onReconnectRequest(aDeviceInfo,
|
||||
aUrl,
|
||||
aPresentationId,
|
||||
aControlChannel);
|
||||
this.releaseControlChannel(aControlChannel);
|
||||
},
|
||||
|
||||
// nsIServerSocketListener (Triggered by nsIServerSocket.init)
|
||||
onSocketAccepted: function(aServerSocket, aClientSocket) {
|
||||
DEBUG && log("PresentationControlService - onSocketAccepted: " +
|
||||
@ -393,6 +408,7 @@ TCPControlChannel.prototype = {
|
||||
_pendingAnswer: null,
|
||||
_pendingClose: null,
|
||||
_pendingCloseReason: null,
|
||||
_pendingReconnect: false,
|
||||
|
||||
sendOffer: function(aOffer) {
|
||||
this._stateMachine.sendOffer(discriptionAsJson(aOffer));
|
||||
@ -555,6 +571,12 @@ TCPControlChannel.prototype = {
|
||||
this._notifyDisconnected(this._pendingCloseReason);
|
||||
this._pendingClose = null;
|
||||
}
|
||||
|
||||
if (this._pendingReconnect) {
|
||||
DEBUG && log("TCPControlChannel - notify pending reconnected"); // jshint ignore:line
|
||||
this._notifyReconnected();
|
||||
this._pendingReconnect = false;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@ -624,6 +646,17 @@ TCPControlChannel.prototype = {
|
||||
this._listener.notifyDisconnected(aReason);
|
||||
},
|
||||
|
||||
_notifyReconnected: function() {
|
||||
if (!this._listener) {
|
||||
this._pendingReconnect = true;
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG && log("TCPControlChannel - notify reconnected with role: " +
|
||||
this._direction); // jshint ignore:line
|
||||
this._listener.notifyReconnected();
|
||||
},
|
||||
|
||||
_closeTransport: function() {
|
||||
if (this._connected) {
|
||||
this._transport.setEventSink(null, null);
|
||||
@ -649,6 +682,16 @@ TCPControlChannel.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
reconnect: function(aPresentationId, aUrl) {
|
||||
DEBUG && log("TCPControlChannel - reconnect with role: " +
|
||||
this._direction); // jshint ignore:line
|
||||
if (this._direction != "sender") {
|
||||
return Cr.NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
this._stateMachine.reconnect(aPresentationId, aUrl);
|
||||
},
|
||||
|
||||
// callback from state machine
|
||||
sendCommand: function(command) {
|
||||
this._send(command);
|
||||
@ -684,9 +727,9 @@ TCPControlChannel.prototype = {
|
||||
if (!this._terminatingId) {
|
||||
this._terminatingId = presentationId;
|
||||
this._presentationService.onSessionTerminate(this._deviceInfo,
|
||||
presentationId,
|
||||
this,
|
||||
this._direction === "sender");
|
||||
presentationId,
|
||||
this,
|
||||
this._direction === "sender");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -700,6 +743,20 @@ TCPControlChannel.prototype = {
|
||||
delete this._terminatingId;
|
||||
},
|
||||
|
||||
notifyReconnect: function(presentationId, url) {
|
||||
switch (this._direction) {
|
||||
case "receiver":
|
||||
this._presentationService.onSessionReconnect(this._deviceInfo,
|
||||
url,
|
||||
presentationId,
|
||||
this);
|
||||
break;
|
||||
case "sender":
|
||||
this._notifyReconnected();
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
notifyOffer: function(offer) {
|
||||
this._onOffer(offer);
|
||||
},
|
||||
|
@ -68,6 +68,14 @@ var handlers = [
|
||||
case CommandType.ICE_CANDIDATE:
|
||||
stateMachine._notifyChannelDescriptor(command);
|
||||
break;
|
||||
case CommandType.RECONNECT:
|
||||
stateMachine._notifyReconnect(command.presentationId,
|
||||
command.url);
|
||||
stateMachine._sendCommand({
|
||||
type: CommandType.RECONNECT_ACK,
|
||||
presentationId: command.presentationId
|
||||
});
|
||||
break;
|
||||
default:
|
||||
debug("unexpected command: " + JSON.stringify(command));
|
||||
// ignore unexpected command
|
||||
@ -113,6 +121,10 @@ ReceiverStateMachine.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
reconnect: function _reconnect() {
|
||||
debug("receiver shouldn't trigger reconnect");
|
||||
},
|
||||
|
||||
sendOffer: function _sendOffer() {
|
||||
// offer can only be sent by controlling UA.
|
||||
debug("receiver shouldn't generate offer");
|
||||
@ -199,6 +211,10 @@ ReceiverStateMachine.prototype = {
|
||||
this._channel.notifyTerminate(presentationId);
|
||||
},
|
||||
|
||||
_notifyReconnect: function _notifyReconnect(presentationId, url) {
|
||||
this._channel.notifyReconnect(presentationId, url);
|
||||
},
|
||||
|
||||
_notifyChannelDescriptor: function _notifyChannelDescriptor(command) {
|
||||
switch (command.type) {
|
||||
case CommandType.OFFER:
|
||||
|
@ -27,6 +27,8 @@ const CommandType = Object.freeze({
|
||||
LAUNCH_ACK: "launch-ack", // { presentationId: <string> }
|
||||
TERMINATE: "terminate", // { presentationId: <string> }
|
||||
TERMINATE_ACK: "terminate-ack", // { presentationId: <string> }
|
||||
RECONNECT: "reconnect", // { presentationId: <string> }
|
||||
RECONNECT_ACK: "reconnect-ack", // { presentationId: <string> }
|
||||
// session transport establishment
|
||||
OFFER: "offer", // { offer: <json> }
|
||||
ANSWER: "answer", // { answer: <json> }
|
||||
|
@ -24,6 +24,7 @@ TestPresentationControlChannel.prototype = {
|
||||
disconnect: function() {},
|
||||
launch: function() {},
|
||||
terminate: function() {},
|
||||
reconnect: function() {},
|
||||
set listener(listener) {},
|
||||
get listener() {},
|
||||
};
|
||||
@ -161,6 +162,25 @@ function terminateRequest() {
|
||||
testControlChannel, testIsFromReceiver);
|
||||
}
|
||||
|
||||
function reconnectRequest() {
|
||||
let testUrl = 'http://www.example.org/';
|
||||
let testPresentationId = 'test-presentation-id';
|
||||
let testControlChannel = new TestPresentationControlChannel();
|
||||
Services.obs.addObserver(function observer(subject, topic, data) {
|
||||
Services.obs.removeObserver(observer, topic);
|
||||
|
||||
let request = subject.QueryInterface(Ci.nsIPresentationSessionRequest);
|
||||
|
||||
Assert.equal(request.device.id, testDevice.id, 'expected device');
|
||||
Assert.equal(request.url, testUrl, 'expected requesting URL');
|
||||
Assert.equal(request.presentationId, testPresentationId, 'expected presentation Id');
|
||||
|
||||
run_next_test();
|
||||
}, 'presentation-reconnect-request', false);
|
||||
manager.QueryInterface(Ci.nsIPresentationDeviceListener)
|
||||
.onReconnectRequest(testDevice, testUrl, testPresentationId, testControlChannel);
|
||||
}
|
||||
|
||||
function removeDevice() {
|
||||
Services.obs.addObserver(function observer(subject, topic, data) {
|
||||
Services.obs.removeObserver(observer, topic);
|
||||
@ -199,6 +219,7 @@ add_test(addDevice);
|
||||
add_test(updateDevice);
|
||||
add_test(sessionRequest);
|
||||
add_test(terminateRequest);
|
||||
add_test(reconnectRequest);
|
||||
add_test(removeDevice);
|
||||
add_test(removeProvider);
|
||||
|
||||
|
@ -67,22 +67,24 @@ function loopOfferAnser() {
|
||||
|
||||
function testPresentationServer() {
|
||||
let yayFuncs = makeJointSuccess(['controllerControlChannelClose',
|
||||
'presenterControlChannelClose']);
|
||||
let controllerControlChannel;
|
||||
'presenterControlChannelClose',
|
||||
'controllerControlChannelReconnect',
|
||||
'presenterControlChannelReconnect']);
|
||||
let presenterControlChannel;
|
||||
|
||||
pcs.listener = {
|
||||
|
||||
onSessionRequest: function(deviceInfo, url, presentationId, controlChannel) {
|
||||
controllerControlChannel = controlChannel;
|
||||
presenterControlChannel = controlChannel;
|
||||
Assert.equal(deviceInfo.id, pcs.id, 'expected device id');
|
||||
Assert.equal(deviceInfo.address, '127.0.0.1', 'expected device address');
|
||||
Assert.equal(url, 'http://example.com', 'expected url');
|
||||
Assert.equal(presentationId, 'testPresentationId', 'expected presentation id');
|
||||
|
||||
controllerControlChannel.listener = {
|
||||
presenterControlChannel.listener = {
|
||||
status: 'created',
|
||||
onOffer: function(aOffer) {
|
||||
Assert.equal(this.status, 'opened', '1. controllerControlChannel: get offer, send answer');
|
||||
Assert.equal(this.status, 'opened', '1. presenterControlChannel: get offer, send answer');
|
||||
this.status = 'onOffer';
|
||||
|
||||
let offer = aOffer.QueryInterface(Ci.nsIPresentationChannelDescription);
|
||||
@ -93,7 +95,7 @@ function testPresentationServer() {
|
||||
try {
|
||||
let tcpType = Ci.nsIPresentationChannelDescription.TYPE_TCP;
|
||||
let answer = new TestDescription(tcpType, [ANSWER_ADDRESS], ANSWER_PORT);
|
||||
controllerControlChannel.sendAnswer(answer);
|
||||
presenterControlChannel.sendAnswer(answer);
|
||||
} catch (e) {
|
||||
Assert.ok(false, 'sending answer fails' + e);
|
||||
}
|
||||
@ -102,28 +104,33 @@ function testPresentationServer() {
|
||||
Assert.ok(false, 'get answer');
|
||||
},
|
||||
onIceCandidate: function(aCandidate) {
|
||||
Assert.ok(true, '3. controllerControlChannel: get ice candidate, close channel');
|
||||
Assert.ok(true, '3. presenterControlChannel: get ice candidate, close channel');
|
||||
let recvCandidate = JSON.parse(aCandidate);
|
||||
for (let key in recvCandidate) {
|
||||
if (typeof(recvCandidate[key]) !== "function") {
|
||||
Assert.equal(recvCandidate[key], candidate[key], "key " + key + " should match.");
|
||||
}
|
||||
}
|
||||
controllerControlChannel.disconnect(CLOSE_CONTROL_CHANNEL_REASON);
|
||||
presenterControlChannel.disconnect(CLOSE_CONTROL_CHANNEL_REASON);
|
||||
},
|
||||
notifyConnected: function() {
|
||||
Assert.equal(this.status, 'created', '0. controllerControlChannel: opened');
|
||||
Assert.equal(this.status, 'created', '0. presenterControlChannel: opened');
|
||||
this.status = 'opened';
|
||||
},
|
||||
notifyDisconnected: function(aReason) {
|
||||
Assert.equal(this.status, 'onOffer', '4. controllerControlChannel: closed');
|
||||
Assert.equal(aReason, CLOSE_CONTROL_CHANNEL_REASON, 'controllerControlChannel notify closed');
|
||||
Assert.equal(this.status, 'onOffer', '4. presenterControlChannel: closed');
|
||||
Assert.equal(aReason, CLOSE_CONTROL_CHANNEL_REASON, 'presenterControlChannel notify closed');
|
||||
this.status = 'closed';
|
||||
yayFuncs.controllerControlChannelClose();
|
||||
},
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationControlChannelListener]),
|
||||
};
|
||||
},
|
||||
onReconnectRequest: function(deviceInfo, url, presentationId, controlChannel) {
|
||||
Assert.equal(url, 'http://example.com', 'expected url');
|
||||
Assert.equal(presentationId, 'testPresentationId', 'expected presentation id');
|
||||
yayFuncs.presenterControlChannelReconnect();
|
||||
},
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationControlServerListener]),
|
||||
};
|
||||
@ -135,15 +142,15 @@ function testPresentationServer() {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsITCPDeviceInfo]),
|
||||
};
|
||||
|
||||
let presenterControlChannel = pcs.connect(presenterDeviceInfo);
|
||||
let controllerControlChannel = pcs.connect(presenterDeviceInfo);
|
||||
|
||||
presenterControlChannel.listener = {
|
||||
controllerControlChannel.listener = {
|
||||
status: 'created',
|
||||
onOffer: function(offer) {
|
||||
Assert.ok(false, 'get offer');
|
||||
},
|
||||
onAnswer: function(aAnswer) {
|
||||
Assert.equal(this.status, 'opened', '2. presenterControlChannel: get answer, send ICE candidate');
|
||||
Assert.equal(this.status, 'opened', '2. controllerControlChannel: get answer, send ICE candidate');
|
||||
|
||||
let answer = aAnswer.QueryInterface(Ci.nsIPresentationChannelDescription);
|
||||
Assert.strictEqual(answer.tcpAddress.queryElementAt(0,Ci.nsISupportsCString).data,
|
||||
@ -155,27 +162,38 @@ function testPresentationServer() {
|
||||
sdpMid: "helloworld",
|
||||
sdpMLineIndex: 1
|
||||
};
|
||||
presenterControlChannel.sendIceCandidate(JSON.stringify(candidate));
|
||||
controllerControlChannel.sendIceCandidate(JSON.stringify(candidate));
|
||||
},
|
||||
onIceCandidate: function(aCandidate) {
|
||||
Assert.ok(false, 'get ICE candidate');
|
||||
},
|
||||
notifyConnected: function() {
|
||||
Assert.equal(this.status, 'created', '0. presenterControlChannel: opened, send offer');
|
||||
presenterControlChannel.launch('testPresentationId', 'http://example.com');
|
||||
Assert.equal(this.status, 'created', '0. controllerControlChannel: opened, send offer');
|
||||
controllerControlChannel.launch('testPresentationId', 'http://example.com');
|
||||
this.status = 'opened';
|
||||
try {
|
||||
let tcpType = Ci.nsIPresentationChannelDescription.TYPE_TCP;
|
||||
let offer = new TestDescription(tcpType, [OFFER_ADDRESS], OFFER_PORT)
|
||||
presenterControlChannel.sendOffer(offer);
|
||||
controllerControlChannel.sendOffer(offer);
|
||||
} catch (e) {
|
||||
Assert.ok(false, 'sending offer fails:' + e);
|
||||
}
|
||||
},
|
||||
notifyDisconnected: function(aReason) {
|
||||
this.status = 'closed';
|
||||
Assert.equal(aReason, CLOSE_CONTROL_CHANNEL_REASON, '4. presenterControlChannel notify closed');
|
||||
Assert.equal(aReason, CLOSE_CONTROL_CHANNEL_REASON, '4. controllerControlChannel notify closed');
|
||||
yayFuncs.presenterControlChannelClose();
|
||||
|
||||
let reconnectControllerControlChannel = pcs.connect(presenterDeviceInfo);
|
||||
reconnectControllerControlChannel.listener = {
|
||||
notifyConnected: function() {
|
||||
reconnectControllerControlChannel.reconnect('testPresentationId', 'http://example.com');
|
||||
},
|
||||
notifyReconnected: function() {
|
||||
yayFuncs.controllerControlChannelReconnect();
|
||||
},
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationControlChannelListener]),
|
||||
};
|
||||
},
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationControlChannelListener]),
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user