зеркало из https://github.com/mozilla/gecko-dev.git
Merge inbound to central, a=merge
This commit is contained in:
Коммит
a9e2fe1637
|
@ -805,7 +805,11 @@ getParentCB(AtkObject *aAtkObj)
|
|||
atkParent = GetWrapperFor(parent);
|
||||
} else {
|
||||
// Otherwise this should be the proxy for the tab's top level document.
|
||||
atkParent = AccessibleWrap::GetAtkObject(proxy->OuterDocOfRemoteBrowser());
|
||||
Accessible* outerDocParent = proxy->OuterDocOfRemoteBrowser();
|
||||
NS_ASSERTION(outerDocParent, "this document should have an outerDoc as a parent");
|
||||
if (outerDocParent) {
|
||||
atkParent = AccessibleWrap::GetAtkObject(outerDocParent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -152,7 +152,11 @@
|
|||
work correctly on the menupopup. ContentSelectDropdown expects the
|
||||
popuponly menulist to be its immediate parent. -->
|
||||
<menulist popuponly="true" id="ContentSelectDropdown" hidden="true">
|
||||
<menupopup rolluponmousewheel="true"/>
|
||||
<menupopup rolluponmousewheel="true"
|
||||
#ifdef XP_WIN
|
||||
consumeoutsideclicks="false"
|
||||
#endif
|
||||
/>
|
||||
</menulist>
|
||||
|
||||
<!-- for invalid form error message -->
|
||||
|
|
|
@ -73,10 +73,6 @@
|
|||
#include "SurfaceCache.h"
|
||||
#include "gfxPrefs.h"
|
||||
|
||||
#if defined(MOZ_CRASHREPORTER)
|
||||
#include "nsExceptionHandler.h"
|
||||
#endif
|
||||
|
||||
#include "VsyncSource.h"
|
||||
#include "DriverInitCrashDetection.h"
|
||||
|
||||
|
@ -1721,16 +1717,12 @@ bool DoesD3D11DeviceWork(ID3D11Device *device)
|
|||
gfxWindowsPlatform::GetDLLVersion(L"dlumd32.dll", displayLinkModuleVersionString);
|
||||
uint64_t displayLinkModuleVersion;
|
||||
if (!ParseDriverVersion(displayLinkModuleVersionString, &displayLinkModuleVersion)) {
|
||||
#if defined(MOZ_CRASHREPORTER)
|
||||
CrashReporter::AppendAppNotesToCrashReport(NS_LITERAL_CSTRING("DisplayLink: could not parse version\n"));
|
||||
#endif
|
||||
gfxCriticalError() << "DisplayLink: could not parse version";
|
||||
gANGLESupportsD3D11 = false;
|
||||
return false;
|
||||
}
|
||||
if (displayLinkModuleVersion <= V(8,6,1,36484)) {
|
||||
#if defined(MOZ_CRASHREPORTER)
|
||||
CrashReporter::AppendAppNotesToCrashReport(NS_LITERAL_CSTRING("DisplayLink: too old version\n"));
|
||||
#endif
|
||||
gfxCriticalError(CriticalLog::DefaultOptions(false)) << "DisplayLink: too old version";
|
||||
gANGLESupportsD3D11 = false;
|
||||
return false;
|
||||
}
|
||||
|
@ -1762,9 +1754,7 @@ bool DoesD3D11TextureSharingWorkInternal(ID3D11Device *device, DXGI_FORMAT forma
|
|||
gfxInfo->GetAdapterVendorID(vendorID);
|
||||
gfxInfo->GetAdapterVendorID2(vendorID2);
|
||||
if (vendorID.EqualsLiteral("0x8086") && vendorID2.IsEmpty()) {
|
||||
#if defined(MOZ_CRASHREPORTER)
|
||||
CrashReporter::AppendAppNotesToCrashReport(NS_LITERAL_CSTRING("Unexpected Intel/AMD dual-GPU setup\n"));
|
||||
#endif
|
||||
gfxCriticalError(CriticalLog::DefaultOptions(false)) << "Unexpected Intel/AMD dual-GPU setup";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1804,6 +1794,7 @@ bool DoesD3D11TextureSharingWorkInternal(ID3D11Device *device, DXGI_FORMAT forma
|
|||
if (FAILED(device->OpenSharedResource(shareHandle, __uuidof(ID3D11Resource),
|
||||
getter_AddRefs(sharedResource))))
|
||||
{
|
||||
gfxCriticalError(CriticalLog::DefaultOptions(false)) << "OpenSharedResource failed for format " << format;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1817,9 +1808,7 @@ bool DoesD3D11TextureSharingWorkInternal(ID3D11Device *device, DXGI_FORMAT forma
|
|||
|
||||
// This if(FAILED()) is the one that actually fails on systems affected by bug 1083071.
|
||||
if (FAILED(device->CreateShaderResourceView(sharedTexture, NULL, byRef(sharedView)))) {
|
||||
#if defined(MOZ_CRASHREPORTER)
|
||||
CrashReporter::AppendAppNotesToCrashReport(NS_LITERAL_CSTRING("CreateShaderResourceView failed\n"));
|
||||
#endif
|
||||
gfxCriticalError(CriticalLog::DefaultOptions(false)) << "CreateShaderResourceView failed for format" << format;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1843,15 +1832,19 @@ bool DoesD3D11AlphaTextureSharingWork(ID3D11Device *device)
|
|||
{
|
||||
nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
|
||||
if (gfxInfo) {
|
||||
// Disable texture sharing if we're blocking d2d since that's the only other time we use it
|
||||
// and it might be broken.
|
||||
int32_t status;
|
||||
if (NS_SUCCEEDED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_DIRECT2D, &status))) {
|
||||
if (status != nsIGfxInfo::FEATURE_STATUS_OK) {
|
||||
// A8 texture sharing crashes on this intel driver version (and no others)
|
||||
// so just avoid using it in that case.
|
||||
nsString adapterVendor;
|
||||
nsString driverVersion;
|
||||
gfxInfo->GetAdapterVendorID(adapterVendor);
|
||||
gfxInfo->GetAdapterDriverVersion(driverVersion);
|
||||
|
||||
nsAString &intelVendorID = (nsAString &)GfxDriverInfo::GetDeviceVendor(VendorIntel);
|
||||
if (adapterVendor.Equals(intelVendorID, nsCaseInsensitiveStringComparator()) &&
|
||||
driverVersion.Equals(NS_LITERAL_STRING("8.15.10.2086"))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return DoesD3D11TextureSharingWorkInternal(device, DXGI_FORMAT_A8_UNORM, D3D11_BIND_SHADER_RESOURCE);
|
||||
}
|
||||
|
@ -1951,6 +1944,8 @@ gfxWindowsPlatform::InitD3D11Devices()
|
|||
featureLevels.Elements(), featureLevels.Length(),
|
||||
D3D11_SDK_VERSION, byRef(mD3D11Device), nullptr, nullptr);
|
||||
} MOZ_SEH_EXCEPT (EXCEPTION_EXECUTE_HANDLER) {
|
||||
gfxCriticalError() << "Crash during D3D11 device creation";
|
||||
|
||||
if (gfxPrefs::LayersD3D11DisableWARP()) {
|
||||
return;
|
||||
}
|
||||
|
@ -1960,6 +1955,7 @@ gfxWindowsPlatform::InitD3D11Devices()
|
|||
}
|
||||
|
||||
if (FAILED(hr) || !DoesD3D11DeviceWork(mD3D11Device)) {
|
||||
gfxCriticalError() << "D3D11 device creation failed" << hexa(hr);
|
||||
if (gfxPrefs::LayersD3D11DisableWARP()) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -28,8 +28,9 @@ MacroAssembler::setFramePushed(uint32_t framePushed)
|
|||
}
|
||||
|
||||
void
|
||||
MacroAssembler::adjustFrame(int value)
|
||||
MacroAssembler::adjustFrame(int32_t value)
|
||||
{
|
||||
MOZ_ASSERT_IF(value < 0, framePushed_ >= uint32_t(-value));
|
||||
setFramePushed(framePushed_ + value);
|
||||
}
|
||||
|
||||
|
@ -37,7 +38,8 @@ void
|
|||
MacroAssembler::implicitPop(uint32_t bytes)
|
||||
{
|
||||
MOZ_ASSERT(bytes % sizeof(intptr_t) == 0);
|
||||
adjustFrame(-bytes);
|
||||
MOZ_ASSERT(bytes <= INT32_MAX);
|
||||
adjustFrame(-int32_t(bytes));
|
||||
}
|
||||
|
||||
// ===============================================================
|
||||
|
|
|
@ -280,7 +280,7 @@ class MacroAssembler : public MacroAssemblerSpecific
|
|||
|
||||
inline uint32_t framePushed() const;
|
||||
inline void setFramePushed(uint32_t framePushed);
|
||||
inline void adjustFrame(int value);
|
||||
inline void adjustFrame(int32_t value);
|
||||
|
||||
// Adjust the frame, to account for implicit modification of the stack
|
||||
// pointer, such that callee can remove arguments on the behalf of the
|
||||
|
|
|
@ -3340,7 +3340,7 @@ bool RangeAnalysis::tryRemovingGuards()
|
|||
MDefinitionVector guards(alloc());
|
||||
|
||||
for (ReversePostorderIterator block = graph_.rpoBegin(); block != graph_.rpoEnd(); block++) {
|
||||
for (MInstructionReverseIterator iter = block->rbegin(); iter != block->rend(); iter++) {
|
||||
for (MDefinitionIterator iter(*block); iter; iter++) {
|
||||
if (!iter->isGuardRangeBailouts())
|
||||
continue;
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include "jsprf.h"
|
||||
|
||||
#include "mozilla/Snprintf.h"
|
||||
#include "mozilla/Vector.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
|
@ -286,8 +287,6 @@ static bool cvt_ll(SprintfState* ss, int64_t num, int width, int prec, int radix
|
|||
/*
|
||||
* Convert a double precision floating point number into its printable
|
||||
* form.
|
||||
*
|
||||
* XXX stop using sprintf to convert floating point
|
||||
*/
|
||||
static bool cvt_f(SprintfState* ss, double d, const char* fmt0, const char* fmt1)
|
||||
{
|
||||
|
@ -303,7 +302,7 @@ static bool cvt_f(SprintfState* ss, double d, const char* fmt0, const char* fmt1
|
|||
js_memcpy(fin, fmt0, (size_t)amount);
|
||||
fin[amount] = 0;
|
||||
|
||||
// Convert floating point using the native sprintf code
|
||||
// Convert floating point using the native snprintf code
|
||||
#ifdef DEBUG
|
||||
{
|
||||
const char* p = fin;
|
||||
|
@ -313,12 +312,7 @@ static bool cvt_f(SprintfState* ss, double d, const char* fmt0, const char* fmt1
|
|||
}
|
||||
}
|
||||
#endif
|
||||
sprintf(fout, fin, d);
|
||||
|
||||
// This assert will catch overflow's of fout, when building with
|
||||
// debugging on. At least this way we can track down the evil piece
|
||||
// of calling code and fix it!
|
||||
MOZ_ASSERT(strlen(fout) < sizeof(fout));
|
||||
snprintf_literal(fout, fin, d);
|
||||
|
||||
return (*ss->stuff)(ss, fout, strlen(fout));
|
||||
}
|
||||
|
|
|
@ -533,19 +533,18 @@ JsepSessionImpl::SetupBundle(Sdp* sdp) const
|
|||
}
|
||||
|
||||
nsresult
|
||||
JsepSessionImpl::FinalizeTransportAttributes(Sdp* offer)
|
||||
JsepSessionImpl::SetupTransportAttributes(const Sdp& newOffer, Sdp* local)
|
||||
{
|
||||
const Sdp* oldAnswer = GetAnswer();
|
||||
|
||||
if (oldAnswer) {
|
||||
// Renegotiation, we might have transport attributes to copy over
|
||||
for (size_t i = 0; i < oldAnswer->GetMediaSectionCount(); ++i) {
|
||||
if (!MsectionIsDisabled(offer->GetMediaSection(i)) &&
|
||||
!MsectionIsDisabled(oldAnswer->GetMediaSection(i)) &&
|
||||
!IsBundleSlave(*oldAnswer, i)) {
|
||||
if (!MsectionIsDisabled(local->GetMediaSection(i)) &&
|
||||
AreOldTransportParamsValid(*oldAnswer, newOffer, i)) {
|
||||
nsresult rv = CopyTransportParams(
|
||||
mCurrentLocalDescription->GetMediaSection(i),
|
||||
&offer->GetMediaSection(i));
|
||||
&local->GetMediaSection(i));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
|
@ -769,7 +768,7 @@ JsepSessionImpl::CreateOffer(const JsepOfferOptions& options,
|
|||
|
||||
SetupBundle(sdp.get());
|
||||
|
||||
rv = FinalizeTransportAttributes(sdp.get());
|
||||
rv = SetupTransportAttributes(*sdp, sdp.get());
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
*offer = sdp->ToString();
|
||||
|
@ -1022,6 +1021,9 @@ JsepSessionImpl::CreateAnswer(const JsepAnswerOptions& options,
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
rv = SetupTransportAttributes(offer, sdp.get());
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
*answer = sdp->ToString();
|
||||
mGeneratedLocalDescription = Move(sdp);
|
||||
|
||||
|
@ -1416,6 +1418,7 @@ JsepSessionImpl::SetLocalDescriptionAnswer(JsepSdpType type,
|
|||
|
||||
mCurrentRemoteDescription = Move(mPendingRemoteDescription);
|
||||
mCurrentLocalDescription = Move(mPendingLocalDescription);
|
||||
mWasOffererLastTime = mIsOfferer;
|
||||
|
||||
SetState(kJsepStateStable);
|
||||
return NS_OK;
|
||||
|
@ -1865,6 +1868,37 @@ JsepSessionImpl::FinalizeTransport(const SdpAttributeList& remote,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
JsepSessionImpl::AreOldTransportParamsValid(const Sdp& oldAnswer,
|
||||
const Sdp& newOffer,
|
||||
size_t level)
|
||||
{
|
||||
if (MsectionIsDisabled(oldAnswer.GetMediaSection(level)) ||
|
||||
MsectionIsDisabled(newOffer.GetMediaSection(level))) {
|
||||
// Obvious
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsBundleSlave(oldAnswer, level)) {
|
||||
// The transport attributes on this m-section were thrown away, because it
|
||||
// was bundled.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (newOffer.GetMediaSection(level).GetAttributeList().HasAttribute(
|
||||
SdpAttribute::kBundleOnlyAttribute) &&
|
||||
IsBundleSlave(newOffer, level)) {
|
||||
// It never makes sense to put transport attributes in a bundle-only
|
||||
// m-section
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO(bug 906986): Check for ICE restart (will need to pass the offerer's
|
||||
// old SDP to compare it against |newOffer|)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
nsresult
|
||||
JsepSessionImpl::AddTransportAttributes(SdpMediaSection* msection,
|
||||
SdpSetupAttribute::Role dtlsRole)
|
||||
|
@ -1886,33 +1920,43 @@ JsepSessionImpl::AddTransportAttributes(SdpMediaSection* msection,
|
|||
}
|
||||
|
||||
nsresult
|
||||
JsepSessionImpl::CopyTransportParams(const SdpMediaSection& source,
|
||||
SdpMediaSection* dest)
|
||||
JsepSessionImpl::CopyTransportParams(const SdpMediaSection& oldLocal,
|
||||
SdpMediaSection* newLocal)
|
||||
{
|
||||
// Copy over m-section details
|
||||
dest->SetPort(source.GetPort());
|
||||
dest->GetConnection() = source.GetConnection();
|
||||
newLocal->SetPort(oldLocal.GetPort());
|
||||
newLocal->GetConnection() = oldLocal.GetConnection();
|
||||
|
||||
auto& sourceAttrs = source.GetAttributeList();
|
||||
auto& destAttrs = dest->GetAttributeList();
|
||||
const SdpAttributeList& oldLocalAttrs = oldLocal.GetAttributeList();
|
||||
SdpAttributeList& newLocalAttrs = newLocal->GetAttributeList();
|
||||
|
||||
// If newLocal is an offer, this will be the number of components we used
|
||||
// last time, and if it is an answer, this will be the number of components
|
||||
// we know we're using now.
|
||||
size_t components = mTransports[oldLocal.GetLevel()]->mComponents;
|
||||
|
||||
// Now we copy over attributes that won't be added by the usual logic
|
||||
if (sourceAttrs.HasAttribute(SdpAttribute::kCandidateAttribute)) {
|
||||
auto* candidateAttrs =
|
||||
new SdpMultiStringAttribute(SdpAttribute::kCandidateAttribute);
|
||||
candidateAttrs->mValues = sourceAttrs.GetCandidate();
|
||||
destAttrs.SetAttribute(candidateAttrs);
|
||||
if (oldLocalAttrs.HasAttribute(SdpAttribute::kCandidateAttribute) &&
|
||||
components) {
|
||||
UniquePtr<SdpMultiStringAttribute> candidateAttrs(
|
||||
new SdpMultiStringAttribute(SdpAttribute::kCandidateAttribute));
|
||||
for (const std::string& candidate : oldLocalAttrs.GetCandidate()) {
|
||||
size_t component;
|
||||
nsresult rv = GetComponent(candidate, &component);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (components >= component) {
|
||||
candidateAttrs->mValues.push_back(candidate);
|
||||
}
|
||||
}
|
||||
if (candidateAttrs->mValues.size()) {
|
||||
newLocalAttrs.SetAttribute(candidateAttrs.release());
|
||||
}
|
||||
}
|
||||
|
||||
if (sourceAttrs.HasAttribute(SdpAttribute::kEndOfCandidatesAttribute)) {
|
||||
destAttrs.SetAttribute(
|
||||
new SdpFlagAttribute(SdpAttribute::kEndOfCandidatesAttribute));
|
||||
}
|
||||
|
||||
if (!destAttrs.HasAttribute(SdpAttribute::kRtcpMuxAttribute) &&
|
||||
sourceAttrs.HasAttribute(SdpAttribute::kRtcpAttribute)) {
|
||||
// copy rtcp attribute
|
||||
destAttrs.SetAttribute(new SdpRtcpAttribute(sourceAttrs.GetRtcp()));
|
||||
if (components == 2 &&
|
||||
oldLocalAttrs.HasAttribute(SdpAttribute::kRtcpAttribute)) {
|
||||
// copy rtcp attribute if we had one that we are using
|
||||
newLocalAttrs.SetAttribute(new SdpRtcpAttribute(oldLocalAttrs.GetRtcp()));
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -2075,6 +2119,7 @@ JsepSessionImpl::SetRemoteDescriptionAnswer(JsepSdpType type,
|
|||
|
||||
mCurrentRemoteDescription = Move(mPendingRemoteDescription);
|
||||
mCurrentLocalDescription = Move(mPendingLocalDescription);
|
||||
mWasOffererLastTime = mIsOfferer;
|
||||
|
||||
SetState(kJsepStateStable);
|
||||
return NS_OK;
|
||||
|
@ -2567,6 +2612,21 @@ JsepSessionImpl::AddCandidateToSdp(Sdp* sdp,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// TODO(bug 1142105): Move this into an SDP helper class. Ideally, we'd like
|
||||
// to have real parse code and a useful representation of candidate attrs.
|
||||
nsresult
|
||||
JsepSessionImpl::GetComponent(const std::string& candidate, size_t* component)
|
||||
{
|
||||
unsigned int temp;
|
||||
int32_t result = PR_sscanf(candidate.c_str(), "%*s %u", &temp);
|
||||
if (result == 1) {
|
||||
*component = temp;
|
||||
return NS_OK;
|
||||
}
|
||||
JSEP_SET_ERROR("Malformed local ICE candidate: " << candidate);
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
nsresult
|
||||
JsepSessionImpl::AddRemoteIceCandidate(const std::string& candidate,
|
||||
const std::string& mid,
|
||||
|
@ -2636,6 +2696,7 @@ static void SetDefaultAddresses(const std::string& defaultCandidateAddr,
|
|||
{
|
||||
msection->GetConnection().SetAddress(defaultCandidateAddr);
|
||||
msection->SetPort(defaultCandidatePort);
|
||||
|
||||
if (!defaultRtcpCandidateAddr.empty()) {
|
||||
sdp::AddrType ipVersion = sdp::kIPv4;
|
||||
if (defaultRtcpCandidateAddr.find(':') != std::string::npos) {
|
||||
|
@ -2669,18 +2730,31 @@ JsepSessionImpl::EndOfLocalCandidates(const std::string& defaultCandidateAddr,
|
|||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
if (level >= sdp->GetMediaSectionCount()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
std::string defaultRtcpCandidateAddrCopy(defaultRtcpCandidateAddr);
|
||||
if (mState == kJsepStateStable && mTransports[level]->mComponents == 1) {
|
||||
// We know we're doing rtcp-mux by now. Don't create an rtcp attr.
|
||||
defaultRtcpCandidateAddrCopy = "";
|
||||
defaultRtcpCandidatePort = 0;
|
||||
}
|
||||
|
||||
SdpMediaSection& msection = sdp->GetMediaSection(level);
|
||||
|
||||
if (mState == kJsepStateStable) {
|
||||
// offer/answer is done. Do we actually incorporate these defaults?
|
||||
const Sdp* answer(GetAnswer());
|
||||
std::set<std::string> bundleMids;
|
||||
const SdpMediaSection* bundleMsection;
|
||||
nsresult rv = GetNegotiatedBundleInfo(&bundleMids, &bundleMsection);
|
||||
nsresult rv = GetBundleInfo(*answer, &bundleMids, &bundleMsection);
|
||||
if (NS_FAILED(rv)) {
|
||||
MOZ_ASSERT(false);
|
||||
mLastError += " (This should have been caught sooner!)";
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (level < sdp->GetMediaSectionCount()) {
|
||||
SdpMediaSection& msection = sdp->GetMediaSection(level);
|
||||
|
||||
if (msection.GetAttributeList().HasAttribute(SdpAttribute::kMidAttribute) &&
|
||||
bundleMids.count(msection.GetAttributeList().GetMid())) {
|
||||
if (msection.GetLevel() != bundleMsection->GetLevel()) {
|
||||
|
@ -2698,15 +2772,16 @@ JsepSessionImpl::EndOfLocalCandidates(const std::string& defaultCandidateAddr,
|
|||
}
|
||||
SetDefaultAddresses(defaultCandidateAddr,
|
||||
defaultCandidatePort,
|
||||
defaultRtcpCandidateAddr,
|
||||
defaultRtcpCandidateAddrCopy,
|
||||
defaultRtcpCandidatePort,
|
||||
bundledMsection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SetDefaultAddresses(defaultCandidateAddr,
|
||||
defaultCandidatePort,
|
||||
defaultRtcpCandidateAddr,
|
||||
defaultRtcpCandidateAddrCopy,
|
||||
defaultRtcpCandidatePort,
|
||||
&msection);
|
||||
|
||||
|
@ -2718,7 +2793,6 @@ JsepSessionImpl::EndOfLocalCandidates(const std::string& defaultCandidateAddr,
|
|||
if (!mIsOfferer) {
|
||||
attrs.RemoveAttribute(SdpAttribute::kIceOptionsAttribute);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -3039,9 +3113,7 @@ JsepSessionImpl::MsectionIsDisabled(const SdpMediaSection& msection) const
|
|||
const Sdp*
|
||||
JsepSessionImpl::GetAnswer() const
|
||||
{
|
||||
MOZ_ASSERT(mState == kJsepStateStable);
|
||||
|
||||
return mIsOfferer ? mCurrentRemoteDescription.get()
|
||||
return mWasOffererLastTime ? mCurrentRemoteDescription.get()
|
||||
: mCurrentLocalDescription.get();
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ public:
|
|||
JsepSessionImpl(const std::string& name, UniquePtr<JsepUuidGenerator> uuidgen)
|
||||
: JsepSession(name),
|
||||
mIsOfferer(false),
|
||||
mWasOffererLastTime(false),
|
||||
mIceControlling(false),
|
||||
mRemoteIsIceLite(false),
|
||||
mSessionId(0),
|
||||
|
@ -240,7 +241,7 @@ private:
|
|||
const Sdp& oldAnswer,
|
||||
Sdp* newSdp);
|
||||
void SetupBundle(Sdp* sdp) const;
|
||||
nsresult FinalizeTransportAttributes(Sdp* sdp);
|
||||
nsresult SetupTransportAttributes(const Sdp& newOffer, Sdp* local);
|
||||
void SetupMsidSemantic(const std::vector<std::string>& msids, Sdp* sdp) const;
|
||||
nsresult GetIdsFromMsid(const Sdp& sdp,
|
||||
const SdpMediaSection& msection,
|
||||
|
@ -286,11 +287,15 @@ private:
|
|||
nsresult FinalizeTransport(const SdpAttributeList& remote,
|
||||
const SdpAttributeList& answer,
|
||||
const RefPtr<JsepTransport>& transport);
|
||||
bool AreOldTransportParamsValid(const Sdp& oldAnswer,
|
||||
const Sdp& newOffer,
|
||||
size_t level);
|
||||
|
||||
nsresult AddCandidateToSdp(Sdp* sdp,
|
||||
const std::string& candidate,
|
||||
const std::string& mid,
|
||||
uint16_t level);
|
||||
nsresult GetComponent(const std::string& candidate, size_t* component);
|
||||
|
||||
SdpMediaSection* FindMsectionByMid(Sdp& sdp,
|
||||
const std::string& mid) const;
|
||||
|
@ -330,6 +335,7 @@ private:
|
|||
std::vector<JsepTrackPair> mNegotiatedTrackPairs;
|
||||
|
||||
bool mIsOfferer;
|
||||
bool mWasOffererLastTime;
|
||||
bool mIceControlling;
|
||||
std::string mIceUfrag;
|
||||
std::string mIcePwd;
|
||||
|
|
|
@ -31,27 +31,8 @@
|
|||
#include "mtransport_test_utils.h"
|
||||
|
||||
namespace mozilla {
|
||||
static const char* kCandidates[] = {
|
||||
"0 1 UDP 9999 192.168.0.1 2000 typ host",
|
||||
"0 1 UDP 9999 192.168.0.1 2001 typ host",
|
||||
"0 1 UDP 9999 192.168.0.2 2002 typ srflx raddr 10.252.34.97 rport 53594",
|
||||
// Mix up order
|
||||
"0 1 UDP 9999 192.168.1.2 2012 typ srflx raddr 10.252.34.97 rport 53595",
|
||||
"0 1 UDP 9999 192.168.1.1 2010 typ host",
|
||||
"0 1 UDP 9999 192.168.1.1 2011 typ host"
|
||||
};
|
||||
|
||||
static const char* kRtcpCandidates[] = {
|
||||
"0 2 UDP 9999 192.168.0.1 3000 typ host",
|
||||
"0 2 UDP 9999 192.168.0.1 3001 typ host",
|
||||
"0 2 UDP 9999 192.168.0.2 3002 typ srflx raddr 10.252.34.97 rport 53596",
|
||||
// Mix up order
|
||||
"0 2 UDP 9999 192.168.1.2 3012 typ srflx raddr 10.252.34.97 rport 53597",
|
||||
"0 2 UDP 9999 192.168.1.1 3010 typ host",
|
||||
"0 2 UDP 9999 192.168.1.1 3011 typ host"
|
||||
};
|
||||
|
||||
static std::string kAEqualsCandidate("a=candidate:");
|
||||
const static size_t kNumCandidatesPerComponent = 3;
|
||||
|
||||
class JsepSessionTestBase : public ::testing::Test
|
||||
{
|
||||
|
@ -372,8 +353,7 @@ protected:
|
|||
}
|
||||
|
||||
UniquePtr<Sdp> GetParsedLocalDescription(const JsepSessionImpl& side) const {
|
||||
SipccSdpParser parser;
|
||||
return mozilla::Move(parser.Parse(side.GetLocalDescription()));
|
||||
return Parse(side.GetLocalDescription());
|
||||
}
|
||||
|
||||
SdpMediaSection* GetMsection(Sdp& sdp,
|
||||
|
@ -591,62 +571,203 @@ protected:
|
|||
DumpTrackPairs(mSessionAns);
|
||||
}
|
||||
|
||||
void
|
||||
GatherCandidates(JsepSession& session)
|
||||
typedef enum {
|
||||
RTP = 1,
|
||||
RTCP = 2
|
||||
} ComponentType;
|
||||
|
||||
class CandidateSet {
|
||||
public:
|
||||
CandidateSet() {}
|
||||
|
||||
void Gather(JsepSession& session,
|
||||
const std::vector<SdpMediaSection::MediaType>& types,
|
||||
ComponentType maxComponent = RTCP)
|
||||
{
|
||||
for (size_t level = 0; level < types.size(); ++level) {
|
||||
Gather(session, level, RTP);
|
||||
if (types[level] != SdpMediaSection::kApplication &&
|
||||
maxComponent == RTCP) {
|
||||
Gather(session, level, RTCP);
|
||||
}
|
||||
}
|
||||
FinishGathering(session);
|
||||
}
|
||||
|
||||
void Gather(JsepSession& session, size_t level, ComponentType component)
|
||||
{
|
||||
static uint16_t port = 1000;
|
||||
std::vector<std::string> candidates;
|
||||
for (size_t i = 0; i < kNumCandidatesPerComponent; ++i) {
|
||||
++port;
|
||||
std::ostringstream candidate;
|
||||
candidate << "0 " << static_cast<uint16_t>(component)
|
||||
<< " UDP 9999 192.168.0.1 " << port << " typ host";
|
||||
bool skipped;
|
||||
for (size_t i = 0; i < 3; ++i) {
|
||||
session.AddLocalIceCandidate(
|
||||
kAEqualsCandidate + kCandidates[i], "", 0, &skipped);
|
||||
session.AddLocalIceCandidate(
|
||||
kAEqualsCandidate + kRtcpCandidates[i], "", 0, &skipped);
|
||||
session.AddLocalIceCandidate(kAEqualsCandidate + candidate.str(),
|
||||
"", level, &skipped);
|
||||
if (!skipped) {
|
||||
mCandidatesToTrickle.push_back(
|
||||
std::pair<uint16_t, std::string>(
|
||||
level, kAEqualsCandidate + candidate.str()));
|
||||
candidates.push_back(candidate.str());
|
||||
}
|
||||
session.EndOfLocalCandidates("192.168.0.2", 2002, "192.168.0.2", 3002, 0);
|
||||
|
||||
for (size_t i = 3; i < 6; ++i) {
|
||||
session.AddLocalIceCandidate(
|
||||
kAEqualsCandidate + kCandidates[i], "", 1, &skipped);
|
||||
session.AddLocalIceCandidate(
|
||||
kAEqualsCandidate + kRtcpCandidates[i], "", 1, &skipped);
|
||||
}
|
||||
session.EndOfLocalCandidates("192.168.1.2", 2012, "192.168.1.2", 3012, 1);
|
||||
|
||||
std::cerr << "local SDP after candidates: "
|
||||
<< session.GetLocalDescription();
|
||||
}
|
||||
|
||||
void
|
||||
TrickleCandidates(JsepSession& session)
|
||||
// Stomp existing candidates
|
||||
mCandidates[level][component] = candidates;
|
||||
|
||||
// Stomp existing defaults
|
||||
mDefaultCandidates[level][component] =
|
||||
std::make_pair("192.168.0.1", port);
|
||||
}
|
||||
|
||||
void FinishGathering(JsepSession& session) const
|
||||
{
|
||||
for (size_t i = 0; i < 3; ++i) {
|
||||
session.AddRemoteIceCandidate(
|
||||
kAEqualsCandidate + kCandidates[i], "", 0);
|
||||
session.AddRemoteIceCandidate(
|
||||
kAEqualsCandidate + kRtcpCandidates[i], "", 0);
|
||||
// Copy so we can be terse and use []
|
||||
for (auto levelAndCandidates : mDefaultCandidates) {
|
||||
ASSERT_EQ(1U, levelAndCandidates.second.count(RTP));
|
||||
session.EndOfLocalCandidates(
|
||||
levelAndCandidates.second[RTP].first,
|
||||
levelAndCandidates.second[RTP].second,
|
||||
// Will be empty string if not present, which is how we indicate
|
||||
// that there is no default for RTCP
|
||||
levelAndCandidates.second[RTCP].first,
|
||||
levelAndCandidates.second[RTCP].second,
|
||||
levelAndCandidates.first);
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 3; i < 6; ++i) {
|
||||
session.AddRemoteIceCandidate(
|
||||
kAEqualsCandidate + kCandidates[i], "", 1);
|
||||
session.AddRemoteIceCandidate(
|
||||
kAEqualsCandidate + kRtcpCandidates[i], "", 1);
|
||||
}
|
||||
|
||||
std::cerr << "remote SDP after candidates: "
|
||||
<< session.GetRemoteDescription();
|
||||
}
|
||||
|
||||
void
|
||||
GatherOffererCandidates()
|
||||
void Trickle(JsepSession& session)
|
||||
{
|
||||
GatherCandidates(mSessionOff);
|
||||
for (const auto& levelAndCandidate : mCandidatesToTrickle) {
|
||||
session.AddRemoteIceCandidate(levelAndCandidate.second,
|
||||
"",
|
||||
levelAndCandidate.first);
|
||||
}
|
||||
mCandidatesToTrickle.clear();
|
||||
}
|
||||
|
||||
void
|
||||
TrickleOffererCandidates()
|
||||
void CheckRtpCandidates(bool expectRtpCandidates,
|
||||
const SdpMediaSection& msection,
|
||||
size_t transportLevel,
|
||||
const std::string& context) const
|
||||
{
|
||||
TrickleCandidates(mSessionAns);
|
||||
auto& attrs = msection.GetAttributeList();
|
||||
|
||||
ASSERT_EQ(expectRtpCandidates,
|
||||
attrs.HasAttribute(SdpAttribute::kCandidateAttribute))
|
||||
<< context << " (level " << msection.GetLevel() << ")";
|
||||
|
||||
if (expectRtpCandidates) {
|
||||
// Copy so we can be terse and use []
|
||||
auto expectedCandidates = mCandidates;
|
||||
ASSERT_LE(kNumCandidatesPerComponent,
|
||||
expectedCandidates[transportLevel][RTP].size());
|
||||
|
||||
auto& candidates = attrs.GetCandidate();
|
||||
ASSERT_LE(kNumCandidatesPerComponent, candidates.size())
|
||||
<< context << " (level " << msection.GetLevel() << ")";
|
||||
for (size_t i = 0; i < kNumCandidatesPerComponent; ++i) {
|
||||
ASSERT_EQ(expectedCandidates[transportLevel][RTP][i], candidates[i])
|
||||
<< context << " (level " << msection.GetLevel() << ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CheckRtcpCandidates(bool expectRtcpCandidates,
|
||||
const SdpMediaSection& msection,
|
||||
size_t transportLevel,
|
||||
const std::string& context) const
|
||||
{
|
||||
auto& attrs = msection.GetAttributeList();
|
||||
|
||||
if (expectRtcpCandidates) {
|
||||
// Copy so we can be terse and use []
|
||||
auto expectedCandidates = mCandidates;
|
||||
ASSERT_LE(kNumCandidatesPerComponent,
|
||||
expectedCandidates[transportLevel][RTCP].size());
|
||||
|
||||
ASSERT_TRUE(attrs.HasAttribute(SdpAttribute::kCandidateAttribute))
|
||||
<< context << " (level " << msection.GetLevel() << ")";
|
||||
auto& candidates = attrs.GetCandidate();
|
||||
ASSERT_EQ(kNumCandidatesPerComponent * 2, candidates.size())
|
||||
<< context << " (level " << msection.GetLevel() << ")";
|
||||
for (size_t i = 0; i < kNumCandidatesPerComponent; ++i) {
|
||||
ASSERT_EQ(expectedCandidates[transportLevel][RTCP][i],
|
||||
candidates[i + kNumCandidatesPerComponent])
|
||||
<< context << " (level " << msection.GetLevel() << ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CheckDefaultRtpCandidate(bool expectDefault,
|
||||
const SdpMediaSection& msection,
|
||||
size_t transportLevel,
|
||||
const std::string& context) const
|
||||
{
|
||||
if (expectDefault) {
|
||||
// Copy so we can be terse and use []
|
||||
auto defaultCandidates = mDefaultCandidates;
|
||||
ASSERT_EQ(defaultCandidates[transportLevel][RTP].first,
|
||||
msection.GetConnection().GetAddress())
|
||||
<< context << " (level " << msection.GetLevel() << ")";
|
||||
ASSERT_EQ(defaultCandidates[transportLevel][RTP].second,
|
||||
msection.GetPort())
|
||||
<< context << " (level " << msection.GetLevel() << ")";
|
||||
} else {
|
||||
ASSERT_EQ("0.0.0.0", msection.GetConnection().GetAddress())
|
||||
<< context << " (level " << msection.GetLevel() << ")";
|
||||
ASSERT_EQ(9U, msection.GetPort())
|
||||
<< context << " (level " << msection.GetLevel() << ")";
|
||||
}
|
||||
}
|
||||
|
||||
void CheckDefaultRtcpCandidate(bool expectDefault,
|
||||
const SdpMediaSection& msection,
|
||||
size_t transportLevel,
|
||||
const std::string& context) const
|
||||
{
|
||||
if (expectDefault) {
|
||||
// Copy so we can be terse and use []
|
||||
auto defaultCandidates = mDefaultCandidates;
|
||||
ASSERT_TRUE(msection.GetAttributeList().HasAttribute(
|
||||
SdpAttribute::kRtcpAttribute))
|
||||
<< context << " (level " << msection.GetLevel() << ")";
|
||||
auto& rtcpAttr = msection.GetAttributeList().GetRtcp();
|
||||
ASSERT_EQ(defaultCandidates[transportLevel][RTCP].second,
|
||||
rtcpAttr.mPort)
|
||||
<< context << " (level " << msection.GetLevel() << ")";
|
||||
ASSERT_EQ(sdp::kInternet, rtcpAttr.mNetType)
|
||||
<< context << " (level " << msection.GetLevel() << ")";
|
||||
ASSERT_EQ(sdp::kIPv4, rtcpAttr.mAddrType)
|
||||
<< context << " (level " << msection.GetLevel() << ")";
|
||||
ASSERT_EQ(defaultCandidates[transportLevel][RTCP].first,
|
||||
rtcpAttr.mAddress)
|
||||
<< context << " (level " << msection.GetLevel() << ")";
|
||||
} else {
|
||||
ASSERT_FALSE(msection.GetAttributeList().HasAttribute(
|
||||
SdpAttribute::kRtcpAttribute))
|
||||
<< context << " (level " << msection.GetLevel() << ")";
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
typedef size_t Level;
|
||||
typedef std::string Candidate;
|
||||
typedef std::string Address;
|
||||
typedef uint16_t Port;
|
||||
// Default candidates are put into the m-line, c-line, and rtcp
|
||||
// attribute for endpoints that don't support ICE.
|
||||
std::map<Level,
|
||||
std::map<ComponentType,
|
||||
std::pair<Address, Port>>> mDefaultCandidates;
|
||||
std::map<Level,
|
||||
std::map<ComponentType,
|
||||
std::vector<Candidate>>> mCandidates;
|
||||
// Level/candidate pairs that need to be trickled
|
||||
std::vector<std::pair<Level, Candidate>> mCandidatesToTrickle;
|
||||
};
|
||||
|
||||
// For streaming parse errors
|
||||
std::string
|
||||
|
@ -661,85 +782,19 @@ protected:
|
|||
return output.str();
|
||||
}
|
||||
|
||||
void
|
||||
ValidateCandidates(JsepSession& session, bool local)
|
||||
void CheckEndOfCandidates(bool expectEoc,
|
||||
const SdpMediaSection& msection,
|
||||
const std::string& context)
|
||||
{
|
||||
std::string sdp =
|
||||
local ? session.GetLocalDescription() : session.GetRemoteDescription();
|
||||
SipccSdpParser parser;
|
||||
UniquePtr<Sdp> parsed = parser.Parse(sdp);
|
||||
ASSERT_TRUE(!!parsed) << "Parse failed on " << std::endl << sdp << std::endl
|
||||
<< "Errors were: " << GetParseErrors(parser);
|
||||
ASSERT_LT(0U, parsed->GetMediaSectionCount());
|
||||
|
||||
auto& msection_0 = parsed->GetMediaSection(0);
|
||||
|
||||
// We should not be doing things like setting the c-line on remote SDP
|
||||
if (local) {
|
||||
ASSERT_EQ("192.168.0.2", msection_0.GetConnection().GetAddress());
|
||||
ASSERT_EQ(2002U, msection_0.GetPort());
|
||||
ASSERT_TRUE(msection_0.GetAttributeList().HasAttribute(
|
||||
SdpAttribute::kRtcpAttribute));
|
||||
auto& rtcpAttr = msection_0.GetAttributeList().GetRtcp();
|
||||
ASSERT_EQ(3002U, rtcpAttr.mPort);
|
||||
ASSERT_EQ(sdp::kInternet, rtcpAttr.mNetType);
|
||||
ASSERT_EQ(sdp::kIPv4, rtcpAttr.mAddrType);
|
||||
ASSERT_EQ("192.168.0.2", rtcpAttr.mAddress);
|
||||
ASSERT_TRUE(msection_0.GetAttributeList().HasAttribute(
|
||||
SdpAttribute::kEndOfCandidatesAttribute));
|
||||
if (expectEoc) {
|
||||
ASSERT_TRUE(msection.GetAttributeList().HasAttribute(
|
||||
SdpAttribute::kEndOfCandidatesAttribute))
|
||||
<< context << " (level " << msection.GetLevel() << ")";
|
||||
} else {
|
||||
ASSERT_FALSE(msection.GetAttributeList().HasAttribute(
|
||||
SdpAttribute::kEndOfCandidatesAttribute))
|
||||
<< context << " (level " << msection.GetLevel() << ")";
|
||||
}
|
||||
|
||||
auto& attrs_0 = msection_0.GetAttributeList();
|
||||
ASSERT_TRUE(attrs_0.HasAttribute(SdpAttribute::kCandidateAttribute));
|
||||
|
||||
auto& candidates_0 = attrs_0.GetCandidate();
|
||||
ASSERT_EQ(6U, candidates_0.size());
|
||||
ASSERT_EQ(kCandidates[0], candidates_0[0]);
|
||||
ASSERT_EQ(kRtcpCandidates[0], candidates_0[1]);
|
||||
ASSERT_EQ(kCandidates[1], candidates_0[2]);
|
||||
ASSERT_EQ(kRtcpCandidates[1], candidates_0[3]);
|
||||
ASSERT_EQ(kCandidates[2], candidates_0[4]);
|
||||
ASSERT_EQ(kRtcpCandidates[2], candidates_0[5]);
|
||||
|
||||
if (parsed->GetMediaSectionCount() > 1) {
|
||||
auto& msection_1 = parsed->GetMediaSection(1);
|
||||
|
||||
if (local) {
|
||||
ASSERT_EQ("192.168.1.2", msection_1.GetConnection().GetAddress());
|
||||
ASSERT_EQ(2012U, msection_1.GetPort());
|
||||
auto& rtcpAttr = msection_1.GetAttributeList().GetRtcp();
|
||||
ASSERT_EQ(3012U, rtcpAttr.mPort);
|
||||
ASSERT_EQ(sdp::kInternet, rtcpAttr.mNetType);
|
||||
ASSERT_EQ(sdp::kIPv4, rtcpAttr.mAddrType);
|
||||
ASSERT_EQ("192.168.1.2", rtcpAttr.mAddress);
|
||||
ASSERT_TRUE(msection_0.GetAttributeList().HasAttribute(
|
||||
SdpAttribute::kEndOfCandidatesAttribute));
|
||||
}
|
||||
|
||||
auto& attrs_1 = msection_1.GetAttributeList();
|
||||
ASSERT_TRUE(attrs_1.HasAttribute(SdpAttribute::kCandidateAttribute));
|
||||
|
||||
auto& candidates_1 = attrs_1.GetCandidate();
|
||||
ASSERT_EQ(6U, candidates_1.size());
|
||||
ASSERT_EQ(kCandidates[3], candidates_1[0]);
|
||||
ASSERT_EQ(kRtcpCandidates[3], candidates_1[1]);
|
||||
ASSERT_EQ(kCandidates[4], candidates_1[2]);
|
||||
ASSERT_EQ(kRtcpCandidates[4], candidates_1[3]);
|
||||
ASSERT_EQ(kCandidates[5], candidates_1[4]);
|
||||
ASSERT_EQ(kRtcpCandidates[5], candidates_1[5]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ValidateOffererCandidates()
|
||||
{
|
||||
ValidateCandidates(mSessionOff, true);
|
||||
}
|
||||
|
||||
void
|
||||
ValidateAnswererCandidates()
|
||||
{
|
||||
ValidateCandidates(mSessionAns, false);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -758,8 +813,7 @@ protected:
|
|||
|
||||
void
|
||||
DisableMsection(std::string* sdp, size_t level) const {
|
||||
SipccSdpParser parser;
|
||||
UniquePtr<Sdp> parsed = parser.Parse(*sdp);
|
||||
UniquePtr<Sdp> parsed(Parse(*sdp));
|
||||
ASSERT_TRUE(parsed.get());
|
||||
ASSERT_LT(level, parsed->GetMediaSectionCount());
|
||||
parsed->GetMediaSection(level).SetPort(0);
|
||||
|
@ -813,18 +867,29 @@ protected:
|
|||
}
|
||||
}
|
||||
|
||||
UniquePtr<Sdp>
|
||||
Parse(const std::string& sdp) const
|
||||
{
|
||||
SipccSdpParser parser;
|
||||
UniquePtr<Sdp> parsed = parser.Parse(sdp);
|
||||
EXPECT_TRUE(parsed.get()) << "Should have valid SDP" << std::endl
|
||||
<< "Errors were: " << GetParseErrors(parser);
|
||||
return parsed;
|
||||
}
|
||||
|
||||
JsepSessionImpl mSessionOff;
|
||||
CandidateSet mOffCandidates;
|
||||
JsepSessionImpl mSessionAns;
|
||||
CandidateSet mAnsCandidates;
|
||||
std::vector<SdpMediaSection::MediaType> types;
|
||||
std::vector<std::pair<std::string, uint16_t>> mGatheredCandidates;
|
||||
|
||||
private:
|
||||
void
|
||||
ValidateTransport(TransportData& source, const std::string& sdp_str)
|
||||
{
|
||||
SipccSdpParser parser;
|
||||
auto sdp = parser.Parse(sdp_str);
|
||||
ASSERT_TRUE(!!sdp) << "Should have valid SDP" << std::endl
|
||||
<< "Errors were: " << GetParseErrors(parser);
|
||||
UniquePtr<Sdp> sdp(Parse(sdp_str));
|
||||
ASSERT_TRUE(!!sdp);
|
||||
size_t num_m_sections = sdp->GetMediaSectionCount();
|
||||
for (size_t i = 0; i < num_m_sections; ++i) {
|
||||
auto& msection = sdp->GetMediaSection(i);
|
||||
|
@ -1993,17 +2058,289 @@ TEST_P(JsepSessionTest, FullCallWithCandidates)
|
|||
AddTracks(mSessionOff);
|
||||
std::string offer = CreateOffer();
|
||||
SetLocalOffer(offer);
|
||||
GatherOffererCandidates();
|
||||
ValidateOffererCandidates();
|
||||
mOffCandidates.Gather(mSessionOff, types);
|
||||
|
||||
UniquePtr<Sdp> localOffer(Parse(mSessionOff.GetLocalDescription()));
|
||||
for (size_t i = 0; i < localOffer->GetMediaSectionCount(); ++i) {
|
||||
mOffCandidates.CheckRtpCandidates(
|
||||
true, localOffer->GetMediaSection(i), i,
|
||||
"Local offer after gathering should have RTP candidates.");
|
||||
mOffCandidates.CheckDefaultRtpCandidate(
|
||||
true, localOffer->GetMediaSection(i), i,
|
||||
"Local offer after gathering should have a default RTP candidate.");
|
||||
mOffCandidates.CheckRtcpCandidates(
|
||||
types[i] != SdpMediaSection::kApplication,
|
||||
localOffer->GetMediaSection(i), i,
|
||||
"Local offer after gathering should have RTCP candidates "
|
||||
"(unless m=application)");
|
||||
mOffCandidates.CheckDefaultRtcpCandidate(
|
||||
types[i] != SdpMediaSection::kApplication,
|
||||
localOffer->GetMediaSection(i), i,
|
||||
"Local offer after gathering should have a default RTCP candidate "
|
||||
"(unless m=application)");
|
||||
CheckEndOfCandidates(true, localOffer->GetMediaSection(i),
|
||||
"Local offer after gathering should have an end-of-candidates.");
|
||||
}
|
||||
|
||||
SetRemoteOffer(offer);
|
||||
TrickleOffererCandidates();
|
||||
ValidateAnswererCandidates();
|
||||
mOffCandidates.Trickle(mSessionAns);
|
||||
|
||||
UniquePtr<Sdp> remoteOffer(Parse(mSessionAns.GetRemoteDescription()));
|
||||
for (size_t i = 0; i < remoteOffer->GetMediaSectionCount(); ++i) {
|
||||
mOffCandidates.CheckRtpCandidates(
|
||||
true, remoteOffer->GetMediaSection(i), i,
|
||||
"Remote offer after trickle should have RTP candidates.");
|
||||
mOffCandidates.CheckDefaultRtpCandidate(
|
||||
false, remoteOffer->GetMediaSection(i), i,
|
||||
"Initial remote offer should not have a default RTP candidate.");
|
||||
mOffCandidates.CheckRtcpCandidates(
|
||||
types[i] != SdpMediaSection::kApplication,
|
||||
remoteOffer->GetMediaSection(i), i,
|
||||
"Remote offer after trickle should have RTCP candidates "
|
||||
"(unless m=application)");
|
||||
mOffCandidates.CheckDefaultRtcpCandidate(
|
||||
false, remoteOffer->GetMediaSection(i), i,
|
||||
"Initial remote offer should not have a default RTCP candidate.");
|
||||
CheckEndOfCandidates(false, remoteOffer->GetMediaSection(i),
|
||||
"Initial remote offer should not have an end-of-candidates.");
|
||||
}
|
||||
|
||||
AddTracks(mSessionAns);
|
||||
std::string answer = CreateAnswer();
|
||||
SetLocalAnswer(answer);
|
||||
// This will gather candidates that mSessionAns knows it doesn't need.
|
||||
// They should not be present in the SDP.
|
||||
mAnsCandidates.Gather(mSessionAns, types);
|
||||
|
||||
UniquePtr<Sdp> localAnswer(Parse(mSessionAns.GetLocalDescription()));
|
||||
for (size_t i = 0; i < localAnswer->GetMediaSectionCount(); ++i) {
|
||||
mAnsCandidates.CheckRtpCandidates(
|
||||
i == 0, localAnswer->GetMediaSection(i), i,
|
||||
"Local answer after gathering should have RTP candidates on level 0.");
|
||||
mAnsCandidates.CheckDefaultRtpCandidate(
|
||||
true, localAnswer->GetMediaSection(i), 0,
|
||||
"Local answer after gathering should have a default RTP candidate "
|
||||
"on all levels that matches transport level 0.");
|
||||
mAnsCandidates.CheckRtcpCandidates(
|
||||
false, localAnswer->GetMediaSection(i), i,
|
||||
"Local answer after gathering should not have RTCP candidates "
|
||||
"(because we're answering with rtcp-mux)");
|
||||
mAnsCandidates.CheckDefaultRtcpCandidate(
|
||||
false, localAnswer->GetMediaSection(i), i,
|
||||
"Local answer after gathering should not have a default RTCP candidate "
|
||||
"(because we're answering with rtcp-mux)");
|
||||
CheckEndOfCandidates(i == 0, localAnswer->GetMediaSection(i),
|
||||
"Local answer after gathering should have an end-of-candidates only for"
|
||||
" level 0.");
|
||||
}
|
||||
|
||||
SetRemoteAnswer(answer);
|
||||
mAnsCandidates.Trickle(mSessionOff);
|
||||
|
||||
UniquePtr<Sdp> remoteAnswer(Parse(mSessionOff.GetRemoteDescription()));
|
||||
for (size_t i = 0; i < remoteAnswer->GetMediaSectionCount(); ++i) {
|
||||
mAnsCandidates.CheckRtpCandidates(
|
||||
i == 0, remoteAnswer->GetMediaSection(i), i,
|
||||
"Remote answer after trickle should have RTP candidates on level 0.");
|
||||
mAnsCandidates.CheckDefaultRtpCandidate(
|
||||
false, remoteAnswer->GetMediaSection(i), i,
|
||||
"Remote answer after trickle should not have a default RTP candidate.");
|
||||
mAnsCandidates.CheckRtcpCandidates(
|
||||
false, remoteAnswer->GetMediaSection(i), i,
|
||||
"Remote answer after trickle should not have RTCP candidates "
|
||||
"(because we're answering with rtcp-mux)");
|
||||
mAnsCandidates.CheckDefaultRtcpCandidate(
|
||||
false, remoteAnswer->GetMediaSection(i), i,
|
||||
"Remote answer after trickle should not have a default RTCP "
|
||||
"candidate.");
|
||||
CheckEndOfCandidates(false, remoteAnswer->GetMediaSection(i),
|
||||
"Remote answer after trickle should not have an end-of-candidates.");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(JsepSessionTest, RenegotiationWithCandidates)
|
||||
{
|
||||
AddTracks(mSessionOff);
|
||||
std::string offer = CreateOffer();
|
||||
SetLocalOffer(offer);
|
||||
mOffCandidates.Gather(mSessionOff, types);
|
||||
SetRemoteOffer(offer);
|
||||
mOffCandidates.Trickle(mSessionAns);
|
||||
AddTracks(mSessionAns);
|
||||
std::string answer = CreateAnswer();
|
||||
SetLocalAnswer(answer);
|
||||
mAnsCandidates.Gather(mSessionAns, types);
|
||||
SetRemoteAnswer(answer);
|
||||
mAnsCandidates.Trickle(mSessionOff);
|
||||
|
||||
offer = CreateOffer();
|
||||
SetLocalOffer(offer);
|
||||
|
||||
UniquePtr<Sdp> parsedOffer(Parse(offer));
|
||||
for (size_t i = 0; i < parsedOffer->GetMediaSectionCount(); ++i) {
|
||||
mOffCandidates.CheckRtpCandidates(
|
||||
i == 0, parsedOffer->GetMediaSection(i), i,
|
||||
"Local reoffer before gathering should have RTP candidates on level 0"
|
||||
" only.");
|
||||
mOffCandidates.CheckDefaultRtpCandidate(
|
||||
i == 0, parsedOffer->GetMediaSection(i), 0,
|
||||
"Local reoffer before gathering should have a default RTP candidate "
|
||||
"on level 0 only.");
|
||||
mOffCandidates.CheckRtcpCandidates(
|
||||
false, parsedOffer->GetMediaSection(i), i,
|
||||
"Local reoffer before gathering should not have RTCP candidates.");
|
||||
mOffCandidates.CheckDefaultRtcpCandidate(
|
||||
false, parsedOffer->GetMediaSection(i), i,
|
||||
"Local reoffer before gathering should not have a default RTCP "
|
||||
"candidate.");
|
||||
CheckEndOfCandidates(false, parsedOffer->GetMediaSection(i),
|
||||
"Local reoffer before gathering should not have an end-of-candidates.");
|
||||
}
|
||||
|
||||
// mSessionAns should generate a reoffer that is similar
|
||||
std::string otherOffer;
|
||||
JsepOfferOptions defaultOptions;
|
||||
nsresult rv = mSessionAns.CreateOffer(defaultOptions, &otherOffer);
|
||||
ASSERT_EQ(NS_OK, rv);
|
||||
parsedOffer = Parse(otherOffer);
|
||||
for (size_t i = 0; i < parsedOffer->GetMediaSectionCount(); ++i) {
|
||||
mAnsCandidates.CheckRtpCandidates(
|
||||
i == 0, parsedOffer->GetMediaSection(i), i,
|
||||
"Local reoffer before gathering should have RTP candidates on level 0"
|
||||
" only. (previous answerer)");
|
||||
mAnsCandidates.CheckDefaultRtpCandidate(
|
||||
i == 0, parsedOffer->GetMediaSection(i), 0,
|
||||
"Local reoffer before gathering should have a default RTP candidate "
|
||||
"on level 0 only. (previous answerer)");
|
||||
mAnsCandidates.CheckRtcpCandidates(
|
||||
false, parsedOffer->GetMediaSection(i), i,
|
||||
"Local reoffer before gathering should not have RTCP candidates."
|
||||
" (previous answerer)");
|
||||
mAnsCandidates.CheckDefaultRtcpCandidate(
|
||||
false, parsedOffer->GetMediaSection(i), i,
|
||||
"Local reoffer before gathering should not have a default RTCP "
|
||||
"candidate. (previous answerer)");
|
||||
CheckEndOfCandidates(false, parsedOffer->GetMediaSection(i),
|
||||
"Local reoffer before gathering should not have an end-of-candidates. "
|
||||
"(previous answerer)");
|
||||
}
|
||||
|
||||
// Ok, let's continue with the renegotiation
|
||||
SetRemoteOffer(offer);
|
||||
|
||||
// PeerConnection will not re-gather for RTP, but it will for RTCP in case
|
||||
// the answerer decides to turn off rtcp-mux.
|
||||
if (types[0] != SdpMediaSection::kApplication) {
|
||||
mOffCandidates.Gather(mSessionOff, 0, RTCP);
|
||||
}
|
||||
|
||||
// Since the remaining levels were bundled, PeerConnection will re-gather for
|
||||
// both RTP and RTCP, in case the answerer rejects bundle.
|
||||
for (size_t level = 1; level < types.size(); ++level) {
|
||||
mOffCandidates.Gather(mSessionOff, level, RTP);
|
||||
if (types[level] != SdpMediaSection::kApplication) {
|
||||
mOffCandidates.Gather(mSessionOff, level, RTCP);
|
||||
}
|
||||
}
|
||||
mOffCandidates.FinishGathering(mSessionOff);
|
||||
|
||||
mOffCandidates.Trickle(mSessionAns);
|
||||
|
||||
UniquePtr<Sdp> localOffer(Parse(mSessionOff.GetLocalDescription()));
|
||||
for (size_t i = 0; i < localOffer->GetMediaSectionCount(); ++i) {
|
||||
mOffCandidates.CheckRtpCandidates(
|
||||
true, localOffer->GetMediaSection(i), i,
|
||||
"Local reoffer after gathering should have RTP candidates.");
|
||||
mOffCandidates.CheckDefaultRtpCandidate(
|
||||
true, localOffer->GetMediaSection(i), i,
|
||||
"Local reoffer after gathering should have a default RTP candidate.");
|
||||
mOffCandidates.CheckRtcpCandidates(
|
||||
types[i] != SdpMediaSection::kApplication,
|
||||
localOffer->GetMediaSection(i), i,
|
||||
"Local reoffer after gathering should have RTCP candidates "
|
||||
"(unless m=application)");
|
||||
mOffCandidates.CheckDefaultRtcpCandidate(
|
||||
types[i] != SdpMediaSection::kApplication,
|
||||
localOffer->GetMediaSection(i), i,
|
||||
"Local reoffer after gathering should have a default RTCP candidate "
|
||||
"(unless m=application)");
|
||||
CheckEndOfCandidates(true, localOffer->GetMediaSection(i),
|
||||
"Local reoffer after gathering should have an end-of-candidates.");
|
||||
}
|
||||
|
||||
UniquePtr<Sdp> remoteOffer(Parse(mSessionAns.GetRemoteDescription()));
|
||||
for (size_t i = 0; i < remoteOffer->GetMediaSectionCount(); ++i) {
|
||||
mOffCandidates.CheckRtpCandidates(
|
||||
true, remoteOffer->GetMediaSection(i), i,
|
||||
"Remote reoffer after trickle should have RTP candidates.");
|
||||
mOffCandidates.CheckDefaultRtpCandidate(
|
||||
i == 0, remoteOffer->GetMediaSection(i), i,
|
||||
"Remote reoffer should have a default RTP candidate on level 0 "
|
||||
"(because it was gathered last offer/answer).");
|
||||
mOffCandidates.CheckRtcpCandidates(
|
||||
types[i] != SdpMediaSection::kApplication,
|
||||
remoteOffer->GetMediaSection(i), i,
|
||||
"Remote reoffer after trickle should have RTCP candidates.");
|
||||
mOffCandidates.CheckDefaultRtcpCandidate(
|
||||
false, remoteOffer->GetMediaSection(i), i,
|
||||
"Remote reoffer should not have a default RTCP candidate.");
|
||||
CheckEndOfCandidates(false, remoteOffer->GetMediaSection(i),
|
||||
"Remote reoffer should not have an end-of-candidates.");
|
||||
}
|
||||
|
||||
answer = CreateAnswer();
|
||||
SetLocalAnswer(answer);
|
||||
SetRemoteAnswer(answer);
|
||||
// No candidates should be gathered at the answerer, but default candidates
|
||||
// should be set.
|
||||
mAnsCandidates.FinishGathering(mSessionAns);
|
||||
|
||||
UniquePtr<Sdp> localAnswer(Parse(mSessionAns.GetLocalDescription()));
|
||||
for (size_t i = 0; i < localAnswer->GetMediaSectionCount(); ++i) {
|
||||
mAnsCandidates.CheckRtpCandidates(
|
||||
i == 0, localAnswer->GetMediaSection(i), i,
|
||||
"Local reanswer after gathering should have RTP candidates on level "
|
||||
"0.");
|
||||
mAnsCandidates.CheckDefaultRtpCandidate(
|
||||
true, localAnswer->GetMediaSection(i), 0,
|
||||
"Local reanswer after gathering should have a default RTP candidate "
|
||||
"on all levels that matches transport level 0.");
|
||||
mAnsCandidates.CheckRtcpCandidates(
|
||||
false, localAnswer->GetMediaSection(i), i,
|
||||
"Local reanswer after gathering should not have RTCP candidates "
|
||||
"(because we're reanswering with rtcp-mux)");
|
||||
mAnsCandidates.CheckDefaultRtcpCandidate(
|
||||
false, localAnswer->GetMediaSection(i), i,
|
||||
"Local reanswer after gathering should not have a default RTCP "
|
||||
"candidate (because we're reanswering with rtcp-mux)");
|
||||
CheckEndOfCandidates(i == 0, localAnswer->GetMediaSection(i),
|
||||
"Local reanswer after gathering should have an end-of-candidates only "
|
||||
"for level 0.");
|
||||
}
|
||||
|
||||
UniquePtr<Sdp> remoteAnswer(Parse(mSessionOff.GetRemoteDescription()));
|
||||
for (size_t i = 0; i < localAnswer->GetMediaSectionCount(); ++i) {
|
||||
mAnsCandidates.CheckRtpCandidates(
|
||||
i == 0, remoteAnswer->GetMediaSection(i), i,
|
||||
"Remote reanswer after trickle should have RTP candidates on level 0.");
|
||||
mAnsCandidates.CheckDefaultRtpCandidate(
|
||||
i == 0, remoteAnswer->GetMediaSection(i), i,
|
||||
"Remote reanswer should have a default RTP candidate on level 0 "
|
||||
"(because it was gathered last offer/answer).");
|
||||
mAnsCandidates.CheckRtcpCandidates(
|
||||
false, remoteAnswer->GetMediaSection(i), i,
|
||||
"Remote reanswer after trickle should not have RTCP candidates "
|
||||
"(because we're reanswering with rtcp-mux)");
|
||||
mAnsCandidates.CheckDefaultRtcpCandidate(
|
||||
false, remoteAnswer->GetMediaSection(i), i,
|
||||
"Remote reanswer after trickle should not have a default RTCP "
|
||||
"candidate.");
|
||||
CheckEndOfCandidates(false, remoteAnswer->GetMediaSection(i),
|
||||
"Remote reanswer after trickle should not have an end-of-candidates.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
Variants,
|
||||
JsepSessionTest,
|
||||
|
@ -2039,10 +2376,8 @@ TEST_F(JsepSessionTest, OfferAnswerRecvOnlyLines)
|
|||
options.mDontOfferDataChannel = Some(true);
|
||||
std::string offer = CreateOffer(Some(options));
|
||||
|
||||
SipccSdpParser parser;
|
||||
UniquePtr<Sdp> parsedOffer = parser.Parse(offer);
|
||||
ASSERT_TRUE(!!parsedOffer) << "Should have valid SDP" << std::endl
|
||||
<< "Errors were: " << GetParseErrors(parser);
|
||||
UniquePtr<Sdp> parsedOffer(Parse(offer));
|
||||
ASSERT_TRUE(!!parsedOffer);
|
||||
|
||||
ASSERT_EQ(3U, parsedOffer->GetMediaSectionCount());
|
||||
ASSERT_EQ(SdpMediaSection::kAudio,
|
||||
|
@ -2079,7 +2414,7 @@ TEST_F(JsepSessionTest, OfferAnswerRecvOnlyLines)
|
|||
SetRemoteOffer(offer, CHECK_SUCCESS);
|
||||
|
||||
std::string answer = CreateAnswer();
|
||||
UniquePtr<Sdp> parsedAnswer = parser.Parse(answer);
|
||||
UniquePtr<Sdp> parsedAnswer(Parse(answer));
|
||||
|
||||
ASSERT_EQ(3U, parsedAnswer->GetMediaSectionCount());
|
||||
ASSERT_EQ(SdpMediaSection::kAudio,
|
||||
|
@ -2118,10 +2453,8 @@ TEST_F(JsepSessionTest, OfferAnswerSendOnlyLines)
|
|||
options.mDontOfferDataChannel = Some(true);
|
||||
std::string offer = CreateOffer(Some(options));
|
||||
|
||||
SipccSdpParser parser;
|
||||
auto outputSdp = parser.Parse(offer);
|
||||
ASSERT_TRUE(!!outputSdp) << "Should have valid SDP" << std::endl
|
||||
<< "Errors were: " << GetParseErrors(parser);
|
||||
UniquePtr<Sdp> outputSdp(Parse(offer));
|
||||
ASSERT_TRUE(!!outputSdp);
|
||||
|
||||
ASSERT_EQ(3U, outputSdp->GetMediaSectionCount());
|
||||
ASSERT_EQ(SdpMediaSection::kAudio,
|
||||
|
@ -2150,7 +2483,7 @@ TEST_F(JsepSessionTest, OfferAnswerSendOnlyLines)
|
|||
SetRemoteOffer(offer, CHECK_SUCCESS);
|
||||
|
||||
std::string answer = CreateAnswer();
|
||||
outputSdp = parser.Parse(answer);
|
||||
outputSdp = Parse(answer);
|
||||
|
||||
ASSERT_EQ(3U, outputSdp->GetMediaSectionCount());
|
||||
ASSERT_EQ(SdpMediaSection::kAudio,
|
||||
|
@ -2174,8 +2507,7 @@ TEST_F(JsepSessionTest, OfferToReceiveAudioNotUsed)
|
|||
|
||||
OfferAnswer(CHECK_SUCCESS, Some(options));
|
||||
|
||||
SipccSdpParser parser;
|
||||
UniquePtr<Sdp> offer(parser.Parse(mSessionOff.GetLocalDescription()));
|
||||
UniquePtr<Sdp> offer(Parse(mSessionOff.GetLocalDescription()));
|
||||
ASSERT_TRUE(offer.get());
|
||||
ASSERT_EQ(1U, offer->GetMediaSectionCount());
|
||||
ASSERT_EQ(SdpMediaSection::kAudio,
|
||||
|
@ -2183,7 +2515,7 @@ TEST_F(JsepSessionTest, OfferToReceiveAudioNotUsed)
|
|||
ASSERT_EQ(SdpDirectionAttribute::kRecvonly,
|
||||
offer->GetMediaSection(0).GetAttributeList().GetDirection());
|
||||
|
||||
UniquePtr<Sdp> answer(parser.Parse(mSessionAns.GetLocalDescription()));
|
||||
UniquePtr<Sdp> answer(Parse(mSessionAns.GetLocalDescription()));
|
||||
ASSERT_TRUE(answer.get());
|
||||
ASSERT_EQ(1U, answer->GetMediaSectionCount());
|
||||
ASSERT_EQ(SdpMediaSection::kAudio,
|
||||
|
@ -2199,8 +2531,7 @@ TEST_F(JsepSessionTest, OfferToReceiveVideoNotUsed)
|
|||
|
||||
OfferAnswer(CHECK_SUCCESS, Some(options));
|
||||
|
||||
SipccSdpParser parser;
|
||||
UniquePtr<Sdp> offer(parser.Parse(mSessionOff.GetLocalDescription()));
|
||||
UniquePtr<Sdp> offer(Parse(mSessionOff.GetLocalDescription()));
|
||||
ASSERT_TRUE(offer.get());
|
||||
ASSERT_EQ(1U, offer->GetMediaSectionCount());
|
||||
ASSERT_EQ(SdpMediaSection::kVideo,
|
||||
|
@ -2208,7 +2539,7 @@ TEST_F(JsepSessionTest, OfferToReceiveVideoNotUsed)
|
|||
ASSERT_EQ(SdpDirectionAttribute::kRecvonly,
|
||||
offer->GetMediaSection(0).GetAttributeList().GetDirection());
|
||||
|
||||
UniquePtr<Sdp> answer(parser.Parse(mSessionAns.GetLocalDescription()));
|
||||
UniquePtr<Sdp> answer(Parse(mSessionAns.GetLocalDescription()));
|
||||
ASSERT_TRUE(answer.get());
|
||||
ASSERT_EQ(1U, answer->GetMediaSectionCount());
|
||||
ASSERT_EQ(SdpMediaSection::kVideo,
|
||||
|
@ -2229,10 +2560,8 @@ TEST_F(JsepSessionTest, CreateOfferNoDatachannelDefault)
|
|||
|
||||
std::string offer = CreateOffer();
|
||||
|
||||
SipccSdpParser parser;
|
||||
auto outputSdp = parser.Parse(offer);
|
||||
ASSERT_TRUE(!!outputSdp) << "Should have valid SDP" << std::endl
|
||||
<< "Errors were: " << GetParseErrors(parser);
|
||||
UniquePtr<Sdp> outputSdp(Parse(offer));
|
||||
ASSERT_TRUE(!!outputSdp);
|
||||
|
||||
ASSERT_EQ(2U, outputSdp->GetMediaSectionCount());
|
||||
ASSERT_EQ(SdpMediaSection::kAudio,
|
||||
|
@ -2255,10 +2584,8 @@ TEST_F(JsepSessionTest, ValidateOfferedCodecParams)
|
|||
|
||||
std::string offer = CreateOffer();
|
||||
|
||||
SipccSdpParser parser;
|
||||
auto outputSdp = parser.Parse(offer);
|
||||
ASSERT_TRUE(!!outputSdp) << "Should have valid SDP" << std::endl
|
||||
<< "Errors were: " << GetParseErrors(parser);
|
||||
UniquePtr<Sdp> outputSdp(Parse(offer));
|
||||
ASSERT_TRUE(!!outputSdp);
|
||||
|
||||
ASSERT_EQ(2U, outputSdp->GetMediaSectionCount());
|
||||
auto& video_section = outputSdp->GetMediaSection(1);
|
||||
|
@ -2389,10 +2716,8 @@ TEST_F(JsepSessionTest, ValidateAnsweredCodecParams)
|
|||
|
||||
std::string answer = CreateAnswer();
|
||||
|
||||
SipccSdpParser parser;
|
||||
auto outputSdp = parser.Parse(answer);
|
||||
ASSERT_TRUE(!!outputSdp) << "Should have valid SDP" << std::endl
|
||||
<< "Errors were: " << GetParseErrors(parser);
|
||||
UniquePtr<Sdp> outputSdp(Parse(answer));
|
||||
ASSERT_TRUE(!!outputSdp);
|
||||
|
||||
ASSERT_EQ(2U, outputSdp->GetMediaSectionCount());
|
||||
auto& video_section = outputSdp->GetMediaSection(1);
|
||||
|
@ -2889,10 +3214,8 @@ TEST_P(JsepSessionTest, TestRejectMline)
|
|||
|
||||
std::string answer = CreateAnswer();
|
||||
|
||||
SipccSdpParser parser;
|
||||
auto outputSdp = parser.Parse(answer);
|
||||
ASSERT_TRUE(!!outputSdp) << "Should have valid SDP" << std::endl
|
||||
<< "Errors were: " << GetParseErrors(parser);
|
||||
UniquePtr<Sdp> outputSdp(Parse(answer));
|
||||
ASSERT_TRUE(!!outputSdp);
|
||||
|
||||
ASSERT_NE(0U, outputSdp->GetMediaSectionCount());
|
||||
SdpMediaSection* failed_section = nullptr;
|
||||
|
@ -2942,8 +3265,7 @@ TEST_F(JsepSessionTest, TestIceLite)
|
|||
std::string offer = CreateOffer();
|
||||
SetLocalOffer(offer, CHECK_SUCCESS);
|
||||
|
||||
SipccSdpParser parser;
|
||||
UniquePtr<Sdp> parsedOffer = parser.Parse(offer);
|
||||
UniquePtr<Sdp> parsedOffer(Parse(offer));
|
||||
parsedOffer->GetAttributeList().SetAttribute(
|
||||
new SdpFlagAttribute(SdpAttribute::kIceLiteAttribute));
|
||||
|
||||
|
@ -2988,8 +3310,7 @@ TEST_F(JsepSessionTest, TestExtmap)
|
|||
SetLocalAnswer(answer, CHECK_SUCCESS);
|
||||
SetRemoteAnswer(answer, CHECK_SUCCESS);
|
||||
|
||||
SipccSdpParser parser;
|
||||
UniquePtr<Sdp> parsedOffer = parser.Parse(offer);
|
||||
UniquePtr<Sdp> parsedOffer(Parse(offer));
|
||||
ASSERT_EQ(1U, parsedOffer->GetMediaSectionCount());
|
||||
|
||||
auto& offerMediaAttrs = parsedOffer->GetMediaSection(0).GetAttributeList();
|
||||
|
@ -3004,7 +3325,7 @@ TEST_F(JsepSessionTest, TestExtmap)
|
|||
ASSERT_EQ("bar", offerExtmap[2].extensionname);
|
||||
ASSERT_EQ(3U, offerExtmap[2].entry);
|
||||
|
||||
UniquePtr<Sdp> parsedAnswer = parser.Parse(answer);
|
||||
UniquePtr<Sdp> parsedAnswer(Parse(answer));
|
||||
ASSERT_EQ(1U, parsedAnswer->GetMediaSectionCount());
|
||||
|
||||
auto& answerMediaAttrs = parsedAnswer->GetMediaSection(0).GetAttributeList();
|
||||
|
@ -3026,8 +3347,7 @@ TEST_F(JsepSessionTest, TestRtcpFbStar)
|
|||
|
||||
std::string offer = CreateOffer();
|
||||
|
||||
SipccSdpParser parser;
|
||||
UniquePtr<Sdp> parsedOffer = parser.Parse(offer);
|
||||
UniquePtr<Sdp> parsedOffer(Parse(offer));
|
||||
auto* rtcpfbs = new SdpRtcpFbAttributeList;
|
||||
rtcpfbs->PushEntry("*", SdpRtcpFbAttributeList::kNack);
|
||||
parsedOffer->GetMediaSection(0).GetAttributeList().SetAttribute(rtcpfbs);
|
||||
|
|
|
@ -18,7 +18,10 @@ from __future__ import unicode_literals
|
|||
|
||||
import os
|
||||
|
||||
from collections import OrderedDict
|
||||
from collections import (
|
||||
Counter,
|
||||
OrderedDict,
|
||||
)
|
||||
from mozbuild.util import (
|
||||
HierarchicalStringList,
|
||||
HierarchicalStringListWithFlagsFactory,
|
||||
|
@ -576,6 +579,49 @@ class Files(SubContext):
|
|||
|
||||
return d
|
||||
|
||||
@staticmethod
|
||||
def aggregate(files):
|
||||
"""Given a mapping of path to Files, obtain aggregate results.
|
||||
|
||||
Consumers may want to extract useful information from a collection of
|
||||
Files describing paths. e.g. given the files info data for N paths,
|
||||
recommend a single bug component based on the most frequent one. This
|
||||
function provides logic for deriving aggregate knowledge from a
|
||||
collection of path File metadata.
|
||||
|
||||
Note: the intent of this function is to operate on the result of
|
||||
:py:func:`mozbuild.frontend.reader.BuildReader.files_info`. The
|
||||
:py:func:`mozbuild.frontend.context.Files` instances passed in are
|
||||
thus the "collapsed" (``__iadd__``ed) results of all ``Files`` from all
|
||||
moz.build files relevant to a specific path, not individual ``Files``
|
||||
instances from a single moz.build file.
|
||||
"""
|
||||
d = {}
|
||||
|
||||
bug_components = Counter()
|
||||
|
||||
for f in files.values():
|
||||
bug_component = f.get('BUG_COMPONENT')
|
||||
if bug_component:
|
||||
bug_components[bug_component] += 1
|
||||
|
||||
d['bug_component_counts'] = []
|
||||
for c, count in bug_components.most_common():
|
||||
component = (c.product, c.component)
|
||||
d['bug_component_counts'].append((c, count))
|
||||
|
||||
if 'recommended_bug_component' not in d:
|
||||
d['recommended_bug_component'] = component
|
||||
recommended_count = count
|
||||
elif count == recommended_count:
|
||||
# Don't recommend a component if it doesn't have a clear lead.
|
||||
d['recommended_bug_component'] = None
|
||||
|
||||
# In case no bug components.
|
||||
d.setdefault('recommended_bug_component', None)
|
||||
|
||||
return d
|
||||
|
||||
|
||||
# This defines functions that create sub-contexts.
|
||||
#
|
||||
|
|
|
@ -11,6 +11,7 @@ from mozbuild.frontend.context import (
|
|||
Context,
|
||||
ContextDerivedTypedList,
|
||||
ContextDerivedTypedListWithItems,
|
||||
Files,
|
||||
FUNCTIONS,
|
||||
ObjDirPath,
|
||||
Path,
|
||||
|
@ -565,5 +566,64 @@ class TestPaths(unittest.TestCase):
|
|||
self.assertEqual(l[p_str].foo, True)
|
||||
self.assertEqual(l[p_path].foo, True)
|
||||
|
||||
|
||||
class TestFiles(unittest.TestCase):
|
||||
def test_aggregate_empty(self):
|
||||
c = Context({})
|
||||
|
||||
files = {'moz.build': Files(c, pattern='**')}
|
||||
|
||||
self.assertEqual(Files.aggregate(files), {
|
||||
'bug_component_counts': [],
|
||||
'recommended_bug_component': None,
|
||||
})
|
||||
|
||||
def test_single_bug_component(self):
|
||||
c = Context({})
|
||||
f = Files(c, pattern='**')
|
||||
f['BUG_COMPONENT'] = (u'Product1', u'Component1')
|
||||
|
||||
files = {'moz.build': f}
|
||||
self.assertEqual(Files.aggregate(files), {
|
||||
'bug_component_counts': [((u'Product1', u'Component1'), 1)],
|
||||
'recommended_bug_component': (u'Product1', u'Component1'),
|
||||
})
|
||||
|
||||
def test_multiple_bug_components(self):
|
||||
c = Context({})
|
||||
f1 = Files(c, pattern='**')
|
||||
f1['BUG_COMPONENT'] = (u'Product1', u'Component1')
|
||||
|
||||
f2 = Files(c, pattern='**')
|
||||
f2['BUG_COMPONENT'] = (u'Product2', u'Component2')
|
||||
|
||||
files = {'a': f1, 'b': f2, 'c': f1}
|
||||
self.assertEqual(Files.aggregate(files), {
|
||||
'bug_component_counts': [
|
||||
((u'Product1', u'Component1'), 2),
|
||||
((u'Product2', u'Component2'), 1),
|
||||
],
|
||||
'recommended_bug_component': (u'Product1', u'Component1'),
|
||||
})
|
||||
|
||||
def test_no_recommended_bug_component(self):
|
||||
"""If there is no clear count winner, we don't recommend a bug component."""
|
||||
c = Context({})
|
||||
f1 = Files(c, pattern='**')
|
||||
f1['BUG_COMPONENT'] = (u'Product1', u'Component1')
|
||||
|
||||
f2 = Files(c, pattern='**')
|
||||
f2['BUG_COMPONENT'] = (u'Product2', u'Component2')
|
||||
|
||||
files = {'a': f1, 'b': f2}
|
||||
self.assertEqual(Files.aggregate(files), {
|
||||
'bug_component_counts': [
|
||||
((u'Product1', u'Component1'), 1),
|
||||
((u'Product2', u'Component2'), 1),
|
||||
],
|
||||
'recommended_bug_component': None,
|
||||
})
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
@ -1,15 +1,29 @@
|
|||
# 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/.
|
||||
# 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/.
|
||||
|
||||
from setuptools import setup
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
VERSION = '0.1'
|
||||
VERSION = '0.2'
|
||||
|
||||
setup(
|
||||
author='Mozilla Foundation',
|
||||
author_email='dev-builds@lists.mozilla.org',
|
||||
name='mozbuild',
|
||||
description='Mozilla build system functionality.',
|
||||
license='MPL 2.0',
|
||||
packages=['mach', 'mozbuild', 'mozpack'],
|
||||
version=VERSION
|
||||
packages=find_packages(),
|
||||
version=VERSION,
|
||||
install_requires=[
|
||||
'jsmin',
|
||||
'mozfile',
|
||||
],
|
||||
classifiers=[
|
||||
'Development Status :: 3 - Alpha',
|
||||
'Topic :: Software Development :: Build Tools',
|
||||
'License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: Implementation :: CPython',
|
||||
],
|
||||
keywords='mozilla build',
|
||||
)
|
||||
|
|
|
@ -462,16 +462,6 @@ CertErrorRunnable::CheckCertOverrides()
|
|||
mDefaultErrorCodeToReport);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISSLSocketControl> sslSocketControl = do_QueryInterface(
|
||||
NS_ISUPPORTS_CAST(nsITransportSecurityInfo*, mInfoObject));
|
||||
if (sslSocketControl &&
|
||||
sslSocketControl->GetBypassAuthentication()) {
|
||||
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
|
||||
("[%p][%p] Bypass Auth in CheckCertOverrides\n",
|
||||
mFdForLogging, this));
|
||||
return new SSLServerCertVerificationResult(mInfoObject, 0);
|
||||
}
|
||||
|
||||
int32_t port;
|
||||
mInfoObject->GetPort(&port);
|
||||
|
||||
|
@ -580,6 +570,8 @@ CertErrorRunnable::CheckCertOverrides()
|
|||
// First, deliver the technical details of the broken SSL status.
|
||||
|
||||
// Try to get a nsIBadCertListener2 implementation from the socket consumer.
|
||||
nsCOMPtr<nsISSLSocketControl> sslSocketControl = do_QueryInterface(
|
||||
NS_ISUPPORTS_CAST(nsITransportSecurityInfo*, mInfoObject));
|
||||
if (sslSocketControl) {
|
||||
nsCOMPtr<nsIInterfaceRequestor> cb;
|
||||
sslSocketControl->GetNotificationCallbacks(getter_AddRefs(cb));
|
||||
|
@ -1462,6 +1454,14 @@ AuthCertificateHook(void* arg, PRFileDesc* fd, PRBool checkSig, PRBool isServer)
|
|||
if (BlockServerCertChangeForSpdy(socketInfo, serverCert) != SECSuccess)
|
||||
return SECFailure;
|
||||
|
||||
nsCOMPtr<nsISSLSocketControl> sslSocketControl = do_QueryInterface(
|
||||
NS_ISUPPORTS_CAST(nsITransportSecurityInfo*, socketInfo));
|
||||
if (sslSocketControl && sslSocketControl->GetBypassAuthentication()) {
|
||||
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
|
||||
("[%p] Bypass Auth in AuthCertificateHook\n", fd));
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
bool onSTSThread;
|
||||
nsresult nrv;
|
||||
nsCOMPtr<nsIEventTarget> sts
|
||||
|
|
|
@ -86,9 +86,9 @@ class SyncTestCommands(MachCommandBase):
|
|||
'-r', '%s/components/httpd.manifest' % self.bindir,
|
||||
'-m',
|
||||
'-s',
|
||||
'-e', 'const _TESTING_MODULES_DIR = "%s/_tests/modules";' % topobjdir,
|
||||
'-f', '%s/testing/xpcshell/head.js' % topsrcdir,
|
||||
'-e', 'const _SERVER_ADDR = "%s";' % hostname,
|
||||
'-e', 'const _TESTING_MODULES_DIR = "%s/_tests/modules";' % topobjdir,
|
||||
'-e', 'const SERVER_PORT = "%s";' % port,
|
||||
'-e', 'const INCLUDE_FILES = [%s];' % ', '.join(head_paths),
|
||||
'-e', '_register_protocol_handlers();',
|
||||
|
|
|
@ -63,7 +63,8 @@ int main(int argc, char** argv)
|
|||
#if defined(HAVE_LIBXSS) && defined(MOZ_WIDGET_GTK)
|
||||
int event_base, error_base;
|
||||
Bool have_xscreensaver =
|
||||
XScreenSaverQueryExtension(GDK_DISPLAY(), &event_base, &error_base);
|
||||
XScreenSaverQueryExtension(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()),
|
||||
&event_base, &error_base);
|
||||
|
||||
if (!have_xscreensaver) {
|
||||
fprintf(stderr, "No XScreenSaver extension on display\n");
|
||||
|
@ -73,7 +74,8 @@ int main(int argc, char** argv)
|
|||
fprintf(stderr, "%s: Out of memory\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
XScreenSaverQueryInfo(GDK_DISPLAY(), GDK_ROOT_WINDOW(), info);
|
||||
XScreenSaverQueryInfo(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()),
|
||||
GDK_ROOT_WINDOW(), info);
|
||||
|
||||
const char* state;
|
||||
const char* til_or_since = nullptr;
|
||||
|
|
|
@ -137,8 +137,19 @@ function getTempFile(aLeafName)
|
|||
do_check_false(file.exists());
|
||||
|
||||
do_register_cleanup(function () {
|
||||
if (file.exists()) {
|
||||
file.remove(false);
|
||||
try {
|
||||
file.remove(false)
|
||||
} catch (e) {
|
||||
if (!(e instanceof Components.Exception &&
|
||||
(e.result == Cr.NS_ERROR_FILE_ACCESS_DENIED ||
|
||||
e.result == Cr.NS_ERROR_FILE_TARGET_DOES_NOT_EXIST ||
|
||||
e.result == Cr.NS_ERROR_FILE_NOT_FOUND))) {
|
||||
throw e;
|
||||
}
|
||||
// On Windows, we may get an access denied error if the file existed before,
|
||||
// and was recently deleted.
|
||||
// Don't bother checking file.exists() as that may also cause an access
|
||||
// denied error.
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -161,7 +161,7 @@ menulist[editable="true"] > menupopup > menucaption {
|
|||
-moz-appearance: none;
|
||||
}
|
||||
|
||||
menulist[editable="true"] > menupopup > :moz-any(menuitem, menucaption) > .menu-iconic-left
|
||||
menulist[editable="true"] > menupopup > :-moz-any(menuitem, menucaption) > .menu-iconic-left {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
|
|
@ -239,7 +239,7 @@ menulist > menupopup > menuitem[disabled="true"]:not([_moz-menuactive="true"]):-
|
|||
text-shadow: none;
|
||||
}
|
||||
|
||||
menulist > menupopup > :moz-any(menuitem, menucaption):not(.menuitem-iconic) > .menu-iconic-text,
|
||||
menulist > menupopup > :-moz-any(menuitem, menucaption):not(.menuitem-iconic) > .menu-iconic-text {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
|
|
|
@ -822,13 +822,13 @@ DrawThemeWithCairo(gfxContext* aContext, DrawTarget* aDrawTarget,
|
|||
|
||||
#ifndef MOZ_TREE_CAIRO
|
||||
// Directly use the Cairo draw target to render the widget if using system Cairo everywhere.
|
||||
BorrowedCairoContext borrow(aDrawTarget);
|
||||
if (borrow.mCairo) {
|
||||
cairo_set_matrix(borrow.mCairo, &mat);
|
||||
BorrowedCairoContext borrowCairo(aDrawTarget);
|
||||
if (borrowCairo.mCairo) {
|
||||
cairo_set_matrix(borrowCairo.mCairo, &mat);
|
||||
|
||||
moz_gtk_widget_paint(aGTKWidgetType, borrow.mCairo, &aGDKRect, &aState, aFlags, aDirection);
|
||||
moz_gtk_widget_paint(aGTKWidgetType, borrowCairo.mCairo, &aGDKRect, &aState, aFlags, aDirection);
|
||||
|
||||
borrow.Finish();
|
||||
borrowCairo.Finish();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
|
Загрузка…
Ссылка в новой задаче