Changeset 200651 in webkit


Ignore:
Timestamp:
May 10, 2016, 4:38:04 PM (9 years ago)
Author:
commit-queue@webkit.org
Message:

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>

Patch by Joseph Pecoraro <Joseph Pecoraro> on 2016-05-10
Reviewed by Brian Burg.

Source/JavaScriptCore:

  • 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.

Source/WebCore:

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.

Source/WebInspectorUI:

  • 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.

LayoutTests:

  • inspector/timeline/setAutoCaptureInstruments-errors-expected.txt: Added.
  • inspector/timeline/setAutoCaptureInstruments-errors.html: Added.
Location:
trunk
Files:
2 added
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r200646 r200651  
     12016-05-10  Joseph Pecoraro  <pecoraro@apple.com>
     2
     3        Web Inspector: Backend should initiate timeline recordings on page navigations to ensure nothing is missed
     4        https://bugs.webkit.org/show_bug.cgi?id=157504
     5        <rdar://problem/26188642>
     6
     7        Reviewed by Brian Burg.
     8
     9        * inspector/timeline/setAutoCaptureInstruments-errors-expected.txt: Added.
     10        * inspector/timeline/setAutoCaptureInstruments-errors.html: Added.
     11
    1122016-05-10  Ryan Haddad  <ryanhaddad@apple.com>
    213
  • trunk/Source/JavaScriptCore/ChangeLog

    r200648 r200651  
     12016-05-10  Joseph Pecoraro  <pecoraro@apple.com>
     2
     3        Web Inspector: Backend should initiate timeline recordings on page navigations to ensure nothing is missed
     4        https://bugs.webkit.org/show_bug.cgi?id=157504
     5        <rdar://problem/26188642>
     6
     7        Reviewed by Brian Burg.
     8
     9        * inspector/protocol/Timeline.json:
     10        Add protocol commands to enable/disable auto capture and list the
     11        instruments that should be enabled when auto capture starts.
     12        Add protocol event for when the backend starts an auto capture.
     13
    1142016-05-10  Joseph Pecoraro  <pecoraro@apple.com>
    215
  • trunk/Source/JavaScriptCore/inspector/protocol/Timeline.json

    r191967 r200651  
    77            "id": "EventType",
    88            "type": "string",
     9            "description": "Timeline record type.",
    910            "enum": [
    1011                "EventDispatch",
     
    2930                "CancelAnimationFrame",
    3031                "FireAnimationFrame"
    31             ],
    32             "description": "Timeline record type."
     32            ]
     33        },
     34        {
     35            "id": "Instrument",
     36            "type": "string",
     37            "description": "Instrument types.",
     38            "enum": [
     39                "ScriptProfiler",
     40                "Timeline",
     41                "Memory",
     42                "Heap"
     43            ]
    3344        },
    3445        {
    3546            "id": "TimelineEvent",
    3647            "type": "object",
     48            "description": "Timeline record contains information about the recorded activity.",
    3749            "properties": [
    3850                { "name": "type", "$ref": "EventType", "description": "Event type." },
    3951                { "name": "data", "type": "object", "description": "Event data." },
    4052                { "name": "children", "type": "array", "optional": true, "items": { "$ref": "TimelineEvent" }, "description": "Nested records." }
    41             ],
    42             "description": "Timeline record contains information about the recorded activity."
     53            ]
    4354        },
    4455        {
     
    8091        {
    8192            "name": "start",
     93            "description": "Starts capturing instrumentation events.",
    8294            "parameters": [
    8395                { "name": "maxCallStackDepth", "optional": true, "type": "integer", "description": "Samples JavaScript stack traces up to <code>maxCallStackDepth</code>, defaults to 5." }
    84             ],
    85             "description": "Starts capturing instrumentation events."
     96            ]
    8697        },
    8798        {
    8899            "name": "stop",
    89100            "description": "Stops capturing instrumentation events."
     101        },
     102        {
     103            "name": "setAutoCaptureEnabled",
     104            "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.",
     105            "parameters": [
     106                { "name": "enabled", "type": "boolean", "description": "New auto capture state." }
     107            ]
     108        },
     109        {
     110            "name": "setAutoCaptureInstruments",
     111            "description": "Instruments to enable when an auto capture starts.",
     112            "parameters": [
     113                { "name": "instruments", "type": "array", "items": { "$ref": "Instrument" }, "description": "Instruments to enable." }
     114            ]
    90115        }
    91116    ],
     
    93118        {
    94119            "name": "eventRecorded",
     120            "description": "Fired for every instrumentation event while timeline is started.",
    95121            "parameters": [
    96122                { "name": "record", "$ref": "TimelineEvent", "description": "Timeline event record data." }
    97             ],
    98             "description": "Fired for every instrumentation event while timeline is started."
     123            ]
    99124        },
    100125        {
    101126            "name": "recordingStarted",
     127            "description": "Fired when recording has started.",
    102128            "parameters": [
    103129                { "name": "startTime", "type": "number", "description": "Start time of this new recording." }
    104             ],
    105             "description": "Fired when recording has started."
     130            ]
    106131        },
    107132        {
    108133            "name": "recordingStopped",
     134            "description": "Fired when recording has stopped.",
    109135            "parameters": [
    110136                { "name": "endTime", "type": "number", "description": "End time of this recording." }
    111             ],
    112             "description": "Fired when recording has stopped."
     137            ]
     138        },
     139        {
     140            "name": "autoCaptureStarted",
     141            "description": "Fired when auto capture started."
    113142        }
    114143    ]
  • trunk/Source/WebCore/ChangeLog

    r200642 r200651  
     12016-05-10  Joseph Pecoraro  <pecoraro@apple.com>
     2
     3        Web Inspector: Backend should initiate timeline recordings on page navigations to ensure nothing is missed
     4        https://bugs.webkit.org/show_bug.cgi?id=157504
     5        <rdar://problem/26188642>
     6
     7        Reviewed by Brian Burg.
     8
     9        Test: inspector/timeline/setAutoCaptureInstruments-errors.html
     10
     11        * inspector/InspectorController.cpp:
     12        (WebCore::InspectorController::InspectorController):
     13        Pass other agents into the TimelineAgent constructor.
     14
     15        * inspector/InspectorInstrumentation.cpp:
     16        (WebCore::InspectorInstrumentation::frameStartedLoadingImpl):
     17        Inform the TimelineAgent whenever the main frame starts a new load.
     18
     19        * inspector/InspectorTimelineAgent.h:
     20        * inspector/InspectorTimelineAgent.cpp:
     21        (WebCore::InspectorTimelineAgent::InspectorTimelineAgent):
     22        Initialize new members.
     23
     24        (WebCore::InspectorTimelineAgent::willDestroyFrontendAndBackend):
     25        Cleanup auto capture state when tearing down.
     26
     27        (WebCore::InspectorTimelineAgent::setAutoCaptureEnabled):
     28        (WebCore::InspectorTimelineAgent::setAutoCaptureInstruments):
     29        Set and validate new auto capture state from the frontend.
     30
     31        (WebCore::InspectorTimelineAgent::mainFrameStartedLoading):
     32        When page navigates start an auto capture if needed.
     33
    1342016-05-10  Csaba Osztrogonác  <ossy@webkit.org>
    235
  • trunk/Source/WebCore/inspector/InspectorController.cpp

    r198786 r200651  
    159159    m_agents.append(WTFMove(domStorageAgentPtr));
    160160
    161     auto timelineAgentPtr = std::make_unique<InspectorTimelineAgent>(pageContext, pageAgent);
    162     m_timelineAgent = timelineAgentPtr.get();
    163     m_agents.append(WTFMove(timelineAgentPtr));
    164 
    165161    auto heapAgentPtr = std::make_unique<InspectorHeapAgent>(pageContext);
    166162    InspectorHeapAgent* heapAgent = heapAgentPtr.get();
    167163    m_agents.append(WTFMove(heapAgentPtr));
     164
     165    auto scriptProfilerAgentPtr = std::make_unique<InspectorScriptProfilerAgent>(pageContext);
     166    InspectorScriptProfilerAgent* scriptProfilerAgent = scriptProfilerAgentPtr.get();
     167    m_agents.append(WTFMove(scriptProfilerAgentPtr));
    168168
    169169    auto consoleAgentPtr = std::make_unique<PageConsoleAgent>(pageContext, heapAgent, m_domAgent);
     
    172172    m_agents.append(WTFMove(consoleAgentPtr));
    173173
     174    auto timelineAgentPtr = std::make_unique<InspectorTimelineAgent>(pageContext, scriptProfilerAgent, heapAgent, pageAgent);
     175    m_timelineAgent = timelineAgentPtr.get();
     176    m_agents.append(WTFMove(timelineAgentPtr));
     177
    174178    auto debuggerAgentPtr = std::make_unique<PageDebuggerAgent>(pageContext, pageAgent, m_overlay.get());
    175179    PageDebuggerAgent* debuggerAgent = debuggerAgentPtr.get();
     
    177181
    178182    m_agents.append(std::make_unique<InspectorDOMDebuggerAgent>(pageContext, m_domAgent, debuggerAgent));
    179     m_agents.append(std::make_unique<InspectorScriptProfilerAgent>(pageContext));
    180183    m_agents.append(std::make_unique<InspectorApplicationCacheAgent>(pageContext, pageAgent));
    181184    m_agents.append(std::make_unique<InspectorLayerTreeAgent>(pageContext));
  • trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp

    r198786 r200651  
    776776        if (PageDebuggerAgent* pageDebuggerAgent = instrumentingAgents.pageDebuggerAgent())
    777777            pageDebuggerAgent->mainFrameStartedLoading();
     778        if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.persistentInspectorTimelineAgent())
     779            timelineAgent->mainFrameStartedLoading();
    778780    }
    779781
  • trunk/Source/WebCore/inspector/InspectorTimelineAgent.cpp

    r199619 r200651  
    3636#include "Event.h"
    3737#include "Frame.h"
     38#include "InspectorMemoryAgent.h"
    3839#include "InspectorPageAgent.h"
    3940#include "InstrumentingAgents.h"
     
    4445#include "TimelineRecordFactory.h"
    4546#include <inspector/ScriptBreakpoint.h>
     47#include <inspector/agents/InspectorDebuggerAgent.h>
     48#include <inspector/agents/InspectorHeapAgent.h>
     49#include <inspector/agents/InspectorScriptProfilerAgent.h>
    4650#include <profiler/LegacyProfiler.h>
    4751#include <wtf/Stopwatch.h>
     
    7882#endif
    7983
     84InspectorTimelineAgent::InspectorTimelineAgent(WebAgentContext& context, InspectorScriptProfilerAgent* scriptProfileAgent, InspectorHeapAgent* heapAgent, InspectorPageAgent* pageAgent)
     85    : InspectorAgentBase(ASCIILiteral("Timeline"), context)
     86    , m_frontendDispatcher(std::make_unique<Inspector::TimelineFrontendDispatcher>(context.frontendRouter))
     87    , m_backendDispatcher(Inspector::TimelineBackendDispatcher::create(context.backendDispatcher, this))
     88    , m_scriptProfilerAgent(scriptProfileAgent)
     89    , m_heapAgent(heapAgent)
     90    , m_pageAgent(pageAgent)
     91{
     92}
     93
    8094InspectorTimelineAgent::~InspectorTimelineAgent()
    8195{
     
    93107    ErrorString unused;
    94108    stop(unused);
     109
     110    m_autoCaptureEnabled = false;
     111    m_autoCaptureInstruments.clear();
    95112}
    96113
     
    107124
    108125    m_enabledFromFrontend = false;
     126}
     127
     128void InspectorTimelineAgent::setAutoCaptureEnabled(ErrorString&, bool enabled)
     129{
     130    m_autoCaptureEnabled = enabled;
     131}
     132
     133void InspectorTimelineAgent::setAutoCaptureInstruments(ErrorString& errorString, const InspectorArray& instruments)
     134{
     135    Vector<Protocol::Timeline::Instrument> newInstruments;
     136    newInstruments.reserveCapacity(instruments.length());
     137
     138    for (auto instrumentValue : instruments) {
     139        String enumValueString;
     140        if (!instrumentValue->asString(enumValueString)) {
     141            errorString = ASCIILiteral("Unexpected type in instruments list, should be string");
     142            return;
     143        }
     144
     145        Optional<Protocol::Timeline::Instrument> instrumentType = Protocol::InspectorHelpers::parseEnumValueFromString<Protocol::Timeline::Instrument>(enumValueString);
     146        if (!instrumentType) {
     147            errorString = makeString("Unexpected enum value: ", enumValueString);
     148            return;
     149        }
     150
     151        newInstruments.uncheckedAppend(*instrumentType);
     152    }
     153
     154    m_autoCaptureInstruments.swap(newInstruments);
    109155}
    110156
     
    383429{
    384430    appendRecord(TimelineRecordFactory::createTimeStampData(message), TimelineRecordType::TimeEnd, true, &frame);
     431}
     432
     433void InspectorTimelineAgent::mainFrameStartedLoading()
     434{
     435    if (m_enabled)
     436        return;
     437
     438    if (!m_autoCaptureEnabled)
     439        return;
     440
     441    if (m_autoCaptureInstruments.isEmpty())
     442        return;
     443
     444    // Pre-emptively disable breakpoints. The frontend must re-enable them.
     445    if (InspectorDebuggerAgent* debuggerAgent = m_instrumentingAgents.inspectorDebuggerAgent()) {
     446        ErrorString unused;
     447        debuggerAgent->setBreakpointsActive(unused, false);
     448    }
     449
     450    // Inform the frontend we started an auto capture. The frontend must stop capture.
     451    m_frontendDispatcher->autoCaptureStarted();
     452
     453    // Enable instruments.
     454    for (auto instrumentType : m_autoCaptureInstruments) {
     455        switch (instrumentType) {
     456        case Inspector::Protocol::Timeline::Instrument::ScriptProfiler: {
     457            if (m_scriptProfilerAgent) {
     458                ErrorString unused;
     459                const bool includeSamples = true;
     460                m_scriptProfilerAgent->startTracking(unused, &includeSamples);
     461            }
     462            break;
     463        }
     464        case Inspector::Protocol::Timeline::Instrument::Heap: {
     465            if (m_heapAgent) {
     466                ErrorString unused;
     467                m_heapAgent->startTracking(unused);
     468            }
     469            break;
     470        }
     471        case Inspector::Protocol::Timeline::Instrument::Memory: {
     472#if ENABLE(RESOURCE_USAGE)
     473            if (InspectorMemoryAgent* memoryAgent = m_instrumentingAgents.inspectorMemoryAgent()) {
     474                ErrorString unused;
     475                memoryAgent->startTracking(unused);
     476            }
     477#endif
     478            break;
     479        }
     480        case Inspector::Protocol::Timeline::Instrument::Timeline:
     481            internalStart();
     482            break;
     483        }
     484    }
    385485}
    386486
     
    525625}
    526626
    527 InspectorTimelineAgent::InspectorTimelineAgent(WebAgentContext& context, InspectorPageAgent* pageAgent)
    528     : InspectorAgentBase(ASCIILiteral("Timeline"), context)
    529     , m_frontendDispatcher(std::make_unique<Inspector::TimelineFrontendDispatcher>(context.frontendRouter))
    530     , m_backendDispatcher(Inspector::TimelineBackendDispatcher::create(context.backendDispatcher, this))
    531     , m_pageAgent(pageAgent)
    532 {
    533 }
    534 
    535627void InspectorTimelineAgent::appendRecord(RefPtr<InspectorObject>&& data, TimelineRecordType type, bool captureCallStack, Frame* frame)
    536628{
  • trunk/Source/WebCore/inspector/InspectorTimelineAgent.h

    r199619 r200651  
    4646}
    4747
     48namespace Inspector {
     49class InspectorHeapAgent;
     50class InspectorScriptProfilerAgent;
     51}
     52
    4853namespace WebCore {
    4954
     
    9398    WTF_MAKE_FAST_ALLOCATED;
    9499public:
    95     InspectorTimelineAgent(WebAgentContext&, InspectorPageAgent*);
     100    InspectorTimelineAgent(WebAgentContext&, Inspector::InspectorScriptProfilerAgent*, Inspector::InspectorHeapAgent*, InspectorPageAgent*);
    96101    virtual ~InspectorTimelineAgent();
    97102
     
    101106    void start(ErrorString&, const int* maxCallStackDepth = nullptr) final;
    102107    void stop(ErrorString&) final;
     108    void setAutoCaptureEnabled(ErrorString&, bool) final;
     109    void setAutoCaptureInstruments(ErrorString&, const Inspector::InspectorArray&) final;
    103110
    104111    int id() const { return m_id; }
     
    138145    void time(Frame&, const String&);
    139146    void timeEnd(Frame&, const String&);
     147    void mainFrameStartedLoading();
    140148
    141149private:
     
    192200    std::unique_ptr<Inspector::TimelineFrontendDispatcher> m_frontendDispatcher;
    193201    RefPtr<Inspector::TimelineBackendDispatcher> m_backendDispatcher;
     202    Inspector::InspectorScriptProfilerAgent* m_scriptProfilerAgent;
     203    Inspector::InspectorHeapAgent* m_heapAgent;
    194204    InspectorPageAgent* m_pageAgent;
    195205
     
    202212    bool m_enabled { false };
    203213    bool m_enabledFromFrontend { false };
     214
     215    bool m_autoCaptureEnabled { false };
     216    Vector<Inspector::Protocol::Timeline::Instrument> m_autoCaptureInstruments;
    204217
    205218#if PLATFORM(COCOA)
  • trunk/Source/WebInspectorUI/ChangeLog

    r200649 r200651  
     12016-05-10  Joseph Pecoraro  <pecoraro@apple.com>
     2
     3        Web Inspector: Backend should initiate timeline recordings on page navigations to ensure nothing is missed
     4        https://bugs.webkit.org/show_bug.cgi?id=157504
     5        <rdar://problem/26188642>
     6
     7        Reviewed by Brian Burg.
     8
     9        * UserInterface/Controllers/TimelineManager.js:
     10        (WebInspector.TimelineManager):
     11        (WebInspector.TimelineManager.prototype.set autoCaptureOnPageLoad):
     12        (WebInspector.TimelineManager.prototype.set enabledTimelineTypes):
     13        (WebInspector.TimelineManager.prototype._updateAutoCaptureInstruments):
     14        For backends that support it, enable/disable auto capture and the instruments to use.
     15
     16        (WebInspector.TimelineManager.prototype.autoCaptureStarted):
     17        New event, stop and start a new recording. Set a flag that we should
     18        detect the auto capturing resource so we know when the stop the
     19        auto capture.
     20
     21        (WebInspector.TimelineManager.prototype._loadNewRecording):
     22        (WebInspector.TimelineManager.prototype._addRecord):
     23        (WebInspector.TimelineManager.prototype._startAutoCapturing): Renamed.
     24        (WebInspector.TimelineManager.prototype._attemptAutoCapturingForFrame):
     25        (WebInspector.TimelineManager.prototype._legacyAttemptStartAutoCapturingForFrame):
     26        (WebInspector.TimelineManager.prototype._stopAutoRecordingSoon):
     27        (WebInspector.TimelineManager.prototype._resetAutoRecordingMaxTimeTimeout):
     28        (WebInspector.TimelineManager.prototype._resetAutoRecordingDeadTimeTimeout):
     29        (WebInspector.TimelineManager.prototype._mainResourceDidChange):
     30        (WebInspector.TimelineManager.prototype._mergeScriptProfileRecords):
     31        Factor out the new path, old path, and shared code for auto capturing.
     32        Renamed _startAutoCapturing to _attemptAutoCapturingForFrame which
     33        better matches what it tries to do.
     34
     35        * UserInterface/Protocol/TimelineObserver.js:
     36        (WebInspector.TimelineObserver.prototype.autoCaptureStarted):
     37        Inform TimelineManager.
     38
    1392016-05-10  Matt Baker  <mattbaker@apple.com>
    240
  • trunk/Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js

    r198867 r200651  
    3030        super();
    3131
    32         WebInspector.Frame.addEventListener(WebInspector.Frame.Event.ProvisionalLoadStarted, this._startAutoCapturing, this);
     32        WebInspector.Frame.addEventListener(WebInspector.Frame.Event.ProvisionalLoadStarted, this._provisionalLoadStarted, this);
    3333        WebInspector.Frame.addEventListener(WebInspector.Frame.Event.MainResourceDidChange, this._mainResourceDidChange, this);
    3434        WebInspector.Frame.addEventListener(WebInspector.Frame.Event.ResourceWasAdded, this._resourceWasAdded, this);
     
    3838
    3939        this._enabledTimelineTypesSetting = new WebInspector.Setting("enabled-instrument-types", WebInspector.TimelineManager.defaultTimelineTypes());
     40        this._updateAutoCaptureInstruments();
    4041
    4142        this._persistentNetworkTimeline = new WebInspector.NetworkTimeline;
     
    4344        this._isCapturing = false;
    4445        this._isCapturingPageReload = false;
    45         this._autoCapturingMainResource = null;
     46        this._autoCaptureOnPageLoad = false;
     47        this._mainResourceForAutoCapturing = null;
     48        this._shouldSetAutoCapturingMainResource = false;
    4649        this._boundStopCapturing = this.stopCapturing.bind(this);
    4750
     
    129132    {
    130133        this._autoCaptureOnPageLoad = autoCapture;
     134
     135        if (window.TimelineAgent && TimelineAgent.setAutoCaptureEnabled)
     136            TimelineAgent.setAutoCaptureEnabled(autoCapture);
    131137    }
    132138
     
    140146    {
    141147        this._enabledTimelineTypesSetting.value = x || [];
     148
     149        this._updateAutoCaptureInstruments();
    142150    }
    143151
     
    205213    capturingStarted(startTime)
    206214    {
     215        // Called from WebInspector.TimelineObserver.
     216
    207217        if (this._isCapturing)
    208218            return;
     
    220230    capturingStopped(endTime)
    221231    {
     232        // Called from WebInspector.TimelineObserver.
     233
    222234        if (!this._isCapturing)
    223235            return;
     
    235247        this._isCapturing = false;
    236248        this._isCapturingPageReload = false;
    237         this._autoCapturingMainResource = null;
     249        this._shouldSetAutoCapturingMainResource = false;
     250        this._mainResourceForAutoCapturing = null;
    238251
    239252        this.dispatchEventToListeners(WebInspector.TimelineManager.Event.CapturingStopped, {endTime});
     253    }
     254
     255    autoCaptureStarted(startTime)
     256    {
     257        // Called from WebInspector.TimelineObserver.
     258
     259        if (this._isCapturing)
     260            this.stopCapturing();
     261
     262        this.startCapturing(true);
     263
     264        this._shouldSetAutoCapturingMainResource = true;
    240265    }
    241266
     
    592617        // will send request timestamp for the new main resource. This way, all new timeline
    593618        // records will be computed relative to the new navigation.
    594         if (this._autoCapturingMainResource && WebInspector.TimelineRecording.isLegacy) {
    595             console.assert(this._autoCapturingMainResource.originalRequestWillBeSentTimestamp);
    596             this._activeRecording.setLegacyBaseTimestamp(this._autoCapturingMainResource.originalRequestWillBeSentTimestamp);
    597             this._autoCapturingMainResource._requestSentTimestamp = 0;
     619        if (this._mainResourceForAutoCapturing && WebInspector.TimelineRecording.isLegacy) {
     620            console.assert(this._mainResourceForAutoCapturing.originalRequestWillBeSentTimestamp);
     621            this._activeRecording.setLegacyBaseTimestamp(this._mainResourceForAutoCapturing.originalRequestWillBeSentTimestamp);
     622            this._mainResourceForAutoCapturing._requestSentTimestamp = 0;
    598623        }
    599624
     
    618643    }
    619644
    620     _startAutoCapturing(event)
     645    _attemptAutoCapturingForFrame(frame)
    621646    {
    622647        if (!this._autoCaptureOnPageLoad)
    623648            return false;
    624649
    625         if (!event.target.isMainFrame() || (this._isCapturing && !this._autoCapturingMainResource))
     650        if (!frame.isMainFrame())
    626651            return false;
    627652
    628         var mainResource = event.target.provisionalMainResource || event.target.mainResource;
    629         if (mainResource === this._autoCapturingMainResource)
     653        // COMPATIBILITY (iOS 9): Timeline.setAutoCaptureEnabled did not exist.
     654        // Perform auto capture in the frontend.
     655        if (!TimelineAgent.setAutoCaptureEnabled)
     656            return this._legacyAttemptStartAutoCapturingForFrame(frame);
     657
     658        if (!this._shouldSetAutoCapturingMainResource)
    630659            return false;
    631660
    632         var oldMainResource = event.target.mainResource || null;
     661        console.assert(this._isCapturing, "We saw autoCaptureStarted so we should already be capturing");
     662
     663        let mainResource = frame.provisionalMainResource || frame.mainResource;
     664        if (mainResource === this._mainResourceForAutoCapturing)
     665            return false;
     666
     667        let oldMainResource = frame.mainResource || null;
     668        this._isCapturingPageReload = oldMainResource !== null && oldMainResource.url === mainResource.url;
     669
     670        this._mainResourceForAutoCapturing = mainResource;
     671
     672        this._addRecord(new WebInspector.ResourceTimelineRecord(mainResource));
     673
     674        this._resetAutoRecordingMaxTimeTimeout();
     675
     676        this._shouldSetAutoCapturingMainResource = false;
     677
     678        return true;
     679    }
     680
     681    _legacyAttemptStartAutoCapturingForFrame(frame)
     682    {
     683        if (this._isCapturing && !this._mainResourceForAutoCapturing)
     684            return false;
     685
     686        let mainResource = frame.provisionalMainResource || frame.mainResource;
     687        if (mainResource === this._mainResourceForAutoCapturing)
     688            return false;
     689
     690        let oldMainResource = frame.mainResource || null;
    633691        this._isCapturingPageReload = oldMainResource !== null && oldMainResource.url === mainResource.url;
    634692
     
    636694            this.stopCapturing();
    637695
    638         this._autoCapturingMainResource = mainResource;
     696        this._mainResourceForAutoCapturing = mainResource;
    639697
    640698        this._loadNewRecording();
     
    644702        this._addRecord(new WebInspector.ResourceTimelineRecord(mainResource));
    645703
     704        this._resetAutoRecordingMaxTimeTimeout();
     705
     706        return true;
     707    }
     708
     709    _stopAutoRecordingSoon()
     710    {
     711        // Only auto stop when auto capturing.
     712        if (!this._isCapturing || !this._mainResourceForAutoCapturing)
     713            return;
     714
     715        if (this._stopCapturingTimeout)
     716            clearTimeout(this._stopCapturingTimeout);
     717        this._stopCapturingTimeout = setTimeout(this._boundStopCapturing, WebInspector.TimelineManager.MaximumAutoRecordDurationAfterLoadEvent);
     718    }
     719
     720    _resetAutoRecordingMaxTimeTimeout()
     721    {
    646722        if (this._stopCapturingTimeout)
    647723            clearTimeout(this._stopCapturingTimeout);
    648724        this._stopCapturingTimeout = setTimeout(this._boundStopCapturing, WebInspector.TimelineManager.MaximumAutoRecordDuration);
    649 
    650         return true;
    651     }
    652 
    653     _stopAutoRecordingSoon()
    654     {
    655         // Only auto stop when auto capturing.
    656         if (!this._isCapturing || !this._autoCapturingMainResource)
    657             return;
    658 
    659         if (this._stopCapturingTimeout)
    660             clearTimeout(this._stopCapturingTimeout);
    661         this._stopCapturingTimeout = setTimeout(this._boundStopCapturing, WebInspector.TimelineManager.MaximumAutoRecordDurationAfterLoadEvent);
    662725    }
    663726
     
    665728    {
    666729        // Only monitor dead time when auto capturing.
    667         if (!this._isCapturing || !this._autoCapturingMainResource)
     730        if (!this._isCapturing || !this._mainResourceForAutoCapturing)
    668731            return;
    669732
     
    673736    }
    674737
     738    _provisionalLoadStarted(event)
     739    {
     740        this._attemptAutoCapturingForFrame(event.target);
     741    }
     742
    675743    _mainResourceDidChange(event)
    676744    {
    677         if (event.target.isMainFrame())
     745        let frame = event.target;
     746        if (frame.isMainFrame())
    678747            this._persistentNetworkTimeline.reset();
    679748
    680         var mainResource = event.target.mainResource;
    681         var record = new WebInspector.ResourceTimelineRecord(mainResource);
     749        let mainResource = frame.mainResource;
     750        let record = new WebInspector.ResourceTimelineRecord(mainResource);
    682751        if (!isNaN(record.startTime))
    683752            this._persistentNetworkTimeline.addRecord(record);
     
    688757            return;
    689758
    690         if (this._startAutoCapturing(event))
     759        if (this._attemptAutoCapturingForFrame(frame))
    691760            return;
    692761
     
    694763            return;
    695764
    696         if (mainResource === this._autoCapturingMainResource)
     765        if (mainResource === this._mainResourceForAutoCapturing)
    697766            return;
    698767
     
    892961        // FIXME: <https://webkit.org/b/152904> Web Inspector: Timeline UI should keep up with processing all incoming records
    893962    }
     963
     964    _updateAutoCaptureInstruments()
     965    {
     966        if (!window.TimelineAgent)
     967            return;
     968
     969        if (!TimelineAgent.setAutoCaptureInstruments)
     970            return;
     971
     972        let instrumentSet = new Set;
     973        let enabledTimelineTypes = this._enabledTimelineTypesSetting.value;
     974
     975        for (let timelineType of enabledTimelineTypes) {
     976            switch (timelineType) {
     977            case WebInspector.TimelineRecord.Type.Script:
     978                instrumentSet.add(TimelineAgent.Instrument.ScriptProfiler);
     979                break;
     980            case WebInspector.TimelineRecord.Type.HeapAllocations:
     981                instrumentSet.add(TimelineAgent.Instrument.Heap);
     982                break;
     983            case WebInspector.TimelineRecord.Type.Network:
     984            case WebInspector.TimelineRecord.Type.RenderingFrame:
     985            case WebInspector.TimelineRecord.Type.Layout:
     986                instrumentSet.add(TimelineAgent.Instrument.Timeline);
     987                break;
     988            case WebInspector.TimelineRecord.Type.Memory:
     989                instrumentSet.add(TimelineAgent.Instrument.Memory);
     990                break;
     991            }
     992        }
     993
     994        TimelineAgent.setAutoCaptureInstruments([...instrumentSet]);
     995    }
    894996};
    895997
  • trunk/Source/WebInspectorUI/UserInterface/Protocol/TimelineObserver.js

    r187211 r200651  
    4242        WebInspector.timelineManager.capturingStopped(endTime);
    4343    }
     44
     45    autoCaptureStarted()
     46    {
     47        WebInspector.timelineManager.autoCaptureStarted();
     48    }
    4449};
Note: See TracChangeset for help on using the changeset viewer.