mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
Bug 1658097 - [fission] Send resource timing data for cross-origin frames to the correct process r=nika,necko-reviewers,dragana
Differential Revision: https://phabricator.services.mozilla.com/D96754
This commit is contained in:
parent
4916cac75d
commit
bd132e112d
@ -196,6 +196,7 @@
|
||||
#include "base/task.h"
|
||||
#include "mozilla/dom/BlobURLProtocolHandler.h"
|
||||
#include "mozilla/dom/PCycleCollectWithLogsChild.h"
|
||||
#include "mozilla/dom/PerformanceStorage.h"
|
||||
#include "nsChromeRegistryContent.h"
|
||||
#include "nsFrameMessageManager.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
@ -4078,6 +4079,24 @@ mozilla::ipc::IPCResult ContentChild::RecvScriptError(
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult ContentChild::RecvReportFrameTimingData(
|
||||
uint64_t innerWindowId, const nsString& entryName,
|
||||
const nsString& initiatorType, UniquePtr<PerformanceTimingData>&& aData) {
|
||||
auto* innerWindow = nsGlobalWindowInner::GetInnerWindowWithId(innerWindowId);
|
||||
if (!innerWindow) {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::dom::Performance* performance = innerWindow->GetPerformance();
|
||||
if (!performance) {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
performance->AsPerformanceStorage()->AddEntry(entryName, initiatorType,
|
||||
std::move(aData));
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult ContentChild::RecvLoadURI(
|
||||
const MaybeDiscarded<BrowsingContext>& aContext,
|
||||
nsDocShellLoadState* aLoadState, bool aSetNavigating,
|
||||
|
@ -763,6 +763,10 @@ class ContentChild final : public PContentChild,
|
||||
const nsCString& aCategory, const bool& aFromPrivateWindow,
|
||||
const uint64_t& aInnerWindowId, const bool& aFromChromeContext);
|
||||
|
||||
mozilla::ipc::IPCResult RecvReportFrameTimingData(
|
||||
uint64_t innerWindowId, const nsString& entryName,
|
||||
const nsString& initiatorType, UniquePtr<PerformanceTimingData>&& aData);
|
||||
|
||||
mozilla::ipc::IPCResult RecvLoadURI(
|
||||
const MaybeDiscarded<BrowsingContext>& aContext,
|
||||
nsDocShellLoadState* aLoadState, bool aSetNavigating,
|
||||
|
@ -4504,6 +4504,23 @@ mozilla::ipc::IPCResult ContentParent::RecvConsoleMessage(
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult ContentParent::RecvReportFrameTimingData(
|
||||
uint64_t aInnerWindowId, const nsString& entryName,
|
||||
const nsString& initiatorType, UniquePtr<PerformanceTimingData>&& aData) {
|
||||
RefPtr<WindowGlobalParent> parent =
|
||||
WindowGlobalParent::GetByInnerWindowId(aInnerWindowId);
|
||||
if (!parent || !parent->GetContentParent()) {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
MOZ_ASSERT(parent->GetContentParent() != this,
|
||||
"No need to bounce around if in the same process");
|
||||
|
||||
Unused << parent->GetContentParent()->SendReportFrameTimingData(
|
||||
aInnerWindowId, entryName, initiatorType, std::move(aData));
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult ContentParent::RecvScriptError(
|
||||
const nsString& aMessage, const nsString& aSourceName,
|
||||
const nsString& aSourceLine, const uint32_t& aLineNumber,
|
||||
|
@ -1097,6 +1097,10 @@ class ContentParent final
|
||||
const nsCString& aCategory, const bool& aIsFromPrivateWindow,
|
||||
const uint64_t& aInnerWindowId, const bool& aIsFromChromeContext);
|
||||
|
||||
mozilla::ipc::IPCResult RecvReportFrameTimingData(
|
||||
uint64_t innerWindowId, const nsString& entryName,
|
||||
const nsString& initiatorType, UniquePtr<PerformanceTimingData>&& aData);
|
||||
|
||||
mozilla::ipc::IPCResult RecvScriptErrorWithStack(
|
||||
const nsString& aMessage, const nsString& aSourceName,
|
||||
const nsString& aSourceLine, const uint32_t& aLineNumber,
|
||||
|
@ -133,6 +133,7 @@ using class mozilla::dom::SessionHistoryInfo from "mozilla/dom/SessionHistoryEnt
|
||||
using nsPoint from "mozilla/GfxMessageUtils.h";
|
||||
using struct mozilla::dom::LoadingSessionHistoryInfo from "mozilla/dom/SessionHistoryEntry.h";
|
||||
using mozilla::PDMFactory::MediaCodecsSupported from "PDMFactory.h";
|
||||
using mozilla::dom::PerformanceTimingData from "mozilla/dom/PerformanceTiming.h";
|
||||
|
||||
union ChromeRegistryItem
|
||||
{
|
||||
@ -1708,6 +1709,16 @@ both:
|
||||
nsCString category, bool privateWindow, uint64_t innerWindowId,
|
||||
bool fromChromeContext);
|
||||
|
||||
/**
|
||||
* Used in fission to report timing data when the parent window is in
|
||||
* another process. Child frame will send data to its ContentParent which
|
||||
* will then identify the ContentParent for the innerWindowId and pass
|
||||
* the data to the correct process.
|
||||
*/
|
||||
async ReportFrameTimingData(uint64_t innerWindowId, nsString entryName,
|
||||
nsString initiatorType,
|
||||
UniquePtr<PerformanceTimingData> aData);
|
||||
|
||||
async CommitBrowsingContextTransaction(MaybeDiscardedBrowsingContext aContext,
|
||||
BrowsingContextTransaction aTransaction,
|
||||
uint64_t aEpoch);
|
||||
|
@ -154,6 +154,12 @@ void PerformanceMainThread::AddEntry(nsIHttpChannel* channel,
|
||||
AddRawEntry(std::move(performanceTimingData), initiatorType, entryName);
|
||||
}
|
||||
|
||||
void PerformanceMainThread::AddEntry(const nsString& entryName,
|
||||
const nsString& initiatorType,
|
||||
UniquePtr<PerformanceTimingData>&& aData) {
|
||||
AddRawEntry(std::move(aData), initiatorType, entryName);
|
||||
}
|
||||
|
||||
void PerformanceMainThread::AddRawEntry(UniquePtr<PerformanceTimingData> aData,
|
||||
const nsAString& aInitiatorType,
|
||||
const nsAString& aEntryName) {
|
||||
|
@ -34,6 +34,9 @@ class PerformanceMainThread final : public Performance,
|
||||
|
||||
virtual void AddEntry(nsIHttpChannel* channel,
|
||||
nsITimedChannel* timedChannel) override;
|
||||
virtual void AddEntry(const nsString& entryName,
|
||||
const nsString& initiatorType,
|
||||
UniquePtr<PerformanceTimingData>&& aData) override;
|
||||
|
||||
void AddRawEntry(UniquePtr<PerformanceTimingData>,
|
||||
const nsAString& aInitiatorType,
|
||||
|
@ -23,6 +23,9 @@ class PerformanceStorage {
|
||||
|
||||
virtual void AddEntry(nsIHttpChannel* aChannel,
|
||||
nsITimedChannel* aTimedChannel) = 0;
|
||||
virtual void AddEntry(const nsString& entryName,
|
||||
const nsString& initiatorType,
|
||||
UniquePtr<PerformanceTimingData>&& aData) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~PerformanceStorage() = default;
|
||||
|
@ -29,7 +29,9 @@ class PerformanceStorageWorker final : public PerformanceStorage {
|
||||
|
||||
void AddEntry(nsIHttpChannel* aChannel,
|
||||
nsITimedChannel* aTimedChannel) override;
|
||||
|
||||
virtual void AddEntry(const nsString& entryName,
|
||||
const nsString& initiatorType,
|
||||
UniquePtr<PerformanceTimingData>&& aData) override {}
|
||||
void AddEntryOnWorker(UniquePtr<PerformanceProxyData>&& aData);
|
||||
|
||||
private:
|
||||
|
@ -16,6 +16,9 @@
|
||||
#include "nsWrapperCache.h"
|
||||
#include "Performance.h"
|
||||
#include "nsITimedChannel.h"
|
||||
#include "mozilla/ipc/IPDLParamTraits.h"
|
||||
#include "ipc/IPCMessageUtils.h"
|
||||
#include "mozilla/net/nsServerTiming.h"
|
||||
|
||||
class nsIHttpChannel;
|
||||
|
||||
@ -26,8 +29,11 @@ class PerformanceTiming;
|
||||
|
||||
class PerformanceTimingData final {
|
||||
friend class PerformanceTiming;
|
||||
friend struct mozilla::ipc::IPDLParamTraits<
|
||||
mozilla::dom::PerformanceTimingData>;
|
||||
|
||||
public:
|
||||
PerformanceTimingData() = default; // For deserialization
|
||||
// This can return null.
|
||||
static PerformanceTimingData* Create(nsITimedChannel* aChannel,
|
||||
nsIHttpChannel* aHttpChannel,
|
||||
@ -181,28 +187,28 @@ class PerformanceTimingData final {
|
||||
// There are only 2 possible values: (1) logicaly equal to navigationStart
|
||||
// TimeStamp (results are absolute timstamps - wallclock); (2) "0" (results
|
||||
// are relative to the navigation start).
|
||||
DOMHighResTimeStamp mZeroTime;
|
||||
DOMHighResTimeStamp mZeroTime = 0;
|
||||
|
||||
DOMHighResTimeStamp mFetchStart;
|
||||
DOMHighResTimeStamp mFetchStart = 0;
|
||||
|
||||
uint64_t mEncodedBodySize;
|
||||
uint64_t mTransferSize;
|
||||
uint64_t mDecodedBodySize;
|
||||
uint64_t mEncodedBodySize = 0;
|
||||
uint64_t mTransferSize = 0;
|
||||
uint64_t mDecodedBodySize = 0;
|
||||
|
||||
uint8_t mRedirectCount;
|
||||
uint8_t mRedirectCount = 0;
|
||||
|
||||
bool mAllRedirectsSameOrigin;
|
||||
bool mAllRedirectsSameOrigin = false;
|
||||
|
||||
// If the resourceTiming object should have non-zero redirectStart and
|
||||
// redirectEnd attributes. It is false if there were no redirects, or if any
|
||||
// of the responses didn't pass the timing-allow-check
|
||||
bool mReportCrossOriginRedirect;
|
||||
bool mReportCrossOriginRedirect = false;
|
||||
|
||||
bool mSecureConnection;
|
||||
bool mSecureConnection = false;
|
||||
|
||||
bool mTimingAllowed;
|
||||
bool mTimingAllowed = false;
|
||||
|
||||
bool mInitialized;
|
||||
bool mInitialized = false;
|
||||
};
|
||||
|
||||
// Script "performance.timing" object
|
||||
@ -408,4 +414,181 @@ class PerformanceTiming final : public nsWrapperCache {
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
|
||||
template <>
|
||||
struct IPDLParamTraits<mozilla::dom::PerformanceTimingData> {
|
||||
typedef mozilla::dom::PerformanceTimingData paramType;
|
||||
static void Write(IPC::Message* aMsg, IProtocol* aActor,
|
||||
const paramType& aParam) {
|
||||
WriteIPDLParam(aMsg, aActor, aParam.mServerTiming);
|
||||
WriteIPDLParam(aMsg, aActor, aParam.mNextHopProtocol);
|
||||
WriteIPDLParam(aMsg, aActor, aParam.mAsyncOpen);
|
||||
WriteIPDLParam(aMsg, aActor, aParam.mRedirectStart);
|
||||
WriteIPDLParam(aMsg, aActor, aParam.mRedirectEnd);
|
||||
WriteIPDLParam(aMsg, aActor, aParam.mDomainLookupStart);
|
||||
WriteIPDLParam(aMsg, aActor, aParam.mDomainLookupEnd);
|
||||
WriteIPDLParam(aMsg, aActor, aParam.mConnectStart);
|
||||
WriteIPDLParam(aMsg, aActor, aParam.mSecureConnectionStart);
|
||||
WriteIPDLParam(aMsg, aActor, aParam.mConnectEnd);
|
||||
WriteIPDLParam(aMsg, aActor, aParam.mRequestStart);
|
||||
WriteIPDLParam(aMsg, aActor, aParam.mResponseStart);
|
||||
WriteIPDLParam(aMsg, aActor, aParam.mCacheReadStart);
|
||||
WriteIPDLParam(aMsg, aActor, aParam.mResponseEnd);
|
||||
WriteIPDLParam(aMsg, aActor, aParam.mCacheReadEnd);
|
||||
WriteIPDLParam(aMsg, aActor, aParam.mWorkerStart);
|
||||
WriteIPDLParam(aMsg, aActor, aParam.mWorkerRequestStart);
|
||||
WriteIPDLParam(aMsg, aActor, aParam.mWorkerResponseEnd);
|
||||
WriteIPDLParam(aMsg, aActor, aParam.mZeroTime);
|
||||
WriteIPDLParam(aMsg, aActor, aParam.mFetchStart);
|
||||
WriteIPDLParam(aMsg, aActor, aParam.mEncodedBodySize);
|
||||
WriteIPDLParam(aMsg, aActor, aParam.mTransferSize);
|
||||
WriteIPDLParam(aMsg, aActor, aParam.mDecodedBodySize);
|
||||
WriteIPDLParam(aMsg, aActor, aParam.mRedirectCount);
|
||||
WriteIPDLParam(aMsg, aActor, aParam.mAllRedirectsSameOrigin);
|
||||
WriteIPDLParam(aMsg, aActor, aParam.mReportCrossOriginRedirect);
|
||||
WriteIPDLParam(aMsg, aActor, aParam.mSecureConnection);
|
||||
WriteIPDLParam(aMsg, aActor, aParam.mTimingAllowed);
|
||||
WriteIPDLParam(aMsg, aActor, aParam.mInitialized);
|
||||
}
|
||||
|
||||
static bool Read(const IPC::Message* aMsg, PickleIterator* aIter,
|
||||
IProtocol* aActor, paramType* aResult) {
|
||||
if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mServerTiming)) {
|
||||
return false;
|
||||
}
|
||||
if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mNextHopProtocol)) {
|
||||
return false;
|
||||
}
|
||||
if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mAsyncOpen)) {
|
||||
return false;
|
||||
}
|
||||
if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mRedirectStart)) {
|
||||
return false;
|
||||
}
|
||||
if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mRedirectEnd)) {
|
||||
return false;
|
||||
}
|
||||
if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mDomainLookupStart)) {
|
||||
return false;
|
||||
}
|
||||
if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mDomainLookupEnd)) {
|
||||
return false;
|
||||
}
|
||||
if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mConnectStart)) {
|
||||
return false;
|
||||
}
|
||||
if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mSecureConnectionStart)) {
|
||||
return false;
|
||||
}
|
||||
if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mConnectEnd)) {
|
||||
return false;
|
||||
}
|
||||
if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mRequestStart)) {
|
||||
return false;
|
||||
}
|
||||
if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mResponseStart)) {
|
||||
return false;
|
||||
}
|
||||
if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mCacheReadStart)) {
|
||||
return false;
|
||||
}
|
||||
if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mResponseEnd)) {
|
||||
return false;
|
||||
}
|
||||
if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mCacheReadEnd)) {
|
||||
return false;
|
||||
}
|
||||
if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mWorkerStart)) {
|
||||
return false;
|
||||
}
|
||||
if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mWorkerRequestStart)) {
|
||||
return false;
|
||||
}
|
||||
if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mWorkerResponseEnd)) {
|
||||
return false;
|
||||
}
|
||||
if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mZeroTime)) {
|
||||
return false;
|
||||
}
|
||||
if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mFetchStart)) {
|
||||
return false;
|
||||
}
|
||||
if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mEncodedBodySize)) {
|
||||
return false;
|
||||
}
|
||||
if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mTransferSize)) {
|
||||
return false;
|
||||
}
|
||||
if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mDecodedBodySize)) {
|
||||
return false;
|
||||
}
|
||||
if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mRedirectCount)) {
|
||||
return false;
|
||||
}
|
||||
if (!ReadIPDLParam(aMsg, aIter, aActor,
|
||||
&aResult->mAllRedirectsSameOrigin)) {
|
||||
return false;
|
||||
}
|
||||
if (!ReadIPDLParam(aMsg, aIter, aActor,
|
||||
&aResult->mReportCrossOriginRedirect)) {
|
||||
return false;
|
||||
}
|
||||
if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mSecureConnection)) {
|
||||
return false;
|
||||
}
|
||||
if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mTimingAllowed)) {
|
||||
return false;
|
||||
}
|
||||
if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mInitialized)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct IPDLParamTraits<nsCOMPtr<nsIServerTiming>> {
|
||||
typedef nsCOMPtr<nsIServerTiming> paramType;
|
||||
static void Write(IPC::Message* aMsg, IProtocol* aActor,
|
||||
const paramType& aParam) {
|
||||
nsAutoCString name;
|
||||
Unused << aParam->GetName(name);
|
||||
double duration = 0;
|
||||
Unused << aParam->GetDuration(&duration);
|
||||
nsAutoCString description;
|
||||
Unused << aParam->GetDescription(description);
|
||||
WriteIPDLParam(aMsg, aActor, name);
|
||||
WriteIPDLParam(aMsg, aActor, duration);
|
||||
WriteIPDLParam(aMsg, aActor, description);
|
||||
}
|
||||
|
||||
static bool Read(const IPC::Message* aMsg, PickleIterator* aIter,
|
||||
IProtocol* aActor, paramType* aResult) {
|
||||
nsAutoCString name;
|
||||
double duration;
|
||||
nsAutoCString description;
|
||||
if (!ReadIPDLParam(aMsg, aIter, aActor, &name)) {
|
||||
return false;
|
||||
}
|
||||
if (!ReadIPDLParam(aMsg, aIter, aActor, &duration)) {
|
||||
return false;
|
||||
}
|
||||
if (!ReadIPDLParam(aMsg, aIter, aActor, &description)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RefPtr<nsServerTiming> timing = new nsServerTiming();
|
||||
timing->SetName(name);
|
||||
timing->SetDuration(duration);
|
||||
timing->SetDescription(description);
|
||||
*aResult = timing;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ipc
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_PerformanceTiming_h
|
||||
|
@ -119,7 +119,6 @@ skip-if = verify
|
||||
[test_resource_timing.html]
|
||||
skip-if = verify
|
||||
[test_resource_timing_cross_origin.html]
|
||||
skip-if = fission # bug 1658097
|
||||
[test_resource_timing_frameset.html]
|
||||
[test_selectevents.html]
|
||||
skip-if = toolkit == 'android' # bug 1627523
|
||||
|
@ -88,6 +88,7 @@
|
||||
#include "mozilla/RemoteLazyInputStreamChild.h"
|
||||
#include "mozilla/RemoteLazyInputStreamUtils.h"
|
||||
#include "mozilla/net/SFVService.h"
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
@ -4831,10 +4832,37 @@ mozilla::dom::PerformanceStorage* HttpBaseChannel::GetPerformanceStorage() {
|
||||
}
|
||||
|
||||
void HttpBaseChannel::MaybeReportTimingData() {
|
||||
if (XRE_IsE10sParentProcess()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mozilla::dom::PerformanceStorage* documentPerformance =
|
||||
GetPerformanceStorage();
|
||||
if (documentPerformance) {
|
||||
documentPerformance->AddEntry(this, this);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!nsGlobalWindowInner::GetInnerWindowWithId(
|
||||
mLoadInfo->GetInnerWindowID())) {
|
||||
// The inner window is in a different process.
|
||||
dom::ContentChild* child = dom::ContentChild::GetSingleton();
|
||||
|
||||
if (!child) {
|
||||
return;
|
||||
}
|
||||
nsAutoString initiatorType;
|
||||
nsAutoString entryName;
|
||||
|
||||
UniquePtr<dom::PerformanceTimingData> performanceTimingData(
|
||||
dom::PerformanceTimingData::Create(this, this, 0, initiatorType,
|
||||
entryName));
|
||||
if (!performanceTimingData) {
|
||||
return;
|
||||
}
|
||||
child->SendReportFrameTimingData(mLoadInfo->GetInnerWindowID(), entryName,
|
||||
initiatorType,
|
||||
std::move(performanceTimingData));
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user