Changeset 244158 in webkit


Ignore:
Timestamp:
Apr 10, 2019 3:48:54 PM (5 years ago)
Author:
Devin Rousso
Message:

Web Inspector: Timelines: can't reliably stop/start a recording
https://bugs.webkit.org/show_bug.cgi?id=196778
<rdar://problem/47606798>

Reviewed by Timothy Hatcher.

Source/JavaScriptCore:

  • inspector/protocol/ScriptProfiler.json:
  • inspector/protocol/Timeline.json:

It is possible to determine when programmatic capturing starts/stops in the frontend based
on the state when the backend causes the state to change, such as if the state is "inactive"
when the frontend is told that the backend has started capturing.

  • inspector/protocol/CPUProfiler.json:
  • inspector/protocol/Memory.json:

Send an end timestamp to match other instruments.

  • inspector/JSGlobalObjectConsoleClient.cpp:

(Inspector::JSGlobalObjectConsoleClient::startConsoleProfile):
(Inspector::JSGlobalObjectConsoleClient::stopConsoleProfile):

  • inspector/agents/InspectorScriptProfilerAgent.h:
  • inspector/agents/InspectorScriptProfilerAgent.cpp:

(Inspector::InspectorScriptProfilerAgent::trackingComplete):
(Inspector::InspectorScriptProfilerAgent::programmaticCaptureStarted): Deleted.
(Inspector::InspectorScriptProfilerAgent::programmaticCaptureStopped): Deleted.

Source/WebCore:

  • inspector/agents/InspectorTimelineAgent.cpp:

(WebCore::InspectorTimelineAgent::startProgrammaticCapture):
(WebCore::InspectorTimelineAgent::stopProgrammaticCapture):
It is possible to determine when programmatic capturing starts/stops in the frontend based
on the state when the backend causes the state to change, such as if the state is "inactive"
when the frontend is told that the backend has started capturing.

  • inspector/agents/InspectorCPUProfilerAgent.cpp:

(WebCore::InspectorCPUProfilerAgent::stopTracking):

  • inspector/agents/InspectorMemoryAgent.cpp:

(WebCore::InspectorMemoryAgent::stopTracking):
Send an end timestamp to match other instruments.

Source/WebInspectorUI:

Rather than have a binary state of capturing/not-capturing, we should use a four state:

  1. inactive (when the backend has stopped capturing)
  2. starting (when the frontend requests capturing to start)
  3. active (when the backend has started capturing)
  4. stopping (when the frontend requests capturing to stop)

Capturing is considered "on" when not in an "inactive" state. Prevent the frontend from
starting/stopping capturing unless we're in a "stable" ("inactive" or "active") state, not a
"transition" ("starting" or "stopping") state.

One "side effect" of this change is that since the capturing is considered active until the
backend has stopped capturing, we will continue to process records in the frontend even if
the frontend has requested to stop capturing. <https://webkit.org/b/152904>

  • UserInterface/Controllers/TimelineManager.js:

(WI.TimelineManager):
(WI.TimelineManager.prototype.get capturingState): Added.
(WI.TimelineManager.prototype.reset):
(WI.TimelineManager.prototype.get activeRecording):
(WI.TimelineManager.prototype.set autoCaptureOnPageLoad):
(WI.TimelineManager.prototype.isCapturing):
(WI.TimelineManager.prototype.startCapturing):
(WI.TimelineManager.prototype.stopCapturing):
(WI.TimelineManager.prototype.processJSON):
(WI.TimelineManager.prototype.capturingStarted):
(WI.TimelineManager.prototype.capturingStopped):
(WI.TimelineManager.prototype.autoCaptureStarted):
(WI.TimelineManager.prototype.eventRecorded):
(WI.TimelineManager.prototype.pageDOMContentLoadedEventFired):
(WI.TimelineManager.prototype.pageLoadEventFired):
(WI.TimelineManager.prototype.cpuProfilerTrackingUpdated):
(WI.TimelineManager.prototype.cpuProfilerTrackingCompleted):
(WI.TimelineManager.prototype.memoryTrackingUpdated):
(WI.TimelineManager.prototype.memoryTrackingCompleted):
(WI.TimelineManager.prototype.heapTrackingStarted):
(WI.TimelineManager.prototype.heapTrackingCompleted):
(WI.TimelineManager.prototype.heapSnapshotAdded):
(WI.TimelineManager.prototype._updateCapturingState): Added.
(WI.TimelineManager.prototype._processRecord):
(WI.TimelineManager.prototype._processEvent):
(WI.TimelineManager.prototype._loadNewRecording):
(WI.TimelineManager.prototype._addRecord):
(WI.TimelineManager.prototype._attemptAutoCapturingForFrame):
(WI.TimelineManager.prototype._legacyAttemptStartAutoCapturingForFrame):
(WI.TimelineManager.prototype._stopAutoRecordingSoon):
(WI.TimelineManager.prototype._resetAutoRecordingDeadTimeTimeout):
(WI.TimelineManager.prototype._mainResourceDidChange):
(WI.TimelineManager.prototype._resourceWasAdded):
(WI.TimelineManager.prototype._garbageCollected):
(WI.TimelineManager.prototype._memoryPressure):
(WI.TimelineManager.prototype._handleTimelinesAutoStopSettingChanged):
(WI.TimelineManager.prototype.scriptProfilerTrackingCompleted):
(WI.TimelineManager.prototype._handleDOMNodeDidFireEvent):
(WI.TimelineManager.prototype._handleDOMNodeLowPowerChanged):
(WI.TimelineManager.prototype.unloadRecording): Deleted.
(WI.TimelineManager.prototype.programmaticCaptureStarted): Deleted.
(WI.TimelineManager.prototype.programmaticCaptureStopped): Deleted.
(WI.TimelineManager.prototype.scriptProfilerProgrammaticCaptureStarted): Deleted.
(WI.TimelineManager.prototype.scriptProfilerProgrammaticCaptureStopped): Deleted.

  • UserInterface/Protocol/ScriptProfilerObserver.js:

(WI.ScriptProfilerObserver.prototype.trackingComplete):
(WI.ScriptProfilerObserver.prototype.programmaticCaptureStarted):
(WI.ScriptProfilerObserver.prototype.programmaticCaptureStopped):

  • UserInterface/Protocol/TimelineObserver.js:

(WI.TimelineObserver.prototype.programmaticCaptureStarted):
(WI.TimelineObserver.prototype.programmaticCaptureStopped):
It is possible to determine when programmatic capturing starts/stops in the frontend based
on the state when the backend causes the state to change, such as if the state is "inactive"
when the frontend is told that the backend has started capturing.

  • UserInterface/Protocol/CPUProfilerObserver.js:

(WI.CPUProfilerObserver.prototype.trackingComplete):

  • UserInterface/Protocol/MemoryObserver.js:

(WI.MemoryObserver.prototype.trackingComplete):
Send an end timestamp to match other instruments.

  • UserInterface/Controllers/DebuggerManager.js:

(WI.DebuggerManager):
(WI.DebuggerManager.prototype._handleTimelineCapturingStateChanged): Added.
(WI.DebuggerManager.prototype._timelineCapturingWillStart): Deleted.
(WI.DebuggerManager.prototype._timelineCapturingStopped): Deleted.

  • UserInterface/Models/DefaultDashboard.js:

(WI.DefaultDashboard):
(WI.DefaultDashboard.prototype._handleTimelineCapturingStateChanged): Added.
(WI.DefaultDashboard.prototype._capturingStopped): Deleted.

  • UserInterface/Views/DebuggerSidebarPanel.js:

(WI.DebuggerSidebarPanel):
(WI.DebuggerSidebarPanel.prototype._handleTimelineCapturingStateChanged): Added.
(WI.DebuggerSidebarPanel.prototype._timelineCapturingWillStart): Deleted.
(WI.DebuggerSidebarPanel.prototype._timelineCapturingStopped): Deleted.

  • UserInterface/Views/SourcesNavigationSidebarPanel.js:

(WI.SourcesNavigationSidebarPanel):
(WI.SourcesNavigationSidebarPanel.prototype._handleTimelineCapturingStateChanged): Added.
(WI.SourcesNavigationSidebarPanel.prototype._handleTimelineCapturingWillStart): Deleted.
(WI.SourcesNavigationSidebarPanel.prototype._handleTimelineCapturingStopped): Deleted.

  • UserInterface/Views/TimelineOverview.js:

(WI.TimelineOverview):
(WI.TimelineOverview.prototype._handleTimelineCapturingStateChanged): Added.
(WI.TimelineOverview.prototype._capturingStarted): Deleted.
(WI.TimelineOverview.prototype._capturingStopped): Deleted.

  • UserInterface/Views/TimelineRecordingContentView.js:

(WI.TimelineRecordingContentView):
(WI.TimelineRecordingContentView.prototype._handleTimelineCapturingStateChanged): Added.
(WI.TimelineRecordingContentView.prototype._recordingUnloaded):
(WI.TimelineRecordingContentView.prototype._capturingStarted): Deleted.
(WI.TimelineRecordingContentView.prototype._capturingStopped): Deleted.

  • UserInterface/Views/TimelineTabContentView.js:

(WI.TimelineTabContentView):
(WI.TimelineTabContentView.prototype._handleTimelineCapturingStateChanged): Added.
(WI.TimelineTabContentView.prototype._capturingStartedOrStopped): Deleted.
Use the new single event for all Timelines capture state changes.
Prevent the record button from being clicked when capturing is in a transition state.

Location:
trunk/Source
Files:
25 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r244149 r244158  
     12019-04-10  Devin Rousso  <drousso@apple.com>
     2
     3        Web Inspector: Timelines: can't reliably stop/start a recording
     4        https://bugs.webkit.org/show_bug.cgi?id=196778
     5        <rdar://problem/47606798>
     6
     7        Reviewed by Timothy Hatcher.
     8
     9        * inspector/protocol/ScriptProfiler.json:
     10        * inspector/protocol/Timeline.json:
     11        It is possible to determine when programmatic capturing starts/stops in the frontend based
     12        on the state when the backend causes the state to change, such as if the state is "inactive"
     13        when the frontend is told that the backend has started capturing.
     14
     15        * inspector/protocol/CPUProfiler.json:
     16        * inspector/protocol/Memory.json:
     17        Send an end timestamp to match other instruments.
     18
     19        * inspector/JSGlobalObjectConsoleClient.cpp:
     20        (Inspector::JSGlobalObjectConsoleClient::startConsoleProfile):
     21        (Inspector::JSGlobalObjectConsoleClient::stopConsoleProfile):
     22
     23        * inspector/agents/InspectorScriptProfilerAgent.h:
     24        * inspector/agents/InspectorScriptProfilerAgent.cpp:
     25        (Inspector::InspectorScriptProfilerAgent::trackingComplete):
     26        (Inspector::InspectorScriptProfilerAgent::programmaticCaptureStarted): Deleted.
     27        (Inspector::InspectorScriptProfilerAgent::programmaticCaptureStopped): Deleted.
     28
    1292019-04-10  Tadeu Zagallo  <tzagallo@apple.com>
    230
  • trunk/Source/JavaScriptCore/inspector/JSGlobalObjectConsoleClient.cpp

    r243192 r244158  
    122122    ErrorString unused;
    123123
    124     // FIXME: <https://webkit.org/b/158753> Generalize the concept of Instruments on the backend to work equally for JSContext and Web inspection
    125     if (m_scriptProfilerAgent)
    126         m_scriptProfilerAgent->programmaticCaptureStarted();
    127 
    128124    if (m_debuggerAgent) {
    129125        m_profileRestoreBreakpointActiveValue = m_debuggerAgent->breakpointsActive();
     
    146142    if (m_debuggerAgent)
    147143        m_debuggerAgent->setBreakpointsActive(unused, m_profileRestoreBreakpointActiveValue);
    148 
    149     // FIXME: <https://webkit.org/b/158753> Generalize the concept of Instruments on the backend to work equally for JSContext and Web inspection
    150     if (m_scriptProfilerAgent)
    151         m_scriptProfilerAgent->programmaticCaptureStopped();
    152144}
    153145
  • trunk/Source/JavaScriptCore/inspector/agents/InspectorScriptProfilerAgent.cpp

    r236382 r244158  
    204204void InspectorScriptProfilerAgent::trackingComplete()
    205205{
     206    auto timestamp = m_environment.executionStopwatch()->elapsedTime().seconds();
     207
    206208#if ENABLE(SAMPLING_PROFILER)
    207209    if (m_enabledSamplingProfiler) {
     
    221223        m_enabledSamplingProfiler = false;
    222224
    223         m_frontendDispatcher->trackingComplete(WTFMove(samples));
     225        m_frontendDispatcher->trackingComplete(timestamp, WTFMove(samples));
    224226    } else
    225         m_frontendDispatcher->trackingComplete(nullptr);
     227        m_frontendDispatcher->trackingComplete(timestamp, nullptr);
    226228#else
    227     m_frontendDispatcher->trackingComplete(nullptr);
     229    m_frontendDispatcher->trackingComplete(timestamp, nullptr);
    228230#endif // ENABLE(SAMPLING_PROFILER)
    229231}
     
    247249}
    248250
    249 void InspectorScriptProfilerAgent::programmaticCaptureStarted()
    250 {
    251     m_frontendDispatcher->programmaticCaptureStarted();
    252 }
    253 
    254 void InspectorScriptProfilerAgent::programmaticCaptureStopped()
    255 {
    256     m_frontendDispatcher->programmaticCaptureStopped();
    257 }
    258 
    259251} // namespace Inspector
  • trunk/Source/JavaScriptCore/inspector/agents/InspectorScriptProfilerAgent.h

    r229174 r244158  
    5454    void stopTracking(ErrorString&) override;
    5555
    56     void programmaticCaptureStarted();
    57     void programmaticCaptureStopped();
    58 
    5956    // Debugger::ProfilingClient
    6057    bool isAlreadyProfiling() const override;
  • trunk/Source/JavaScriptCore/inspector/protocol/CPUProfiler.json

    r241739 r244158  
    5353        {
    5454            "name": "trackingComplete",
    55             "description": "Tracking stopped. Includes any buffered data during tracking, such as profiling information."
     55            "description": "Tracking stopped.",
     56            "parameters": [
     57                { "name": "timestamp", "type": "number" }
     58            ]
    5659        }
    5760    ]
  • trunk/Source/JavaScriptCore/inspector/protocol/Memory.json

    r224634 r244158  
    6565        {
    6666            "name": "trackingComplete",
    67             "description": "Tracking stopped."
     67            "description": "Tracking stopped.",
     68            "parameters": [
     69                { "name": "timestamp", "type": "number" }
     70            ]
    6871        }
    6972    ]
  • trunk/Source/JavaScriptCore/inspector/protocol/ScriptProfiler.json

    r237997 r244158  
    8686            "description": "Tracking stopped. Includes any buffered data during tracking, such as profiling information.",
    8787            "parameters": [
     88                { "name": "timestamp", "type": "number" },
    8889                { "name": "samples", "$ref": "Samples", "optional": true, "description": "Stack traces." }
    8990            ]
    90         },
    91         {
    92             "name": "programmaticCaptureStarted",
    93             "description": "Fired when programmatic capture starts (console.profile). JSContext inspection only."
    94         },
    95         {
    96             "name": "programmaticCaptureStopped",
    97             "description": "Fired when programmatic capture stops (console.profileEnd). JSContext inspection only."
    9891        }
    9992    ]
  • trunk/Source/JavaScriptCore/inspector/protocol/Timeline.json

    r240457 r244158  
    108108            "name": "autoCaptureStarted",
    109109            "description": "Fired when auto capture started."
    110         },
    111         {
    112             "name": "programmaticCaptureStarted",
    113             "description": "Fired when programmatic capture starts (console.profile)."
    114         },
    115         {
    116             "name": "programmaticCaptureStopped",
    117             "description": "Fired when programmatic capture stops (console.profileEnd)."
    118110        }
    119111    ]
  • trunk/Source/WebCore/ChangeLog

    r244151 r244158  
     12019-04-10  Devin Rousso  <drousso@apple.com>
     2
     3        Web Inspector: Timelines: can't reliably stop/start a recording
     4        https://bugs.webkit.org/show_bug.cgi?id=196778
     5        <rdar://problem/47606798>
     6
     7        Reviewed by Timothy Hatcher.
     8
     9        * inspector/agents/InspectorTimelineAgent.cpp:
     10        (WebCore::InspectorTimelineAgent::startProgrammaticCapture):
     11        (WebCore::InspectorTimelineAgent::stopProgrammaticCapture):
     12        It is possible to determine when programmatic capturing starts/stops in the frontend based
     13        on the state when the backend causes the state to change, such as if the state is "inactive"
     14        when the frontend is told that the backend has started capturing.
     15
     16        * inspector/agents/InspectorCPUProfilerAgent.cpp:
     17        (WebCore::InspectorCPUProfilerAgent::stopTracking):
     18        * inspector/agents/InspectorMemoryAgent.cpp:
     19        (WebCore::InspectorMemoryAgent::stopTracking):
     20        Send an end timestamp to match other instruments.
     21
    1222019-04-10  Tim Horton  <timothy_horton@apple.com>
    223
  • trunk/Source/WebCore/inspector/agents/InspectorCPUProfilerAgent.cpp

    r241739 r244158  
    7878    m_tracking = false;
    7979
    80     m_frontendDispatcher->trackingComplete();
     80    m_frontendDispatcher->trackingComplete(m_environment.executionStopwatch()->elapsedTime().seconds());
    8181}
    8282
  • trunk/Source/WebCore/inspector/agents/InspectorMemoryAgent.cpp

    r240457 r244158  
    9393    m_tracking = false;
    9494
    95     m_frontendDispatcher->trackingComplete();
     95    m_frontendDispatcher->trackingComplete(m_environment.executionStopwatch()->elapsedTime().seconds());
    9696}
    9797
  • trunk/Source/WebCore/inspector/agents/InspectorTimelineAgent.cpp

    r243269 r244158  
    478478        m_programmaticCaptureRestoreBreakpointActiveValue = false;
    479479
    480     m_frontendDispatcher->programmaticCaptureStarted();
    481 
    482480    toggleScriptProfilerInstrument(InstrumentState::Start); // Ensure JavaScript samping data.
    483481    toggleTimelineInstrument(InstrumentState::Start); // Ensure Console Profile event records.
     
    501499        }
    502500    }
    503 
    504     m_frontendDispatcher->programmaticCaptureStopped();
    505501}
    506502
  • trunk/Source/WebInspectorUI/ChangeLog

    r244157 r244158  
     12019-04-10  Devin Rousso  <drousso@apple.com>
     2
     3        Web Inspector: Timelines: can't reliably stop/start a recording
     4        https://bugs.webkit.org/show_bug.cgi?id=196778
     5        <rdar://problem/47606798>
     6
     7        Reviewed by Timothy Hatcher.
     8
     9        Rather than have a binary state of capturing/not-capturing, we should use a four state:
     10         1. inactive (when the backend has stopped capturing)
     11         2. starting (when the frontend requests capturing to start)
     12         3. active (when the backend has started capturing)
     13         4. stopping (when the frontend requests capturing to stop)
     14
     15        Capturing is considered "on" when not in an "inactive" state. Prevent the frontend from
     16        starting/stopping capturing unless we're in a "stable" ("inactive" or "active") state, not a
     17        "transition" ("starting" or "stopping") state.
     18
     19        One "side effect" of this change is that since the capturing is considered active until the
     20        backend has stopped capturing, we will continue to process records in the frontend even if
     21        the frontend has requested to stop capturing. <https://webkit.org/b/152904>
     22
     23        * UserInterface/Controllers/TimelineManager.js:
     24        (WI.TimelineManager):
     25        (WI.TimelineManager.prototype.get capturingState): Added.
     26        (WI.TimelineManager.prototype.reset):
     27        (WI.TimelineManager.prototype.get activeRecording):
     28        (WI.TimelineManager.prototype.set autoCaptureOnPageLoad):
     29        (WI.TimelineManager.prototype.isCapturing):
     30        (WI.TimelineManager.prototype.startCapturing):
     31        (WI.TimelineManager.prototype.stopCapturing):
     32        (WI.TimelineManager.prototype.processJSON):
     33        (WI.TimelineManager.prototype.capturingStarted):
     34        (WI.TimelineManager.prototype.capturingStopped):
     35        (WI.TimelineManager.prototype.autoCaptureStarted):
     36        (WI.TimelineManager.prototype.eventRecorded):
     37        (WI.TimelineManager.prototype.pageDOMContentLoadedEventFired):
     38        (WI.TimelineManager.prototype.pageLoadEventFired):
     39        (WI.TimelineManager.prototype.cpuProfilerTrackingUpdated):
     40        (WI.TimelineManager.prototype.cpuProfilerTrackingCompleted):
     41        (WI.TimelineManager.prototype.memoryTrackingUpdated):
     42        (WI.TimelineManager.prototype.memoryTrackingCompleted):
     43        (WI.TimelineManager.prototype.heapTrackingStarted):
     44        (WI.TimelineManager.prototype.heapTrackingCompleted):
     45        (WI.TimelineManager.prototype.heapSnapshotAdded):
     46        (WI.TimelineManager.prototype._updateCapturingState): Added.
     47        (WI.TimelineManager.prototype._processRecord):
     48        (WI.TimelineManager.prototype._processEvent):
     49        (WI.TimelineManager.prototype._loadNewRecording):
     50        (WI.TimelineManager.prototype._addRecord):
     51        (WI.TimelineManager.prototype._attemptAutoCapturingForFrame):
     52        (WI.TimelineManager.prototype._legacyAttemptStartAutoCapturingForFrame):
     53        (WI.TimelineManager.prototype._stopAutoRecordingSoon):
     54        (WI.TimelineManager.prototype._resetAutoRecordingDeadTimeTimeout):
     55        (WI.TimelineManager.prototype._mainResourceDidChange):
     56        (WI.TimelineManager.prototype._resourceWasAdded):
     57        (WI.TimelineManager.prototype._garbageCollected):
     58        (WI.TimelineManager.prototype._memoryPressure):
     59        (WI.TimelineManager.prototype._handleTimelinesAutoStopSettingChanged):
     60        (WI.TimelineManager.prototype.scriptProfilerTrackingCompleted):
     61        (WI.TimelineManager.prototype._handleDOMNodeDidFireEvent):
     62        (WI.TimelineManager.prototype._handleDOMNodeLowPowerChanged):
     63        (WI.TimelineManager.prototype.unloadRecording): Deleted.
     64        (WI.TimelineManager.prototype.programmaticCaptureStarted): Deleted.
     65        (WI.TimelineManager.prototype.programmaticCaptureStopped): Deleted.
     66        (WI.TimelineManager.prototype.scriptProfilerProgrammaticCaptureStarted): Deleted.
     67        (WI.TimelineManager.prototype.scriptProfilerProgrammaticCaptureStopped): Deleted.
     68
     69        * UserInterface/Protocol/ScriptProfilerObserver.js:
     70        (WI.ScriptProfilerObserver.prototype.trackingComplete):
     71        (WI.ScriptProfilerObserver.prototype.programmaticCaptureStarted):
     72        (WI.ScriptProfilerObserver.prototype.programmaticCaptureStopped):
     73        * UserInterface/Protocol/TimelineObserver.js:
     74        (WI.TimelineObserver.prototype.programmaticCaptureStarted):
     75        (WI.TimelineObserver.prototype.programmaticCaptureStopped):
     76        It is possible to determine when programmatic capturing starts/stops in the frontend based
     77        on the state when the backend causes the state to change, such as if the state is "inactive"
     78        when the frontend is told that the backend has started capturing.
     79
     80        * UserInterface/Protocol/CPUProfilerObserver.js:
     81        (WI.CPUProfilerObserver.prototype.trackingComplete):
     82        * UserInterface/Protocol/MemoryObserver.js:
     83        (WI.MemoryObserver.prototype.trackingComplete):
     84        Send an end timestamp to match other instruments.
     85
     86        * UserInterface/Controllers/DebuggerManager.js:
     87        (WI.DebuggerManager):
     88        (WI.DebuggerManager.prototype._handleTimelineCapturingStateChanged): Added.
     89        (WI.DebuggerManager.prototype._timelineCapturingWillStart): Deleted.
     90        (WI.DebuggerManager.prototype._timelineCapturingStopped): Deleted.
     91        * UserInterface/Models/DefaultDashboard.js:
     92        (WI.DefaultDashboard):
     93        (WI.DefaultDashboard.prototype._handleTimelineCapturingStateChanged): Added.
     94        (WI.DefaultDashboard.prototype._capturingStopped): Deleted.
     95        * UserInterface/Views/DebuggerSidebarPanel.js:
     96        (WI.DebuggerSidebarPanel):
     97        (WI.DebuggerSidebarPanel.prototype._handleTimelineCapturingStateChanged): Added.
     98        (WI.DebuggerSidebarPanel.prototype._timelineCapturingWillStart): Deleted.
     99        (WI.DebuggerSidebarPanel.prototype._timelineCapturingStopped): Deleted.
     100        * UserInterface/Views/SourcesNavigationSidebarPanel.js:
     101        (WI.SourcesNavigationSidebarPanel):
     102        (WI.SourcesNavigationSidebarPanel.prototype._handleTimelineCapturingStateChanged): Added.
     103        (WI.SourcesNavigationSidebarPanel.prototype._handleTimelineCapturingWillStart): Deleted.
     104        (WI.SourcesNavigationSidebarPanel.prototype._handleTimelineCapturingStopped): Deleted.
     105        * UserInterface/Views/TimelineOverview.js:
     106        (WI.TimelineOverview):
     107        (WI.TimelineOverview.prototype._handleTimelineCapturingStateChanged): Added.
     108        (WI.TimelineOverview.prototype._capturingStarted): Deleted.
     109        (WI.TimelineOverview.prototype._capturingStopped): Deleted.
     110        * UserInterface/Views/TimelineRecordingContentView.js:
     111        (WI.TimelineRecordingContentView):
     112        (WI.TimelineRecordingContentView.prototype._handleTimelineCapturingStateChanged): Added.
     113        (WI.TimelineRecordingContentView.prototype._recordingUnloaded):
     114        (WI.TimelineRecordingContentView.prototype._capturingStarted): Deleted.
     115        (WI.TimelineRecordingContentView.prototype._capturingStopped): Deleted.
     116        * UserInterface/Views/TimelineTabContentView.js:
     117        (WI.TimelineTabContentView):
     118        (WI.TimelineTabContentView.prototype._handleTimelineCapturingStateChanged): Added.
     119        (WI.TimelineTabContentView.prototype._capturingStartedOrStopped): Deleted.
     120        Use the new single event for all Timelines capture state changes.
     121        Prevent the record button from being clicked when capturing is in a transition state.
     122
    11232019-04-10  Devin Rousso  <drousso@apple.com>
    2124
  • trunk/Source/WebInspectorUI/UserInterface/Controllers/DebuggerManager.js

    r243727 r244158  
    3939        WI.Breakpoint.addEventListener(WI.Breakpoint.Event.ActionsDidChange, this._handleBreakpointActionsDidChange, this);
    4040
    41         WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingWillStart, this._timelineCapturingWillStart, this);
    42         WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingStopped, this._timelineCapturingStopped, this);
     41        WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingStateChanged, this._handleTimelineCapturingStateChanged, this);
    4342
    4443        WI.auditManager.addEventListener(WI.AuditManager.Event.TestScheduled, this._handleAuditManagerTestScheduled, this);
     
    11381137    }
    11391138
    1140     _timelineCapturingWillStart(event)
    1141     {
    1142         this._startDisablingBreakpointsTemporarily();
    1143 
    1144         if (this.paused)
    1145             this.resume();
    1146     }
    1147 
    1148     _timelineCapturingStopped(event)
    1149     {
    1150         this._stopDisablingBreakpointsTemporarily();
     1139    _handleTimelineCapturingStateChanged(event)
     1140    {
     1141        switch (WI.timelineManager.capturingState) {
     1142        case WI.TimelineManager.CapturingState.Starting:
     1143            this._startDisablingBreakpointsTemporarily();
     1144            if (this.paused)
     1145                this.resume();
     1146            break;
     1147
     1148        case WI.TimelineManager.CapturingState.Inactive:
     1149            this._stopDisablingBreakpointsTemporarily();
     1150            break;
     1151        }
    11511152    }
    11521153
  • trunk/Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js

    r243269 r244158  
    3434        WI.Frame.addEventListener(WI.Frame.Event.ProvisionalLoadStarted, this._provisionalLoadStarted, this);
    3535        WI.Frame.addEventListener(WI.Frame.Event.MainResourceDidChange, this._mainResourceDidChange, this);
    36         WI.Frame.addEventListener(WI.Frame.Event.ResourceWasAdded, this._resourceWasAdded, this);
    37         WI.Target.addEventListener(WI.Target.Event.ResourceAdded, this._resourceWasAdded, this);
    38 
    39         WI.heapManager.addEventListener(WI.HeapManager.Event.GarbageCollected, this._garbageCollected, this);
    40         WI.memoryManager.addEventListener(WI.MemoryManager.Event.MemoryPressure, this._memoryPressure, this);
    41 
    42         WI.settings.timelinesAutoStop.addEventListener(WI.Setting.Event.Changed, this._handleTimelinesAutoStopSettingChanged, this);
    4336
    4437        this._enabledTimelineTypesSetting = new WI.Setting("enabled-instrument-types", WI.TimelineManager.defaultTimelineTypes());
    4538
    46         this._isCapturing = false;
     39        this._capturingState = TimelineManager.CapturingState.Inactive;
     40        this._capturingInstrumentCount = 0;
     41        this._capturingStartTime = NaN;
     42        this._capturingEndTime = NaN;
     43
    4744        this._initiatedByBackendStart = false;
    4845        this._initiatedByBackendStop = false;
    49         this._waitingForCapturingStartedEvent = false;
     46
    5047        this._isCapturingPageReload = false;
    5148        this._autoCaptureOnPageLoad = false;
     
    5350        this._shouldSetAutoCapturingMainResource = false;
    5451        this._transitioningPageTarget = false;
    55         this._boundStopCapturing = this.stopCapturing.bind(this);
    5652
    5753        this._webTimelineScriptRecordsExpectingScriptProfilerEvents = null;
    5854        this._scriptProfilerRecords = null;
    5955
     56        this._boundStopCapturing = this.stopCapturing.bind(this);
    6057        this._stopCapturingTimeout = undefined;
    6158        this._deadTimeTimeout = undefined;
     
    154151    // Public
    155152
     153    get capturingState() { return this._capturingState; }
     154
    156155    reset()
    157156    {
    158         if (this._isCapturing)
     157        if (this.isCapturing())
    159158            this.stopCapturing();
    160159
     
    169168    get activeRecording()
    170169    {
    171         console.assert(this._activeRecording || !this._isCapturing);
     170        console.assert(this._activeRecording || !this.isCapturing());
    172171        return this._activeRecording;
    173172    }
     
    192191        this._autoCaptureOnPageLoad = autoCapture;
    193192
    194         if (window.TimelineAgent && TimelineAgent.setAutoCaptureEnabled)
    195             TimelineAgent.setAutoCaptureEnabled(this._autoCaptureOnPageLoad);
     193        for (let target of WI.targets) {
     194            if (target.TimelineAgent)
     195                target.TimelineAgent.setAutoCaptureEnabled(this._autoCaptureOnPageLoad);
     196        }
    196197    }
    197198
     
    211212    isCapturing()
    212213    {
    213         return this._isCapturing;
     214        return this._capturingState !== TimelineManager.CapturingState.Inactive;
    214215    }
    215216
     
    239240    startCapturing(shouldCreateRecording)
    240241    {
    241         console.assert(!this._isCapturing, "TimelineManager is already capturing.");
     242        console.assert(this._capturingState === TimelineManager.CapturingState.Stopping || this._capturingState === TimelineManager.CapturingState.Inactive, "TimelineManager is already capturing.");
     243        if (this._capturingState !== TimelineManager.CapturingState.Stopping && this._capturingState !== TimelineManager.CapturingState.Inactive)
     244            return;
    242245
    243246        if (!this._activeRecording || shouldCreateRecording)
    244247            this._loadNewRecording();
    245248
    246         this._waitingForCapturingStartedEvent = true;
    247 
    248         this.dispatchEventToListeners(WI.TimelineManager.Event.CapturingWillStart);
    249 
     249        this._updateCapturingState(TimelineManager.CapturingState.Starting);
     250
     251        this._capturingStartTime = NaN;
    250252        this._activeRecording.start(this._initiatedByBackendStart);
    251253    }
     
    253255    stopCapturing()
    254256    {
    255         console.assert(this._isCapturing, "TimelineManager is not capturing.");
    256 
     257        console.assert(this._capturingState === TimelineManager.CapturingState.Starting || this._capturingState === TimelineManager.CapturingState.Active, "TimelineManager is not capturing.");
     258        if (this._capturingState !== TimelineManager.CapturingState.Starting && this._capturingState !== TimelineManager.CapturingState.Active)
     259            return;
     260
     261        this._updateCapturingState(TimelineManager.CapturingState.Stopping);
     262
     263        this._capturingEndTime = NaN;
    257264        this._activeRecording.stop(this._initiatedByBackendStop);
    258 
    259         // NOTE: Always stop immediately instead of waiting for a Timeline.recordingStopped event.
    260         // This way the UI feels as responsive to a stop as possible.
    261         // FIXME: <https://webkit.org/b/152904> Web Inspector: Timeline UI should keep up with processing all incoming records
    262         this.capturingStopped();
    263     }
    264 
    265     unloadRecording()
    266     {
    267         if (!this._activeRecording)
    268             return;
    269 
    270         if (this._isCapturing)
    271             this.stopCapturing();
    272 
    273         this._activeRecording.unloaded();
    274         this._activeRecording = null;
    275265    }
    276266
     
    306296        this.dispatchEventToListeners(WI.TimelineManager.Event.RecordingCreated, {recording: newRecording});
    307297
    308         if (this._isCapturing)
     298        if (this.isCapturing())
    309299            this.stopCapturing();
    310300
     
    340330        // Called from WI.TimelineObserver.
    341331
    342         if (this._isCapturing)
    343             return;
    344 
    345         this._waitingForCapturingStartedEvent = false;
    346         this._isCapturing = true;
     332        // The frontend didn't start capturing, so this was a programmatic start.
     333        if (this._capturingState === TimelineManager.CapturingState.Inactive) {
     334            this._initiatedByBackendStart = true;
     335            this._activeRecording.addScriptInstrumentForProgrammaticCapture();
     336            this.startCapturing();
     337        }
     338
     339        if (!isNaN(startTime)) {
     340            if (isNaN(this._capturingStartTime) || startTime < this._capturingStartTime)
     341                this._capturingStartTime = startTime;
     342
     343            this._activeRecording.initializeTimeBoundsIfNecessary(startTime);
     344        }
     345
     346        this._capturingInstrumentCount++;
     347        console.assert(this._capturingInstrumentCount);
     348        if (this._capturingInstrumentCount > 1)
     349            return;
     350
     351        if (this._capturingState === TimelineManager.CapturingState.Active)
     352            return;
    347353
    348354        this._lastDeadTimeTickle = 0;
    349355
    350         if (startTime)
    351             this.activeRecording.initializeTimeBoundsIfNecessary(startTime);
    352 
    353356        this._webTimelineScriptRecordsExpectingScriptProfilerEvents = [];
     357
     358        WI.settings.timelinesAutoStop.addEventListener(WI.Setting.Event.Changed, this._handleTimelinesAutoStopSettingChanged, this);
     359
     360        WI.Frame.addEventListener(WI.Frame.Event.ResourceWasAdded, this._resourceWasAdded, this);
     361        WI.Target.addEventListener(WI.Target.Event.ResourceAdded, this._resourceWasAdded, this);
     362
     363        WI.heapManager.addEventListener(WI.HeapManager.Event.GarbageCollected, this._garbageCollected, this);
     364
     365        WI.memoryManager.addEventListener(WI.MemoryManager.Event.MemoryPressure, this._memoryPressure, this);
    354366
    355367        WI.DOMNode.addEventListener(WI.DOMNode.Event.DidFireEvent, this._handleDOMNodeDidFireEvent, this);
    356368        WI.DOMNode.addEventListener(WI.DOMNode.Event.LowPowerChanged, this._handleDOMNodeLowPowerChanged, this);
    357369
    358         this.dispatchEventToListeners(WI.TimelineManager.Event.CapturingStarted, {startTime});
     370        this._updateCapturingState(TimelineManager.CapturingState.Active, {startTime: this._capturingStartTime});
    359371    }
    360372
     
    363375        // Called from WI.TimelineObserver.
    364376
    365         if (!this._isCapturing)
     377        // The frontend didn't stop capturing, so this was a programmatic stop.
     378        if (this._capturingState === TimelineManager.CapturingState.Active) {
     379            this._initiatedByBackendStop = true;
     380            this.stopCapturing();
     381        }
     382
     383        if (!isNaN(endTime)) {
     384            if (isNaN(this._capturingEndTime) || endTime > this._capturingEndTime)
     385                this._capturingEndTime = endTime;
     386        }
     387
     388        this._capturingInstrumentCount--;
     389        console.assert(this._capturingInstrumentCount >= 0);
     390        if (this._capturingInstrumentCount)
     391            return;
     392
     393        if (this._capturingState === TimelineManager.CapturingState.Inactive)
    366394            return;
    367395
    368396        WI.DOMNode.removeEventListener(null, null, this);
     397        WI.memoryManager.removeEventListener(null, null, this);
     398        WI.heapManager.removeEventListener(null, null, this);
     399        WI.Target.removeEventListener(WI.Target.Event.ResourceAdded, this._resourceWasAdded, this);
     400        WI.Frame.removeEventListener(WI.Frame.Event.ResourceWasAdded, this._resourceWasAdded, this);
     401        WI.settings.timelinesAutoStop.removeEventListener(null, null, this);
    369402
    370403        this.relaxAutoStop();
    371404
    372         this._isCapturing = false;
    373405        this._isCapturingPageReload = false;
    374406        this._shouldSetAutoCapturingMainResource = false;
     
    377409        this._initiatedByBackendStop = false;
    378410
    379         this.dispatchEventToListeners(WI.TimelineManager.Event.CapturingStopped, {endTime});
     411        this._updateCapturingState(TimelineManager.CapturingState.Inactive, {endTime: this._capturingEndTime});
    380412    }
    381413
     
    384416        // Called from WI.TimelineObserver.
    385417
    386         if (this._isCapturing)
     418        let waitingForCapturingStartedEvent = this._capturingState === TimelineManager.CapturingState.Starting;
     419
     420        if (this.isCapturing())
    387421            this.stopCapturing();
    388422
     
    392426        // between sending the Timeline.start command and receiving Timeline.capturingStarted event.
    393427        // In that case, there is no need to call startCapturing again. Reuse the fresh recording.
    394         if (!this._waitingForCapturingStartedEvent) {
     428        if (!waitingForCapturingStartedEvent) {
    395429            const createNewRecording = true;
    396430            this.startCapturing(createNewRecording);
     
    400434    }
    401435
    402     programmaticCaptureStarted()
     436    eventRecorded(recordPayload)
    403437    {
    404438        // Called from WI.TimelineObserver.
    405439
    406         this._initiatedByBackendStart = true;
    407 
    408         this._activeRecording.addScriptInstrumentForProgrammaticCapture();
    409 
    410         const createNewRecording = false;
    411         this.startCapturing(createNewRecording);
    412     }
    413 
    414     programmaticCaptureStopped()
    415     {
    416         // Called from WI.TimelineObserver.
    417 
    418         this._initiatedByBackendStop = true;
    419 
    420         // FIXME: This is purely to avoid a noisy assert. Previously
    421         // it was impossible to stop without stopping from the UI.
    422         console.assert(!this._isCapturing);
    423         this._isCapturing = true;
    424 
    425         this.stopCapturing();
    426     }
    427 
    428     eventRecorded(recordPayload)
    429     {
    430         // Called from WI.TimelineObserver.
    431 
    432         if (!this._isCapturing)
     440        console.assert(this.isCapturing());
     441        if (!this.isCapturing())
    433442            return;
    434443
     
    470479    }
    471480
    472     // Protected
    473 
    474481    pageDOMContentLoadedEventFired(timestamp)
    475482    {
     
    479486        console.assert(isNaN(WI.networkManager.mainFrame.domContentReadyEventTimestamp));
    480487
    481         let computedTimestamp = this.activeRecording.computeElapsedTime(timestamp);
     488        let computedTimestamp = this._activeRecording.computeElapsedTime(timestamp);
    482489
    483490        WI.networkManager.mainFrame.markDOMContentReadyEvent(computedTimestamp);
     
    494501        console.assert(isNaN(WI.networkManager.mainFrame.loadEventTimestamp));
    495502
    496         let computedTimestamp = this.activeRecording.computeElapsedTime(timestamp);
     503        let computedTimestamp = this._activeRecording.computeElapsedTime(timestamp);
    497504
    498505        WI.networkManager.mainFrame.markLoadEvent(computedTimestamp);
     
    515522        // Called from WI.CPUProfilerObserver.
    516523
    517         if (!this._isCapturing)
     524        console.assert(this.isCapturing());
     525        if (!this.isCapturing())
    518526            return;
    519527
     
    521529    }
    522530
    523     cpuProfilerTrackingCompleted()
     531    cpuProfilerTrackingCompleted(timestamp)
    524532    {
    525533        // Called from WI.CPUProfilerObserver.
     534
     535        this.capturingStopped(timestamp);
    526536    }
    527537
     
    537547        // Called from WI.MemoryObserver.
    538548
    539         if (!this._isCapturing)
     549        console.assert(this.isCapturing());
     550        if (!this.isCapturing())
    540551            return;
    541552
     
    543554    }
    544555
    545     memoryTrackingCompleted()
     556    memoryTrackingCompleted(timestamp)
    546557    {
    547558        // Called from WI.MemoryObserver.
     559
     560        this.capturingStopped(timestamp);
    548561    }
    549562
     
    552565        // Called from WI.HeapObserver.
    553566
     567        this.capturingStarted(timestamp);
     568
    554569        this._addRecord(new WI.HeapAllocationsTimelineRecord(timestamp, snapshot));
    555 
    556         this.capturingStarted(timestamp);
    557570    }
    558571
     
    562575
    563576        this._addRecord(new WI.HeapAllocationsTimelineRecord(timestamp, snapshot));
     577
     578        this.capturingStopped();
    564579    }
    565580
     
    568583        // Called from WI.HeapAllocationsInstrument.
    569584
     585        console.assert(this.isCapturing());
     586        if (!this.isCapturing())
     587            return;
     588
    570589        this._addRecord(new WI.HeapAllocationsTimelineRecord(timestamp, snapshot));
    571590    }
     
    573592    // Private
    574593
     594    _updateCapturingState(state, data = {})
     595    {
     596        if (this._capturingState === state)
     597            return;
     598
     599        this._capturingState = state;
     600
     601        this.dispatchEventToListeners(TimelineManager.Event.CapturingStateChanged, data);
     602    }
     603
    575604    _processRecord(recordPayload, parentRecordPayload)
    576605    {
    577         var startTime = this.activeRecording.computeElapsedTime(recordPayload.startTime);
    578         var endTime = this.activeRecording.computeElapsedTime(recordPayload.endTime);
     606        console.assert(this.isCapturing());
     607
     608        var startTime = this._activeRecording.computeElapsedTime(recordPayload.startTime);
     609        var endTime = this._activeRecording.computeElapsedTime(recordPayload.endTime);
    579610        var callFrames = this._callFramesFromPayload(recordPayload.stackTrace);
    580611
     
    763794    _processEvent(recordPayload, parentRecordPayload)
    764795    {
     796        console.assert(this.isCapturing());
     797
    765798        switch (recordPayload.type) {
    766799        case TimelineAgent.EventType.TimeStamp:
    767             var timestamp = this.activeRecording.computeElapsedTime(recordPayload.startTime);
     800            var timestamp = this._activeRecording.computeElapsedTime(recordPayload.startTime);
    768801            var eventMarker = new WI.TimelineMarker(timestamp, WI.TimelineMarker.Type.TimeStamp, recordPayload.data.message);
    769802            this._activeRecording.addEventMarker(eventMarker);
     
    795828        this.dispatchEventToListeners(WI.TimelineManager.Event.RecordingCreated, {recording: newRecording});
    796829
    797         if (this._isCapturing)
     830        if (this.isCapturing())
    798831            this.stopCapturing();
    799832
     
    828861    _addRecord(record)
    829862    {
     863        console.assert(this.isCapturing());
     864
    830865        this._activeRecording.addRecord(record);
    831866
     
    845880        // COMPATIBILITY (iOS 9): Timeline.setAutoCaptureEnabled did not exist.
    846881        // Perform auto capture in the frontend.
    847         if (!window.TimelineAgent)
     882        if (!InspectorBackend.domains.Timeline)
    848883            return false;
    849         if (!TimelineAgent.setAutoCaptureEnabled)
     884        if (!InspectorBackend.domains.Timeline.setAutoCaptureEnabled)
    850885            return this._legacyAttemptStartAutoCapturingForFrame(frame);
    851886
     
    853888            return false;
    854889
    855         console.assert(this._isCapturing, "We saw autoCaptureStarted so we should already be capturing");
     890        console.assert(this.isCapturing(), "We saw autoCaptureStarted so we should already be capturing");
    856891
    857892        let mainResource = frame.provisionalMainResource || frame.mainResource;
     
    875910    _legacyAttemptStartAutoCapturingForFrame(frame)
    876911    {
    877         if (this._isCapturing && !this._mainResourceForAutoCapturing)
     912        if (this.isCapturing() && !this._mainResourceForAutoCapturing)
    878913            return false;
    879914
     
    885920        this._isCapturingPageReload = oldMainResource !== null && oldMainResource.url === mainResource.url;
    886921
    887         if (this._isCapturing)
     922        if (this.isCapturing())
    888923            this.stopCapturing();
    889924
     
    907942
    908943        // Only auto stop when auto capturing.
    909         if (!this._isCapturing || !this._mainResourceForAutoCapturing)
     944        if (!this.isCapturing() || !this._mainResourceForAutoCapturing)
    910945            return;
    911946
     
    931966
    932967        // Only monitor dead time when auto capturing.
    933         if (!this._isCapturing || !this._mainResourceForAutoCapturing)
     968        if (!this.isCapturing() || !this._mainResourceForAutoCapturing)
    934969            return;
    935970
     
    9721007            return;
    9731008
    974         if (!this._isCapturing)
     1009        console.assert(this.isCapturing());
     1010        if (!this.isCapturing())
    9751011            return;
    9761012
     
    9841020    _resourceWasAdded(event)
    9851021    {
    986 
    9871022        // Ignore resource events when there isn't a main frame yet. Those events are triggered by
    9881023        // loading the cached resources when the inspector opens, and they do not have timing information.
     
    9901025            return;
    9911026
    992         if (!this._isCapturing)
    993             return;
    994 
    9951027        this._addRecord(new WI.ResourceTimelineRecord(event.data.resource));
    9961028    }
     
    9981030    _garbageCollected(event)
    9991031    {
    1000         if (!this._isCapturing)
    1001             return;
    1002 
    1003         let collection = event.data.collection;
     1032        let {collection} = event.data;
    10041033        this._addRecord(new WI.ScriptTimelineRecord(WI.ScriptTimelineRecord.EventType.GarbageCollected, collection.startTime, collection.endTime, null, null, collection));
    10051034    }
     
    10071036    _memoryPressure(event)
    10081037    {
    1009         if (!this._isCapturing)
    1010             return;
    1011 
    1012         this.activeRecording.addMemoryPressureEvent(event.data.memoryPressureEvent);
     1038        this._activeRecording.addMemoryPressureEvent(event.data.memoryPressureEvent);
    10131039    }
    10141040
    10151041    _handleTimelinesAutoStopSettingChanged(event)
    10161042    {
    1017         if (!this._isCapturing)
    1018             return;
    1019 
    10201043        if (WI.settings.timelinesAutoStop.value) {
    10211044            if (this._mainResourceForAutoCapturing && !isNaN(this._mainResourceForAutoCapturing.parentFrame.loadEventTimestamp))
     
    10401063    }
    10411064
    1042     scriptProfilerProgrammaticCaptureStarted()
    1043     {
    1044         // FIXME: <https://webkit.org/b/158753> Generalize the concept of Instruments on the backend to work equally for JSContext and Web inspection
    1045         console.assert(WI.sharedApp.debuggableType === WI.DebuggableType.JavaScript);
    1046         console.assert(!this._isCapturing);
    1047 
    1048         this.programmaticCaptureStarted();
    1049     }
    1050 
    1051     scriptProfilerProgrammaticCaptureStopped()
    1052     {
    1053         // FIXME: <https://webkit.org/b/158753> Generalize the concept of Instruments on the backend to work equally for JSContext and Web inspection
    1054         console.assert(WI.sharedApp.debuggableType === WI.DebuggableType.JavaScript);
    1055         console.assert(this._isCapturing);
    1056 
    1057         this.programmaticCaptureStopped();
    1058     }
    1059 
    10601065    scriptProfilerTrackingStarted(timestamp)
    10611066    {
     
    10811086    }
    10821087
    1083     scriptProfilerTrackingCompleted(samples)
     1088    scriptProfilerTrackingCompleted(timestamp, samples)
    10841089    {
    10851090        console.assert(!this._webTimelineScriptRecordsExpectingScriptProfilerEvents || this._scriptProfilerRecords.length >= this._webTimelineScriptRecordsExpectingScriptProfilerEvents.length);
     
    10871092        if (samples) {
    10881093            let {stackTraces} = samples;
    1089             let topDownCallingContextTree = this.activeRecording.topDownCallingContextTree;
     1094            let topDownCallingContextTree = this._activeRecording.topDownCallingContextTree;
    10901095
    10911096            // Calculate a per-sample duration.
     
    11211126                sampleDurations.fill(defaultDuration, sampleDurationIndex);
    11221127
    1123             this.activeRecording.initializeCallingContextTrees(stackTraces, sampleDurations);
     1128            this._activeRecording.initializeCallingContextTrees(stackTraces, sampleDurations);
    11241129
    11251130            // FIXME: This transformation should not be needed after introducing ProfileView.
     
    11411146        this._scriptProfilerRecords = null;
    11421147
    1143         let timeline = this.activeRecording.timelineForRecordType(WI.TimelineRecord.Type.Script);
     1148        let timeline = this._activeRecording.timelineForRecordType(WI.TimelineRecord.Type.Script);
    11441149        timeline.refresh();
     1150
     1151        this.capturingStopped(timestamp);
    11451152    }
    11461153
     
    12411248    _handleDOMNodeDidFireEvent(event)
    12421249    {
    1243         console.assert(this._isCapturing);
    1244 
    12451250        let {domEvent} = event.data;
    12461251
     
    12531258    _handleDOMNodeLowPowerChanged(event)
    12541259    {
    1255         console.assert(this._isCapturing);
    1256 
    12571260        let {timestamp, isLowPower} = event.data;
    12581261
     
    12641267};
    12651268
     1269WI.TimelineManager.CapturingState = {
     1270    Inactive: "inactive",
     1271    Starting: "starting",
     1272    Active: "active",
     1273    Stopping: "stopping",
     1274};
     1275
    12661276WI.TimelineManager.Event = {
     1277    CapturingStateChanged: "timeline-manager-capturing-started",
    12671278    RecordingCreated: "timeline-manager-recording-created",
    12681279    RecordingLoaded: "timeline-manager-recording-loaded",
    12691280    RecordingImported: "timeline-manager-recording-imported",
    1270     CapturingWillStart: "timeline-manager-capturing-will-start",
    1271     CapturingStarted: "timeline-manager-capturing-started",
    1272     CapturingStopped: "timeline-manager-capturing-stopped"
    12731281};
    12741282
  • trunk/Source/WebInspectorUI/UserInterface/Models/DefaultDashboard.js

    r243452 r244158  
    3434        // Necessary event required to track page load time and resource sizes.
    3535        WI.Frame.addEventListener(WI.Frame.Event.MainResourceDidChange, this._mainResourceDidChange, this);
    36         WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingStopped, this._capturingStopped, this);
     36        WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingStateChanged, this._handleTimelineCapturingStateChanged, this);
    3737
    3838        // Necessary events required to track load of resources.
     
    164164    }
    165165
    166     _capturingStopped(event)
    167     {
     166    _handleTimelineCapturingStateChanged(event)
     167    {
     168        if (WI.timelineManager.isCapturing())
     169            return;
     170
    168171        // If recording stops, we should stop the timer if it hasn't stopped already.
    169172        this._stopUpdatingTime();
  • trunk/Source/WebInspectorUI/UserInterface/Protocol/CPUProfilerObserver.js

    r240457 r244158  
    3838    }
    3939
    40     trackingComplete(samples)
     40    trackingComplete(timestamp)
    4141    {
    42         WI.timelineManager.cpuProfilerTrackingCompleted(samples);
     42        WI.timelineManager.cpuProfilerTrackingCompleted(timestamp);
    4343    }
    4444};
  • trunk/Source/WebInspectorUI/UserInterface/Protocol/MemoryObserver.js

    r240457 r244158  
    4343    }
    4444
    45     trackingComplete()
     45    trackingComplete(timestamp)
    4646    {
    47         WI.timelineManager.memoryTrackingCompleted();
     47        WI.timelineManager.memoryTrackingCompleted(timestamp);
    4848    }
    4949};
  • trunk/Source/WebInspectorUI/UserInterface/Protocol/ScriptProfilerObserver.js

    r220119 r244158  
    3838    }
    3939
    40     trackingComplete(samples)
     40    trackingComplete(timestamp, samples)
    4141    {
    42         WI.timelineManager.scriptProfilerTrackingCompleted(samples);
     42        WI.timelineManager.scriptProfilerTrackingCompleted(timestamp, samples);
    4343    }
    4444
    4545    programmaticCaptureStarted()
    4646    {
    47         WI.timelineManager.scriptProfilerProgrammaticCaptureStarted();
     47        // COMPATIBILITY (iOS 12.2): ScriptProfiler.programmaticCaptureStarted was removed after iOS 12.2.
    4848    }
    4949
    5050    programmaticCaptureStopped()
    5151    {
    52         WI.timelineManager.scriptProfilerProgrammaticCaptureStopped();
     52        // COMPATIBILITY (iOS 12.2): ScriptProfiler.programmaticCaptureStopped was removed after iOS 12.2.
    5353    }
    5454};
  • trunk/Source/WebInspectorUI/UserInterface/Protocol/TimelineObserver.js

    r220119 r244158  
    5050    programmaticCaptureStarted()
    5151    {
    52         WI.timelineManager.programmaticCaptureStarted();
     52        // COMPATIBILITY (iOS 12.2): Timeline.programmaticCaptureStarted was removed after iOS 12.2.
    5353    }
    5454
    5555    programmaticCaptureStopped()
    5656    {
    57         WI.timelineManager.programmaticCaptureStopped();
     57        // COMPATIBILITY (iOS 12.2): Timeline.programmaticCaptureStopped was removed after iOS 12.2.
    5858    }
    5959};
  • trunk/Source/WebInspectorUI/UserInterface/Views/DebuggerSidebarPanel.js

    r243727 r244158  
    5656        WI.DOMBreakpoint.addEventListener(WI.DOMBreakpoint.Event.DOMNodeChanged, this._handleDOMBreakpointDOMNodeChanged, this);
    5757
    58         WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingWillStart, this._timelineCapturingWillStart, this);
    59         WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingStopped, this._timelineCapturingStopped, this);
     58        WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingStateChanged, this._handleTimelineCapturingStateChanged, this);
    6059
    6160        WI.auditManager.addEventListener(WI.AuditManager.Event.TestScheduled, this._handleAuditManagerTestScheduled, this);
     
    252251
    253252        if (WI.debuggerManager.breakpointsDisabledTemporarily) {
    254             if (WI.timelineManager.isCapturing())
    255                 this._timelineCapturingWillStart();
     253            this._handleTimelineCapturingStateChanged();
    256254
    257255            if (WI.auditManager.runningState === WI.AuditManager.RunningState.Active || WI.auditManager.runningState === WI.AuditManager.RunningState.Stopping)
     
    649647    }
    650648
    651     _timelineCapturingWillStart(event)
     649    _handleTimelineCapturingStateChanged(event)
    652650    {
    653651        this._updateTemporarilyDisabledBreakpointsButtons();
    654652
    655         this.contentView.element.insertBefore(this._timelineRecordingWarningElement, this.contentView.element.firstChild);
    656         this._updateBreakpointsDisabledBanner();
    657     }
    658 
    659     _timelineCapturingStopped(event)
    660     {
    661         this._updateTemporarilyDisabledBreakpointsButtons();
    662 
    663         this._timelineRecordingWarningElement.remove();
     653        switch (WI.timelineManager.capturingState) {
     654        case WI.TimelineManager.CapturingState.Starting:
     655            this.contentView.element.insertBefore(this._timelineRecordingWarningElement, this.contentView.element.firstChild);
     656            break;
     657
     658        case WI.TimelineManager.CapturingState.Inactive:
     659            this._timelineRecordingWarningElement.remove();
     660            break;
     661        }
     662
    664663        this._updateBreakpointsDisabledBanner();
    665664    }
  • trunk/Source/WebInspectorUI/UserInterface/Views/SourcesNavigationSidebarPanel.js

    r243715 r244158  
    283283        WI.consoleManager.addEventListener(WI.ConsoleManager.Event.Cleared, this._handleConsoleCleared, this);
    284284
    285         WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingWillStart, this._handleTimelineCapturingWillStart, this);
    286         WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingStopped, this._handleTimelineCapturingStopped, this);
     285        WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingStateChanged, this._handleTimelineCapturingStateChanged, this);
    287286
    288287        WI.auditManager.addEventListener(WI.AuditManager.Event.TestScheduled, this._handleAuditManagerTestScheduled, this);
     
    338337
    339338        if (WI.debuggerManager.breakpointsDisabledTemporarily) {
    340             if (WI.timelineManager.isCapturing())
    341                 this._handleTimelineCapturingWillStart();
     339            this._handleTimelineCapturingStateChanged();
    342340
    343341            if (WI.auditManager.runningState === WI.AuditManager.RunningState.Active || WI.auditManager.runningState === WI.AuditManager.RunningState.Stopping)
     
    18211819    }
    18221820
    1823     _handleTimelineCapturingWillStart(event)
     1821    _handleTimelineCapturingStateChanged(event)
    18241822    {
    18251823        this._updateTemporarilyDisabledBreakpointsButtons();
    18261824
    1827         if (!this._timelineRecordingWarningElement) {
    1828             let stopRecordingButton = document.createElement("button");
    1829             stopRecordingButton.textContent = WI.UIString("Stop recording");
    1830             stopRecordingButton.addEventListener("click", () => {
    1831                 WI.timelineManager.stopCapturing();
    1832             });
    1833 
    1834             this._timelineRecordingWarningElement = document.createElement("div");
    1835             this._timelineRecordingWarningElement.classList.add("warning-banner");
    1836             this._timelineRecordingWarningElement.append(WI.UIString("Debugger disabled during Timeline recording"), document.createElement("br"), stopRecordingButton);
    1837         }
    1838 
    1839         this.contentView.element.insertBefore(this._timelineRecordingWarningElement, this.contentView.element.firstChild);
    1840 
    1841         this._updateBreakpointsDisabledBanner();
    1842     }
    1843 
    1844     _handleTimelineCapturingStopped(event)
    1845     {
    1846         this._updateTemporarilyDisabledBreakpointsButtons();
    1847 
    1848         if (this._timelineRecordingWarningElement) {
    1849             this._timelineRecordingWarningElement.remove();
    1850             this._timelineRecordingWarningElement = null;
     1825        switch (WI.timelineManager.capturingState) {
     1826        case WI.TimelineManager.CapturingState.Starting:
     1827            if (!this._timelineRecordingWarningElement) {
     1828                let stopRecordingButton = document.createElement("button");
     1829                stopRecordingButton.textContent = WI.UIString("Stop recording");
     1830                stopRecordingButton.addEventListener("click", () => {
     1831                    WI.timelineManager.stopCapturing();
     1832                });
     1833
     1834                this._timelineRecordingWarningElement = document.createElement("div");
     1835                this._timelineRecordingWarningElement.classList.add("warning-banner");
     1836                this._timelineRecordingWarningElement.append(WI.UIString("Debugger disabled during Timeline recording"), document.createElement("br"), stopRecordingButton);
     1837            }
     1838
     1839            this.contentView.element.insertBefore(this._timelineRecordingWarningElement, this.contentView.element.firstChild);
     1840            break;
     1841
     1842        case WI.TimelineManager.CapturingState.Inactive:
     1843            if (this._timelineRecordingWarningElement) {
     1844                this._timelineRecordingWarningElement.remove();
     1845                this._timelineRecordingWarningElement = null;
     1846            }
     1847            break;
    18511848        }
    18521849
  • trunk/Source/WebInspectorUI/UserInterface/Views/TimelineOverview.js

    r243166 r244158  
    117117        this._viewModeDidChange();
    118118
     119        WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingStateChanged, this._handleTimelineCapturingStateChanged, this);
    119120        WI.timelineManager.addEventListener(WI.TimelineManager.Event.RecordingImported, this._recordingImported, this);
    120         WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingStarted, this._capturingStarted, this);
    121         WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingStopped, this._capturingStopped, this);
    122121    }
    123122
     
    10331032    }
    10341033
     1034    _handleTimelineCapturingStateChanged(event)
     1035    {
     1036        switch (WI.timelineManager.capturingState) {
     1037        case WI.TimelineManager.CapturingState.Active:
     1038            this._editInstrumentsButton.enabled = false;
     1039            this._stopEditingInstruments();
     1040            break;
     1041
     1042        case WI.TimelineManager.CapturingState.Inactive:
     1043            this._editInstrumentsButton.enabled = true;
     1044            break;
     1045        }
     1046    }
     1047
    10351048    _recordingImported(event)
    10361049    {
     
    10561069    }
    10571070
    1058     _capturingStarted(event)
    1059     {
    1060         this._editInstrumentsButton.enabled = false;
    1061         this._stopEditingInstruments();
    1062     }
    1063 
    1064     _capturingStopped(event)
    1065     {
    1066         this._editInstrumentsButton.enabled = true;
    1067     }
    1068 
    10691071    _compareTimelineTreeElements(a, b)
    10701072    {
  • trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRecordingContentView.js

    r243355 r244158  
    103103        this._recording.addEventListener(WI.TimelineRecording.Event.Unloaded, this._recordingUnloaded, this);
    104104
    105         WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingStarted, this._capturingStarted, this);
    106         WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingStopped, this._capturingStopped, this);
     105        WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingStateChanged, this._handleTimelineCapturingStateChanged, this);
    107106
    108107        WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.Paused, this._debuggerPaused, this);
     
    511510    }
    512511
    513     _capturingStarted(event)
    514     {
     512    _handleTimelineCapturingStateChanged(event)
     513    {
     514        let {startTime, endTime} = event.data;
     515
    515516        this._updateProgressView();
    516517
    517         let startTime = event.data.startTime;
    518         if (!this._updating)
    519             this._startUpdatingCurrentTime(startTime);
    520         this._clearTimelineNavigationItem.enabled = !this._recording.readonly;
    521         this._exportButtonNavigationItem.enabled = false;
    522 
    523         // A discontinuity occurs when the recording is stopped and resumed at
    524         // a future time. Capturing started signals the end of the current
    525         // discontinuity, if one exists.
    526         if (!isNaN(this._discontinuityStartTime)) {
    527             this._recording.addDiscontinuity(this._discontinuityStartTime, startTime);
    528             this._discontinuityStartTime = NaN;
    529         }
    530     }
    531 
    532     _capturingStopped(event)
    533     {
    534         this._updateProgressView();
    535 
    536         if (this._updating)
    537             this._stopUpdatingCurrentTime();
    538 
    539         if (this.currentTimelineView)
    540             this._updateTimelineViewTimes(this.currentTimelineView);
    541 
    542         this._discontinuityStartTime = event.data.endTime || this._currentTime;
    543 
    544         this._exportButtonNavigationItem.enabled = this._recording.canExport();
     518        switch (WI.timelineManager.capturingState) {
     519        case WI.TimelineManager.CapturingState.Active:
     520            if (!this._updating)
     521                this._startUpdatingCurrentTime(startTime);
     522
     523            this._clearTimelineNavigationItem.enabled = !this._recording.readonly;
     524            this._exportButtonNavigationItem.enabled = false;
     525
     526            // A discontinuity occurs when the recording is stopped and resumed at
     527            // a future time. Capturing started signals the end of the current
     528            // discontinuity, if one exists.
     529            if (!isNaN(this._discontinuityStartTime)) {
     530                this._recording.addDiscontinuity(this._discontinuityStartTime, startTime);
     531                this._discontinuityStartTime = NaN;
     532            }
     533            break;
     534
     535        case WI.TimelineManager.CapturingState.Inactive:
     536            if (this._updating)
     537                this._stopUpdatingCurrentTime();
     538
     539            if (this.currentTimelineView)
     540                this._updateTimelineViewTimes(this.currentTimelineView);
     541
     542            this._discontinuityStartTime = endTime || this._currentTime;
     543
     544            this._exportButtonNavigationItem.enabled = this._recording.canExport();
     545            break;
     546        }
    545547    }
    546548
     
    732734        console.assert(!this._updating);
    733735
    734         WI.timelineManager.removeEventListener(WI.TimelineManager.Event.CapturingStarted, this._capturingStarted, this);
    735         WI.timelineManager.removeEventListener(WI.TimelineManager.Event.CapturingStopped, this._capturingStopped, this);
     736        WI.timelineManager.removeEventListener(null, null, this);
    736737    }
    737738
  • trunk/Source/WebInspectorUI/UserInterface/Views/TimelineTabContentView.js

    r242785 r244158  
    7272        }
    7373
     74        WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingStateChanged, this._handleTimelineCapturingStateChanged, this);
    7475        WI.timelineManager.addEventListener(WI.TimelineManager.Event.RecordingCreated, this._recordingCreated, this);
    7576        WI.timelineManager.addEventListener(WI.TimelineManager.Event.RecordingLoaded, this._recordingLoaded, this);
    76 
    77         WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingStarted, this._capturingStartedOrStopped, this);
    78         WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingStopped, this._capturingStartedOrStopped, this);
    7977
    8078        WI.notifications.addEventListener(WI.Notification.VisibilityStateDidChange, this._inspectorVisibilityChanged, this);
     
    426424    }
    427425
    428     _capturingStartedOrStopped(event)
    429     {
    430         let isCapturing = WI.timelineManager.isCapturing();
    431         this._recordButton.toggled = isCapturing;
     426    _handleTimelineCapturingStateChanged(event)
     427    {
     428        let enabled = WI.timelineManager.capturingState === WI.TimelineManager.CapturingState.Active || WI.timelineManager.capturingState === WI.TimelineManager.CapturingState.Inactive;
     429
     430        this._toggleRecordingShortcut.disabled = !enabled;
     431        this._toggleNewRecordingShortcut.disabled = !enabled;
     432
     433        this._recordButton.toggled = WI.timelineManager.isCapturing();
     434        this._recordButton.enabled = enabled;
    432435
    433436        this._updateNavigationBarButtons();
Note: See TracChangeset for help on using the changeset viewer.