diff --git a/accessible/atk/AccessibleWrap.cpp b/accessible/atk/AccessibleWrap.cpp
index 6df4f57cc17d..0dd7dfec2013 100644
--- a/accessible/atk/AccessibleWrap.cpp
+++ b/accessible/atk/AccessibleWrap.cpp
@@ -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);
+ }
}
}
diff --git a/browser/base/content/browser.xul b/browser/base/content/browser.xul
index a2a8161ff2e0..e419ecba3a43 100644
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -152,7 +152,11 @@
work correctly on the menupopup. ContentSelectDropdown expects the
popuponly menulist to be its immediate parent. -->
-
+
diff --git a/gfx/thebes/gfxWindowsPlatform.cpp b/gfx/thebes/gfxWindowsPlatform.cpp
index 1e2e179c5b17..1b24cb4233d6 100644
--- a/gfx/thebes/gfxWindowsPlatform.cpp
+++ b/gfx/thebes/gfxWindowsPlatform.cpp
@@ -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,13 +1832,17 @@ bool DoesD3D11AlphaTextureSharingWork(ID3D11Device *device)
{
nsCOMPtr 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) {
- return false;
- }
+ // 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;
}
}
@@ -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;
}
diff --git a/js/src/jit/MacroAssembler-inl.h b/js/src/jit/MacroAssembler-inl.h
index 490543e36f89..fb898d8c71ec 100644
--- a/js/src/jit/MacroAssembler-inl.h
+++ b/js/src/jit/MacroAssembler-inl.h
@@ -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));
}
// ===============================================================
diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h
index cf57663828af..0fae63acb5df 100644
--- a/js/src/jit/MacroAssembler.h
+++ b/js/src/jit/MacroAssembler.h
@@ -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
diff --git a/js/src/jit/RangeAnalysis.cpp b/js/src/jit/RangeAnalysis.cpp
index 75d3f924c594..955d9ca38600 100644
--- a/js/src/jit/RangeAnalysis.cpp
+++ b/js/src/jit/RangeAnalysis.cpp
@@ -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;
diff --git a/js/src/jsprf.cpp b/js/src/jsprf.cpp
index cc2db3246c17..b5bdb7cc3523 100644
--- a/js/src/jsprf.cpp
+++ b/js/src/jsprf.cpp
@@ -12,6 +12,7 @@
#include "jsprf.h"
+#include "mozilla/Snprintf.h"
#include "mozilla/Vector.h"
#include
@@ -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));
}
diff --git a/media/webrtc/signaling/src/jsep/JsepSessionImpl.cpp b/media/webrtc/signaling/src/jsep/JsepSessionImpl.cpp
index 253ca8cc75ff..e56ac9c54a94 100644
--- a/media/webrtc/signaling/src/jsep/JsepSessionImpl.cpp
+++ b/media/webrtc/signaling/src/jsep/JsepSessionImpl.cpp
@@ -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 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,17 +2730,30 @@ JsepSessionImpl::EndOfLocalCandidates(const std::string& defaultCandidateAddr,
return NS_ERROR_UNEXPECTED;
}
- std::set bundleMids;
- const SdpMediaSection* bundleMsection;
- nsresult rv = GetNegotiatedBundleInfo(&bundleMids, &bundleMsection);
- if (NS_FAILED(rv)) {
- MOZ_ASSERT(false);
- mLastError += " (This should have been caught sooner!)";
- return NS_ERROR_FAILURE;
+ if (level >= sdp->GetMediaSectionCount()) {
+ return NS_OK;
}
- if (level < sdp->GetMediaSectionCount()) {
- SdpMediaSection& msection = sdp->GetMediaSection(level);
+ 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 bundleMids;
+ const SdpMediaSection* 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 (msection.GetAttributeList().HasAttribute(SdpAttribute::kMidAttribute) &&
bundleMids.count(msection.GetAttributeList().GetMid())) {
@@ -2698,26 +2772,26 @@ JsepSessionImpl::EndOfLocalCandidates(const std::string& defaultCandidateAddr,
}
SetDefaultAddresses(defaultCandidateAddr,
defaultCandidatePort,
- defaultRtcpCandidateAddr,
+ defaultRtcpCandidateAddrCopy,
defaultRtcpCandidatePort,
bundledMsection);
}
}
+ }
- SetDefaultAddresses(defaultCandidateAddr,
- defaultCandidatePort,
- defaultRtcpCandidateAddr,
- defaultRtcpCandidatePort,
- &msection);
+ SetDefaultAddresses(defaultCandidateAddr,
+ defaultCandidatePort,
+ defaultRtcpCandidateAddrCopy,
+ defaultRtcpCandidatePort,
+ &msection);
- // TODO(bug 1095793): Will this have an mid someday?
+ // TODO(bug 1095793): Will this have an mid someday?
- SdpAttributeList& attrs = msection.GetAttributeList();
- attrs.SetAttribute(
- new SdpFlagAttribute(SdpAttribute::kEndOfCandidatesAttribute));
- if (!mIsOfferer) {
- attrs.RemoveAttribute(SdpAttribute::kIceOptionsAttribute);
- }
+ SdpAttributeList& attrs = msection.GetAttributeList();
+ attrs.SetAttribute(
+ new SdpFlagAttribute(SdpAttribute::kEndOfCandidatesAttribute));
+ if (!mIsOfferer) {
+ attrs.RemoveAttribute(SdpAttribute::kIceOptionsAttribute);
}
return NS_OK;
@@ -3039,10 +3113,8 @@ JsepSessionImpl::MsectionIsDisabled(const SdpMediaSection& msection) const
const Sdp*
JsepSessionImpl::GetAnswer() const
{
- MOZ_ASSERT(mState == kJsepStateStable);
-
- return mIsOfferer ? mCurrentRemoteDescription.get()
- : mCurrentLocalDescription.get();
+ return mWasOffererLastTime ? mCurrentRemoteDescription.get()
+ : mCurrentLocalDescription.get();
}
nsresult
diff --git a/media/webrtc/signaling/src/jsep/JsepSessionImpl.h b/media/webrtc/signaling/src/jsep/JsepSessionImpl.h
index a6bfcc2e01b6..12a823dbf0da 100644
--- a/media/webrtc/signaling/src/jsep/JsepSessionImpl.h
+++ b/media/webrtc/signaling/src/jsep/JsepSessionImpl.h
@@ -32,6 +32,7 @@ public:
JsepSessionImpl(const std::string& name, UniquePtr 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& 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& 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 mNegotiatedTrackPairs;
bool mIsOfferer;
+ bool mWasOffererLastTime;
bool mIceControlling;
std::string mIceUfrag;
std::string mIcePwd;
diff --git a/media/webrtc/signaling/test/jsep_session_unittest.cpp b/media/webrtc/signaling/test/jsep_session_unittest.cpp
index 7d802561ed23..d2fa350e61f4 100644
--- a/media/webrtc/signaling/test/jsep_session_unittest.cpp
+++ b/media/webrtc/signaling/test/jsep_session_unittest.cpp
@@ -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 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)
- {
- 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.EndOfLocalCandidates("192.168.0.2", 2002, "192.168.0.2", 3002, 0);
+ typedef enum {
+ RTP = 1,
+ RTCP = 2
+ } ComponentType;
- 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);
+ class CandidateSet {
+ public:
+ CandidateSet() {}
- std::cerr << "local SDP after candidates: "
- << session.GetLocalDescription();
- }
+ void Gather(JsepSession& session,
+ const std::vector& 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
- TrickleCandidates(JsepSession& session)
- {
- for (size_t i = 0; i < 3; ++i) {
- session.AddRemoteIceCandidate(
- kAEqualsCandidate + kCandidates[i], "", 0);
- session.AddRemoteIceCandidate(
- kAEqualsCandidate + kRtcpCandidates[i], "", 0);
- }
+ void Gather(JsepSession& session, size_t level, ComponentType component)
+ {
+ static uint16_t port = 1000;
+ std::vector candidates;
+ for (size_t i = 0; i < kNumCandidatesPerComponent; ++i) {
+ ++port;
+ std::ostringstream candidate;
+ candidate << "0 " << static_cast(component)
+ << " UDP 9999 192.168.0.1 " << port << " typ host";
+ bool skipped;
+ session.AddLocalIceCandidate(kAEqualsCandidate + candidate.str(),
+ "", level, &skipped);
+ if (!skipped) {
+ mCandidatesToTrickle.push_back(
+ std::pair(
+ level, kAEqualsCandidate + candidate.str()));
+ candidates.push_back(candidate.str());
+ }
+ }
- for (size_t i = 3; i < 6; ++i) {
- session.AddRemoteIceCandidate(
- kAEqualsCandidate + kCandidates[i], "", 1);
- session.AddRemoteIceCandidate(
- kAEqualsCandidate + kRtcpCandidates[i], "", 1);
- }
+ // Stomp existing candidates
+ mCandidates[level][component] = candidates;
- std::cerr << "remote SDP after candidates: "
- << session.GetRemoteDescription();
- }
+ // Stomp existing defaults
+ mDefaultCandidates[level][component] =
+ std::make_pair("192.168.0.1", port);
+ }
- void
- GatherOffererCandidates()
- {
- GatherCandidates(mSessionOff);
- }
+ void FinishGathering(JsepSession& session) const
+ {
+ // 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);
+ }
+ }
- void
- TrickleOffererCandidates()
- {
- TrickleCandidates(mSessionAns);
- }
+ void Trickle(JsepSession& session)
+ {
+ for (const auto& levelAndCandidate : mCandidatesToTrickle) {
+ session.AddRemoteIceCandidate(levelAndCandidate.second,
+ "",
+ levelAndCandidate.first);
+ }
+ mCandidatesToTrickle.clear();
+ }
+
+ void CheckRtpCandidates(bool expectRtpCandidates,
+ const SdpMediaSection& msection,
+ size_t transportLevel,
+ const std::string& context) const
+ {
+ 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>> mDefaultCandidates;
+ std::map>> mCandidates;
+ // Level/candidate pairs that need to be trickled
+ std::vector> 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 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 parsed = parser.Parse(*sdp);
+ UniquePtr parsed(Parse(*sdp));
ASSERT_TRUE(parsed.get());
ASSERT_LT(level, parsed->GetMediaSectionCount());
parsed->GetMediaSection(level).SetPort(0);
@@ -813,18 +867,29 @@ protected:
}
}
+ UniquePtr
+ Parse(const std::string& sdp) const
+ {
+ SipccSdpParser parser;
+ UniquePtr 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 types;
+ std::vector> 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(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 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 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 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 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 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 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 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 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 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 parsedOffer = parser.Parse(offer);
- ASSERT_TRUE(!!parsedOffer) << "Should have valid SDP" << std::endl
- << "Errors were: " << GetParseErrors(parser);
+ UniquePtr 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 parsedAnswer = parser.Parse(answer);
+ UniquePtr 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 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 offer(parser.Parse(mSessionOff.GetLocalDescription()));
+ UniquePtr 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 answer(parser.Parse(mSessionAns.GetLocalDescription()));
+ UniquePtr 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 offer(parser.Parse(mSessionOff.GetLocalDescription()));
+ UniquePtr 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 answer(parser.Parse(mSessionAns.GetLocalDescription()));
+ UniquePtr 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 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 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 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 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 parsedOffer = parser.Parse(offer);
+ UniquePtr 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 parsedOffer = parser.Parse(offer);
+ UniquePtr 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 parsedAnswer = parser.Parse(answer);
+ UniquePtr 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 parsedOffer = parser.Parse(offer);
+ UniquePtr parsedOffer(Parse(offer));
auto* rtcpfbs = new SdpRtcpFbAttributeList;
rtcpfbs->PushEntry("*", SdpRtcpFbAttributeList::kNack);
parsedOffer->GetMediaSection(0).GetAttributeList().SetAttribute(rtcpfbs);
diff --git a/python/mozbuild/mozbuild/frontend/context.py b/python/mozbuild/mozbuild/frontend/context.py
index 11b089545f70..eb552058e2dc 100644
--- a/python/mozbuild/mozbuild/frontend/context.py
+++ b/python/mozbuild/mozbuild/frontend/context.py
@@ -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.
#
diff --git a/python/mozbuild/mozbuild/test/frontend/test_context.py b/python/mozbuild/mozbuild/test/frontend/test_context.py
index f59c7de60088..74c971e69b18 100644
--- a/python/mozbuild/mozbuild/test/frontend/test_context.py
+++ b/python/mozbuild/mozbuild/test/frontend/test_context.py
@@ -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()
diff --git a/python/mozbuild/setup.py b/python/mozbuild/setup.py
index 285bfd5a0364..448a1362a3d9 100644
--- a/python/mozbuild/setup.py
+++ b/python/mozbuild/setup.py
@@ -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',
)
diff --git a/security/manager/ssl/SSLServerCertVerification.cpp b/security/manager/ssl/SSLServerCertVerification.cpp
index 406f4de254e9..7a04f2feb30d 100644
--- a/security/manager/ssl/SSLServerCertVerification.cpp
+++ b/security/manager/ssl/SSLServerCertVerification.cpp
@@ -462,16 +462,6 @@ CertErrorRunnable::CheckCertOverrides()
mDefaultErrorCodeToReport);
}
- nsCOMPtr 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 sslSocketControl = do_QueryInterface(
+ NS_ISUPPORTS_CAST(nsITransportSecurityInfo*, mInfoObject));
if (sslSocketControl) {
nsCOMPtr 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 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 sts
diff --git a/services/common/tests/mach_commands.py b/services/common/tests/mach_commands.py
index c45904971fb9..b48cfbdf3c35 100644
--- a/services/common/tests/mach_commands.py
+++ b/services/common/tests/mach_commands.py
@@ -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();',
diff --git a/testing/tools/screenshot/gdk-screenshot.cpp b/testing/tools/screenshot/gdk-screenshot.cpp
index 9cdeac577ace..cdf3eee5608a 100644
--- a/testing/tools/screenshot/gdk-screenshot.cpp
+++ b/testing/tools/screenshot/gdk-screenshot.cpp
@@ -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;
diff --git a/toolkit/components/jsdownloads/test/unit/head.js b/toolkit/components/jsdownloads/test/unit/head.js
index 70d34f1e2a7a..e03e672f8a06 100644
--- a/toolkit/components/jsdownloads/test/unit/head.js
+++ b/toolkit/components/jsdownloads/test/unit/head.js
@@ -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.
}
});
diff --git a/toolkit/themes/osx/global/menu.css b/toolkit/themes/osx/global/menu.css
index 1805e68d3347..87c1b36a4c6d 100644
--- a/toolkit/themes/osx/global/menu.css
+++ b/toolkit/themes/osx/global/menu.css
@@ -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;
}
diff --git a/toolkit/themes/windows/global/menu.css b/toolkit/themes/windows/global/menu.css
index 0c74e7a566c8..a526a708195c 100644
--- a/toolkit/themes/windows/global/menu.css
+++ b/toolkit/themes/windows/global/menu.css
@@ -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;
}
diff --git a/widget/gtk/nsNativeThemeGTK.cpp b/widget/gtk/nsNativeThemeGTK.cpp
index 233d769ecce7..b310002de947 100644
--- a/widget/gtk/nsNativeThemeGTK.cpp
+++ b/widget/gtk/nsNativeThemeGTK.cpp
@@ -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