Diff
Modified: branches/safari-602.1.32-branch/LayoutTests/ChangeLog (201147 => 201148)
--- branches/safari-602.1.32-branch/LayoutTests/ChangeLog 2016-05-19 08:40:55 UTC (rev 201147)
+++ branches/safari-602.1.32-branch/LayoutTests/ChangeLog 2016-05-19 08:41:03 UTC (rev 201148)
@@ -1,5 +1,20 @@
2016-05-19 Babak Shafiei <[email protected]>
+ Merge r200651. rdar://problem/26188642
+
+ 2016-05-10 Joseph Pecoraro <[email protected]>
+
+ Web Inspector: Backend should initiate timeline recordings on page navigations to ensure nothing is missed
+ https://bugs.webkit.org/show_bug.cgi?id=157504
+ <rdar://problem/26188642>
+
+ Reviewed by Brian Burg.
+
+ * inspector/timeline/setAutoCaptureInstruments-errors-expected.txt: Added.
+ * inspector/timeline/setAutoCaptureInstruments-errors.html: Added.
+
+2016-05-19 Babak Shafiei <[email protected]>
+
Merge r201090. rdar://problem/26334636
2016-05-18 Simon Fraser <[email protected]>
Added: branches/safari-602.1.32-branch/LayoutTests/inspector/timeline/setAutoCaptureInstruments-errors-expected.txt (0 => 201148)
--- branches/safari-602.1.32-branch/LayoutTests/inspector/timeline/setAutoCaptureInstruments-errors-expected.txt (rev 0)
+++ branches/safari-602.1.32-branch/LayoutTests/inspector/timeline/setAutoCaptureInstruments-errors-expected.txt 2016-05-19 08:41:03 UTC (rev 201148)
@@ -0,0 +1,16 @@
+Tests for error cases with Timeline.setAutoCaptureInstruments.
+
+
+== Running test suite: Timeline.setAutoCaptureInstruments.errors
+-- Running test case: MissingRequiredArgument
+PASS: Should be an error: Some arguments of method 'Timeline.setAutoCaptureInstruments' can't be processed
+
+-- Running test case: InvalidTypeInInstrumentsList
+PASS: Should be an error: Unexpected type in instruments list, should be string
+
+-- Running test case: InvalidInstrumentInInstrumentsList
+PASS: Should be an error: Unexpected enum value: NoSuchInstrument
+
+-- Running test case: ValidInstrumentInInstrumentsList
+PASS: Should not be an error setting valid instruments.
+
Added: branches/safari-602.1.32-branch/LayoutTests/inspector/timeline/setAutoCaptureInstruments-errors.html (0 => 201148)
--- branches/safari-602.1.32-branch/LayoutTests/inspector/timeline/setAutoCaptureInstruments-errors.html (rev 0)
+++ branches/safari-602.1.32-branch/LayoutTests/inspector/timeline/setAutoCaptureInstruments-errors.html 2016-05-19 08:41:03 UTC (rev 201148)
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script>
+function test()
+{
+ let suite = ProtocolTest.createAsyncSuite("Timeline.setAutoCaptureInstruments.errors");
+
+ ProtocolTest.dumpActivityToSystemConsole = true;
+ ProtocolTest.dumpInspectorProtocolMessages = true;
+
+ suite.addTestCase({
+ name: "MissingRequiredArgument",
+ test: (resolve, reject) => {
+ InspectorProtocol.sendCommand("Timeline.setAutoCaptureInstruments", {}, (messageObject) => {
+ ProtocolTest.expectThat(messageObject.error, `Should be an error: ${messageObject.error ? messageObject.error.message : ""}`);
+ resolve();
+ });
+ }
+ });
+
+ suite.addTestCase({
+ name: "InvalidTypeInInstrumentsList",
+ test: (resolve, reject) => {
+ InspectorProtocol.sendCommand("Timeline.setAutoCaptureInstruments", {"instruments": [123]}, (messageObject) => {
+ ProtocolTest.expectThat(messageObject.error, `Should be an error: ${messageObject.error ? messageObject.error.message : ""}`);
+ resolve();
+ });
+ }
+ });
+
+ suite.addTestCase({
+ name: "InvalidInstrumentInInstrumentsList",
+ test: (resolve, reject) => {
+ InspectorProtocol.sendCommand("Timeline.setAutoCaptureInstruments", {"instruments": ["NoSuchInstrument"]}, (messageObject) => {
+ ProtocolTest.expectThat(messageObject.error, `Should be an error: ${messageObject.error ? messageObject.error.message : ""}`);
+ resolve();
+ });
+ }
+ });
+
+ suite.addTestCase({
+ name: "ValidInstrumentInInstrumentsList",
+ test: (resolve, reject) => {
+ InspectorProtocol.sendCommand("Timeline.setAutoCaptureInstruments", {"instruments": ["ScriptProfiler", "Heap", "Timeline", "Memory"]}, (messageObject) => {
+ ProtocolTest.expectThat(!messageObject.error, "Should not be an error setting valid instruments.");
+ resolve();
+ });
+ }
+ });
+
+ suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body _onload_="runTest()">
+<p>Tests for error cases with Timeline.setAutoCaptureInstruments.</p>
+</body>
+</html>
Modified: branches/safari-602.1.32-branch/Source/_javascript_Core/ChangeLog (201147 => 201148)
--- branches/safari-602.1.32-branch/Source/_javascript_Core/ChangeLog 2016-05-19 08:40:55 UTC (rev 201147)
+++ branches/safari-602.1.32-branch/Source/_javascript_Core/ChangeLog 2016-05-19 08:41:03 UTC (rev 201148)
@@ -1,3 +1,20 @@
+2016-05-19 Babak Shafiei <[email protected]>
+
+ Merge r200651. rdar://problem/26188642
+
+ 2016-05-10 Joseph Pecoraro <[email protected]>
+
+ Web Inspector: Backend should initiate timeline recordings on page navigations to ensure nothing is missed
+ https://bugs.webkit.org/show_bug.cgi?id=157504
+ <rdar://problem/26188642>
+
+ Reviewed by Brian Burg.
+
+ * inspector/protocol/Timeline.json:
+ Add protocol commands to enable/disable auto capture and list the
+ instruments that should be enabled when auto capture starts.
+ Add protocol event for when the backend starts an auto capture.
+
2016-05-17 Babak Shafiei <[email protected]>
Merge r200866. rdar://problem/26253396
Modified: branches/safari-602.1.32-branch/Source/_javascript_Core/inspector/protocol/Timeline.json (201147 => 201148)
--- branches/safari-602.1.32-branch/Source/_javascript_Core/inspector/protocol/Timeline.json 2016-05-19 08:40:55 UTC (rev 201147)
+++ branches/safari-602.1.32-branch/Source/_javascript_Core/inspector/protocol/Timeline.json 2016-05-19 08:41:03 UTC (rev 201148)
@@ -6,6 +6,7 @@
{
"id": "EventType",
"type": "string",
+ "description": "Timeline record type.",
"enum": [
"EventDispatch",
"ScheduleStyleRecalculation",
@@ -28,18 +29,28 @@
"RequestAnimationFrame",
"CancelAnimationFrame",
"FireAnimationFrame"
- ],
- "description": "Timeline record type."
+ ]
},
{
+ "id": "Instrument",
+ "type": "string",
+ "description": "Instrument types.",
+ "enum": [
+ "ScriptProfiler",
+ "Timeline",
+ "Memory",
+ "Heap"
+ ]
+ },
+ {
"id": "TimelineEvent",
"type": "object",
+ "description": "Timeline record contains information about the recorded activity.",
"properties": [
{ "name": "type", "$ref": "EventType", "description": "Event type." },
{ "name": "data", "type": "object", "description": "Event data." },
{ "name": "children", "type": "array", "optional": true, "items": { "$ref": "TimelineEvent" }, "description": "Nested records." }
- ],
- "description": "Timeline record contains information about the recorded activity."
+ ]
},
{
"id": "CPUProfileNodeAggregateCallInfo",
@@ -79,37 +90,55 @@
"commands": [
{
"name": "start",
+ "description": "Starts capturing instrumentation events.",
"parameters": [
{ "name": "maxCallStackDepth", "optional": true, "type": "integer", "description": "Samples _javascript_ stack traces up to <code>maxCallStackDepth</code>, defaults to 5." }
- ],
- "description": "Starts capturing instrumentation events."
+ ]
},
{
"name": "stop",
"description": "Stops capturing instrumentation events."
+ },
+ {
+ "name": "setAutoCaptureEnabled",
+ "description": "Toggle auto capture state. If <code>true</code> the backend will disable breakpoints and start capturing on navigation. The backend will fire the <code>autoCaptureStarted</code> event when an auto capture starts. The frontend should stop the auto capture when appropriate and re-enable breakpoints.",
+ "parameters": [
+ { "name": "enabled", "type": "boolean", "description": "New auto capture state." }
+ ]
+ },
+ {
+ "name": "setAutoCaptureInstruments",
+ "description": "Instruments to enable when an auto capture starts.",
+ "parameters": [
+ { "name": "instruments", "type": "array", "items": { "$ref": "Instrument" }, "description": "Instruments to enable." }
+ ]
}
],
"events": [
{
"name": "eventRecorded",
+ "description": "Fired for every instrumentation event while timeline is started.",
"parameters": [
{ "name": "record", "$ref": "TimelineEvent", "description": "Timeline event record data." }
- ],
- "description": "Fired for every instrumentation event while timeline is started."
+ ]
},
{
"name": "recordingStarted",
+ "description": "Fired when recording has started.",
"parameters": [
{ "name": "startTime", "type": "number", "description": "Start time of this new recording." }
- ],
- "description": "Fired when recording has started."
+ ]
},
{
"name": "recordingStopped",
+ "description": "Fired when recording has stopped.",
"parameters": [
{ "name": "endTime", "type": "number", "description": "End time of this recording." }
- ],
- "description": "Fired when recording has stopped."
+ ]
+ },
+ {
+ "name": "autoCaptureStarted",
+ "description": "Fired when auto capture started."
}
]
}
Modified: branches/safari-602.1.32-branch/Source/WebCore/ChangeLog (201147 => 201148)
--- branches/safari-602.1.32-branch/Source/WebCore/ChangeLog 2016-05-19 08:40:55 UTC (rev 201147)
+++ branches/safari-602.1.32-branch/Source/WebCore/ChangeLog 2016-05-19 08:41:03 UTC (rev 201148)
@@ -1,5 +1,42 @@
2016-05-19 Babak Shafiei <[email protected]>
+ Merge r200651. rdar://problem/26188642
+
+ 2016-05-10 Joseph Pecoraro <[email protected]>
+
+ Web Inspector: Backend should initiate timeline recordings on page navigations to ensure nothing is missed
+ https://bugs.webkit.org/show_bug.cgi?id=157504
+ <rdar://problem/26188642>
+
+ Reviewed by Brian Burg.
+
+ Test: inspector/timeline/setAutoCaptureInstruments-errors.html
+
+ * inspector/InspectorController.cpp:
+ (WebCore::InspectorController::InspectorController):
+ Pass other agents into the TimelineAgent constructor.
+
+ * inspector/InspectorInstrumentation.cpp:
+ (WebCore::InspectorInstrumentation::frameStartedLoadingImpl):
+ Inform the TimelineAgent whenever the main frame starts a new load.
+
+ * inspector/InspectorTimelineAgent.h:
+ * inspector/InspectorTimelineAgent.cpp:
+ (WebCore::InspectorTimelineAgent::InspectorTimelineAgent):
+ Initialize new members.
+
+ (WebCore::InspectorTimelineAgent::willDestroyFrontendAndBackend):
+ Cleanup auto capture state when tearing down.
+
+ (WebCore::InspectorTimelineAgent::setAutoCaptureEnabled):
+ (WebCore::InspectorTimelineAgent::setAutoCaptureInstruments):
+ Set and validate new auto capture state from the frontend.
+
+ (WebCore::InspectorTimelineAgent::mainFrameStartedLoading):
+ When page navigates start an auto capture if needed.
+
+2016-05-19 Babak Shafiei <[email protected]>
+
Merge r201090. rdar://problem/26334636
2016-05-18 Simon Fraser <[email protected]>
Modified: branches/safari-602.1.32-branch/Source/WebCore/inspector/InspectorController.cpp (201147 => 201148)
--- branches/safari-602.1.32-branch/Source/WebCore/inspector/InspectorController.cpp 2016-05-19 08:40:55 UTC (rev 201147)
+++ branches/safari-602.1.32-branch/Source/WebCore/inspector/InspectorController.cpp 2016-05-19 08:41:03 UTC (rev 201148)
@@ -158,25 +158,28 @@
InspectorDOMStorageAgent* domStorageAgent = domStorageAgentPtr.get();
m_agents.append(WTFMove(domStorageAgentPtr));
- auto timelineAgentPtr = std::make_unique<InspectorTimelineAgent>(pageContext, pageAgent);
- m_timelineAgent = timelineAgentPtr.get();
- m_agents.append(WTFMove(timelineAgentPtr));
-
auto heapAgentPtr = std::make_unique<InspectorHeapAgent>(pageContext);
InspectorHeapAgent* heapAgent = heapAgentPtr.get();
m_agents.append(WTFMove(heapAgentPtr));
+ auto scriptProfilerAgentPtr = std::make_unique<InspectorScriptProfilerAgent>(pageContext);
+ InspectorScriptProfilerAgent* scriptProfilerAgent = scriptProfilerAgentPtr.get();
+ m_agents.append(WTFMove(scriptProfilerAgentPtr));
+
auto consoleAgentPtr = std::make_unique<PageConsoleAgent>(pageContext, heapAgent, m_domAgent);
WebConsoleAgent* consoleAgent = consoleAgentPtr.get();
m_instrumentingAgents->setWebConsoleAgent(consoleAgentPtr.get());
m_agents.append(WTFMove(consoleAgentPtr));
+ auto timelineAgentPtr = std::make_unique<InspectorTimelineAgent>(pageContext, scriptProfilerAgent, heapAgent, pageAgent);
+ m_timelineAgent = timelineAgentPtr.get();
+ m_agents.append(WTFMove(timelineAgentPtr));
+
auto debuggerAgentPtr = std::make_unique<PageDebuggerAgent>(pageContext, pageAgent, m_overlay.get());
PageDebuggerAgent* debuggerAgent = debuggerAgentPtr.get();
m_agents.append(WTFMove(debuggerAgentPtr));
m_agents.append(std::make_unique<InspectorDOMDebuggerAgent>(pageContext, m_domAgent, debuggerAgent));
- m_agents.append(std::make_unique<InspectorScriptProfilerAgent>(pageContext));
m_agents.append(std::make_unique<InspectorApplicationCacheAgent>(pageContext, pageAgent));
m_agents.append(std::make_unique<InspectorLayerTreeAgent>(pageContext));
Modified: branches/safari-602.1.32-branch/Source/WebCore/inspector/InspectorInstrumentation.cpp (201147 => 201148)
--- branches/safari-602.1.32-branch/Source/WebCore/inspector/InspectorInstrumentation.cpp 2016-05-19 08:40:55 UTC (rev 201147)
+++ branches/safari-602.1.32-branch/Source/WebCore/inspector/InspectorInstrumentation.cpp 2016-05-19 08:41:03 UTC (rev 201148)
@@ -775,6 +775,8 @@
if (frame.isMainFrame()) {
if (PageDebuggerAgent* pageDebuggerAgent = instrumentingAgents.pageDebuggerAgent())
pageDebuggerAgent->mainFrameStartedLoading();
+ if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.persistentInspectorTimelineAgent())
+ timelineAgent->mainFrameStartedLoading();
}
if (InspectorPageAgent* inspectorPageAgent = instrumentingAgents.inspectorPageAgent())
Modified: branches/safari-602.1.32-branch/Source/WebCore/inspector/InspectorTimelineAgent.cpp (201147 => 201148)
--- branches/safari-602.1.32-branch/Source/WebCore/inspector/InspectorTimelineAgent.cpp 2016-05-19 08:40:55 UTC (rev 201147)
+++ branches/safari-602.1.32-branch/Source/WebCore/inspector/InspectorTimelineAgent.cpp 2016-05-19 08:41:03 UTC (rev 201148)
@@ -35,6 +35,7 @@
#include "Event.h"
#include "Frame.h"
+#include "InspectorMemoryAgent.h"
#include "InspectorPageAgent.h"
#include "InstrumentingAgents.h"
#include "JSDOMWindow.h"
@@ -43,6 +44,9 @@
#include "ScriptState.h"
#include "TimelineRecordFactory.h"
#include <inspector/ScriptBreakpoint.h>
+#include <inspector/agents/InspectorDebuggerAgent.h>
+#include <inspector/agents/InspectorHeapAgent.h>
+#include <inspector/agents/InspectorScriptProfilerAgent.h>
#include <profiler/LegacyProfiler.h>
#include <wtf/Stopwatch.h>
@@ -77,6 +81,16 @@
}
#endif
+InspectorTimelineAgent::InspectorTimelineAgent(WebAgentContext& context, InspectorScriptProfilerAgent* scriptProfileAgent, InspectorHeapAgent* heapAgent, InspectorPageAgent* pageAgent)
+ : InspectorAgentBase(ASCIILiteral("Timeline"), context)
+ , m_frontendDispatcher(std::make_unique<Inspector::TimelineFrontendDispatcher>(context.frontendRouter))
+ , m_backendDispatcher(Inspector::TimelineBackendDispatcher::create(context.backendDispatcher, this))
+ , m_scriptProfilerAgent(scriptProfileAgent)
+ , m_heapAgent(heapAgent)
+ , m_pageAgent(pageAgent)
+{
+}
+
InspectorTimelineAgent::~InspectorTimelineAgent()
{
}
@@ -92,6 +106,9 @@
ErrorString unused;
stop(unused);
+
+ m_autoCaptureEnabled = false;
+ m_autoCaptureInstruments.clear();
}
void InspectorTimelineAgent::start(ErrorString&, const int* maxCallStackDepth)
@@ -108,6 +125,35 @@
m_enabledFromFrontend = false;
}
+void InspectorTimelineAgent::setAutoCaptureEnabled(ErrorString&, bool enabled)
+{
+ m_autoCaptureEnabled = enabled;
+}
+
+void InspectorTimelineAgent::setAutoCaptureInstruments(ErrorString& errorString, const InspectorArray& instruments)
+{
+ Vector<Protocol::Timeline::Instrument> newInstruments;
+ newInstruments.reserveCapacity(instruments.length());
+
+ for (auto instrumentValue : instruments) {
+ String enumValueString;
+ if (!instrumentValue->asString(enumValueString)) {
+ errorString = ASCIILiteral("Unexpected type in instruments list, should be string");
+ return;
+ }
+
+ Optional<Protocol::Timeline::Instrument> instrumentType = Protocol::InspectorHelpers::parseEnumValueFromString<Protocol::Timeline::Instrument>(enumValueString);
+ if (!instrumentType) {
+ errorString = makeString("Unexpected enum value: ", enumValueString);
+ return;
+ }
+
+ newInstruments.uncheckedAppend(*instrumentType);
+ }
+
+ m_autoCaptureInstruments.swap(newInstruments);
+}
+
void InspectorTimelineAgent::internalStart(const int* maxCallStackDepth)
{
if (m_enabled)
@@ -384,6 +430,60 @@
appendRecord(TimelineRecordFactory::createTimeStampData(message), TimelineRecordType::TimeEnd, true, &frame);
}
+void InspectorTimelineAgent::mainFrameStartedLoading()
+{
+ if (m_enabled)
+ return;
+
+ if (!m_autoCaptureEnabled)
+ return;
+
+ if (m_autoCaptureInstruments.isEmpty())
+ return;
+
+ // Pre-emptively disable breakpoints. The frontend must re-enable them.
+ if (InspectorDebuggerAgent* debuggerAgent = m_instrumentingAgents.inspectorDebuggerAgent()) {
+ ErrorString unused;
+ debuggerAgent->setBreakpointsActive(unused, false);
+ }
+
+ // Inform the frontend we started an auto capture. The frontend must stop capture.
+ m_frontendDispatcher->autoCaptureStarted();
+
+ // Enable instruments.
+ for (auto instrumentType : m_autoCaptureInstruments) {
+ switch (instrumentType) {
+ case Inspector::Protocol::Timeline::Instrument::ScriptProfiler: {
+ if (m_scriptProfilerAgent) {
+ ErrorString unused;
+ const bool includeSamples = true;
+ m_scriptProfilerAgent->startTracking(unused, &includeSamples);
+ }
+ break;
+ }
+ case Inspector::Protocol::Timeline::Instrument::Heap: {
+ if (m_heapAgent) {
+ ErrorString unused;
+ m_heapAgent->startTracking(unused);
+ }
+ break;
+ }
+ case Inspector::Protocol::Timeline::Instrument::Memory: {
+#if ENABLE(RESOURCE_USAGE)
+ if (InspectorMemoryAgent* memoryAgent = m_instrumentingAgents.inspectorMemoryAgent()) {
+ ErrorString unused;
+ memoryAgent->startTracking(unused);
+ }
+#endif
+ break;
+ }
+ case Inspector::Protocol::Timeline::Instrument::Timeline:
+ internalStart();
+ break;
+ }
+ }
+}
+
void InspectorTimelineAgent::didCommitLoad()
{
clearRecordStack();
@@ -524,14 +624,6 @@
}
}
-InspectorTimelineAgent::InspectorTimelineAgent(WebAgentContext& context, InspectorPageAgent* pageAgent)
- : InspectorAgentBase(ASCIILiteral("Timeline"), context)
- , m_frontendDispatcher(std::make_unique<Inspector::TimelineFrontendDispatcher>(context.frontendRouter))
- , m_backendDispatcher(Inspector::TimelineBackendDispatcher::create(context.backendDispatcher, this))
- , m_pageAgent(pageAgent)
-{
-}
-
void InspectorTimelineAgent::appendRecord(RefPtr<InspectorObject>&& data, TimelineRecordType type, bool captureCallStack, Frame* frame)
{
Ref<InspectorObject> record = TimelineRecordFactory::createGenericRecord(timestamp(), captureCallStack ? m_maxCallStackDepth : 0);
Modified: branches/safari-602.1.32-branch/Source/WebCore/inspector/InspectorTimelineAgent.h (201147 => 201148)
--- branches/safari-602.1.32-branch/Source/WebCore/inspector/InspectorTimelineAgent.h 2016-05-19 08:40:55 UTC (rev 201147)
+++ branches/safari-602.1.32-branch/Source/WebCore/inspector/InspectorTimelineAgent.h 2016-05-19 08:41:03 UTC (rev 201148)
@@ -45,6 +45,11 @@
class Profile;
}
+namespace Inspector {
+class InspectorHeapAgent;
+class InspectorScriptProfilerAgent;
+}
+
namespace WebCore {
class Event;
@@ -92,7 +97,7 @@
WTF_MAKE_NONCOPYABLE(InspectorTimelineAgent);
WTF_MAKE_FAST_ALLOCATED;
public:
- InspectorTimelineAgent(WebAgentContext&, InspectorPageAgent*);
+ InspectorTimelineAgent(WebAgentContext&, Inspector::InspectorScriptProfilerAgent*, Inspector::InspectorHeapAgent*, InspectorPageAgent*);
virtual ~InspectorTimelineAgent();
void didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) final;
@@ -100,6 +105,8 @@
void start(ErrorString&, const int* maxCallStackDepth = nullptr) final;
void stop(ErrorString&) final;
+ void setAutoCaptureEnabled(ErrorString&, bool) final;
+ void setAutoCaptureInstruments(ErrorString&, const Inspector::InspectorArray&) final;
int id() const { return m_id; }
@@ -137,6 +144,7 @@
void didFireAnimationFrame();
void time(Frame&, const String&);
void timeEnd(Frame&, const String&);
+ void mainFrameStartedLoading();
private:
// ScriptDebugListener
@@ -191,6 +199,8 @@
std::unique_ptr<Inspector::TimelineFrontendDispatcher> m_frontendDispatcher;
RefPtr<Inspector::TimelineBackendDispatcher> m_backendDispatcher;
+ Inspector::InspectorScriptProfilerAgent* m_scriptProfilerAgent;
+ Inspector::InspectorHeapAgent* m_heapAgent;
InspectorPageAgent* m_pageAgent;
Vector<TimelineRecordEntry> m_recordStack;
@@ -202,6 +212,9 @@
bool m_enabled { false };
bool m_enabledFromFrontend { false };
+ bool m_autoCaptureEnabled { false };
+ Vector<Inspector::Protocol::Timeline::Instrument> m_autoCaptureInstruments;
+
#if PLATFORM(COCOA)
std::unique_ptr<WebCore::RunLoopObserver> m_frameStartObserver;
std::unique_ptr<WebCore::RunLoopObserver> m_frameStopObserver;
Modified: branches/safari-602.1.32-branch/Source/WebInspectorUI/ChangeLog (201147 => 201148)
--- branches/safari-602.1.32-branch/Source/WebInspectorUI/ChangeLog 2016-05-19 08:40:55 UTC (rev 201147)
+++ branches/safari-602.1.32-branch/Source/WebInspectorUI/ChangeLog 2016-05-19 08:41:03 UTC (rev 201148)
@@ -1,5 +1,47 @@
2016-05-19 Babak Shafiei <[email protected]>
+ Merge r200651. rdar://problem/26188642
+
+ 2016-05-10 Joseph Pecoraro <[email protected]>
+
+ Web Inspector: Backend should initiate timeline recordings on page navigations to ensure nothing is missed
+ https://bugs.webkit.org/show_bug.cgi?id=157504
+ <rdar://problem/26188642>
+
+ Reviewed by Brian Burg.
+
+ * UserInterface/Controllers/TimelineManager.js:
+ (WebInspector.TimelineManager):
+ (WebInspector.TimelineManager.prototype.set autoCaptureOnPageLoad):
+ (WebInspector.TimelineManager.prototype.set enabledTimelineTypes):
+ (WebInspector.TimelineManager.prototype._updateAutoCaptureInstruments):
+ For backends that support it, enable/disable auto capture and the instruments to use.
+
+ (WebInspector.TimelineManager.prototype.autoCaptureStarted):
+ New event, stop and start a new recording. Set a flag that we should
+ detect the auto capturing resource so we know when the stop the
+ auto capture.
+
+ (WebInspector.TimelineManager.prototype._loadNewRecording):
+ (WebInspector.TimelineManager.prototype._addRecord):
+ (WebInspector.TimelineManager.prototype._startAutoCapturing): Renamed.
+ (WebInspector.TimelineManager.prototype._attemptAutoCapturingForFrame):
+ (WebInspector.TimelineManager.prototype._legacyAttemptStartAutoCapturingForFrame):
+ (WebInspector.TimelineManager.prototype._stopAutoRecordingSoon):
+ (WebInspector.TimelineManager.prototype._resetAutoRecordingMaxTimeTimeout):
+ (WebInspector.TimelineManager.prototype._resetAutoRecordingDeadTimeTimeout):
+ (WebInspector.TimelineManager.prototype._mainResourceDidChange):
+ (WebInspector.TimelineManager.prototype._mergeScriptProfileRecords):
+ Factor out the new path, old path, and shared code for auto capturing.
+ Renamed _startAutoCapturing to _attemptAutoCapturingForFrame which
+ better matches what it tries to do.
+
+ * UserInterface/Protocol/TimelineObserver.js:
+ (WebInspector.TimelineObserver.prototype.autoCaptureStarted):
+ Inform TimelineManager.
+
+2016-05-19 Babak Shafiei <[email protected]>
+
Merge r200949. rdar://problem/26262219
2016-05-14 Timothy Hatcher <[email protected]>
Modified: branches/safari-602.1.32-branch/Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js (201147 => 201148)
--- branches/safari-602.1.32-branch/Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js 2016-05-19 08:40:55 UTC (rev 201147)
+++ branches/safari-602.1.32-branch/Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js 2016-05-19 08:41:03 UTC (rev 201148)
@@ -29,7 +29,7 @@
{
super();
- WebInspector.Frame.addEventListener(WebInspector.Frame.Event.ProvisionalLoadStarted, this._startAutoCapturing, this);
+ WebInspector.Frame.addEventListener(WebInspector.Frame.Event.ProvisionalLoadStarted, this._provisionalLoadStarted, this);
WebInspector.Frame.addEventListener(WebInspector.Frame.Event.MainResourceDidChange, this._mainResourceDidChange, this);
WebInspector.Frame.addEventListener(WebInspector.Frame.Event.ResourceWasAdded, this._resourceWasAdded, this);
@@ -37,12 +37,15 @@
WebInspector.memoryManager.addEventListener(WebInspector.MemoryManager.Event.MemoryPressure, this._memoryPressure, this);
this._enabledTimelineTypesSetting = new WebInspector.Setting("enabled-instrument-types", WebInspector.TimelineManager.defaultTimelineTypes());
+ this._updateAutoCaptureInstruments();
this._persistentNetworkTimeline = new WebInspector.NetworkTimeline;
this._isCapturing = false;
this._isCapturingPageReload = false;
- this._autoCapturingMainResource = null;
+ this._autoCaptureOnPageLoad = false;
+ this._mainResourceForAutoCapturing = null;
+ this._shouldSetAutoCapturingMainResource = false;
this._boundStopCapturing = this.stopCapturing.bind(this);
this._webTimelineScriptRecordsExpectingScriptProfilerEvents = null;
@@ -128,6 +131,9 @@
set autoCaptureOnPageLoad(autoCapture)
{
this._autoCaptureOnPageLoad = autoCapture;
+
+ if (window.TimelineAgent && TimelineAgent.setAutoCaptureEnabled)
+ TimelineAgent.setAutoCaptureEnabled(autoCapture);
}
get enabledTimelineTypes()
@@ -139,6 +145,8 @@
set enabledTimelineTypes(x)
{
this._enabledTimelineTypesSetting.value = x || [];
+
+ this._updateAutoCaptureInstruments();
}
isCapturing()
@@ -204,6 +212,8 @@
capturingStarted(startTime)
{
+ // Called from WebInspector.TimelineObserver.
+
if (this._isCapturing)
return;
@@ -219,6 +229,8 @@
capturingStopped(endTime)
{
+ // Called from WebInspector.TimelineObserver.
+
if (!this._isCapturing)
return;
@@ -234,11 +246,24 @@
this._isCapturing = false;
this._isCapturingPageReload = false;
- this._autoCapturingMainResource = null;
+ this._shouldSetAutoCapturingMainResource = false;
+ this._mainResourceForAutoCapturing = null;
this.dispatchEventToListeners(WebInspector.TimelineManager.Event.CapturingStopped, {endTime});
}
+ autoCaptureStarted(startTime)
+ {
+ // Called from WebInspector.TimelineObserver.
+
+ if (this._isCapturing)
+ this.stopCapturing();
+
+ this.startCapturing(true);
+
+ this._shouldSetAutoCapturingMainResource = true;
+ }
+
eventRecorded(recordPayload)
{
// Called from WebInspector.TimelineObserver.
@@ -591,10 +616,10 @@
// Now that we have navigated, we should reset the legacy base timestamp and the
// will send request timestamp for the new main resource. This way, all new timeline
// records will be computed relative to the new navigation.
- if (this._autoCapturingMainResource && WebInspector.TimelineRecording.isLegacy) {
- console.assert(this._autoCapturingMainResource.originalRequestWillBeSentTimestamp);
- this._activeRecording.setLegacyBaseTimestamp(this._autoCapturingMainResource.originalRequestWillBeSentTimestamp);
- this._autoCapturingMainResource._requestSentTimestamp = 0;
+ if (this._mainResourceForAutoCapturing && WebInspector.TimelineRecording.isLegacy) {
+ console.assert(this._mainResourceForAutoCapturing.originalRequestWillBeSentTimestamp);
+ this._activeRecording.setLegacyBaseTimestamp(this._mainResourceForAutoCapturing.originalRequestWillBeSentTimestamp);
+ this._mainResourceForAutoCapturing._requestSentTimestamp = 0;
}
this.dispatchEventToListeners(WebInspector.TimelineManager.Event.RecordingLoaded, {oldRecording});
@@ -617,25 +642,58 @@
this._resetAutoRecordingDeadTimeTimeout();
}
- _startAutoCapturing(event)
+ _attemptAutoCapturingForFrame(frame)
{
if (!this._autoCaptureOnPageLoad)
return false;
- if (!event.target.isMainFrame() || (this._isCapturing && !this._autoCapturingMainResource))
+ if (!frame.isMainFrame())
return false;
- var mainResource = event.target.provisionalMainResource || event.target.mainResource;
- if (mainResource === this._autoCapturingMainResource)
+ // COMPATIBILITY (iOS 9): Timeline.setAutoCaptureEnabled did not exist.
+ // Perform auto capture in the frontend.
+ if (!TimelineAgent.setAutoCaptureEnabled)
+ return this._legacyAttemptStartAutoCapturingForFrame(frame);
+
+ if (!this._shouldSetAutoCapturingMainResource)
return false;
- var oldMainResource = event.target.mainResource || null;
+ console.assert(this._isCapturing, "We saw autoCaptureStarted so we should already be capturing");
+
+ let mainResource = frame.provisionalMainResource || frame.mainResource;
+ if (mainResource === this._mainResourceForAutoCapturing)
+ return false;
+
+ let oldMainResource = frame.mainResource || null;
this._isCapturingPageReload = oldMainResource !== null && oldMainResource.url ="" mainResource.url;
+ this._mainResourceForAutoCapturing = mainResource;
+
+ this._addRecord(new WebInspector.ResourceTimelineRecord(mainResource));
+
+ this._resetAutoRecordingMaxTimeTimeout();
+
+ this._shouldSetAutoCapturingMainResource = false;
+
+ return true;
+ }
+
+ _legacyAttemptStartAutoCapturingForFrame(frame)
+ {
+ if (this._isCapturing && !this._mainResourceForAutoCapturing)
+ return false;
+
+ let mainResource = frame.provisionalMainResource || frame.mainResource;
+ if (mainResource === this._mainResourceForAutoCapturing)
+ return false;
+
+ let oldMainResource = frame.mainResource || null;
+ this._isCapturingPageReload = oldMainResource !== null && oldMainResource.url ="" mainResource.url;
+
if (this._isCapturing)
this.stopCapturing();
- this._autoCapturingMainResource = mainResource;
+ this._mainResourceForAutoCapturing = mainResource;
this._loadNewRecording();
@@ -643,9 +701,7 @@
this._addRecord(new WebInspector.ResourceTimelineRecord(mainResource));
- if (this._stopCapturingTimeout)
- clearTimeout(this._stopCapturingTimeout);
- this._stopCapturingTimeout = setTimeout(this._boundStopCapturing, WebInspector.TimelineManager.MaximumAutoRecordDuration);
+ this._resetAutoRecordingMaxTimeTimeout();
return true;
}
@@ -653,7 +709,7 @@
_stopAutoRecordingSoon()
{
// Only auto stop when auto capturing.
- if (!this._isCapturing || !this._autoCapturingMainResource)
+ if (!this._isCapturing || !this._mainResourceForAutoCapturing)
return;
if (this._stopCapturingTimeout)
@@ -661,10 +717,17 @@
this._stopCapturingTimeout = setTimeout(this._boundStopCapturing, WebInspector.TimelineManager.MaximumAutoRecordDurationAfterLoadEvent);
}
+ _resetAutoRecordingMaxTimeTimeout()
+ {
+ if (this._stopCapturingTimeout)
+ clearTimeout(this._stopCapturingTimeout);
+ this._stopCapturingTimeout = setTimeout(this._boundStopCapturing, WebInspector.TimelineManager.MaximumAutoRecordDuration);
+ }
+
_resetAutoRecordingDeadTimeTimeout()
{
// Only monitor dead time when auto capturing.
- if (!this._isCapturing || !this._autoCapturingMainResource)
+ if (!this._isCapturing || !this._mainResourceForAutoCapturing)
return;
if (this._deadTimeTimeout)
@@ -672,13 +735,19 @@
this._deadTimeTimeout = setTimeout(this._boundStopCapturing, WebInspector.TimelineManager.DeadTimeRequiredToStopAutoRecordingEarly);
}
+ _provisionalLoadStarted(event)
+ {
+ this._attemptAutoCapturingForFrame(event.target);
+ }
+
_mainResourceDidChange(event)
{
- if (event.target.isMainFrame())
+ let frame = event.target;
+ if (frame.isMainFrame())
this._persistentNetworkTimeline.reset();
- var mainResource = event.target.mainResource;
- var record = new WebInspector.ResourceTimelineRecord(mainResource);
+ let mainResource = frame.mainResource;
+ let record = new WebInspector.ResourceTimelineRecord(mainResource);
if (!isNaN(record.startTime))
this._persistentNetworkTimeline.addRecord(record);
@@ -687,13 +756,13 @@
if (!WebInspector.frameResourceManager.mainFrame)
return;
- if (this._startAutoCapturing(event))
+ if (this._attemptAutoCapturingForFrame(frame))
return;
if (!this._isCapturing)
return;
- if (mainResource === this._autoCapturingMainResource)
+ if (mainResource === this._mainResourceForAutoCapturing)
return;
this._addRecord(record);
@@ -891,6 +960,39 @@
// However, the remaining ScriptProfiler records are valid and could be shown.
// FIXME: <https://webkit.org/b/152904> Web Inspector: Timeline UI should keep up with processing all incoming records
}
+
+ _updateAutoCaptureInstruments()
+ {
+ if (!window.TimelineAgent)
+ return;
+
+ if (!TimelineAgent.setAutoCaptureInstruments)
+ return;
+
+ let instrumentSet = new Set;
+ let enabledTimelineTypes = this._enabledTimelineTypesSetting.value;
+
+ for (let timelineType of enabledTimelineTypes) {
+ switch (timelineType) {
+ case WebInspector.TimelineRecord.Type.Script:
+ instrumentSet.add(TimelineAgent.Instrument.ScriptProfiler);
+ break;
+ case WebInspector.TimelineRecord.Type.HeapAllocations:
+ instrumentSet.add(TimelineAgent.Instrument.Heap);
+ break;
+ case WebInspector.TimelineRecord.Type.Network:
+ case WebInspector.TimelineRecord.Type.RenderingFrame:
+ case WebInspector.TimelineRecord.Type.Layout:
+ instrumentSet.add(TimelineAgent.Instrument.Timeline);
+ break;
+ case WebInspector.TimelineRecord.Type.Memory:
+ instrumentSet.add(TimelineAgent.Instrument.Memory);
+ break;
+ }
+ }
+
+ TimelineAgent.setAutoCaptureInstruments([...instrumentSet]);
+ }
};
WebInspector.TimelineManager.Event = {
Modified: branches/safari-602.1.32-branch/Source/WebInspectorUI/UserInterface/Protocol/TimelineObserver.js (201147 => 201148)
--- branches/safari-602.1.32-branch/Source/WebInspectorUI/UserInterface/Protocol/TimelineObserver.js 2016-05-19 08:40:55 UTC (rev 201147)
+++ branches/safari-602.1.32-branch/Source/WebInspectorUI/UserInterface/Protocol/TimelineObserver.js 2016-05-19 08:41:03 UTC (rev 201148)
@@ -41,4 +41,9 @@
{
WebInspector.timelineManager.capturingStopped(endTime);
}
+
+ autoCaptureStarted()
+ {
+ WebInspector.timelineManager.autoCaptureStarted();
+ }
};