Title: [201148] branches/safari-602.1.32-branch

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();
+    }
 };
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to