Unreviewed, rolling out r244158.
authortsavell@apple.com <tsavell@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 11 Apr 2019 17:45:05 +0000 (17:45 +0000)
committertsavell@apple.com <tsavell@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 11 Apr 2019 17:45:05 +0000 (17:45 +0000)
Casued 8 inspector/timeline/ test failures.

Reverted changeset:

"Web Inspector: Timelines: can't reliably stop/start a
recording"
https://bugs.webkit.org/show_bug.cgi?id=196778
https://trac.webkit.org/changeset/244158

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@244191 268f45cc-cd09-0410-ab3c-d52691b4dbfc

25 files changed:
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/inspector/JSGlobalObjectConsoleClient.cpp
Source/JavaScriptCore/inspector/agents/InspectorScriptProfilerAgent.cpp
Source/JavaScriptCore/inspector/agents/InspectorScriptProfilerAgent.h
Source/JavaScriptCore/inspector/protocol/CPUProfiler.json
Source/JavaScriptCore/inspector/protocol/Memory.json
Source/JavaScriptCore/inspector/protocol/ScriptProfiler.json
Source/JavaScriptCore/inspector/protocol/Timeline.json
Source/WebCore/ChangeLog
Source/WebCore/inspector/agents/InspectorCPUProfilerAgent.cpp
Source/WebCore/inspector/agents/InspectorMemoryAgent.cpp
Source/WebCore/inspector/agents/InspectorTimelineAgent.cpp
Source/WebInspectorUI/ChangeLog
Source/WebInspectorUI/UserInterface/Controllers/DebuggerManager.js
Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js
Source/WebInspectorUI/UserInterface/Models/DefaultDashboard.js
Source/WebInspectorUI/UserInterface/Protocol/CPUProfilerObserver.js
Source/WebInspectorUI/UserInterface/Protocol/MemoryObserver.js
Source/WebInspectorUI/UserInterface/Protocol/ScriptProfilerObserver.js
Source/WebInspectorUI/UserInterface/Protocol/TimelineObserver.js
Source/WebInspectorUI/UserInterface/Views/DebuggerSidebarPanel.js
Source/WebInspectorUI/UserInterface/Views/SourcesNavigationSidebarPanel.js
Source/WebInspectorUI/UserInterface/Views/TimelineOverview.js
Source/WebInspectorUI/UserInterface/Views/TimelineRecordingContentView.js
Source/WebInspectorUI/UserInterface/Views/TimelineTabContentView.js

index 35b39e7..642836e 100644 (file)
@@ -1,3 +1,16 @@
+2019-04-11  Truitt Savell  <tsavell@apple.com>
+
+        Unreviewed, rolling out r244158.
+
+        Casued 8 inspector/timeline/ test failures.
+
+        Reverted changeset:
+
+        "Web Inspector: Timelines: can't reliably stop/start a
+        recording"
+        https://bugs.webkit.org/show_bug.cgi?id=196778
+        https://trac.webkit.org/changeset/244158
+
 2019-04-10  Saam Barati  <sbarati@apple.com>
 
         AbstractValue::validateOSREntryValue is wrong for Int52 constants
index 0cd9227..d1bd391 100644 (file)
@@ -121,6 +121,10 @@ void JSGlobalObjectConsoleClient::startConsoleProfile()
 {
     ErrorString unused;
 
+    // FIXME: <https://webkit.org/b/158753> Generalize the concept of Instruments on the backend to work equally for JSContext and Web inspection
+    if (m_scriptProfilerAgent)
+        m_scriptProfilerAgent->programmaticCaptureStarted();
+
     if (m_debuggerAgent) {
         m_profileRestoreBreakpointActiveValue = m_debuggerAgent->breakpointsActive();
         m_debuggerAgent->setBreakpointsActive(unused, false);
@@ -141,6 +145,10 @@ void JSGlobalObjectConsoleClient::stopConsoleProfile()
 
     if (m_debuggerAgent)
         m_debuggerAgent->setBreakpointsActive(unused, m_profileRestoreBreakpointActiveValue);
+
+    // FIXME: <https://webkit.org/b/158753> Generalize the concept of Instruments on the backend to work equally for JSContext and Web inspection
+    if (m_scriptProfilerAgent)
+        m_scriptProfilerAgent->programmaticCaptureStopped();
 }
 
 void JSGlobalObjectConsoleClient::takeHeapSnapshot(JSC::ExecState*, const String& title)
index 56fc1b7..1ec25c4 100644 (file)
@@ -203,8 +203,6 @@ static Ref<Protocol::ScriptProfiler::Samples> buildSamples(VM& vm, Vector<Sampli
 
 void InspectorScriptProfilerAgent::trackingComplete()
 {
-    auto timestamp = m_environment.executionStopwatch()->elapsedTime().seconds();
-
 #if ENABLE(SAMPLING_PROFILER)
     if (m_enabledSamplingProfiler) {
         VM& vm = m_environment.scriptDebugServer().vm();
@@ -222,11 +220,11 @@ void InspectorScriptProfilerAgent::trackingComplete()
 
         m_enabledSamplingProfiler = false;
 
-        m_frontendDispatcher->trackingComplete(timestamp, WTFMove(samples));
+        m_frontendDispatcher->trackingComplete(WTFMove(samples));
     } else
-        m_frontendDispatcher->trackingComplete(timestamp, nullptr);
+        m_frontendDispatcher->trackingComplete(nullptr);
 #else
-    m_frontendDispatcher->trackingComplete(timestamp, nullptr);
+    m_frontendDispatcher->trackingComplete(nullptr);
 #endif // ENABLE(SAMPLING_PROFILER)
 }
 
@@ -248,4 +246,14 @@ void InspectorScriptProfilerAgent::stopSamplingWhenDisconnecting()
 #endif
 }
 
+void InspectorScriptProfilerAgent::programmaticCaptureStarted()
+{
+    m_frontendDispatcher->programmaticCaptureStarted();
+}
+
+void InspectorScriptProfilerAgent::programmaticCaptureStopped()
+{
+    m_frontendDispatcher->programmaticCaptureStopped();
+}
+
 } // namespace Inspector
index 8a287d8..dab774f 100644 (file)
@@ -53,6 +53,9 @@ public:
     void startTracking(ErrorString&, const bool* includeSamples) override;
     void stopTracking(ErrorString&) override;
 
+    void programmaticCaptureStarted();
+    void programmaticCaptureStopped();
+
     // Debugger::ProfilingClient
     bool isAlreadyProfiling() const override;
     Seconds willEvaluateScript() override;
index 1f60d9d..cddf9ca 100644 (file)
         },
         {
             "name": "trackingComplete",
-            "description": "Tracking stopped.",
-            "parameters": [
-                { "name": "timestamp", "type": "number" }
-            ]
+            "description": "Tracking stopped. Includes any buffered data during tracking, such as profiling information."
         }
     ]
 }
index 1c3d01b..b6b3db9 100644 (file)
         },
         {
             "name": "trackingComplete",
-            "description": "Tracking stopped.",
-            "parameters": [
-                { "name": "timestamp", "type": "number" }
-            ]
+            "description": "Tracking stopped."
         }
     ]
 }
index 60ca687..35032a5 100644 (file)
             "name": "trackingComplete",
             "description": "Tracking stopped. Includes any buffered data during tracking, such as profiling information.",
             "parameters": [
-                { "name": "timestamp", "type": "number" },
                 { "name": "samples", "$ref": "Samples", "optional": true, "description": "Stack traces." }
             ]
+        },
+        {
+            "name": "programmaticCaptureStarted",
+            "description": "Fired when programmatic capture starts (console.profile). JSContext inspection only."
+        },
+        {
+            "name": "programmaticCaptureStopped",
+            "description": "Fired when programmatic capture stops (console.profileEnd). JSContext inspection only."
         }
     ]
 }
index 9880032..b9c4f84 100644 (file)
         {
             "name": "autoCaptureStarted",
             "description": "Fired when auto capture started."
+        },
+        {
+            "name": "programmaticCaptureStarted",
+            "description": "Fired when programmatic capture starts (console.profile)."
+        },
+        {
+            "name": "programmaticCaptureStopped",
+            "description": "Fired when programmatic capture stops (console.profileEnd)."
         }
     ]
 }
index 9762bf4..b07f17d 100644 (file)
@@ -1,3 +1,16 @@
+2019-04-11  Truitt Savell  <tsavell@apple.com>
+
+        Unreviewed, rolling out r244158.
+
+        Casued 8 inspector/timeline/ test failures.
+
+        Reverted changeset:
+
+        "Web Inspector: Timelines: can't reliably stop/start a
+        recording"
+        https://bugs.webkit.org/show_bug.cgi?id=196778
+        https://trac.webkit.org/changeset/244158
+
 2019-04-11  Pablo Saavedra  <psaavedra@igalia.com>
 
         [WPE] Build error with ENABLE_VIDEO=OFF after r244078
index 6a2972d..8f15504 100644 (file)
@@ -77,7 +77,7 @@ void InspectorCPUProfilerAgent::stopTracking(ErrorString&)
 
     m_tracking = false;
 
-    m_frontendDispatcher->trackingComplete(m_environment.executionStopwatch()->elapsedTime().seconds());
+    m_frontendDispatcher->trackingComplete();
 }
 
 static Ref<Protocol::CPUProfiler::ThreadInfo> buildThreadInfo(const ThreadCPUInfo& thread)
index 22d47f5..5bc56ea 100644 (file)
@@ -92,7 +92,7 @@ void InspectorMemoryAgent::stopTracking(ErrorString&)
 
     m_tracking = false;
 
-    m_frontendDispatcher->trackingComplete(m_environment.executionStopwatch()->elapsedTime().seconds());
+    m_frontendDispatcher->trackingComplete();
 }
 
 void InspectorMemoryAgent::didHandleMemoryPressure(Critical critical)
index a1d3d91..81dedce 100644 (file)
@@ -477,6 +477,8 @@ void InspectorTimelineAgent::startProgrammaticCapture()
     } else
         m_programmaticCaptureRestoreBreakpointActiveValue = false;
 
+    m_frontendDispatcher->programmaticCaptureStarted();
+
     toggleScriptProfilerInstrument(InstrumentState::Start); // Ensure JavaScript samping data.
     toggleTimelineInstrument(InstrumentState::Start); // Ensure Console Profile event records.
     toggleInstruments(InstrumentState::Start); // Any other instruments the frontend wants us to record.
@@ -498,6 +500,8 @@ void InspectorTimelineAgent::stopProgrammaticCapture()
             debuggerAgent->setBreakpointsActive(unused, true);
         }
     }
+
+    m_frontendDispatcher->programmaticCaptureStopped();
 }
 
 void InspectorTimelineAgent::toggleInstruments(InstrumentState state)
index 8529cbd..5a0583b 100644 (file)
@@ -1,3 +1,16 @@
+2019-04-11  Truitt Savell  <tsavell@apple.com>
+
+        Unreviewed, rolling out r244158.
+
+        Casued 8 inspector/timeline/ test failures.
+
+        Reverted changeset:
+
+        "Web Inspector: Timelines: can't reliably stop/start a
+        recording"
+        https://bugs.webkit.org/show_bug.cgi?id=196778
+        https://trac.webkit.org/changeset/244158
+
 2019-04-10  Devin Rousso  <drousso@apple.com>
 
         Web Inspector: save sheet should be anchored underneath the tab bar when detached
index 68df3af..2a6a20f 100644 (file)
@@ -38,7 +38,8 @@ WI.DebuggerManager = class DebuggerManager extends WI.Object
         WI.Breakpoint.addEventListener(WI.Breakpoint.Event.AutoContinueDidChange, this._breakpointEditablePropertyDidChange, this);
         WI.Breakpoint.addEventListener(WI.Breakpoint.Event.ActionsDidChange, this._handleBreakpointActionsDidChange, this);
 
-        WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingStateChanged, this._handleTimelineCapturingStateChanged, this);
+        WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingWillStart, this._timelineCapturingWillStart, this);
+        WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingStopped, this._timelineCapturingStopped, this);
 
         WI.auditManager.addEventListener(WI.AuditManager.Event.TestScheduled, this._handleAuditManagerTestScheduled, this);
         WI.auditManager.addEventListener(WI.AuditManager.Event.TestCompleted, this._handleAuditManagerTestCompleted, this);
@@ -1136,19 +1137,17 @@ WI.DebuggerManager = class DebuggerManager extends WI.Object
         this.breakpointsEnabled = restoreState;
     }
 
-    _handleTimelineCapturingStateChanged(event)
+    _timelineCapturingWillStart(event)
     {
-        switch (WI.timelineManager.capturingState) {
-        case WI.TimelineManager.CapturingState.Starting:
-            this._startDisablingBreakpointsTemporarily();
-            if (this.paused)
-                this.resume();
-            break;
+        this._startDisablingBreakpointsTemporarily();
 
-        case WI.TimelineManager.CapturingState.Inactive:
-            this._stopDisablingBreakpointsTemporarily();
-            break;
-        }
+        if (this.paused)
+            this.resume();
+    }
+
+    _timelineCapturingStopped(event)
+    {
+        this._stopDisablingBreakpointsTemporarily();
     }
 
     _handleAuditManagerTestScheduled(event)
index 78aea0d..e4b72ec 100644 (file)
@@ -33,27 +33,30 @@ WI.TimelineManager = class TimelineManager extends WI.Object
 
         WI.Frame.addEventListener(WI.Frame.Event.ProvisionalLoadStarted, this._provisionalLoadStarted, this);
         WI.Frame.addEventListener(WI.Frame.Event.MainResourceDidChange, this._mainResourceDidChange, this);
+        WI.Frame.addEventListener(WI.Frame.Event.ResourceWasAdded, this._resourceWasAdded, this);
+        WI.Target.addEventListener(WI.Target.Event.ResourceAdded, this._resourceWasAdded, this);
 
-        this._enabledTimelineTypesSetting = new WI.Setting("enabled-instrument-types", WI.TimelineManager.defaultTimelineTypes());
+        WI.heapManager.addEventListener(WI.HeapManager.Event.GarbageCollected, this._garbageCollected, this);
+        WI.memoryManager.addEventListener(WI.MemoryManager.Event.MemoryPressure, this._memoryPressure, this);
+
+        WI.settings.timelinesAutoStop.addEventListener(WI.Setting.Event.Changed, this._handleTimelinesAutoStopSettingChanged, this);
 
-        this._capturingState = TimelineManager.CapturingState.Inactive;
-        this._capturingInstrumentCount = 0;
-        this._capturingStartTime = NaN;
-        this._capturingEndTime = NaN;
+        this._enabledTimelineTypesSetting = new WI.Setting("enabled-instrument-types", WI.TimelineManager.defaultTimelineTypes());
 
+        this._isCapturing = false;
         this._initiatedByBackendStart = false;
         this._initiatedByBackendStop = false;
-
+        this._waitingForCapturingStartedEvent = false;
         this._isCapturingPageReload = false;
         this._autoCaptureOnPageLoad = false;
         this._mainResourceForAutoCapturing = null;
         this._shouldSetAutoCapturingMainResource = false;
         this._transitioningPageTarget = false;
+        this._boundStopCapturing = this.stopCapturing.bind(this);
 
         this._webTimelineScriptRecordsExpectingScriptProfilerEvents = null;
         this._scriptProfilerRecords = null;
 
-        this._boundStopCapturing = this.stopCapturing.bind(this);
         this._stopCapturingTimeout = undefined;
         this._deadTimeTimeout = undefined;
         this._lastDeadTimeTickle = 0;
@@ -150,11 +153,9 @@ WI.TimelineManager = class TimelineManager extends WI.Object
 
     // Public
 
-    get capturingState() { return this._capturingState; }
-
     reset()
     {
-        if (this.isCapturing())
+        if (this._isCapturing)
             this.stopCapturing();
 
         this._recordings = [];
@@ -167,7 +168,7 @@ WI.TimelineManager = class TimelineManager extends WI.Object
     // The current recording that new timeline records will be appended to, if any.
     get activeRecording()
     {
-        console.assert(this._activeRecording || !this.isCapturing());
+        console.assert(this._activeRecording || !this._isCapturing);
         return this._activeRecording;
     }
 
@@ -190,10 +191,8 @@ WI.TimelineManager = class TimelineManager extends WI.Object
 
         this._autoCaptureOnPageLoad = autoCapture;
 
-        for (let target of WI.targets) {
-            if (target.TimelineAgent)
-                target.TimelineAgent.setAutoCaptureEnabled(this._autoCaptureOnPageLoad);
-        }
+        if (window.TimelineAgent && TimelineAgent.setAutoCaptureEnabled)
+            TimelineAgent.setAutoCaptureEnabled(this._autoCaptureOnPageLoad);
     }
 
     get enabledTimelineTypes()
@@ -211,7 +210,7 @@ WI.TimelineManager = class TimelineManager extends WI.Object
 
     isCapturing()
     {
-        return this._capturingState !== TimelineManager.CapturingState.Inactive;
+        return this._isCapturing;
     }
 
     isCapturingPageReload()
@@ -239,29 +238,40 @@ WI.TimelineManager = class TimelineManager extends WI.Object
 
     startCapturing(shouldCreateRecording)
     {
-        console.assert(this._capturingState === TimelineManager.CapturingState.Stopping || this._capturingState === TimelineManager.CapturingState.Inactive, "TimelineManager is already capturing.");
-        if (this._capturingState !== TimelineManager.CapturingState.Stopping && this._capturingState !== TimelineManager.CapturingState.Inactive)
-            return;
+        console.assert(!this._isCapturing, "TimelineManager is already capturing.");
 
         if (!this._activeRecording || shouldCreateRecording)
             this._loadNewRecording();
 
-        this._updateCapturingState(TimelineManager.CapturingState.Starting);
+        this._waitingForCapturingStartedEvent = true;
+
+        this.dispatchEventToListeners(WI.TimelineManager.Event.CapturingWillStart);
 
-        this._capturingStartTime = NaN;
         this._activeRecording.start(this._initiatedByBackendStart);
     }
 
     stopCapturing()
     {
-        console.assert(this._capturingState === TimelineManager.CapturingState.Starting || this._capturingState === TimelineManager.CapturingState.Active, "TimelineManager is not capturing.");
-        if (this._capturingState !== TimelineManager.CapturingState.Starting && this._capturingState !== TimelineManager.CapturingState.Active)
+        console.assert(this._isCapturing, "TimelineManager is not capturing.");
+
+        this._activeRecording.stop(this._initiatedByBackendStop);
+
+        // NOTE: Always stop immediately instead of waiting for a Timeline.recordingStopped event.
+        // This way the UI feels as responsive to a stop as possible.
+        // FIXME: <https://webkit.org/b/152904> Web Inspector: Timeline UI should keep up with processing all incoming records
+        this.capturingStopped();
+    }
+
+    unloadRecording()
+    {
+        if (!this._activeRecording)
             return;
 
-        this._updateCapturingState(TimelineManager.CapturingState.Stopping);
+        if (this._isCapturing)
+            this.stopCapturing();
 
-        this._capturingEndTime = NaN;
-        this._activeRecording.stop(this._initiatedByBackendStop);
+        this._activeRecording.unloaded();
+        this._activeRecording = null;
     }
 
     processJSON({filename, json, error})
@@ -295,7 +305,7 @@ WI.TimelineManager = class TimelineManager extends WI.Object
 
         this.dispatchEventToListeners(WI.TimelineManager.Event.RecordingCreated, {recording: newRecording});
 
-        if (this.isCapturing())
+        if (this._isCapturing)
             this.stopCapturing();
 
         let oldRecording = this._activeRecording;
@@ -329,95 +339,51 @@ WI.TimelineManager = class TimelineManager extends WI.Object
     {
         // Called from WI.TimelineObserver.
 
-        // The frontend didn't start capturing, so this was a programmatic start.
-        if (this._capturingState === TimelineManager.CapturingState.Inactive) {
-            this._initiatedByBackendStart = true;
-            this._activeRecording.addScriptInstrumentForProgrammaticCapture();
-            this.startCapturing();
-        }
-
-        if (!isNaN(startTime)) {
-            if (isNaN(this._capturingStartTime) || startTime < this._capturingStartTime)
-                this._capturingStartTime = startTime;
-
-            this._activeRecording.initializeTimeBoundsIfNecessary(startTime);
-        }
-
-        this._capturingInstrumentCount++;
-        console.assert(this._capturingInstrumentCount);
-        if (this._capturingInstrumentCount > 1)
+        if (this._isCapturing)
             return;
 
-        if (this._capturingState === TimelineManager.CapturingState.Active)
-            return;
+        this._waitingForCapturingStartedEvent = false;
+        this._isCapturing = true;
 
         this._lastDeadTimeTickle = 0;
 
-        this._webTimelineScriptRecordsExpectingScriptProfilerEvents = [];
-
-        WI.settings.timelinesAutoStop.addEventListener(WI.Setting.Event.Changed, this._handleTimelinesAutoStopSettingChanged, this);
-
-        WI.Frame.addEventListener(WI.Frame.Event.ResourceWasAdded, this._resourceWasAdded, this);
-        WI.Target.addEventListener(WI.Target.Event.ResourceAdded, this._resourceWasAdded, this);
-
-        WI.heapManager.addEventListener(WI.HeapManager.Event.GarbageCollected, this._garbageCollected, this);
+        if (startTime)
+            this.activeRecording.initializeTimeBoundsIfNecessary(startTime);
 
-        WI.memoryManager.addEventListener(WI.MemoryManager.Event.MemoryPressure, this._memoryPressure, this);
+        this._webTimelineScriptRecordsExpectingScriptProfilerEvents = [];
 
         WI.DOMNode.addEventListener(WI.DOMNode.Event.DidFireEvent, this._handleDOMNodeDidFireEvent, this);
         WI.DOMNode.addEventListener(WI.DOMNode.Event.LowPowerChanged, this._handleDOMNodeLowPowerChanged, this);
 
-        this._updateCapturingState(TimelineManager.CapturingState.Active, {startTime: this._capturingStartTime});
+        this.dispatchEventToListeners(WI.TimelineManager.Event.CapturingStarted, {startTime});
     }
 
     capturingStopped(endTime)
     {
         // Called from WI.TimelineObserver.
 
-        // The frontend didn't stop capturing, so this was a programmatic stop.
-        if (this._capturingState === TimelineManager.CapturingState.Active) {
-            this._initiatedByBackendStop = true;
-            this.stopCapturing();
-        }
-
-        if (!isNaN(endTime)) {
-            if (isNaN(this._capturingEndTime) || endTime > this._capturingEndTime)
-                this._capturingEndTime = endTime;
-        }
-
-        this._capturingInstrumentCount--;
-        console.assert(this._capturingInstrumentCount >= 0);
-        if (this._capturingInstrumentCount)
-            return;
-
-        if (this._capturingState === TimelineManager.CapturingState.Inactive)
+        if (!this._isCapturing)
             return;
 
         WI.DOMNode.removeEventListener(null, null, this);
-        WI.memoryManager.removeEventListener(null, null, this);
-        WI.heapManager.removeEventListener(null, null, this);
-        WI.Target.removeEventListener(WI.Target.Event.ResourceAdded, this._resourceWasAdded, this);
-        WI.Frame.removeEventListener(WI.Frame.Event.ResourceWasAdded, this._resourceWasAdded, this);
-        WI.settings.timelinesAutoStop.removeEventListener(null, null, this);
 
         this.relaxAutoStop();
 
+        this._isCapturing = false;
         this._isCapturingPageReload = false;
         this._shouldSetAutoCapturingMainResource = false;
         this._mainResourceForAutoCapturing = null;
         this._initiatedByBackendStart = false;
         this._initiatedByBackendStop = false;
 
-        this._updateCapturingState(TimelineManager.CapturingState.Inactive, {endTime: this._capturingEndTime});
+        this.dispatchEventToListeners(WI.TimelineManager.Event.CapturingStopped, {endTime});
     }
 
     autoCaptureStarted()
     {
         // Called from WI.TimelineObserver.
 
-        let waitingForCapturingStartedEvent = this._capturingState === TimelineManager.CapturingState.Starting;
-
-        if (this.isCapturing())
+        if (this._isCapturing)
             this.stopCapturing();
 
         this._initiatedByBackendStart = true;
@@ -425,7 +391,7 @@ WI.TimelineManager = class TimelineManager extends WI.Object
         // We may already have an fresh TimelineRecording created if autoCaptureStarted is received
         // between sending the Timeline.start command and receiving Timeline.capturingStarted event.
         // In that case, there is no need to call startCapturing again. Reuse the fresh recording.
-        if (!waitingForCapturingStartedEvent) {
+        if (!this._waitingForCapturingStartedEvent) {
             const createNewRecording = true;
             this.startCapturing(createNewRecording);
         }
@@ -433,12 +399,37 @@ WI.TimelineManager = class TimelineManager extends WI.Object
         this._shouldSetAutoCapturingMainResource = true;
     }
 
+    programmaticCaptureStarted()
+    {
+        // Called from WI.TimelineObserver.
+
+        this._initiatedByBackendStart = true;
+
+        this._activeRecording.addScriptInstrumentForProgrammaticCapture();
+
+        const createNewRecording = false;
+        this.startCapturing(createNewRecording);
+    }
+
+    programmaticCaptureStopped()
+    {
+        // Called from WI.TimelineObserver.
+
+        this._initiatedByBackendStop = true;
+
+        // FIXME: This is purely to avoid a noisy assert. Previously
+        // it was impossible to stop without stopping from the UI.
+        console.assert(!this._isCapturing);
+        this._isCapturing = true;
+
+        this.stopCapturing();
+    }
+
     eventRecorded(recordPayload)
     {
         // Called from WI.TimelineObserver.
 
-        console.assert(this.isCapturing());
-        if (!this.isCapturing())
+        if (!this._isCapturing)
             return;
 
         var records = [];
@@ -478,6 +469,8 @@ WI.TimelineManager = class TimelineManager extends WI.Object
         }
     }
 
+    // Protected
+
     pageDOMContentLoadedEventFired(timestamp)
     {
         // Called from WI.PageObserver.
@@ -485,7 +478,7 @@ WI.TimelineManager = class TimelineManager extends WI.Object
         console.assert(this._activeRecording);
         console.assert(isNaN(WI.networkManager.mainFrame.domContentReadyEventTimestamp));
 
-        let computedTimestamp = this._activeRecording.computeElapsedTime(timestamp);
+        let computedTimestamp = this.activeRecording.computeElapsedTime(timestamp);
 
         WI.networkManager.mainFrame.markDOMContentReadyEvent(computedTimestamp);
 
@@ -500,7 +493,7 @@ WI.TimelineManager = class TimelineManager extends WI.Object
         console.assert(this._activeRecording);
         console.assert(isNaN(WI.networkManager.mainFrame.loadEventTimestamp));
 
-        let computedTimestamp = this._activeRecording.computeElapsedTime(timestamp);
+        let computedTimestamp = this.activeRecording.computeElapsedTime(timestamp);
 
         WI.networkManager.mainFrame.markLoadEvent(computedTimestamp);
 
@@ -521,18 +514,15 @@ WI.TimelineManager = class TimelineManager extends WI.Object
     {
         // Called from WI.CPUProfilerObserver.
 
-        console.assert(this.isCapturing());
-        if (!this.isCapturing())
+        if (!this._isCapturing)
             return;
 
         this._addRecord(new WI.CPUTimelineRecord(event));
     }
 
-    cpuProfilerTrackingCompleted(timestamp)
+    cpuProfilerTrackingCompleted()
     {
         // Called from WI.CPUProfilerObserver.
-
-        this.capturingStopped(timestamp);
     }
 
     memoryTrackingStarted(timestamp)
@@ -546,27 +536,24 @@ WI.TimelineManager = class TimelineManager extends WI.Object
     {
         // Called from WI.MemoryObserver.
 
-        console.assert(this.isCapturing());
-        if (!this.isCapturing())
+        if (!this._isCapturing)
             return;
 
         this._addRecord(new WI.MemoryTimelineRecord(event.timestamp, event.categories));
     }
 
-    memoryTrackingCompleted(timestamp)
+    memoryTrackingCompleted()
     {
         // Called from WI.MemoryObserver.
-
-        this.capturingStopped(timestamp);
     }
 
     heapTrackingStarted(timestamp, snapshot)
     {
         // Called from WI.HeapObserver.
 
-        this.capturingStarted(timestamp);
-
         this._addRecord(new WI.HeapAllocationsTimelineRecord(timestamp, snapshot));
+
+        this.capturingStarted(timestamp);
     }
 
     heapTrackingCompleted(timestamp, snapshot)
@@ -574,39 +561,21 @@ WI.TimelineManager = class TimelineManager extends WI.Object
         // Called from WI.HeapObserver.
 
         this._addRecord(new WI.HeapAllocationsTimelineRecord(timestamp, snapshot));
-
-        this.capturingStopped();
     }
 
     heapSnapshotAdded(timestamp, snapshot)
     {
         // Called from WI.HeapAllocationsInstrument.
 
-        console.assert(this.isCapturing());
-        if (!this.isCapturing())
-            return;
-
         this._addRecord(new WI.HeapAllocationsTimelineRecord(timestamp, snapshot));
     }
 
     // Private
 
-    _updateCapturingState(state, data = {})
-    {
-        if (this._capturingState === state)
-            return;
-
-        this._capturingState = state;
-
-        this.dispatchEventToListeners(TimelineManager.Event.CapturingStateChanged, data);
-    }
-
     _processRecord(recordPayload, parentRecordPayload)
     {
-        console.assert(this.isCapturing());
-
-        var startTime = this._activeRecording.computeElapsedTime(recordPayload.startTime);
-        var endTime = this._activeRecording.computeElapsedTime(recordPayload.endTime);
+        var startTime = this.activeRecording.computeElapsedTime(recordPayload.startTime);
+        var endTime = this.activeRecording.computeElapsedTime(recordPayload.endTime);
         var callFrames = this._callFramesFromPayload(recordPayload.stackTrace);
 
         var significantCallFrame = null;
@@ -793,11 +762,9 @@ WI.TimelineManager = class TimelineManager extends WI.Object
 
     _processEvent(recordPayload, parentRecordPayload)
     {
-        console.assert(this.isCapturing());
-
         switch (recordPayload.type) {
         case TimelineAgent.EventType.TimeStamp:
-            var timestamp = this._activeRecording.computeElapsedTime(recordPayload.startTime);
+            var timestamp = this.activeRecording.computeElapsedTime(recordPayload.startTime);
             var eventMarker = new WI.TimelineMarker(timestamp, WI.TimelineMarker.Type.TimeStamp, recordPayload.data.message);
             this._activeRecording.addEventMarker(eventMarker);
             break;
@@ -827,7 +794,7 @@ WI.TimelineManager = class TimelineManager extends WI.Object
         this._recordings.push(newRecording);
         this.dispatchEventToListeners(WI.TimelineManager.Event.RecordingCreated, {recording: newRecording});
 
-        if (this.isCapturing())
+        if (this._isCapturing)
             this.stopCapturing();
 
         var oldRecording = this._activeRecording;
@@ -860,8 +827,6 @@ WI.TimelineManager = class TimelineManager extends WI.Object
 
     _addRecord(record)
     {
-        console.assert(this.isCapturing());
-
         this._activeRecording.addRecord(record);
 
         // Only worry about dead time after the load event.
@@ -879,15 +844,15 @@ WI.TimelineManager = class TimelineManager extends WI.Object
 
         // COMPATIBILITY (iOS 9): Timeline.setAutoCaptureEnabled did not exist.
         // Perform auto capture in the frontend.
-        if (!InspectorBackend.domains.Timeline)
+        if (!window.TimelineAgent)
             return false;
-        if (!InspectorBackend.domains.Timeline.setAutoCaptureEnabled)
+        if (!TimelineAgent.setAutoCaptureEnabled)
             return this._legacyAttemptStartAutoCapturingForFrame(frame);
 
         if (!this._shouldSetAutoCapturingMainResource)
             return false;
 
-        console.assert(this.isCapturing(), "We saw autoCaptureStarted so we should already be capturing");
+        console.assert(this._isCapturing, "We saw autoCaptureStarted so we should already be capturing");
 
         let mainResource = frame.provisionalMainResource || frame.mainResource;
         if (mainResource === this._mainResourceForAutoCapturing)
@@ -909,7 +874,7 @@ WI.TimelineManager = class TimelineManager extends WI.Object
 
     _legacyAttemptStartAutoCapturingForFrame(frame)
     {
-        if (this.isCapturing() && !this._mainResourceForAutoCapturing)
+        if (this._isCapturing && !this._mainResourceForAutoCapturing)
             return false;
 
         let mainResource = frame.provisionalMainResource || frame.mainResource;
@@ -919,7 +884,7 @@ WI.TimelineManager = class TimelineManager extends WI.Object
         let oldMainResource = frame.mainResource || null;
         this._isCapturingPageReload = oldMainResource !== null && oldMainResource.url === mainResource.url;
 
-        if (this.isCapturing())
+        if (this._isCapturing)
             this.stopCapturing();
 
         this._mainResourceForAutoCapturing = mainResource;
@@ -941,7 +906,7 @@ WI.TimelineManager = class TimelineManager extends WI.Object
             return;
 
         // Only auto stop when auto capturing.
-        if (!this.isCapturing() || !this._mainResourceForAutoCapturing)
+        if (!this._isCapturing || !this._mainResourceForAutoCapturing)
             return;
 
         if (this._stopCapturingTimeout)
@@ -965,7 +930,7 @@ WI.TimelineManager = class TimelineManager extends WI.Object
             return;
 
         // Only monitor dead time when auto capturing.
-        if (!this.isCapturing() || !this._mainResourceForAutoCapturing)
+        if (!this._isCapturing || !this._mainResourceForAutoCapturing)
             return;
 
         // Avoid unnecessary churning of timeout identifier by not tickling until 10ms have passed.
@@ -1006,8 +971,7 @@ WI.TimelineManager = class TimelineManager extends WI.Object
         if (this._attemptAutoCapturingForFrame(frame))
             return;
 
-        console.assert(this.isCapturing());
-        if (!this.isCapturing())
+        if (!this._isCapturing)
             return;
 
         let mainResource = frame.mainResource;
@@ -1019,27 +983,40 @@ WI.TimelineManager = class TimelineManager extends WI.Object
 
     _resourceWasAdded(event)
     {
+
         // Ignore resource events when there isn't a main frame yet. Those events are triggered by
         // loading the cached resources when the inspector opens, and they do not have timing information.
         if (!WI.networkManager.mainFrame)
             return;
 
+        if (!this._isCapturing)
+            return;
+
         this._addRecord(new WI.ResourceTimelineRecord(event.data.resource));
     }
 
     _garbageCollected(event)
     {
-        let {collection} = event.data;
+        if (!this._isCapturing)
+            return;
+
+        let collection = event.data.collection;
         this._addRecord(new WI.ScriptTimelineRecord(WI.ScriptTimelineRecord.EventType.GarbageCollected, collection.startTime, collection.endTime, null, null, collection));
     }
 
     _memoryPressure(event)
     {
-        this._activeRecording.addMemoryPressureEvent(event.data.memoryPressureEvent);
+        if (!this._isCapturing)
+            return;
+
+        this.activeRecording.addMemoryPressureEvent(event.data.memoryPressureEvent);
     }
 
     _handleTimelinesAutoStopSettingChanged(event)
     {
+        if (!this._isCapturing)
+            return;
+
         if (WI.settings.timelinesAutoStop.value) {
             if (this._mainResourceForAutoCapturing && !isNaN(this._mainResourceForAutoCapturing.parentFrame.loadEventTimestamp))
                 this._stopAutoRecordingSoon();
@@ -1062,6 +1039,24 @@ WI.TimelineManager = class TimelineManager extends WI.Object
         }
     }
 
+    scriptProfilerProgrammaticCaptureStarted()
+    {
+        // FIXME: <https://webkit.org/b/158753> Generalize the concept of Instruments on the backend to work equally for JSContext and Web inspection
+        console.assert(WI.sharedApp.debuggableType === WI.DebuggableType.JavaScript);
+        console.assert(!this._isCapturing);
+
+        this.programmaticCaptureStarted();
+    }
+
+    scriptProfilerProgrammaticCaptureStopped()
+    {
+        // FIXME: <https://webkit.org/b/158753> Generalize the concept of Instruments on the backend to work equally for JSContext and Web inspection
+        console.assert(WI.sharedApp.debuggableType === WI.DebuggableType.JavaScript);
+        console.assert(this._isCapturing);
+
+        this.programmaticCaptureStopped();
+    }
+
     scriptProfilerTrackingStarted(timestamp)
     {
         this._scriptProfilerRecords = [];
@@ -1085,13 +1080,13 @@ WI.TimelineManager = class TimelineManager extends WI.Object
             this._addRecord(record);
     }
 
-    scriptProfilerTrackingCompleted(timestamp, samples)
+    scriptProfilerTrackingCompleted(samples)
     {
         console.assert(!this._webTimelineScriptRecordsExpectingScriptProfilerEvents || this._scriptProfilerRecords.length >= this._webTimelineScriptRecordsExpectingScriptProfilerEvents.length);
 
         if (samples) {
             let {stackTraces} = samples;
-            let topDownCallingContextTree = this._activeRecording.topDownCallingContextTree;
+            let topDownCallingContextTree = this.activeRecording.topDownCallingContextTree;
 
             // Calculate a per-sample duration.
             let timestampIndex = 0;
@@ -1125,7 +1120,7 @@ WI.TimelineManager = class TimelineManager extends WI.Object
             if (timestampIndex < timestampCount)
                 sampleDurations.fill(defaultDuration, sampleDurationIndex);
 
-            this._activeRecording.initializeCallingContextTrees(stackTraces, sampleDurations);
+            this.activeRecording.initializeCallingContextTrees(stackTraces, sampleDurations);
 
             // FIXME: This transformation should not be needed after introducing ProfileView.
             // Once we eliminate ProfileNodeTreeElements and ProfileNodeDataGridNodes.
@@ -1145,10 +1140,8 @@ WI.TimelineManager = class TimelineManager extends WI.Object
 
         this._scriptProfilerRecords = null;
 
-        let timeline = this._activeRecording.timelineForRecordType(WI.TimelineRecord.Type.Script);
+        let timeline = this.activeRecording.timelineForRecordType(WI.TimelineRecord.Type.Script);
         timeline.refresh();
-
-        this.capturingStopped(timestamp);
     }
 
     _mergeScriptProfileRecords()
@@ -1247,6 +1240,8 @@ WI.TimelineManager = class TimelineManager extends WI.Object
 
     _handleDOMNodeDidFireEvent(event)
     {
+        console.assert(this._isCapturing);
+
         let {domEvent} = event.data;
 
         this._addRecord(new WI.MediaTimelineRecord(WI.MediaTimelineRecord.EventType.DOMEvent, domEvent.timestamp, {
@@ -1257,6 +1252,8 @@ WI.TimelineManager = class TimelineManager extends WI.Object
 
     _handleDOMNodeLowPowerChanged(event)
     {
+        console.assert(this._isCapturing);
+
         let {timestamp, isLowPower} = event.data;
 
         this._addRecord(new WI.MediaTimelineRecord(WI.MediaTimelineRecord.EventType.LowPower, timestamp, {
@@ -1266,18 +1263,13 @@ WI.TimelineManager = class TimelineManager extends WI.Object
     }
 };
 
-WI.TimelineManager.CapturingState = {
-    Inactive: "inactive",
-    Starting: "starting",
-    Active: "active",
-    Stopping: "stopping",
-};
-
 WI.TimelineManager.Event = {
-    CapturingStateChanged: "timeline-manager-capturing-started",
     RecordingCreated: "timeline-manager-recording-created",
     RecordingLoaded: "timeline-manager-recording-loaded",
     RecordingImported: "timeline-manager-recording-imported",
+    CapturingWillStart: "timeline-manager-capturing-will-start",
+    CapturingStarted: "timeline-manager-capturing-started",
+    CapturingStopped: "timeline-manager-capturing-stopped"
 };
 
 WI.TimelineManager.MaximumAutoRecordDuration = 90000; // 90 seconds
index c8cb9f5..645f993 100644 (file)
@@ -33,7 +33,7 @@ WI.DefaultDashboard = class DefaultDashboard extends WI.Object
 
         // Necessary event required to track page load time and resource sizes.
         WI.Frame.addEventListener(WI.Frame.Event.MainResourceDidChange, this._mainResourceDidChange, this);
-        WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingStateChanged, this._handleTimelineCapturingStateChanged, this);
+        WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingStopped, this._capturingStopped, this);
 
         // Necessary events required to track load of resources.
         WI.Frame.addEventListener(WI.Frame.Event.ResourceWasAdded, this._resourceWasAdded, this);
@@ -163,11 +163,8 @@ WI.DefaultDashboard = class DefaultDashboard extends WI.Object
             this._transitioningPageTarget = false;
     }
 
-    _handleTimelineCapturingStateChanged(event)
+    _capturingStopped(event)
     {
-        if (WI.timelineManager.isCapturing())
-            return;
-
         // If recording stops, we should stop the timer if it hasn't stopped already.
         this._stopUpdatingTime();
     }
index 0513470..49a2345 100644 (file)
@@ -37,8 +37,8 @@ WI.CPUProfilerObserver = class CPUProfilerObserver
         WI.timelineManager.cpuProfilerTrackingUpdated(event);
     }
 
-    trackingComplete(timestamp)
+    trackingComplete(samples)
     {
-        WI.timelineManager.cpuProfilerTrackingCompleted(timestamp);
+        WI.timelineManager.cpuProfilerTrackingCompleted(samples);
     }
 };
index e84225b..7224de2 100644 (file)
@@ -42,8 +42,8 @@ WI.MemoryObserver = class MemoryObserver
         WI.timelineManager.memoryTrackingUpdated(event);
     }
 
-    trackingComplete(timestamp)
+    trackingComplete()
     {
-        WI.timelineManager.memoryTrackingCompleted(timestamp);
+        WI.timelineManager.memoryTrackingCompleted();
     }
 };
index 6b7b558..f1b54cc 100644 (file)
@@ -37,18 +37,18 @@ WI.ScriptProfilerObserver = class ScriptProfilerObserver
         WI.timelineManager.scriptProfilerTrackingUpdated(event);
     }
 
-    trackingComplete(timestamp, samples)
+    trackingComplete(samples)
     {
-        WI.timelineManager.scriptProfilerTrackingCompleted(timestamp, samples);
+        WI.timelineManager.scriptProfilerTrackingCompleted(samples);
     }
 
     programmaticCaptureStarted()
     {
-        // COMPATIBILITY (iOS 12.2): ScriptProfiler.programmaticCaptureStarted was removed after iOS 12.2.
+        WI.timelineManager.scriptProfilerProgrammaticCaptureStarted();
     }
 
     programmaticCaptureStopped()
     {
-        // COMPATIBILITY (iOS 12.2): ScriptProfiler.programmaticCaptureStopped was removed after iOS 12.2.
+        WI.timelineManager.scriptProfilerProgrammaticCaptureStopped();
     }
 };
index c9b0aa7..ba9d019 100644 (file)
@@ -49,11 +49,11 @@ WI.TimelineObserver = class TimelineObserver
 
     programmaticCaptureStarted()
     {
-        // COMPATIBILITY (iOS 12.2): Timeline.programmaticCaptureStarted was removed after iOS 12.2.
+        WI.timelineManager.programmaticCaptureStarted();
     }
 
     programmaticCaptureStopped()
     {
-        // COMPATIBILITY (iOS 12.2): Timeline.programmaticCaptureStopped was removed after iOS 12.2.
+        WI.timelineManager.programmaticCaptureStopped();
     }
 };
index 4e7c40a..8c1c56b 100644 (file)
@@ -55,7 +55,8 @@ WI.DebuggerSidebarPanel = class DebuggerSidebarPanel extends WI.NavigationSideba
 
         WI.DOMBreakpoint.addEventListener(WI.DOMBreakpoint.Event.DOMNodeChanged, this._handleDOMBreakpointDOMNodeChanged, this);
 
-        WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingStateChanged, this._handleTimelineCapturingStateChanged, this);
+        WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingWillStart, this._timelineCapturingWillStart, this);
+        WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingStopped, this._timelineCapturingStopped, this);
 
         WI.auditManager.addEventListener(WI.AuditManager.Event.TestScheduled, this._handleAuditManagerTestScheduled, this);
         WI.auditManager.addEventListener(WI.AuditManager.Event.TestCompleted, this._handleAuditManagerTestCompleted, this);
@@ -250,7 +251,8 @@ WI.DebuggerSidebarPanel = class DebuggerSidebarPanel extends WI.NavigationSideba
             this._debuggerDidPause(null);
 
         if (WI.debuggerManager.breakpointsDisabledTemporarily) {
-            this._handleTimelineCapturingStateChanged();
+            if (WI.timelineManager.isCapturing())
+                this._timelineCapturingWillStart();
 
             if (WI.auditManager.runningState === WI.AuditManager.RunningState.Active || WI.auditManager.runningState === WI.AuditManager.RunningState.Stopping)
                 this._handleAuditManagerTestScheduled();
@@ -646,20 +648,19 @@ WI.DebuggerSidebarPanel = class DebuggerSidebarPanel extends WI.NavigationSideba
         }
     }
 
-    _handleTimelineCapturingStateChanged(event)
+    _timelineCapturingWillStart(event)
     {
         this._updateTemporarilyDisabledBreakpointsButtons();
 
-        switch (WI.timelineManager.capturingState) {
-        case WI.TimelineManager.CapturingState.Starting:
-            this.contentView.element.insertBefore(this._timelineRecordingWarningElement, this.contentView.element.firstChild);
-            break;
+        this.contentView.element.insertBefore(this._timelineRecordingWarningElement, this.contentView.element.firstChild);
+        this._updateBreakpointsDisabledBanner();
+    }
 
-        case WI.TimelineManager.CapturingState.Inactive:
-            this._timelineRecordingWarningElement.remove();
-            break;
-        }
+    _timelineCapturingStopped(event)
+    {
+        this._updateTemporarilyDisabledBreakpointsButtons();
 
+        this._timelineRecordingWarningElement.remove();
         this._updateBreakpointsDisabledBanner();
     }
 
index f0e94fb..568a3cd 100644 (file)
@@ -282,7 +282,8 @@ WI.SourcesNavigationSidebarPanel = class SourcesNavigationSidebarPanel extends W
         WI.consoleManager.addEventListener(WI.ConsoleManager.Event.IssueAdded, this._handleConsoleIssueAdded, this);
         WI.consoleManager.addEventListener(WI.ConsoleManager.Event.Cleared, this._handleConsoleCleared, this);
 
-        WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingStateChanged, this._handleTimelineCapturingStateChanged, this);
+        WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingWillStart, this._handleTimelineCapturingWillStart, this);
+        WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingStopped, this._handleTimelineCapturingStopped, this);
 
         WI.auditManager.addEventListener(WI.AuditManager.Event.TestScheduled, this._handleAuditManagerTestScheduled, this);
         WI.auditManager.addEventListener(WI.AuditManager.Event.TestCompleted, this._handleAuditManagerTestCompleted, this);
@@ -336,7 +337,8 @@ WI.SourcesNavigationSidebarPanel = class SourcesNavigationSidebarPanel extends W
             this._handleDebuggerPaused();
 
         if (WI.debuggerManager.breakpointsDisabledTemporarily) {
-            this._handleTimelineCapturingStateChanged();
+            if (WI.timelineManager.isCapturing())
+                this._handleTimelineCapturingWillStart();
 
             if (WI.auditManager.runningState === WI.AuditManager.RunningState.Active || WI.auditManager.runningState === WI.AuditManager.RunningState.Stopping)
                 this._handleAuditManagerTestScheduled();
@@ -1818,33 +1820,34 @@ WI.SourcesNavigationSidebarPanel = class SourcesNavigationSidebarPanel extends W
         issueTreeElements.forEach((treeElement) => treeElement.parent.removeChild(treeElement));
     }
 
-    _handleTimelineCapturingStateChanged(event)
+    _handleTimelineCapturingWillStart(event)
     {
         this._updateTemporarilyDisabledBreakpointsButtons();
 
-        switch (WI.timelineManager.capturingState) {
-        case WI.TimelineManager.CapturingState.Starting:
-            if (!this._timelineRecordingWarningElement) {
-                let stopRecordingButton = document.createElement("button");
-                stopRecordingButton.textContent = WI.UIString("Stop recording");
-                stopRecordingButton.addEventListener("click", () => {
-                    WI.timelineManager.stopCapturing();
-                });
+        if (!this._timelineRecordingWarningElement) {
+            let stopRecordingButton = document.createElement("button");
+            stopRecordingButton.textContent = WI.UIString("Stop recording");
+            stopRecordingButton.addEventListener("click", () => {
+                WI.timelineManager.stopCapturing();
+            });
 
-                this._timelineRecordingWarningElement = document.createElement("div");
-                this._timelineRecordingWarningElement.classList.add("warning-banner");
-                this._timelineRecordingWarningElement.append(WI.UIString("Debugger disabled during Timeline recording"), document.createElement("br"), stopRecordingButton);
-            }
+            this._timelineRecordingWarningElement = document.createElement("div");
+            this._timelineRecordingWarningElement.classList.add("warning-banner");
+            this._timelineRecordingWarningElement.append(WI.UIString("Debugger disabled during Timeline recording"), document.createElement("br"), stopRecordingButton);
+        }
 
-            this.contentView.element.insertBefore(this._timelineRecordingWarningElement, this.contentView.element.firstChild);
-            break;
+        this.contentView.element.insertBefore(this._timelineRecordingWarningElement, this.contentView.element.firstChild);
 
-        case WI.TimelineManager.CapturingState.Inactive:
-            if (this._timelineRecordingWarningElement) {
-                this._timelineRecordingWarningElement.remove();
-                this._timelineRecordingWarningElement = null;
-            }
-            break;
+        this._updateBreakpointsDisabledBanner();
+    }
+
+    _handleTimelineCapturingStopped(event)
+    {
+        this._updateTemporarilyDisabledBreakpointsButtons();
+
+        if (this._timelineRecordingWarningElement) {
+            this._timelineRecordingWarningElement.remove();
+            this._timelineRecordingWarningElement = null;
         }
 
         this._updateBreakpointsDisabledBanner();
index 3cec4fb..a1560e9 100644 (file)
@@ -116,8 +116,9 @@ WI.TimelineOverview = class TimelineOverview extends WI.View
 
         this._viewModeDidChange();
 
-        WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingStateChanged, this._handleTimelineCapturingStateChanged, this);
         WI.timelineManager.addEventListener(WI.TimelineManager.Event.RecordingImported, this._recordingImported, this);
+        WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingStarted, this._capturingStarted, this);
+        WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingStopped, this._capturingStopped, this);
     }
 
     // Import / Export
@@ -1031,20 +1032,6 @@ WI.TimelineOverview = class TimelineOverview extends WI.View
         this._editingInstrumentsDidChange();
     }
 
-    _handleTimelineCapturingStateChanged(event)
-    {
-        switch (WI.timelineManager.capturingState) {
-        case WI.TimelineManager.CapturingState.Active:
-            this._editInstrumentsButton.enabled = false;
-            this._stopEditingInstruments();
-            break;
-
-        case WI.TimelineManager.CapturingState.Inactive:
-            this._editInstrumentsButton.enabled = true;
-            break;
-        }
-    }
-
     _recordingImported(event)
     {
         let {overviewData} = event.data;
@@ -1068,6 +1055,17 @@ WI.TimelineOverview = class TimelineOverview extends WI.View
         }
     }
 
+    _capturingStarted(event)
+    {
+        this._editInstrumentsButton.enabled = false;
+        this._stopEditingInstruments();
+    }
+
+    _capturingStopped(event)
+    {
+        this._editInstrumentsButton.enabled = true;
+    }
+
     _compareTimelineTreeElements(a, b)
     {
         let aTimelineType = a.representedObject.type;
index 56292cc..0e16973 100644 (file)
@@ -102,7 +102,8 @@ WI.TimelineRecordingContentView = class TimelineRecordingContentView extends WI.
         this._recording.addEventListener(WI.TimelineRecording.Event.Reset, this._recordingReset, this);
         this._recording.addEventListener(WI.TimelineRecording.Event.Unloaded, this._recordingUnloaded, this);
 
-        WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingStateChanged, this._handleTimelineCapturingStateChanged, this);
+        WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingStarted, this._capturingStarted, this);
+        WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingStopped, this._capturingStopped, this);
 
         WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.Paused, this._debuggerPaused, this);
         WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.Resumed, this._debuggerResumed, this);
@@ -509,41 +510,38 @@ WI.TimelineRecordingContentView = class TimelineRecordingContentView extends WI.
         }
     }
 
-    _handleTimelineCapturingStateChanged(event)
+    _capturingStarted(event)
     {
-        let {startTime, endTime} = event.data;
-
         this._updateProgressView();
 
-        switch (WI.timelineManager.capturingState) {
-        case WI.TimelineManager.CapturingState.Active:
-            if (!this._updating)
-                this._startUpdatingCurrentTime(startTime);
+        let startTime = event.data.startTime;
+        if (!this._updating)
+            this._startUpdatingCurrentTime(startTime);
+        this._clearTimelineNavigationItem.enabled = !this._recording.readonly;
+        this._exportButtonNavigationItem.enabled = false;
 
-            this._clearTimelineNavigationItem.enabled = !this._recording.readonly;
-            this._exportButtonNavigationItem.enabled = false;
+        // A discontinuity occurs when the recording is stopped and resumed at
+        // a future time. Capturing started signals the end of the current
+        // discontinuity, if one exists.
+        if (!isNaN(this._discontinuityStartTime)) {
+            this._recording.addDiscontinuity(this._discontinuityStartTime, startTime);
+            this._discontinuityStartTime = NaN;
+        }
+    }
 
-            // A discontinuity occurs when the recording is stopped and resumed at
-            // a future time. Capturing started signals the end of the current
-            // discontinuity, if one exists.
-            if (!isNaN(this._discontinuityStartTime)) {
-                this._recording.addDiscontinuity(this._discontinuityStartTime, startTime);
-                this._discontinuityStartTime = NaN;
-            }
-            break;
+    _capturingStopped(event)
+    {
+        this._updateProgressView();
 
-        case WI.TimelineManager.CapturingState.Inactive:
-            if (this._updating)
-                this._stopUpdatingCurrentTime();
+        if (this._updating)
+            this._stopUpdatingCurrentTime();
 
-            if (this.currentTimelineView)
-                this._updateTimelineViewTimes(this.currentTimelineView);
+        if (this.currentTimelineView)
+            this._updateTimelineViewTimes(this.currentTimelineView);
 
-            this._discontinuityStartTime = endTime || this._currentTime;
+        this._discontinuityStartTime = event.data.endTime || this._currentTime;
 
-            this._exportButtonNavigationItem.enabled = this._recording.canExport();
-            break;
-        }
+        this._exportButtonNavigationItem.enabled = this._recording.canExport();
     }
 
     _debuggerPaused(event)
@@ -733,7 +731,8 @@ WI.TimelineRecordingContentView = class TimelineRecordingContentView extends WI.
     {
         console.assert(!this._updating);
 
-        WI.timelineManager.removeEventListener(null, null, this);
+        WI.timelineManager.removeEventListener(WI.TimelineManager.Event.CapturingStarted, this._capturingStarted, this);
+        WI.timelineManager.removeEventListener(WI.TimelineManager.Event.CapturingStopped, this._capturingStopped, this);
     }
 
     _timeRangeSelectionChanged(event)
index 8dea771..4d085f7 100644 (file)
@@ -71,10 +71,12 @@ WI.TimelineTabContentView = class TimelineTabContentView extends WI.ContentBrows
             this.contentBrowser.navigationBar.addEventListener(WI.NavigationBar.Event.NavigationItemSelected, this._viewModeSelected, this);
         }
 
-        WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingStateChanged, this._handleTimelineCapturingStateChanged, this);
         WI.timelineManager.addEventListener(WI.TimelineManager.Event.RecordingCreated, this._recordingCreated, this);
         WI.timelineManager.addEventListener(WI.TimelineManager.Event.RecordingLoaded, this._recordingLoaded, this);
 
+        WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingStarted, this._capturingStartedOrStopped, this);
+        WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingStopped, this._capturingStartedOrStopped, this);
+
         WI.notifications.addEventListener(WI.Notification.VisibilityStateDidChange, this._inspectorVisibilityChanged, this);
         WI.notifications.addEventListener(WI.Notification.GlobalModifierKeysDidChange, this._globalModifierKeysDidChange, this);
 
@@ -423,15 +425,10 @@ WI.TimelineTabContentView = class TimelineTabContentView extends WI.ContentBrows
             this._showContinueButton();
     }
 
-    _handleTimelineCapturingStateChanged(event)
+    _capturingStartedOrStopped(event)
     {
-        let enabled = WI.timelineManager.capturingState === WI.TimelineManager.CapturingState.Active || WI.timelineManager.capturingState === WI.TimelineManager.CapturingState.Inactive;
-
-        this._toggleRecordingShortcut.disabled = !enabled;
-        this._toggleNewRecordingShortcut.disabled = !enabled;
-
-        this._recordButton.toggled = WI.timelineManager.isCapturing();
-        this._recordButton.enabled = enabled;
+        let isCapturing = WI.timelineManager.isCapturing();
+        this._recordButton.toggled = isCapturing;
 
         this._updateNavigationBarButtons();
     }