commit 5c49f08417b342a2750110a372ef918f97d34bda parent 5f344ba28907a8387bf92aecddcd83bff5c582d6 Author: Valentin Gosu <valentin.gosu@gmail.com> Date: Wed, 17 Dec 2025 10:09:12 +0000 Bug 2003793 - Add priorityHeader marker to profiler r=acreskey,necko-reviewers,kershaw,profiler-reviewers,canaltinova Differential Revision: https://phabricator.services.mozilla.com/D274927 Diffstat:
13 files changed, 207 insertions(+), 49 deletions(-)
diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/HttpChannelChild.cpp @@ -996,9 +996,8 @@ void HttpChannelChild::OnStopRequest( mURI, requestMethod, priority, mChannelId, NetworkLoadType::LOAD_STOP, mLastStatusReported, now, mTransferSize, kCacheUnknown, mLoadInfo->GetInnerWindowID(), - mLoadInfo->GetOriginAttributes().IsPrivateBrowsing(), - mClassOfService.Flags(), mStatus, &mTransactionTimings, - std::move(mSource), httpVersion, responseStatus, + mLoadInfo->GetOriginAttributes().IsPrivateBrowsing(), this, mStatus, + &mTransactionTimings, std::move(mSource), httpVersion, responseStatus, Some(nsDependentCString(contentType.get()))); } @@ -1692,9 +1691,8 @@ void HttpChannelChild::Redirect1Begin( mURI, requestMethod, mPriority, mChannelId, NetworkLoadType::LOAD_REDIRECT, mLastStatusReported, TimeStamp::Now(), 0, kCacheUnknown, mLoadInfo->GetInnerWindowID(), - mLoadInfo->GetOriginAttributes().IsPrivateBrowsing(), - mClassOfService.Flags(), mStatus, &mTransactionTimings, - std::move(mSource), Some(responseHead.Version()), + mLoadInfo->GetOriginAttributes().IsPrivateBrowsing(), this, mStatus, + &mTransactionTimings, std::move(mSource), Some(responseHead.Version()), Some(responseHead.Status()), Some(nsDependentCString(contentType.get())), newOriginalURI, redirectFlags, channelId); @@ -2017,8 +2015,7 @@ HttpChannelChild::CompleteRedirectSetup(nsIStreamListener* aListener) { mURI, requestMethod, mPriority, mChannelId, NetworkLoadType::LOAD_START, mChannelCreationTimestamp, mLastStatusReported, 0, kCacheUnknown, mLoadInfo->GetInnerWindowID(), - mLoadInfo->GetOriginAttributes().IsPrivateBrowsing(), - mClassOfService.Flags(), mStatus); + mLoadInfo->GetOriginAttributes().IsPrivateBrowsing(), this, mStatus); } StoreIsPending(true); StoreWasOpened(true); @@ -2383,8 +2380,7 @@ nsresult HttpChannelChild::AsyncOpenInternal(nsIStreamListener* aListener) { mURI, requestMethod, mPriority, mChannelId, NetworkLoadType::LOAD_START, mChannelCreationTimestamp, mLastStatusReported, 0, kCacheUnknown, mLoadInfo->GetInnerWindowID(), - mLoadInfo->GetOriginAttributes().IsPrivateBrowsing(), - mClassOfService.Flags(), mStatus); + mLoadInfo->GetOriginAttributes().IsPrivateBrowsing(), this, mStatus); } StoreIsPending(true); StoreWasOpened(true); diff --git a/netwerk/protocol/http/InterceptedHttpChannel.cpp b/netwerk/protocol/http/InterceptedHttpChannel.cpp @@ -111,8 +111,7 @@ void InterceptedHttpChannel::AsyncOpenInternal() { mURI, requestMethod, mPriority, mChannelId, NetworkLoadType::LOAD_START, mChannelCreationTimestamp, mLastStatusReported, 0, kCacheUnknown, mLoadInfo->GetInnerWindowID(), - mLoadInfo->GetOriginAttributes().IsPrivateBrowsing(), - mClassOfService.Flags(), mStatus); + mLoadInfo->GetOriginAttributes().IsPrivateBrowsing(), this, mStatus); } // If an error occurs in this file we must ensure mListener callbacks are @@ -546,9 +545,8 @@ InterceptedHttpChannel::Cancel(nsresult aStatus) { mURI, requestMethod, priority, mChannelId, NetworkLoadType::LOAD_CANCEL, mLastStatusReported, TimeStamp::Now(), size, kCacheUnknown, mLoadInfo->GetInnerWindowID(), - mLoadInfo->GetOriginAttributes().IsPrivateBrowsing(), - mClassOfService.Flags(), mStatus, &mTransactionTimings, - std::move(mSource)); + mLoadInfo->GetOriginAttributes().IsPrivateBrowsing(), this, mStatus, + &mTransactionTimings, std::move(mSource)); } MOZ_DIAGNOSTIC_ASSERT(NS_FAILED(aStatus)); @@ -780,9 +778,8 @@ InterceptedHttpChannel::ResetInterception(bool aBypass) { mURI, requestMethod, priority, mChannelId, NetworkLoadType::LOAD_REDIRECT, mLastStatusReported, TimeStamp::Now(), size, kCacheUnknown, mLoadInfo->GetInnerWindowID(), - mLoadInfo->GetOriginAttributes().IsPrivateBrowsing(), - mClassOfService.Flags(), mStatus, &mTransactionTimings, - std::move(mSource), httpVersion, responseStatus, + mLoadInfo->GetOriginAttributes().IsPrivateBrowsing(), this, mStatus, + &mTransactionTimings, std::move(mSource), httpVersion, responseStatus, Some(nsDependentCString(contentType.get())), mURI, flags, newBaseChannel->ChannelId()); } @@ -1230,9 +1227,8 @@ InterceptedHttpChannel::OnStopRequest(nsIRequest* aRequest, nsresult aStatus) { mURI, requestMethod, priority, mChannelId, NetworkLoadType::LOAD_STOP, mLastStatusReported, TimeStamp::Now(), size, kCacheUnknown, mLoadInfo->GetInnerWindowID(), - mLoadInfo->GetOriginAttributes().IsPrivateBrowsing(), - mClassOfService.Flags(), mStatus, &mTransactionTimings, - std::move(mSource), httpVersion, responseStatus, + mLoadInfo->GetOriginAttributes().IsPrivateBrowsing(), this, mStatus, + &mTransactionTimings, std::move(mSource), httpVersion, responseStatus, Some(nsDependentCString(contentType.get()))); } diff --git a/netwerk/protocol/http/NetworkMarker.cpp b/netwerk/protocol/http/NetworkMarker.cpp @@ -10,6 +10,8 @@ #include "nsIChannelEventSink.h" #include "mozilla/Perfetto.h" #include "mozilla/ErrorNames.h" +#include "nsHttpHandler.h" +#include "nsIClassOfService.h" namespace mozilla::net { struct NetworkMarker { @@ -25,8 +27,8 @@ struct NetworkMarker { bool aIsPrivateBrowsing, const net::TimingStruct& aTimings, const ProfilerString8View& aRedirectURI, const ProfilerString8View& aContentType, uint32_t aRedirectFlags, - int64_t aRedirectChannelId, unsigned long aClassOfServiceFlag, - nsresult aRequestStatus, + int64_t aRedirectChannelId, uint32_t aClassOfServiceFlags, + bool aClassOfServiceIncremental, nsresult aRequestStatus, const mozilla::Maybe<mozilla::net::HttpVersion> aHttpVersion, mozilla::Maybe<uint32_t> aResponseStatus) { // This payload still streams a startTime and endTime property because it @@ -40,12 +42,22 @@ struct NetworkMarker { // Bug 1919148 - Moved aClassOfServiceStr here to ensure that we call // aWriter.StringProperty before the lifetime of nsAutoCString ends nsAutoCString aClassOfServiceStr; - GetClassOfService(aClassOfServiceStr, aClassOfServiceFlag); + GetClassOfService(aClassOfServiceStr, aClassOfServiceFlags); MOZ_ASSERT(aClassOfServiceStr.Length() > 0, "aClassOfServiceStr should be set after GetClassOfService"); aWriter.StringProperty("classOfService", MakeStringSpan(aClassOfServiceStr.get())); + uint8_t urgency = + nsHttpHandler::UrgencyFromCoSFlags(aClassOfServiceFlags, aPri); + nsAutoCString priorityHeader; + priorityHeader.AppendPrintf("u=%d", urgency); + if (aClassOfServiceIncremental) { + priorityHeader.Append(", i"); + } + aWriter.StringProperty("priorityHeader", + MakeStringSpan(priorityHeader.get())); + nsAutoCString aRequestStatusStr; GetErrorName(aRequestStatus, aRequestStatusStr); aWriter.StringProperty("requestStatus", @@ -165,7 +177,7 @@ struct NetworkMarker { // Update an empty string aClassOfServiceStr based on aClassOfServiceFlag static void GetClassOfService(nsAutoCString& aClassOfServiceStr, - unsigned long aClassOfServiceFlag) { + uint32_t aClassOfServiceFlag) { MOZ_ASSERT(aClassOfServiceStr.IsEmpty(), "Flags should not be appended to aClassOfServiceStr before " "calling GetClassOfService"); @@ -389,7 +401,7 @@ void profiler_add_network_marker( mozilla::TimeStamp aEnd, int64_t aCount, nsICacheInfoChannel::CacheDisposition aCacheDisposition, uint64_t aInnerWindowID, bool aIsPrivateBrowsing, - unsigned long aClassOfServiceFlag, nsresult aRequestStatus, + nsIClassOfService* aClassOfService, nsresult aRequestStatus, const mozilla::net::TimingStruct* aTimings, UniquePtr<ProfileChunkedBuffer> aSource, const Maybe<mozilla::net::HttpVersion> aHttpVersion, @@ -418,6 +430,13 @@ void profiler_add_network_marker( aRedirectURI->GetAsciiSpec(redirect_spec); } + uint32_t classOfServiceFlags = 0; + bool classOfServiceIncremental = false; + if (aClassOfService) { + aClassOfService->GetClassFlags(&classOfServiceFlags); + aClassOfService->GetIncremental(&classOfServiceIncremental); + } + profiler_add_marker( name, geckoprofiler::category::NETWORK, {MarkerTiming::Interval(aStart, aEnd), @@ -428,7 +447,7 @@ void profiler_add_network_marker( aIsPrivateBrowsing, aTimings ? *aTimings : scEmptyNetTimingStruct, redirect_spec, aContentType ? ProfilerString8View(*aContentType) : ProfilerString8View(), - aRedirectFlags, aRedirectChannelId, aClassOfServiceFlag, aRequestStatus, - aHttpVersion, aResponseStatus); + aRedirectFlags, aRedirectChannelId, classOfServiceFlags, + classOfServiceIncremental, aRequestStatus, aHttpVersion, aResponseStatus); } } // namespace mozilla::net diff --git a/netwerk/protocol/http/NetworkMarker.h b/netwerk/protocol/http/NetworkMarker.h @@ -30,7 +30,7 @@ void profiler_add_network_marker( mozilla::TimeStamp aEnd, int64_t aCount, nsICacheInfoChannel::CacheDisposition aCacheDisposition, uint64_t aInnerWindowID, bool aIsPrivateBrowsing, - unsigned long aClassOfServiceFlag, nsresult aRequestStatus, + nsIClassOfService* aClassOfService, nsresult aRequestStatus, const mozilla::net::TimingStruct* aTimings = nullptr, mozilla::UniquePtr<mozilla::ProfileChunkedBuffer> aSource = nullptr, const mozilla::Maybe<mozilla::net::HttpVersion> aHttpVersion = diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp @@ -6559,9 +6559,8 @@ nsresult nsHttpChannel::SetupReplacementChannel(nsIURI* newURI, mURI, requestMethod, priority, mChannelId, NetworkLoadType::LOAD_REDIRECT, mLastStatusReported, TimeStamp::Now(), size, mCacheDisposition, mLoadInfo->GetInnerWindowID(), - mLoadInfo->GetOriginAttributes().IsPrivateBrowsing(), - mClassOfService.Flags(), mStatus, &timings, std::move(mSource), - httpVersion, responseStatus, + mLoadInfo->GetOriginAttributes().IsPrivateBrowsing(), this, mStatus, + &timings, std::move(mSource), httpVersion, responseStatus, Some(nsDependentCString(contentType.get())), newURI, redirectFlags, channelId); } @@ -7228,9 +7227,8 @@ nsresult nsHttpChannel::CancelInternal(nsresult status) { mURI, requestMethod, priority, mChannelId, NetworkLoadType::LOAD_CANCEL, mLastStatusReported, TimeStamp::Now(), size, mCacheDisposition, mLoadInfo->GetInnerWindowID(), - mLoadInfo->GetOriginAttributes().IsPrivateBrowsing(), - mClassOfService.Flags(), mStatus, &mTransactionTimings, - std::move(mSource)); + mLoadInfo->GetOriginAttributes().IsPrivateBrowsing(), this, mStatus, + &mTransactionTimings, std::move(mSource)); } // If we don't have mTransactionPump and mCachePump, we need to call @@ -7621,8 +7619,7 @@ void nsHttpChannel::AsyncOpenFinal(TimeStamp aTimeStamp) { mURI, requestMethod, mPriority, mChannelId, NetworkLoadType::LOAD_START, mChannelCreationTimestamp, mLastStatusReported, 0, mCacheDisposition, mLoadInfo->GetInnerWindowID(), - mLoadInfo->GetOriginAttributes().IsPrivateBrowsing(), - mClassOfService.Flags(), mStatus); + mLoadInfo->GetOriginAttributes().IsPrivateBrowsing(), this, mStatus); } // Added due to PauseTask/DelayHttpChannel @@ -10362,9 +10359,8 @@ nsresult nsHttpChannel::ContinueOnStopRequest(nsresult aStatus, bool aIsFromNet, mURI, requestMethod, priority, mChannelId, NetworkLoadType::LOAD_STOP, mLastStatusReported, TimeStamp::Now(), size, mCacheDisposition, mLoadInfo->GetInnerWindowID(), - mLoadInfo->GetOriginAttributes().IsPrivateBrowsing(), - mClassOfService.Flags(), mStatus, &mTransactionTimings, - std::move(mSource), httpVersion, responseStatus, + mLoadInfo->GetOriginAttributes().IsPrivateBrowsing(), this, mStatus, + &mTransactionTimings, std::move(mSource), httpVersion, responseStatus, Some(nsDependentCString(contentType.get()))); } diff --git a/tools/profiler/tests/browser/browser_test_marker_network_cancel.js b/tools/profiler/tests/browser/browser_test_marker_network_cancel.js @@ -66,6 +66,7 @@ add_task(async function test_network_markers_early_cancel() { endTime: Expect.number(), id: Expect.number(), pri: Expect.number(), + priorityHeader: Expect.string(), cache: "Unresolved", }), }; diff --git a/tools/profiler/tests/browser/browser_test_marker_network_redirect.js b/tools/profiler/tests/browser/browser_test_marker_network_redirect.js @@ -98,6 +98,7 @@ add_task(async function test_network_markers_redirect_simple() { id: Expect.number(), redirectId: parentStopMarker.data.id, pri: Expect.number(), + priorityHeader: Expect.string(), cache: Expect.stringMatches(/Missed|Unresolved/), redirectType: "Permanent", isHttpToHttpsRedirect: false, @@ -133,6 +134,7 @@ add_task(async function test_network_markers_redirect_simple() { id: Expect.number(), count: Expect.number(), pri: Expect.number(), + priorityHeader: Expect.string(), }; Assert.objectContains(parentStopMarker, expectedProperties); @@ -245,6 +247,7 @@ add_task(async function test_network_markers_redirect_resources() { endTime: Expect.number(), id: Expect.number(), pri: Expect.number(), + priorityHeader: Expect.string(), innerWindowID: Expect.number(), requestStart: Expect.number(), responseStart: Expect.number(), diff --git a/tools/profiler/tests/browser/browser_test_marker_network_serviceworker_cache_first.js b/tools/profiler/tests/browser/browser_test_marker_network_serviceworker_cache_first.js @@ -321,6 +321,7 @@ add_task(async function test_network_markers_service_worker_use() { endTime: Expect.number(), id: Expect.number(), pri: Expect.number(), + priorityHeader: Expect.string(), }; const expectedProperties = { diff --git a/tools/profiler/tests/browser/browser_test_marker_network_serviceworker_no_fetch_handler.js b/tools/profiler/tests/browser/browser_test_marker_network_serviceworker_no_fetch_handler.js @@ -179,6 +179,7 @@ add_task(async function test_network_markers_service_worker_use() { endTime: Expect.number(), id: Expect.number(), pri: Expect.number(), + priorityHeader: Expect.string(), count: Expect.number(), domainLookupStart: Expect.number(), domainLookupEnd: Expect.number(), diff --git a/tools/profiler/tests/browser/browser_test_marker_network_serviceworker_no_respondWith_in_fetch_handler.js b/tools/profiler/tests/browser/browser_test_marker_network_serviceworker_no_respondWith_in_fetch_handler.js @@ -216,6 +216,7 @@ add_task(async function test_network_markers_service_worker_use() { endTime: Expect.number(), id: Expect.number(), pri: Expect.number(), + priorityHeader: Expect.string(), count: Expect.number(), domainLookupStart: Expect.number(), domainLookupEnd: Expect.number(), @@ -241,6 +242,7 @@ add_task(async function test_network_markers_service_worker_use() { endTime: Expect.number(), id: Expect.number(), pri: Expect.number(), + priorityHeader: Expect.string(), redirectType: "Internal", isHttpToHttpsRedirect: false, }; diff --git a/tools/profiler/tests/browser/browser_test_marker_network_serviceworker_synthetized_response.js b/tools/profiler/tests/browser/browser_test_marker_network_serviceworker_synthetized_response.js @@ -234,6 +234,7 @@ add_task(async function test_network_markers_service_worker_use() { endTime: Expect.number(), id: Expect.number(), pri: Expect.number(), + priorityHeader: Expect.string(), redirectId: htmlFetch1.data.id, redirectType: "Internal", isHttpToHttpsRedirect: false, @@ -258,6 +259,7 @@ add_task(async function test_network_markers_service_worker_use() { endTime: Expect.number(), id: Expect.number(), pri: Expect.number(), + priorityHeader: Expect.string(), }), }); Assert.objectContains(htmlFetch2, { @@ -290,6 +292,7 @@ add_task(async function test_network_markers_service_worker_use() { id: Expect.number(), count: Expect.number(), pri: Expect.number(), + priorityHeader: Expect.string(), }), }); /* ----- /HTML FILE ---- */ @@ -309,6 +312,7 @@ add_task(async function test_network_markers_service_worker_use() { endTime: Expect.number(), id: Expect.number(), pri: Expect.number(), + priorityHeader: Expect.string(), redirectId: generatedSvgFetch.data.id, redirectType: "Internal", isHttpToHttpsRedirect: false, @@ -333,6 +337,7 @@ add_task(async function test_network_markers_service_worker_use() { endTime: Expect.number(), id: Expect.number(), pri: Expect.number(), + priorityHeader: Expect.string(), innerWindowID: Expect.number(), }), }); @@ -352,6 +357,7 @@ add_task(async function test_network_markers_service_worker_use() { endTime: Expect.number(), id: Expect.number(), pri: Expect.number(), + priorityHeader: Expect.string(), redirectId: firefoxSvgFetch1.data.id, redirectType: "Internal", isHttpToHttpsRedirect: false, @@ -376,6 +382,7 @@ add_task(async function test_network_markers_service_worker_use() { endTime: Expect.number(), id: Expect.number(), pri: Expect.number(), + priorityHeader: Expect.string(), innerWindowID: Expect.number(), }), }); @@ -409,6 +416,7 @@ add_task(async function test_network_markers_service_worker_use() { id: Expect.number(), count: Expect.number(), pri: Expect.number(), + priorityHeader: Expect.string(), // Note: no innerWindowID here, is that a bug? }), }); @@ -481,6 +489,7 @@ add_task(async function test_network_markers_service_worker_use() { endTime: Expect.number(), id: Expect.number(), pri: Expect.number(), + priorityHeader: Expect.string(), }), }); Assert.objectContains(generatedSvgFetch1, { @@ -499,6 +508,7 @@ add_task(async function test_network_markers_service_worker_use() { endTime: Expect.number(), id: Expect.number(), pri: Expect.number(), + priorityHeader: Expect.string(), innerWindowID: Expect.number(), }), }); @@ -518,6 +528,7 @@ add_task(async function test_network_markers_service_worker_use() { endTime: Expect.number(), id: Expect.number(), pri: Expect.number(), + priorityHeader: Expect.string(), innerWindowID: Expect.number(), }), }); diff --git a/tools/profiler/tests/browser/browser_test_marker_network_sts.js b/tools/profiler/tests/browser/browser_test_marker_network_sts.js @@ -84,6 +84,7 @@ add_task(async function test_network_markers_redirect_to_https() { id: Expect.number(), redirectId: parentStopMarker.data.id, pri: Expect.number(), + priorityHeader: Expect.string(), cache: "Unresolved", redirectType: "Permanent", isHttpToHttpsRedirect: true, @@ -119,6 +120,7 @@ add_task(async function test_network_markers_redirect_to_https() { id: Expect.number(), count: Expect.number(), pri: Expect.number(), + priorityHeader: Expect.string(), }; Assert.objectContains(parentStopMarker, expectedProperties); diff --git a/tools/profiler/tests/gtest/GeckoProfiler.cpp b/tools/profiler/tests/gtest/GeckoProfiler.cpp @@ -2285,6 +2285,77 @@ TEST(GeckoProfiler, Pause) }}.join(); } +// Mock nsIClassOfService for network marker tests +class MockClassOfService final : public nsIClassOfService { + public: + NS_DECL_ISUPPORTS + + explicit MockClassOfService(uint32_t aClassFlags, bool aIncremental = false, + nsIClassOfService::FetchPriority aFetchPriority = + nsIClassOfService::FETCHPRIORITY_UNSET) + : mClassFlags(aClassFlags), + mIncremental(aIncremental), + mFetchPriority(aFetchPriority) {} + + NS_IMETHOD GetClassFlags(uint32_t* aFlags) override { + *aFlags = mClassFlags; + return NS_OK; + } + + NS_IMETHOD SetClassFlags(uint32_t aFlags) override { + mClassFlags = aFlags; + return NS_OK; + } + + NS_IMETHOD ClearClassFlags(uint32_t aFlags) override { + mClassFlags &= ~aFlags; + return NS_OK; + } + + NS_IMETHOD AddClassFlags(uint32_t aFlags) override { + mClassFlags |= aFlags; + return NS_OK; + } + + NS_IMETHOD GetIncremental(bool* aIncremental) override { + *aIncremental = mIncremental; + return NS_OK; + } + + NS_IMETHOD SetIncremental(bool aIncremental) override { + mIncremental = aIncremental; + return NS_OK; + } + + NS_IMETHOD GetFetchPriority( + nsIClassOfService::FetchPriority* aFetchPriority) override { + *aFetchPriority = mFetchPriority; + return NS_OK; + } + + NS_IMETHOD SetFetchPriority( + nsIClassOfService::FetchPriority aFetchPriority) override { + mFetchPriority = aFetchPriority; + return NS_OK; + } + + NS_IMETHOD SetClassOfService(mozilla::net::ClassOfService s) override { + return NS_ERROR_NOT_IMPLEMENTED; + } + + NS_IMETHOD_(void) + SetFetchPriorityDOM(mozilla::dom::FetchPriority aPriority) override {} + + private: + ~MockClassOfService() = default; + + uint32_t mClassFlags; + bool mIncremental; + nsIClassOfService::FetchPriority mFetchPriority; +}; + +NS_IMPL_ISUPPORTS(MockClassOfService, nsIClassOfService) + TEST(GeckoProfiler, Markers) { uint32_t features = ProfilerFeature::StackWalk; @@ -2510,6 +2581,8 @@ TEST(GeckoProfiler, Markers) ASSERT_TRUE( NS_SUCCEEDED(NS_NewURI(getter_AddRefs(uri), "http://mozilla.org/"_ns))); // The marker name will be "Load <aChannelId>: <aURI>". + RefPtr<MockClassOfService> classOfService1 = + new MockClassOfService(nsIClassOfService::Leader); profiler_add_network_marker( /* nsIURI* aURI */ uri, /* const nsACString& aRequestMethod */ "GET"_ns, @@ -2523,7 +2596,7 @@ TEST(GeckoProfiler, Markers) nsICacheInfoChannel::kCacheHit, /* uint64_t aInnerWindowID */ 78, /* bool aIsPrivateBrowsing */ false, - /* unsigned long aClassOfServiceFlag */ nsIClassOfService::Leader, + /* nsIClassOfService* aClassOfService */ classOfService1, /* nsresult aRequestStatus */ NS_OK /* const mozilla::net::TimingStruct* aTimings = nullptr */ /* mozilla::UniquePtr<mozilla::ProfileChunkedBuffer> aSource = @@ -2537,6 +2610,8 @@ TEST(GeckoProfiler, Markers) /* uint64_t aRedirectChannelId = 0 */ ); + RefPtr<MockClassOfService> classOfService2 = + new MockClassOfService(nsIClassOfService::Follower); profiler_add_network_marker( /* nsIURI* aURI */ uri, /* const nsACString& aRequestMethod */ "GET"_ns, @@ -2550,7 +2625,7 @@ TEST(GeckoProfiler, Markers) nsICacheInfoChannel::kCacheUnresolved, /* uint64_t aInnerWindowID */ 78, /* bool aIsPrivateBrowsing */ false, - /* unsigned long aClassOfServiceFlag */ nsIClassOfService::Follower, + /* nsIClassOfService* aClassOfService */ classOfService2, /* nsresult aRequestStatus */ NS_BINDING_ABORTED, /* const mozilla::net::TimingStruct* aTimings = nullptr */ nullptr, /* mozilla::UniquePtr<mozilla::ProfileChunkedBuffer> aSource = @@ -2570,6 +2645,8 @@ TEST(GeckoProfiler, Markers) nsCOMPtr<nsIURI> redirectURI; ASSERT_TRUE(NS_SUCCEEDED( NS_NewURI(getter_AddRefs(redirectURI), "http://example.com/"_ns))); + RefPtr<MockClassOfService> classOfService3 = + new MockClassOfService(nsIClassOfService::Speculative); profiler_add_network_marker( /* nsIURI* aURI */ uri, /* const nsACString& aRequestMethod */ "GET"_ns, @@ -2583,7 +2660,7 @@ TEST(GeckoProfiler, Markers) nsICacheInfoChannel::kCacheUnresolved, /* uint64_t aInnerWindowID */ 78, /* bool aIsPrivateBrowsing */ false, - /* unsigned long aClassOfServiceFlag */ nsIClassOfService::Speculative, + /* nsIClassOfService* aClassOfService */ classOfService3, /* nsresult aRequestStatus */ NS_ERROR_UNEXPECTED, /* const mozilla::net::TimingStruct* aTimings = nullptr */ nullptr, /* mozilla::UniquePtr<mozilla::ProfileChunkedBuffer> aSource = @@ -2602,6 +2679,8 @@ TEST(GeckoProfiler, Markers) nsIChannelEventSink::REDIRECT_TEMPORARY, /* uint64_t aRedirectChannelId = 0 */ 103); + RefPtr<MockClassOfService> classOfService4 = + new MockClassOfService(nsIClassOfService::Background); profiler_add_network_marker( /* nsIURI* aURI */ uri, /* const nsACString& aRequestMethod */ "GET"_ns, @@ -2615,7 +2694,7 @@ TEST(GeckoProfiler, Markers) nsICacheInfoChannel::kCacheUnresolved, /* uint64_t aInnerWindowID */ 78, /* bool aIsPrivateBrowsing */ false, - /* unsigned long aClassOfServiceFlag */ nsIClassOfService::Background, + /* nsIClassOfService* aClassOfService */ classOfService4, /* nsresult aRequestStatus */ NS_ERROR_DOCSHELL_DYING, /* const mozilla::net::TimingStruct* aTimings = nullptr */ nullptr, /* mozilla::UniquePtr<mozilla::ProfileChunkedBuffer> aSource = @@ -2634,6 +2713,8 @@ TEST(GeckoProfiler, Markers) nsIChannelEventSink::REDIRECT_PERMANENT, /* uint64_t aRedirectChannelId = 0 */ 104); + RefPtr<MockClassOfService> classOfService5 = new MockClassOfService( + nsIClassOfService::Unblocked | nsIClassOfService::TailForbidden); profiler_add_network_marker( /* nsIURI* aURI */ uri, /* const nsACString& aRequestMethod */ "GET"_ns, @@ -2647,8 +2728,7 @@ TEST(GeckoProfiler, Markers) nsICacheInfoChannel::kCacheUnresolved, /* uint64_t aInnerWindowID */ 78, /* bool aIsPrivateBrowsing */ false, - /* unsigned long aClassOfServiceFlag */ nsIClassOfService::Unblocked | - nsIClassOfService::TailForbidden, + /* nsIClassOfService* aClassOfService */ classOfService5, /* nsresult aRequestStatus */ NS_ERROR_DOM_CORP_FAILED, /* const mozilla::net::TimingStruct* aTimings = nullptr */ nullptr, /* mozilla::UniquePtr<mozilla::ProfileChunkedBuffer> aSource = @@ -2666,6 +2746,9 @@ TEST(GeckoProfiler, Markers) /* uint32_t aRedirectFlags = 0 */ nsIChannelEventSink::REDIRECT_INTERNAL, /* uint64_t aRedirectChannelId = 0 */ 105); + RefPtr<MockClassOfService> classOfService6 = new MockClassOfService( + nsIClassOfService::Unblocked | nsIClassOfService::Throttleable | + nsIClassOfService::TailForbidden); profiler_add_network_marker( /* nsIURI* aURI */ uri, /* const nsACString& aRequestMethod */ "GET"_ns, @@ -2679,8 +2762,7 @@ TEST(GeckoProfiler, Markers) nsICacheInfoChannel::kCacheUnresolved, /* uint64_t aInnerWindowID */ 78, /* bool aIsPrivateBrowsing */ false, - /* unsigned long aClassOfServiceFlag */ nsIClassOfService::Unblocked | - nsIClassOfService::Throttleable | nsIClassOfService::TailForbidden, + /* nsIClassOfService* aClassOfService */ classOfService6, /* nsresult aRequestStatus */ NS_ERROR_BLOCKED_BY_POLICY, /* const mozilla::net::TimingStruct* aTimings = nullptr */ nullptr, /* mozilla::UniquePtr<mozilla::ProfileChunkedBuffer> aSource = @@ -2698,6 +2780,9 @@ TEST(GeckoProfiler, Markers) /* uint32_t aRedirectFlags = 0 */ nsIChannelEventSink::REDIRECT_INTERNAL | nsIChannelEventSink::REDIRECT_STS_UPGRADE, /* uint64_t aRedirectChannelId = 0 */ 106); + + RefPtr<MockClassOfService> classOfService7 = + new MockClassOfService(nsIClassOfService::Tail); profiler_add_network_marker( /* nsIURI* aURI */ uri, /* const nsACString& aRequestMethod */ "GET"_ns, @@ -2711,7 +2796,7 @@ TEST(GeckoProfiler, Markers) nsICacheInfoChannel::kCacheUnresolved, /* uint64_t aInnerWindowID */ 78, /* bool aIsPrivateBrowsing */ true, - /* unsigned long aClassOfServiceFlag */ nsIClassOfService::Tail, + /* nsIClassOfService* aClassOfService */ classOfService7, /* nsresult aRequestStatus */ NS_BINDING_REDIRECTED /* const mozilla::net::TimingStruct* aTimings = nullptr */ /* mozilla::UniquePtr<mozilla::ProfileChunkedBuffer> aSource = @@ -2725,6 +2810,26 @@ TEST(GeckoProfiler, Markers) /* uint64_t aRedirectChannelId = 0 */ ); + // Test network marker with FetchPriority to verify priorityHeader + RefPtr<MockClassOfService> classOfService8 = + new MockClassOfService(nsIClassOfService::Leader, /* incremental */ true, + nsIClassOfService::FETCHPRIORITY_HIGH); + profiler_add_network_marker( + /* nsIURI* aURI */ uri, + /* const nsACString& aRequestMethod */ "GET"_ns, + /* int32_t aPriority */ 34, + /* uint64_t aChannelId */ 8, + /* NetworkLoadType aType */ net::NetworkLoadType::LOAD_START, + /* mozilla::TimeStamp aStart */ ts1, + /* mozilla::TimeStamp aEnd */ ts2, + /* int64_t aCount */ 56, + /* nsICacheInfoChannel::CacheDisposition aCacheDisposition */ + nsICacheInfoChannel::kCacheHit, + /* uint64_t aInnerWindowID */ 78, + /* bool aIsPrivateBrowsing */ false, + /* nsIClassOfService* aClassOfService */ classOfService8, + /* nsresult aRequestStatus */ NS_OK); + EXPECT_TRUE(profiler_add_marker_impl( "Text in main thread with stack", geckoprofiler::category::OTHER, {MarkerStack::Capture(), MarkerTiming::Interval(ts1, ts2)}, @@ -2824,6 +2929,7 @@ TEST(GeckoProfiler, Markers) S_NetworkMarkerPayload_redirect_internal, S_NetworkMarkerPayload_redirect_internal_sts, S_NetworkMarkerPayload_private_browsing, + S_NetworkMarkerPayload_priorityHeader, S_TextWithStack, S_TextToMTWithStack, @@ -3304,6 +3410,30 @@ TEST(GeckoProfiler, Markers) EXPECT_TRUE(payload["isHttpToHttpsRedirect"].isNull()); EXPECT_TRUE(payload["redirectId"].isNull()); EXPECT_TRUE(payload["contentType"].isNull()); + + } else if (nameString == "Load 8: http://mozilla.org/") { + EXPECT_EQ(state, S_NetworkMarkerPayload_priorityHeader); + state = State(S_NetworkMarkerPayload_priorityHeader + 1); + EXPECT_EQ(typeString, "Network"); + EXPECT_EQ_JSON(payload["startTime"], Double, ts1Double); + EXPECT_EQ_JSON(payload["endTime"], Double, ts2Double); + EXPECT_EQ_JSON(payload["id"], Int64, 8); + EXPECT_EQ_JSON(payload["URI"], String, "http://mozilla.org/"); + EXPECT_EQ_JSON(payload["requestMethod"], String, "GET"); + EXPECT_EQ_JSON(payload["pri"], Int64, 34); + EXPECT_EQ_JSON(payload["count"], Int64, 56); + EXPECT_EQ_JSON(payload["cache"], String, "Hit"); + EXPECT_TRUE(payload["isPrivateBrowsing"].isNull()); + EXPECT_EQ_JSON(payload["classOfService"], String, "Leader"); + EXPECT_EQ_JSON(payload["requestStatus"], String, "NS_OK"); + EXPECT_TRUE(payload["RedirectURI"].isNull()); + EXPECT_TRUE(payload["redirectType"].isNull()); + EXPECT_TRUE(payload["isHttpToHttpsRedirect"].isNull()); + EXPECT_TRUE(payload["redirectId"].isNull()); + EXPECT_TRUE(payload["contentType"].isNull()); + EXPECT_FALSE(payload["priorityHeader"].isNull()); + EXPECT_EQ_JSON(payload["priorityHeader"], String, "u=4, i"); + } else if (nameString == "Text in main thread with stack") { EXPECT_EQ(state, S_TextWithStack); state = State(S_TextWithStack + 1);