Bug 935723. Part 1. Decouple ICE state with ICE gathering state r=ekr,abr,jesup

This commit is contained in:
Byron Campen [:bwc] 2013-11-13 14:53:30 -08:00
Родитель aebc089f65
Коммит 67f0c411ba
14 изменённых файлов: 345 добавлений и 191 удалений

Просмотреть файл

@ -18,5 +18,4 @@
# Modifying this file will now automatically clobber the buildbot machines \o/
#
WebIDL dictionary modification requires clobber on Windows (bug 928195), part of
bug 906990.
Another Windows WebIDL clobber needed due to bug 928195

Просмотреть файл

@ -1016,21 +1016,8 @@ PeerConnectionObserver.prototype = {
},
// This method is primarily responsible for updating two attributes:
// iceGatheringState and iceConnectionState. These states are defined
// in the WebRTC specification as follows:
//
// iceGatheringState:
// ------------------
// new The object was just created, and no networking has occurred
// yet.
//
// gathering The ICE engine is in the process of gathering candidates for
// this RTCPeerConnection.
//
// complete The ICE engine has completed gathering. Events such as adding
// a new interface or a new TURN server will cause the state to
// go back to gathering.
// This method is primarily responsible for updating iceConnectionState.
// This state is defined in the WebRTC specification as follows:
//
// iceConnectionState:
// -------------------
@ -1064,36 +1051,38 @@ PeerConnectionObserver.prototype = {
// closed The ICE Agent has shut down and is no longer responding to
// STUN requests.
handleIceStateChanges: function(iceState) {
handleIceConnectionStateChange: function(iceState) {
var histogram = Services.telemetry.getHistogramById("WEBRTC_ICE_SUCCESS_RATE");
const STATE_MAP = {
IceGathering:
{ gathering: "gathering" },
IceWaiting:
{ connection: "new", gathering: "complete" },
IceChecking:
{ connection: "checking" },
IceConnected:
{ connection: "connected", success: true },
IceFailed:
{ connection: "failed", success: false }
};
// These are all the allowed inputs.
let transitions = STATE_MAP[iceState];
if ("connection" in transitions) {
this._dompc.changeIceConnectionState(transitions.connection);
if (iceState === 'failed') {
histogram.add(false);
}
if ("gathering" in transitions) {
this._dompc.changeIceGatheringState(transitions.gathering);
}
if ("success" in transitions) {
histogram.add(transitions.success);
if (this._dompc.iceConnectionState === 'checking' &&
(iceState === 'completed' || iceState === 'connected')) {
histogram.add(true);
}
this._dompc.changeIceConnectionState(iceState);
},
if (iceState == "IceWaiting") {
// This method is responsible for updating iceGatheringState. This
// state is defined in the WebRTC specification as follows:
//
// iceGatheringState:
// ------------------
// new The object was just created, and no networking has occurred
// yet.
//
// gathering The ICE engine is in the process of gathering candidates for
// this RTCPeerConnection.
//
// complete The ICE engine has completed gathering. Events such as adding
// a new interface or a new TURN server will cause the state to
// go back to gathering.
//
handleIceGatheringStateChange: function(gatheringState) {
this._dompc.changeIceGatheringState(gatheringState);
if (gatheringState === "complete") {
if (!this._dompc._trickleIce) {
// If we are not trickling, then the queue is in a pending state
// waiting for ICE gathering and executeNext frees it
@ -1115,8 +1104,12 @@ PeerConnectionObserver.prototype = {
this._dompc.signalingState);
break;
case "IceState":
this.handleIceStateChanges(this._dompc._pc.iceState);
case "IceConnectionState":
this.handleIceConnectionStateChange(this._dompc._pc.iceState);
break;
case "IceGatheringState":
this.handleIceGatheringStateChange(this._dompc._pc.iceGatheringState);
break;
case "SdpState":

Просмотреть файл

@ -70,7 +70,8 @@ interface PeerConnectionImpl {
readonly attribute DOMString localDescription;
readonly attribute DOMString remoteDescription;
readonly attribute PCImplIceState iceState;
readonly attribute PCImplIceConnectionState iceConnectionState;
readonly attribute PCImplIceGatheringState iceGatheringState;
readonly attribute PCImplReadyState readyState;
readonly attribute PCImplSignalingState signalingState;
readonly attribute PCImplSipccState sipccState;

Просмотреть файл

@ -31,11 +31,20 @@ enum PCImplSipccState {
"Started"
};
// TODO(ekr@rtfm.com): make this conform to the specifications
enum PCImplIceState {
"IceGathering",
"IceWaiting",
"IceChecking",
"IceConnected",
"IceFailed"
enum PCImplIceConnectionState {
"new",
"checking",
"connected",
"completed",
"failed",
"disconnected",
"closed"
};
// Deliberately identical to the values specified in webrtc
enum PCImplIceGatheringState {
"new",
"gathering",
"complete"
};

Просмотреть файл

@ -9,7 +9,8 @@
enum PCObserverStateType {
"None",
"ReadyState",
"IceState",
"IceConnectionState",
"IceGatheringState",
"SdpState",
"SipccState",
"SignalingState"

Просмотреть файл

@ -276,7 +276,7 @@ int NrIceCtx::stream_failed(void *obj, nr_ice_media_stream *stream) {
// Streams which do not exist should never fail.
MOZ_ASSERT(s);
ctx->SetState(ICE_CTX_FAILED);
ctx->SetConnectionState(ICE_CTX_FAILED);
s -> SignalFailed(s);
return 0;
}
@ -287,7 +287,7 @@ int NrIceCtx::ice_completed(void *obj, nr_ice_peer_ctx *pctx) {
// Get the ICE ctx
NrIceCtx *ctx = static_cast<NrIceCtx *>(obj);
ctx->SetState(ICE_CTX_OPEN);
ctx->SetConnectionState(ICE_CTX_OPEN);
return 0;
}
@ -551,7 +551,7 @@ nsresult NrIceCtx::StartGathering() {
if (ctx_->state != ICE_CTX_INIT) {
MOZ_MTLOG(ML_ERROR, "ICE ctx in the wrong state for gathering: '"
<< name_ << "'");
SetState(ICE_CTX_FAILED);
SetConnectionState(ICE_CTX_FAILED);
return NS_ERROR_FAILURE;
}
@ -561,11 +561,11 @@ nsresult NrIceCtx::StartGathering() {
if (r && r != R_WOULDBLOCK) {
MOZ_MTLOG(ML_ERROR, "Couldn't gather ICE candidates for '"
<< name_ << "'");
SetState(ICE_CTX_FAILED);
SetConnectionState(ICE_CTX_FAILED);
return NS_ERROR_FAILURE;
}
SetState(ICE_CTX_GATHERING);
SetGatheringState(ICE_CTX_GATHER_STARTED);
return NS_OK;
}
@ -630,7 +630,7 @@ nsresult NrIceCtx::StartChecks() {
if (r) {
MOZ_MTLOG(ML_ERROR, "Couldn't pair candidates on "
<< name_ << "'");
SetState(ICE_CTX_FAILED);
SetConnectionState(ICE_CTX_FAILED);
return NS_ERROR_FAILURE;
}
@ -642,11 +642,11 @@ nsresult NrIceCtx::StartChecks() {
} else {
MOZ_MTLOG(ML_ERROR, "Couldn't start peer checks on "
<< name_ << "'");
SetState(ICE_CTX_FAILED);
SetConnectionState(ICE_CTX_FAILED);
return NS_ERROR_FAILURE;
}
} else {
SetState(ICE_CTX_CHECKING);
SetConnectionState(ICE_CTX_CHECKING);
}
return NS_OK;
@ -656,7 +656,7 @@ nsresult NrIceCtx::StartChecks() {
void NrIceCtx::initialized_cb(NR_SOCKET s, int h, void *arg) {
NrIceCtx *ctx = static_cast<NrIceCtx *>(arg);
ctx->SetState(ICE_CTX_GATHERED);
ctx->SetGatheringState(ICE_CTX_GATHER_COMPLETE);
}
nsresult NrIceCtx::Finalize() {
@ -671,27 +671,26 @@ nsresult NrIceCtx::Finalize() {
return NS_OK;
}
void NrIceCtx::SetState(State state) {
if (state == state_)
void NrIceCtx::SetConnectionState(ConnectionState state) {
if (state == connection_state_)
return;
MOZ_MTLOG(ML_INFO, "NrIceCtx(" << name_ << "): state " <<
state_ << "->" << state);
state_ = state;
connection_state_ << "->" << state);
connection_state_ = state;
switch(state_) {
case ICE_CTX_GATHERED:
SignalGatheringCompleted(this);
break;
case ICE_CTX_OPEN:
SignalCompleted(this);
break;
case ICE_CTX_FAILED:
SignalFailed(this);
break;
default:
break;
}
SignalConnectionStateChange(this, state);
}
void NrIceCtx::SetGatheringState(GatheringState state) {
if (state == gathering_state_)
return;
MOZ_MTLOG(ML_DEBUG, "NrIceCtx(" << name_ << "): gathering state " <<
gathering_state_ << "->" << state);
gathering_state_ = state;
SignalGatheringStateChange(this, state);
}
} // close namespace

Просмотреть файл

@ -163,12 +163,15 @@ class NrIceTurnServer : public NrIceStunServer {
class NrIceCtx {
public:
enum State { ICE_CTX_INIT,
ICE_CTX_GATHERING,
ICE_CTX_GATHERED,
ICE_CTX_CHECKING,
ICE_CTX_OPEN,
ICE_CTX_FAILED
enum ConnectionState { ICE_CTX_INIT,
ICE_CTX_CHECKING,
ICE_CTX_OPEN,
ICE_CTX_FAILED
};
enum GatheringState { ICE_CTX_GATHER_INIT,
ICE_CTX_GATHER_STARTED,
ICE_CTX_GATHER_COMPLETE
};
enum Controlling { ICE_CONTROLLING,
@ -194,7 +197,14 @@ class NrIceCtx {
const std::string& name() const { return name_; }
// Current state
State state() const { return state_; }
ConnectionState connection_state() const {
return connection_state_;
}
// Current state
GatheringState gathering_state() const {
return gathering_state_;
}
// Get the global attributes
std::vector<std::string> GetGlobalAttributes();
@ -232,11 +242,10 @@ class NrIceCtx {
// Signals to indicate events. API users can (and should)
// register for these.
// TODO(ekr@rtfm.com): refactor this to be state change instead
// so we don't need to keep adding signals?
sigslot::signal1<NrIceCtx *> SignalGatheringCompleted; // Done gathering
sigslot::signal1<NrIceCtx *> SignalCompleted; // Done handshaking
sigslot::signal1<NrIceCtx *> SignalFailed; // Failure.
sigslot::signal2<NrIceCtx*, NrIceCtx::GatheringState>
SignalGatheringStateChange;
sigslot::signal2<NrIceCtx*, NrIceCtx::ConnectionState>
SignalConnectionStateChange;
// The thread to direct method calls to
nsCOMPtr<nsIEventTarget> thread() { return sts_target_; }
@ -246,7 +255,8 @@ class NrIceCtx {
private:
NrIceCtx(const std::string& name,
bool offerer)
: state_(ICE_CTX_INIT),
: connection_state_(ICE_CTX_INIT),
gathering_state_(ICE_CTX_GATHER_INIT),
name_(name),
offerer_(offerer),
streams_(),
@ -281,9 +291,13 @@ class NrIceCtx {
RefPtr<NrIceMediaStream> FindStream(nr_ice_media_stream *stream);
// Set the state
void SetState(State state);
void SetConnectionState(ConnectionState state);
State state_;
// Set the state
void SetGatheringState(GatheringState state);
ConnectionState connection_state_;
GatheringState gathering_state_;
const std::string name_;
bool offerer_;
std::vector<RefPtr<NrIceMediaStream> > streams_;

Просмотреть файл

@ -143,9 +143,12 @@ class IceTestPeer : public sigslot::has_slots<> {
expected_remote_type_(NrIceCandidate::ICE_HOST),
trickle_mode_(TRICKLE_NONE),
trickled_(0) {
ice_ctx_->SignalGatheringCompleted.connect(this,
&IceTestPeer::GatheringComplete);
ice_ctx_->SignalCompleted.connect(this, &IceTestPeer::IceCompleted);
ice_ctx_->SignalGatheringStateChange.connect(
this,
&IceTestPeer::GatheringStateChange);
ice_ctx_->SignalConnectionStateChange.connect(
this,
&IceTestPeer::ConnectionStateChange);
}
~IceTestPeer() {
@ -426,7 +429,13 @@ class IceTestPeer : public sigslot::has_slots<> {
}
// Handle events
void GatheringComplete(NrIceCtx *ctx) {
void GatheringStateChange(NrIceCtx* ctx,
NrIceCtx::GatheringState state) {
(void)ctx;
if (state != NrIceCtx::ICE_CTX_GATHER_COMPLETE) {
return;
}
std::cerr << "Gathering complete for " << name_ << std::endl;
gathering_complete_ = true;
@ -598,7 +607,12 @@ class IceTestPeer : public sigslot::has_slots<> {
DumpCandidatePairs(stream);
}
void IceCompleted(NrIceCtx *ctx) {
void ConnectionStateChange(NrIceCtx* ctx,
NrIceCtx::ConnectionState state) {
(void)ctx;
if (state != NrIceCtx::ICE_CTX_OPEN) {
return;
}
std::cerr << "ICE completed " << name_ << std::endl;
ice_complete_ = true;
}

Просмотреть файл

@ -237,8 +237,8 @@ class TransportTestPeer : public sigslot::has_slots<> {
nsresult res;
// Attach our slots
ice_ctx_->SignalGatheringCompleted.
connect(this, &TransportTestPeer::GatheringComplete);
ice_ctx_->SignalGatheringStateChange.
connect(this, &TransportTestPeer::GatheringStateChange);
char name[100];
snprintf(name, sizeof(name), "%s:stream%d", name_.c_str(),
@ -285,7 +285,7 @@ class TransportTestPeer : public sigslot::has_slots<> {
// If gathering is already complete, push the candidates over
if (gathering_complete_)
GatheringComplete(ice_ctx_);
GatheringComplete();
}
// New candidate
@ -294,9 +294,17 @@ class TransportTestPeer : public sigslot::has_slots<> {
candidates_[stream->name()].push_back(candidate);
}
void GatheringStateChange(NrIceCtx* ctx,
NrIceCtx::GatheringState state) {
(void)ctx;
if (state == NrIceCtx::ICE_CTX_GATHER_COMPLETE) {
GatheringComplete();
}
}
// Gathering complete, so send our candidates and start
// connecting on the other peer.
void GatheringComplete(NrIceCtx *ctx) {
void GatheringComplete() {
nsresult res;
// Don't send to the other side

Просмотреть файл

@ -456,7 +456,8 @@ PeerConnectionImpl::PeerConnectionImpl(const GlobalObject* aGlobal)
, mInternal(new Internal())
, mReadyState(PCImplReadyState::New)
, mSignalingState(PCImplSignalingState::SignalingStable)
, mIceState(PCImplIceState::IceGathering)
, mIceConnectionState(PCImplIceConnectionState::New)
, mIceGatheringState(PCImplIceGatheringState::New)
, mWindow(nullptr)
, mIdentity(nullptr)
, mSTSThread(nullptr)
@ -753,9 +754,12 @@ PeerConnectionImpl::Initialize(PeerConnectionObserver& aObserver,
mMedia = new PeerConnectionMedia(this);
// Connect ICE slots.
mMedia->SignalIceGatheringCompleted.connect(this, &PeerConnectionImpl::IceGatheringCompleted);
mMedia->SignalIceCompleted.connect(this, &PeerConnectionImpl::IceCompleted);
mMedia->SignalIceFailed.connect(this, &PeerConnectionImpl::IceFailed);
mMedia->SignalIceGatheringStateChange.connect(
this,
&PeerConnectionImpl::IceGatheringStateChange);
mMedia->SignalIceConnectionStateChange.connect(
this,
&PeerConnectionImpl::IceConnectionStateChange);
// Initialize the media object.
res = mMedia->Init(aConfiguration->getStunServers(),
@ -1418,12 +1422,22 @@ PeerConnectionImpl::SipccState(PCImplSipccState* aState)
}
NS_IMETHODIMP
PeerConnectionImpl::IceState(PCImplIceState* aState)
PeerConnectionImpl::IceConnectionState(PCImplIceConnectionState* aState)
{
PC_AUTO_ENTER_API_CALL_NO_CHECK();
MOZ_ASSERT(aState);
*aState = mIceState;
*aState = mIceConnectionState;
return NS_OK;
}
NS_IMETHODIMP
PeerConnectionImpl::IceGatheringState(PCImplIceGatheringState* aState)
{
PC_AUTO_ENTER_API_CALL_NO_CHECK();
MOZ_ASSERT(aState);
*aState = mIceGatheringState;
return NS_OK;
}
@ -1432,7 +1446,7 @@ PeerConnectionImpl::CheckApiState(bool assert_ice_ready) const
{
PC_AUTO_ENTER_API_CALL_NO_CHECK();
MOZ_ASSERT(mTrickle || !assert_ice_ready ||
(mIceState != PCImplIceState::IceGathering));
(mIceGatheringState == PCImplIceGatheringState::Complete));
if (mReadyState == PCImplReadyState::Closed)
return NS_ERROR_FAILURE;
@ -1630,72 +1644,97 @@ PeerConnectionImpl::GetHandle()
return mHandle;
}
static mozilla::dom::PCImplIceConnectionState
toDomIceConnectionState(NrIceCtx::ConnectionState state) {
switch (state) {
case NrIceCtx::ICE_CTX_INIT:
return PCImplIceConnectionState::New;
case NrIceCtx::ICE_CTX_CHECKING:
return PCImplIceConnectionState::Checking;
case NrIceCtx::ICE_CTX_OPEN:
return PCImplIceConnectionState::Connected;
case NrIceCtx::ICE_CTX_FAILED:
return PCImplIceConnectionState::Failed;
}
MOZ_CRASH();
}
static mozilla::dom::PCImplIceGatheringState
toDomIceGatheringState(NrIceCtx::GatheringState state) {
switch (state) {
case NrIceCtx::ICE_CTX_GATHER_INIT:
return PCImplIceGatheringState::New;
case NrIceCtx::ICE_CTX_GATHER_STARTED:
return PCImplIceGatheringState::Gathering;
case NrIceCtx::ICE_CTX_GATHER_COMPLETE:
return PCImplIceGatheringState::Complete;
}
MOZ_CRASH();
}
// This is called from the STS thread and so we need to thunk
// to the main thread.
void
PeerConnectionImpl::IceGatheringCompleted(NrIceCtx *aCtx)
{
(void) aCtx;
void PeerConnectionImpl::IceConnectionStateChange(
NrIceCtx* ctx,
NrIceCtx::ConnectionState state) {
(void)ctx;
// Do an async call here to unwind the stack. refptr keeps the PC alive.
nsRefPtr<PeerConnectionImpl> pc(this);
RUN_ON_THREAD(mThread,
WrapRunnable(pc,
&PeerConnectionImpl::IceStateChange_m,
PCImplIceState::IceWaiting),
&PeerConnectionImpl::IceConnectionStateChange_m,
toDomIceConnectionState(state)),
NS_DISPATCH_NORMAL);
}
void
PeerConnectionImpl::IceCompleted(NrIceCtx *aCtx)
PeerConnectionImpl::IceGatheringStateChange(
NrIceCtx* ctx,
NrIceCtx::GatheringState state)
{
(void) aCtx;
(void)ctx;
// Do an async call here to unwind the stack. refptr keeps the PC alive.
nsRefPtr<PeerConnectionImpl> pc(this);
RUN_ON_THREAD(mThread,
WrapRunnable(pc,
&PeerConnectionImpl::IceStateChange_m,
PCImplIceState::IceConnected),
NS_DISPATCH_NORMAL);
}
void
PeerConnectionImpl::IceFailed(NrIceCtx *aCtx)
{
(void) aCtx;
// Do an async call here to unwind the stack. refptr keeps the PC alive.
nsRefPtr<PeerConnectionImpl> pc(this);
RUN_ON_THREAD(mThread,
WrapRunnable(pc,
&PeerConnectionImpl::IceStateChange_m,
PCImplIceState::IceFailed),
&PeerConnectionImpl::IceGatheringStateChange_m,
toDomIceGatheringState(state)),
NS_DISPATCH_NORMAL);
}
nsresult
PeerConnectionImpl::IceStateChange_m(PCImplIceState aState)
PeerConnectionImpl::IceConnectionStateChange_m(PCImplIceConnectionState aState)
{
PC_AUTO_ENTER_API_CALL(false);
CSFLogDebug(logTag, "%s", __FUNCTION__);
mIceState = aState;
mIceConnectionState = aState;
switch (mIceState) {
case PCImplIceState::IceGathering:
STAMP_TIMECARD(mTimeCard, "Ice state: gathering");
// Would be nice if we had a means of converting one of these dom enums
// to a string that wasn't almost as much text as this switch statement...
switch (mIceConnectionState) {
case PCImplIceConnectionState::New:
STAMP_TIMECARD(mTimeCard, "Ice state: new");
break;
case PCImplIceState::IceWaiting:
STAMP_TIMECARD(mTimeCard, "Ice state: waiting");
break;
case PCImplIceState::IceChecking:
case PCImplIceConnectionState::Checking:
STAMP_TIMECARD(mTimeCard, "Ice state: checking");
break;
case PCImplIceState::IceConnected:
case PCImplIceConnectionState::Connected:
STAMP_TIMECARD(mTimeCard, "Ice state: connected");
break;
case PCImplIceState::IceFailed:
case PCImplIceConnectionState::Completed:
STAMP_TIMECARD(mTimeCard, "Ice state: completed");
break;
case PCImplIceConnectionState::Failed:
STAMP_TIMECARD(mTimeCard, "Ice state: failed");
break;
case PCImplIceConnectionState::Disconnected:
STAMP_TIMECARD(mTimeCard, "Ice state: disconnected");
break;
case PCImplIceConnectionState::Closed:
STAMP_TIMECARD(mTimeCard, "Ice state: closed");
break;
}
nsRefPtr<PeerConnectionObserver> pco = do_QueryObjectReferent(mPCObserver);
@ -1706,7 +1745,44 @@ PeerConnectionImpl::IceStateChange_m(PCImplIceState aState)
RUN_ON_THREAD(mThread,
WrapRunnable(pco,
&PeerConnectionObserver::OnStateChange,
PCObserverStateType::IceState,
PCObserverStateType::IceConnectionState,
rv, static_cast<JSCompartment*>(nullptr)),
NS_DISPATCH_NORMAL);
return NS_OK;
}
nsresult
PeerConnectionImpl::IceGatheringStateChange_m(PCImplIceGatheringState aState)
{
PC_AUTO_ENTER_API_CALL(false);
CSFLogDebug(logTag, "%s", __FUNCTION__);
mIceGatheringState = aState;
// Would be nice if we had a means of converting one of these dom enums
// to a string that wasn't almost as much text as this switch statement...
switch (mIceGatheringState) {
case PCImplIceGatheringState::New:
STAMP_TIMECARD(mTimeCard, "Ice gathering state: new");
break;
case PCImplIceGatheringState::Gathering:
STAMP_TIMECARD(mTimeCard, "Ice gathering state: gathering");
break;
case PCImplIceGatheringState::Complete:
STAMP_TIMECARD(mTimeCard, "Ice state: complete");
break;
}
nsRefPtr<PeerConnectionObserver> pco = do_QueryObjectReferent(mPCObserver);
if (!pco) {
return NS_OK;
}
WrappableJSErrorResult rv;
RUN_ON_THREAD(mThread,
WrapRunnable(pco,
&PeerConnectionObserver::OnStateChange,
PCObserverStateType::IceGatheringState,
rv, static_cast<JSCompartment*>(nullptr)),
NS_DISPATCH_NORMAL);
return NS_OK;

Просмотреть файл

@ -222,9 +222,10 @@ public:
virtual const std::string& GetHandle();
// ICE events
void IceGatheringCompleted(NrIceCtx *aCtx);
void IceCompleted(NrIceCtx *aCtx);
void IceFailed(NrIceCtx *aCtx);
void IceConnectionStateChange(NrIceCtx* ctx,
NrIceCtx::ConnectionState state);
void IceGatheringStateChange(NrIceCtx* ctx,
NrIceCtx::GatheringState state);
void IceStreamReady(NrIceMediaStream *aStream);
static void ListenThread(void *aData);
@ -290,12 +291,14 @@ public:
NS_IMETHODIMP CreateAnswer(const MediaConstraintsExternal& aConstraints);
NS_IMETHODIMP SetLocalDescription (int32_t aAction, const char* aSDP);
void SetLocalDescription (int32_t aAction, const nsAString& aSDP, ErrorResult &rv)
{
rv = SetLocalDescription(aAction, NS_ConvertUTF16toUTF8(aSDP).get());
}
NS_IMETHODIMP SetRemoteDescription (int32_t aAction, const char* aSDP);
void SetRemoteDescription (int32_t aAction, const nsAString& aSDP, ErrorResult &rv)
{
rv = SetRemoteDescription(aAction, NS_ConvertUTF16toUTF8(aSDP).get());
@ -316,6 +319,7 @@ public:
NS_IMETHODIMP AddIceCandidate(const char* aCandidate, const char* aMid,
unsigned short aLevel);
void AddIceCandidate(const nsAString& aCandidate, const nsAString& aMid,
unsigned short aLevel, ErrorResult &rv)
{
@ -324,6 +328,7 @@ public:
}
NS_IMETHODIMP CloseStreams();
void CloseStreams(ErrorResult &rv)
{
rv = CloseStreams();
@ -342,6 +347,7 @@ public:
}
NS_IMETHODIMP GetLocalDescription(char** aSDP);
void GetLocalDescription(nsAString& aSDP)
{
char *tmp;
@ -351,6 +357,7 @@ public:
}
NS_IMETHODIMP GetRemoteDescription(char** aSDP);
void GetRemoteDescription(nsAString& aSDP)
{
char *tmp;
@ -360,6 +367,7 @@ public:
}
NS_IMETHODIMP ReadyState(mozilla::dom::PCImplReadyState* aState);
mozilla::dom::PCImplReadyState ReadyState()
{
mozilla::dom::PCImplReadyState state;
@ -368,6 +376,7 @@ public:
}
NS_IMETHODIMP SignalingState(mozilla::dom::PCImplSignalingState* aState);
mozilla::dom::PCImplSignalingState SignalingState()
{
mozilla::dom::PCImplSignalingState state;
@ -376,6 +385,7 @@ public:
}
NS_IMETHODIMP SipccState(mozilla::dom::PCImplSipccState* aState);
mozilla::dom::PCImplSipccState SipccState()
{
mozilla::dom::PCImplSipccState state;
@ -383,15 +393,28 @@ public:
return state;
}
NS_IMETHODIMP IceState(mozilla::dom::PCImplIceState* aState);
mozilla::dom::PCImplIceState IceState()
NS_IMETHODIMP IceConnectionState(
mozilla::dom::PCImplIceConnectionState* aState);
mozilla::dom::PCImplIceConnectionState IceConnectionState()
{
mozilla::dom::PCImplIceState state;
IceState(&state);
mozilla::dom::PCImplIceConnectionState state;
IceConnectionState(&state);
return state;
}
NS_IMETHODIMP IceGatheringState(
mozilla::dom::PCImplIceGatheringState* aState);
mozilla::dom::PCImplIceGatheringState IceGatheringState()
{
mozilla::dom::PCImplIceGatheringState state;
IceGatheringState(&state);
return state;
}
NS_IMETHODIMP Close();
void Close(ErrorResult &rv)
{
rv = Close();
@ -489,7 +512,10 @@ private:
void ShutdownMedia();
// ICE callbacks run on the right thread.
nsresult IceStateChange_m(mozilla::dom::PCImplIceState aState);
nsresult IceConnectionStateChange_m(
mozilla::dom::PCImplIceConnectionState aState);
nsresult IceGatheringStateChange_m(
mozilla::dom::PCImplIceGatheringState aState);
#ifdef MOZILLA_INTERNAL_API
// Fills in an RTCStatsReportInternal. Must be run on STS.
@ -521,7 +547,8 @@ private:
mozilla::dom::PCImplSignalingState mSignalingState;
// ICE State
mozilla::dom::PCImplIceState mIceState;
mozilla::dom::PCImplIceConnectionState mIceConnectionState;
mozilla::dom::PCImplIceGatheringState mIceGatheringState;
nsCOMPtr<nsIThread> mThread;
// TODO: Remove if we ever properly wire PeerConnection for cycle-collection.

Просмотреть файл

@ -178,12 +178,12 @@ nsresult PeerConnectionMedia::Init(const std::vector<NrIceStunServer>& stun_serv
CSFLogError(logTag, "%s: Failed to get dns resolver", __FUNCTION__);
return rv;
}
mIceCtx->SignalGatheringCompleted.connect(this,
&PeerConnectionMedia::IceGatheringCompleted);
mIceCtx->SignalCompleted.connect(this,
&PeerConnectionMedia::IceCompleted);
mIceCtx->SignalFailed.connect(this,
&PeerConnectionMedia::IceFailed);
mIceCtx->SignalGatheringStateChange.connect(
this,
&PeerConnectionMedia::IceGatheringStateChange);
mIceCtx->SignalConnectionStateChange.connect(
this,
&PeerConnectionMedia::IceConnectionStateChange);
// Create three streams to start with.
// One each for audio, video and DataChannel
@ -424,24 +424,17 @@ PeerConnectionMedia::AddRemoteStreamHint(int aIndex, bool aIsVideo)
void
PeerConnectionMedia::IceGatheringCompleted(NrIceCtx *aCtx)
PeerConnectionMedia::IceGatheringStateChange(NrIceCtx* ctx,
NrIceCtx::GatheringState state)
{
MOZ_ASSERT(aCtx);
SignalIceGatheringCompleted(aCtx);
SignalIceGatheringStateChange(ctx, state);
}
void
PeerConnectionMedia::IceCompleted(NrIceCtx *aCtx)
PeerConnectionMedia::IceConnectionStateChange(NrIceCtx* ctx,
NrIceCtx::ConnectionState state)
{
MOZ_ASSERT(aCtx);
SignalIceCompleted(aCtx);
}
void
PeerConnectionMedia::IceFailed(NrIceCtx *aCtx)
{
MOZ_ASSERT(aCtx);
SignalIceFailed(aCtx);
SignalIceConnectionStateChange(ctx, state);
}
void

Просмотреть файл

@ -334,9 +334,10 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
}
// ICE state signals
sigslot::signal1<mozilla::NrIceCtx *> SignalIceGatheringCompleted; // Done gathering
sigslot::signal1<mozilla::NrIceCtx *> SignalIceCompleted; // Done handshaking
sigslot::signal1<mozilla::NrIceCtx *> SignalIceFailed; // Self explanatory
sigslot::signal2<mozilla::NrIceCtx*, mozilla::NrIceCtx::GatheringState>
SignalIceGatheringStateChange;
sigslot::signal2<mozilla::NrIceCtx*, mozilla::NrIceCtx::ConnectionState>
SignalIceConnectionStateChange;
private:
// Shutdown media transport. Must be called on STS thread.
@ -347,9 +348,10 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
void SelfDestruct_m();
// ICE events
void IceGatheringCompleted(mozilla::NrIceCtx *aCtx);
void IceCompleted(mozilla::NrIceCtx *aCtx);
void IceFailed(mozilla::NrIceCtx *aCtx);
void IceGatheringStateChange(mozilla::NrIceCtx* ctx,
mozilla::NrIceCtx::GatheringState state);
void IceConnectionStateChange(mozilla::NrIceCtx* ctx,
mozilla::NrIceCtx::ConnectionState state);
void IceStreamReady(mozilla::NrIceMediaStream *aStream);
// The parent PC

Просмотреть файл

@ -416,7 +416,8 @@ TestObserver::OnStateChange(PCObserverStateType state_type, ER&, void*)
{
nsresult rv;
PCImplReadyState gotready;
PCImplIceState gotice;
PCImplIceConnectionState gotice;
PCImplIceGatheringState goticegathering;
PCImplSipccState gotsipcc;
PCImplSignalingState gotsignaling;
@ -431,13 +432,21 @@ TestObserver::OnStateChange(PCObserverStateType state_type, ER&, void*)
<< PCImplReadyStateValues::strings[int(gotready)].value
<< std::endl;
break;
case PCObserverStateType::IceState:
rv = pc->IceState(&gotice);
case PCObserverStateType::IceConnectionState:
rv = pc->IceConnectionState(&gotice);
NS_ENSURE_SUCCESS(rv, rv);
std::cout << "ICE State: "
<< PCImplIceStateValues::strings[int(gotice)].value
std::cout << "ICE Connection State: "
<< PCImplIceConnectionStateValues::strings[int(gotice)].value
<< std::endl;
break;
case PCObserverStateType::IceGatheringState:
rv = pc->IceGatheringState(&goticegathering);
NS_ENSURE_SUCCESS(rv, rv);
std::cout
<< "ICE Gathering State: "
<< PCImplIceGatheringStateValues::strings[int(goticegathering)].value
<< std::endl;
break;
case PCObserverStateType::SdpState:
std::cout << "SDP State: " << std::endl;
// NS_ENSURE_SUCCESS(rv, rv);
@ -458,6 +467,7 @@ TestObserver::OnStateChange(PCObserverStateType state_type, ER&, void*)
break;
default:
// Unknown State
MOZ_CRASH("Unknown state change type.");
break;
}
@ -759,16 +769,19 @@ class SignalingAgent {
}
void WaitForGather() {
ASSERT_TRUE_WAIT(ice_state() == PCImplIceState::IceWaiting, 5000);
ASSERT_TRUE_WAIT(ice_gathering_state() == PCImplIceGatheringState::Complete,
5000);
std::cout << name << ": Init Complete" << std::endl;
}
bool WaitForGatherAllowFail() {
EXPECT_TRUE_WAIT(ice_state() == PCImplIceState::IceWaiting ||
ice_state() == PCImplIceState::IceFailed, 5000);
EXPECT_TRUE_WAIT(
ice_gathering_state() == PCImplIceGatheringState::Complete ||
ice_connection_state() == PCImplIceConnectionState::Failed,
5000);
if (ice_state() == PCImplIceState::IceFailed) {
if (ice_connection_state() == PCImplIceConnectionState::Failed) {
std::cout << name << ": Init Failed" << std::endl;
return false;
}
@ -782,9 +795,14 @@ class SignalingAgent {
return pc->SipccState();
}
PCImplIceState ice_state()
PCImplIceConnectionState ice_connection_state()
{
return pc->IceState();
return pc->IceConnectionState();
}
PCImplIceGatheringState ice_gathering_state()
{
return pc->IceGatheringState();
}
PCImplSignalingState signaling_state()
@ -1041,7 +1059,7 @@ void CreateAnswer(sipcc::MediaConstraints& constraints, std::string offer,
bool IceCompleted() {
return pc->IceState() == PCImplIceState::IceConnected;
return pc->IceConnectionState() == PCImplIceConnectionState::Connected;
}
void AddIceCandidate(const char* candidate, const char* mid, unsigned short level,