/*
 * Copyright (C) 2013, 2016 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

// FIXME: TimelineManager lacks advanced multi-target support. (Instruments/Profilers per-target)

WI.TimelineManager = class TimelineManager extends WI.Object
{
    constructor()
    {
        super();

        this._enabled = false;

        WI.Frame.addEventListener(WI.Frame.Event.ProvisionalLoadStarted, this._provisionalLoadStarted, this);
        WI.Frame.addEventListener(WI.Frame.Event.MainResourceDidChange, this._mainResourceDidChange, this);

        this._enabledTimelineTypesSetting = new WI.Setting("enabled-instrument-types", WI.TimelineManager.defaultTimelineTypes());

        this._capturingState = TimelineManager.CapturingState.Inactive;
        this._capturingInstrumentCount = 0;
        this._capturingStartTime = NaN;
        this._capturingEndTime = NaN;

        this._initiatedByBackendStart = false;
        this._initiatedByBackendStop = false;

        this._isCapturingPageReload = false;
        this._autoCaptureOnPageLoad = false;
        this._mainResourceForAutoCapturing = null;
        this._shouldSetAutoCapturingMainResource = false;
        this._transitioningPageTarget = false;

        this._webTimelineScriptRecordsExpectingScriptProfilerEvents = null;
        this._scriptProfilerRecords = null;

        this._boundStopCapturing = this.stopCapturing.bind(this);
        this._stopCapturingTimeout = undefined;
        this._deadTimeTimeout = undefined;
        this._lastDeadTimeTickle = 0;

        this.reset();
    }

    // Agent

    get domains() { return ["Timeline"]; }

    activateExtraDomain(domain)
    {
        console.assert(domain === "Timeline");

        for (let target of WI.targets)
            this.initializeTarget(target);
    }

    // Target

    initializeTarget(target)
    {
        if (!this._enabled)
            return;

        if (target.hasDomain("Timeline")) {
            // COMPATIBILITY (iOS 13): Timeline.enable did not exist yet.
            if (target.hasCommand("Timeline.enable"))
                target.TimelineAgent.enable();

            this._updateAutoCaptureInstruments([target]);

            // COMPATIBILITY (iOS 9): Timeline.setAutoCaptureEnabled did not exist.
            if (target.hasCommand("Timeline.setAutoCaptureEnabled"))
                target.TimelineAgent.setAutoCaptureEnabled(this._autoCaptureOnPageLoad);
        }
    }

    transitionPageTarget()
    {
        this._transitioningPageTarget = true;
    }

    // Static

    static defaultTimelineTypes()
    {
        if (WI.sharedApp.debuggableType === WI.DebuggableType.JavaScript) {
            let defaultTypes = [WI.TimelineRecord.Type.Script];
            if (WI.HeapAllocationsInstrument.supported())
                defaultTypes.push(WI.TimelineRecord.Type.HeapAllocations);
            return defaultTypes;
        }

        if (WI.sharedApp.debuggableType === WI.DebuggableType.ServiceWorker) {
            // FIXME: Support Network Timeline in ServiceWorker.
            let defaultTypes = [WI.TimelineRecord.Type.Script];
            if (WI.HeapAllocationsInstrument.supported())
                defaultTypes.push(WI.TimelineRecord.Type.HeapAllocations);
            return defaultTypes;
        }

        let defaultTypes = [
            WI.TimelineRecord.Type.Network,
            WI.TimelineRecord.Type.Layout,
            WI.TimelineRecord.Type.Script,
        ];

        if (WI.CPUInstrument.supported())
            defaultTypes.push(WI.TimelineRecord.Type.CPU);

        if (WI.FPSInstrument.supported())
            defaultTypes.push(WI.TimelineRecord.Type.RenderingFrame);

        return defaultTypes;
    }

    static availableTimelineTypes()
    {
        let types = WI.TimelineManager.defaultTimelineTypes();
        if (WI.sharedApp.debuggableType === WI.DebuggableType.JavaScript || WI.sharedApp.debuggableType === WI.DebuggableType.ServiceWorker)
            return types;

        if (WI.MemoryInstrument.supported())
            types.push(WI.TimelineRecord.Type.Memory);

        if (WI.HeapAllocationsInstrument.supported())
            types.push(WI.TimelineRecord.Type.HeapAllocations);

        if (WI.MediaInstrument.supported()) {
            let insertionIndex = types.indexOf(WI.TimelineRecord.Type.Layout) + 1;
            types.insertAtIndex(WI.TimelineRecord.Type.Media, insertionIndex || types.length);
        }

        return types;
    }

    static synthesizeImportError(message)
    {
        message = WI.UIString("Timeline Recording Import Error: %s").format(message);

        if (window.InspectorTest) {
            console.error(message);
            return;
        }

        let consoleMessage = new WI.ConsoleMessage(WI.mainTarget, WI.ConsoleMessage.MessageSource.Other, WI.ConsoleMessage.MessageLevel.Error, message);
        consoleMessage.shouldRevealConsole = true;

        WI.consoleLogViewController.appendConsoleMessage(consoleMessage);
    }

    // Public

    get capturingState() { return this._capturingState; }

    reset()
    {
        if (this._capturingState === TimelineManager.CapturingState.Starting || this._capturingState === TimelineManager.CapturingState.Active)
            this.stopCapturing();

        this._recordings = [];
        this._activeRecording = null;
        this._nextRecordingIdentifier = 1;

        this._loadNewRecording();
    }

    // The current recording that new timeline records will be appended to, if any.
    get activeRecording()
    {
        console.assert(this._activeRecording || !this.isCapturing());
        return this._activeRecording;
    }

    get recordings()
    {
        return this._recordings.slice();
    }

    get autoCaptureOnPageLoad()
    {
        return this._autoCaptureOnPageLoad;
    }

    set autoCaptureOnPageLoad(autoCapture)
    {
        console.assert(this._enabled);

        autoCapture = !!autoCapture;

        if (this._autoCaptureOnPageLoad === autoCapture)
            return;

        this._autoCaptureOnPageLoad = autoCapture;

        for (let target of WI.targets) {
            // COMPATIBILITY (iOS 9): Timeline.setAutoCaptureEnabled did not exist yet.
            if (target.hasCommand("Timeline.setAutoCaptureEnabled"))
                target.TimelineAgent.setAutoCaptureEnabled(this._autoCaptureOnPageLoad);
        }
    }

    get enabledTimelineTypes()
    {
        let availableTimelineTypes = WI.TimelineManager.availableTimelineTypes();
        return this._enabledTimelineTypesSetting.value.filter((type) => availableTimelineTypes.includes(type));
    }

    set enabledTimelineTypes(x)
    {
        this._enabledTimelineTypesSetting.value = x || [];

        this._updateAutoCaptureInstruments(WI.targets);
    }

    isCapturing()
    {
        return this._capturingState !== TimelineManager.CapturingState.Inactive;
    }

    isCapturingPageReload()
    {
        return this._isCapturingPageReload;
    }

    willAutoStop()
    {
        return !!this._stopCapturingTimeout;
    }

    relaxAutoStop()
    {
        if (this._stopCapturingTimeout) {
            clearTimeout(this._stopCapturingTimeout);
            this._stopCapturingTimeout = undefined;
        }

        if (this._deadTimeTimeout) {
            clearTimeout(this._deadTimeTimeout);
            this._deadTimeTimeout = undefined;
        }
    }

    enable()
    {
        if (this._enabled)
            return;

        this._enabled = true;

        this.reset();

        for (let target of WI.targets)
            this.initializeTarget(target);
    }

    disable()
    {
        if (!this._enabled)
            return;

        this.reset();

        for (let target of WI.targets) {
            // COMPATIBILITY (iOS 13): Timeline.disable did not exist yet.
            if (target.hasCommand("Timeline.disable"))
                target.TimelineAgent.disable();
        }

        this._enabled = false;
    }

    startCapturing(shouldCreateRecording)
    {
        console.assert(this._enabled);

        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;

        if (!this._activeRecording || shouldCreateRecording)
            this._loadNewRecording();

        this._updateCapturingState(TimelineManager.CapturingState.Starting);

        this._capturingStartTime = NaN;
        this._activeRecording.start(this._initiatedByBackendStart);
    }

    stopCapturing()
    {
        console.assert(this._enabled);

        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)
            return;

        this._updateCapturingState(TimelineManager.CapturingState.Stopping);

        this._capturingEndTime = NaN;
        this._activeRecording.stop(this._initiatedByBackendStop);
    }

    async processJSON({filename, json, error})
    {
        if (error) {
            WI.TimelineManager.synthesizeImportError(error);
            return;
        }

        if (typeof json !== "object" || json === null) {
            WI.TimelineManager.synthesizeImportError(WI.UIString("invalid JSON"));
            return;
        }

        if (!json.recording || typeof json.recording !== "object" || !json.overview || typeof json.overview !== "object" || typeof json.version !== "number") {
            WI.TimelineManager.synthesizeImportError(WI.UIString("invalid JSON"));
            return;
        }

        if (json.version !== WI.TimelineRecording.SerializationVersion) {
            WI.NetworkManager.synthesizeImportError(WI.UIString("unsupported version"));
            return;
        }

        let recordingData = json.recording;
        let overviewData = json.overview;

        let identifier = this._nextRecordingIdentifier++;
        let newRecording = WI.TimelineRecording.import(identifier, recordingData, filename);
        this._recordings.push(newRecording);

        this.dispatchEventToListeners(WI.TimelineManager.Event.RecordingCreated, {recording: newRecording});

        if (this._capturingState === TimelineManager.CapturingState.Starting || this._capturingState === TimelineManager.CapturingState.Active)
            this.stopCapturing();

        let oldRecording = this._activeRecording;
        if (oldRecording) {
            const importing = true;
            oldRecording.unloaded(importing);
        }

        this._activeRecording = newRecording;

        this.dispatchEventToListeners(WI.TimelineManager.Event.RecordingLoaded, {oldRecording});
        this.dispatchEventToListeners(WI.TimelineManager.Event.RecordingImported, {overviewData});
    }

    computeElapsedTime(timestamp)
    {
        if (!this._activeRecording)
            return 0;

        return this._activeRecording.computeElapsedTime(timestamp);
    }

    scriptProfilerIsTracking()
    {
        return this._scriptProfilerRecords !== null;
    }

    // ConsoleObserver

    heapSnapshotAdded(timestamp, snapshot)
    {
        if (!this._enabled)
            return;

        this._addRecord(new WI.HeapAllocationsTimelineRecord(timestamp, snapshot));
    }

    // TimelineObserver

    capturingStarted(startTime)
    {
        // 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)
            return;

        if (this._capturingState === TimelineManager.CapturingState.Active)
            return;

        this._lastDeadTimeTickle = 0;

        this._webTimelineScriptRecordsExpectingScriptProfilerEvents = [];

        this._activeRecording.capturingStarted(this._capturingStartTime);

        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);

        WI.memoryManager.addEventListener(WI.MemoryManager.Event.MemoryPressure, this._memoryPressure, this);

        WI.DOMNode.addEventListener(WI.DOMNode.Event.DidFireEvent, this._handleDOMNodeDidFireEvent, this);
        WI.DOMNode.addEventListener(WI.DOMNode.Event.PowerEfficientPlaybackStateChanged, this._handleDOMNodePowerEfficientPlaybackStateChanged, this);

        this._updateCapturingState(TimelineManager.CapturingState.Active, {startTime: this._capturingStartTime});
    }

    capturingStopped(endTime)
    {
        // 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)
            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._activeRecording.capturingStopped(this._capturingEndTime);

        this.relaxAutoStop();

        this._isCapturingPageReload = false;
        this._shouldSetAutoCapturingMainResource = false;
        this._mainResourceForAutoCapturing = null;
        this._initiatedByBackendStart = false;
        this._initiatedByBackendStop = false;

        this._updateCapturingState(TimelineManager.CapturingState.Inactive, {endTime: this._capturingEndTime});
    }

    autoCaptureStarted()
    {
        console.assert(this._enabled);

        let waitingForCapturingStartedEvent = this._capturingState === TimelineManager.CapturingState.Starting;

        if (this._capturingState === TimelineManager.CapturingState.Starting || this._capturingState === TimelineManager.CapturingState.Active)
            this.stopCapturing();

        this._initiatedByBackendStart = true;

        // 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) {
            const createNewRecording = true;
            this.startCapturing(createNewRecording);
        }

        this._shouldSetAutoCapturingMainResource = true;
    }

    eventRecorded(recordPayload)
    {
        if (!this._enabled)
            return;

        console.assert(this.isCapturing());
        if (!this.isCapturing())
            return;

        var records = [];

        // Iterate over the records tree using a stack. Doing this recursively has
        // been known to cause a call stack overflow. https://webkit.org/b/79106
        var stack = [{array: [recordPayload], parent: null, parentRecord: null, index: 0}];
        while (stack.length) {
            var entry = stack.lastValue;
            var recordPayloads = entry.array;

            if (entry.index < recordPayloads.length) {
                var recordPayload = recordPayloads[entry.index];
                var record = this._processEvent(recordPayload, entry.parent);
                if (record) {
                    record.parent = entry.parentRecord;
                    records.push(record);
                    if (entry.parentRecord)
                        entry.parentRecord.children.push(record);
                }

                if (recordPayload.children && recordPayload.children.length)
                    stack.push({array: recordPayload.children, parent: recordPayload, parentRecord: record || entry.parentRecord, index: 0});
                ++entry.index;
            } else
                stack.pop();
        }

        for (var record of records) {
            if (record.type === WI.TimelineRecord.Type.RenderingFrame) {
                if (!record.children.length)
                    continue;
                record.setupFrameIndex();
            }

            this._addRecord(record);
        }
    }

    // PageObserver

    pageDOMContentLoadedEventFired(timestamp)
    {
        if (!this._enabled)
            return;

        console.assert(this._activeRecording);

        let computedTimestamp = this._activeRecording.computeElapsedTime(timestamp);

        if (WI.networkManager.mainFrame)
            WI.networkManager.mainFrame.markDOMContentReadyEvent(computedTimestamp);

        let eventMarker = new WI.TimelineMarker(computedTimestamp, WI.TimelineMarker.Type.DOMContentEvent);
        this._activeRecording.addEventMarker(eventMarker);
    }

    pageLoadEventFired(timestamp)
    {
        if (!this._enabled)
            return;

        console.assert(this._activeRecording);

        let computedTimestamp = this._activeRecording.computeElapsedTime(timestamp);

        if (WI.networkManager.mainFrame)
            WI.networkManager.mainFrame.markLoadEvent(computedTimestamp);

        let eventMarker = new WI.TimelineMarker(computedTimestamp, WI.TimelineMarker.Type.LoadEvent);
        this._activeRecording.addEventMarker(eventMarker);

        this._stopAutoRecordingSoon();
    }

    // CPUProfilerObserver

    cpuProfilerTrackingStarted(timestamp)
    {
        this.capturingStarted(timestamp);
    }

    cpuProfilerTrackingUpdated(event)
    {
        if (!this._enabled)
            return;

        console.assert(this.isCapturing());
        if (!this.isCapturing())
            return;

        this._addRecord(new WI.CPUTimelineRecord(event));
    }

    cpuProfilerTrackingCompleted(timestamp)
    {
        this.capturingStopped(timestamp);
    }

    // ScriptProfilerObserver

    scriptProfilerTrackingStarted(timestamp)
    {
        this._scriptProfilerRecords = [];

        this.capturingStarted(timestamp);
    }

    scriptProfilerTrackingUpdated(event)
    {
        if (!this._enabled)
            return;

        let {startTime, endTime, type} = event;
        let scriptRecordType = this._scriptProfilerTypeToScriptTimelineRecordType(type);
        let record = new WI.ScriptTimelineRecord(scriptRecordType, startTime, endTime, null, null, null, null);
        record.__scriptProfilerType = type;
        this._scriptProfilerRecords.push(record);

        // "Other" events, generated by Web content, will have wrapping Timeline records
        // and need to be merged. Non-Other events, generated purely by the JavaScript
        // engine or outside of the page via APIs, will not have wrapping Timeline
        // records, so these records can just be added right now.
        if (type !== InspectorBackend.Enum.ScriptProfiler.EventType.Other)
            this._addRecord(record);
    }

    scriptProfilerTrackingCompleted(timestamp, samples)
    {
        if (this._enabled) {
            console.assert(!this._webTimelineScriptRecordsExpectingScriptProfilerEvents || this._scriptProfilerRecords.length >= this._webTimelineScriptRecordsExpectingScriptProfilerEvents.length);

            if (samples) {
                let {stackTraces} = samples;
                let topDownCallingContextTree = this._activeRecording.topDownCallingContextTree;

                // Calculate a per-sample duration.
                let timestampIndex = 0;
                let timestampCount = stackTraces.length;
                let sampleDurations = new Array(timestampCount);
                let sampleDurationIndex = 0;
                const defaultDuration = 1 / 1000; // 1ms.
                for (let i = 0; i < this._scriptProfilerRecords.length; ++i) {
                    let record = this._scriptProfilerRecords[i];

                    // Use a default duration for timestamps recorded outside of ScriptProfiler events.
                    while (timestampIndex < timestampCount && stackTraces[timestampIndex].timestamp < record.startTime) {
                        sampleDurations[sampleDurationIndex++] = defaultDuration;
                        timestampIndex++;
                    }

                    // Average the duration per sample across all samples during the record.
                    let samplesInRecord = 0;
                    while (timestampIndex < timestampCount && stackTraces[timestampIndex].timestamp < record.endTime) {
                        timestampIndex++;
                        samplesInRecord++;
                    }
                    if (samplesInRecord) {
                        let averageDuration = (record.endTime - record.startTime) / samplesInRecord;
                        sampleDurations.fill(averageDuration, sampleDurationIndex, sampleDurationIndex + samplesInRecord);
                        sampleDurationIndex += samplesInRecord;
                    }
                }

                // Use a default duration for timestamps recorded outside of ScriptProfiler events.
                if (timestampIndex < timestampCount)
                    sampleDurations.fill(defaultDuration, sampleDurationIndex);

                this._activeRecording.initializeCallingContextTrees(stackTraces, sampleDurations);

                // FIXME: This transformation should not be needed after introducing ProfileView.
                // Once we eliminate ProfileNodeTreeElements and ProfileNodeDataGridNodes.
                // <https://webkit.org/b/154973> Web Inspector: Timelines UI redesign: Remove TimelineSidebarPanel
                for (let i = 0; i < this._scriptProfilerRecords.length; ++i) {
                    let record = this._scriptProfilerRecords[i];
                    record.profilePayload = topDownCallingContextTree.toCPUProfilePayload(record.startTime, record.endTime);
                }
            }

            // Associate the ScriptProfiler created records with Web Timeline records.
            // Filter out the already added ScriptProfiler events which should not have been wrapped.
            if (WI.sharedApp.debuggableType !== WI.DebuggableType.JavaScript) {
                this._scriptProfilerRecords = this._scriptProfilerRecords.filter((x) => x.__scriptProfilerType === InspectorBackend.Enum.ScriptProfiler.EventType.Other);
                this._mergeScriptProfileRecords();
            }

            this._scriptProfilerRecords = null;

            let timeline = this._activeRecording.timelineForRecordType(WI.TimelineRecord.Type.Script);
            timeline.refresh();
        }

        this.capturingStopped(timestamp);
    }

    // MemoryObserver

    memoryTrackingStarted(timestamp)
    {
        this.capturingStarted(timestamp);
    }

    memoryTrackingUpdated(event)
    {
        if (!this._enabled)
            return;

        console.assert(this.isCapturing());
        if (!this.isCapturing())
            return;

        this._addRecord(new WI.MemoryTimelineRecord(event.timestamp, event.categories));
    }

    memoryTrackingCompleted(timestamp)
    {
        this.capturingStopped(timestamp);
    }

    // HeapObserver

    heapTrackingStarted(timestamp, snapshot)
    {
        this.capturingStarted(timestamp);

        if (this._enabled)
            this._addRecord(new WI.HeapAllocationsTimelineRecord(timestamp, snapshot));
    }

    heapTrackingCompleted(timestamp, snapshot)
    {
        if (this._enabled)
            this._addRecord(new WI.HeapAllocationsTimelineRecord(timestamp, snapshot));

        this.capturingStopped();
    }

    // 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 callFrames = this._callFramesFromPayload(recordPayload.stackTrace);

        var significantCallFrame = null;
        if (callFrames) {
            for (var i = 0; i < callFrames.length; ++i) {
                if (callFrames[i].nativeCode)
                    continue;
                significantCallFrame = callFrames[i];
                break;
            }
        }

        var sourceCodeLocation = significantCallFrame && significantCallFrame.sourceCodeLocation;

        switch (recordPayload.type) {
        case InspectorBackend.Enum.Timeline.EventType.ScheduleStyleRecalculation:
            console.assert(isNaN(endTime));

            // Pass the startTime as the endTime since this record type has no duration.
            return new WI.LayoutTimelineRecord(WI.LayoutTimelineRecord.EventType.InvalidateStyles, startTime, startTime, callFrames, sourceCodeLocation);

        case InspectorBackend.Enum.Timeline.EventType.RecalculateStyles:
            return new WI.LayoutTimelineRecord(WI.LayoutTimelineRecord.EventType.RecalculateStyles, startTime, endTime, callFrames, sourceCodeLocation);

        case InspectorBackend.Enum.Timeline.EventType.InvalidateLayout:
            console.assert(isNaN(endTime));

            // Pass the startTime as the endTime since this record type has no duration.
            return new WI.LayoutTimelineRecord(WI.LayoutTimelineRecord.EventType.InvalidateLayout, startTime, startTime, callFrames, sourceCodeLocation);

        case InspectorBackend.Enum.Timeline.EventType.Layout:
            var layoutRecordType = sourceCodeLocation ? WI.LayoutTimelineRecord.EventType.ForcedLayout : WI.LayoutTimelineRecord.EventType.Layout;
            var quad = new WI.Quad(recordPayload.data.root);
            return new WI.LayoutTimelineRecord(layoutRecordType, startTime, endTime, callFrames, sourceCodeLocation, quad);

        case InspectorBackend.Enum.Timeline.EventType.Paint:
            var quad = new WI.Quad(recordPayload.data.clip);
            return new WI.LayoutTimelineRecord(WI.LayoutTimelineRecord.EventType.Paint, startTime, endTime, callFrames, sourceCodeLocation, quad);

        case InspectorBackend.Enum.Timeline.EventType.Composite:
            return new WI.LayoutTimelineRecord(WI.LayoutTimelineRecord.EventType.Composite, startTime, endTime, callFrames, sourceCodeLocation);

        case InspectorBackend.Enum.Timeline.EventType.RenderingFrame:
            if (!recordPayload.children || !recordPayload.children.length)
                return null;

            return new WI.RenderingFrameTimelineRecord(startTime, endTime);

        case InspectorBackend.Enum.Timeline.EventType.EvaluateScript:
            if (!sourceCodeLocation) {
                var mainFrame = WI.networkManager.mainFrame;
                var scriptResource = mainFrame.url === recordPayload.data.url ? mainFrame.mainResource : mainFrame.resourceForURL(recordPayload.data.url, true);
                if (scriptResource) {
                    // The lineNumber is 1-based, but we expect 0-based.
                    let lineNumber = recordPayload.data.lineNumber - 1;
                    let columnNumber = "columnNumber" in recordPayload.data ? recordPayload.data.columnNumber - 1 : 0;
                    sourceCodeLocation = scriptResource.createSourceCodeLocation(lineNumber, columnNumber);
                }
            }

            var profileData = recordPayload.data.profile;

            var record;
            switch (parentRecordPayload && parentRecordPayload.type) {
            case InspectorBackend.Enum.Timeline.EventType.TimerFire:
                record = new WI.ScriptTimelineRecord(WI.ScriptTimelineRecord.EventType.TimerFired, startTime, endTime, callFrames, sourceCodeLocation, parentRecordPayload.data.timerId, profileData);
                break;
            case InspectorBackend.Enum.Timeline.EventType.ObserverCallback:
                record = new WI.ScriptTimelineRecord(WI.ScriptTimelineRecord.EventType.ObserverCallback, startTime, endTime, callFrames, sourceCodeLocation, parentRecordPayload.data.type, profileData);
                break;
            case InspectorBackend.Enum.Timeline.EventType.FireAnimationFrame:
                record = new WI.ScriptTimelineRecord(WI.ScriptTimelineRecord.EventType.AnimationFrameFired, startTime, endTime, callFrames, sourceCodeLocation, parentRecordPayload.data.id, profileData);
                break;
            default:
                record = new WI.ScriptTimelineRecord(WI.ScriptTimelineRecord.EventType.ScriptEvaluated, startTime, endTime, callFrames, sourceCodeLocation, null, profileData);
                break;
            }

            this._webTimelineScriptRecordsExpectingScriptProfilerEvents.push(record);
            return record;

        case InspectorBackend.Enum.Timeline.EventType.ConsoleProfile:
            var profileData = recordPayload.data.profile;
            // COMPATIBILITY (iOS 9): With the Sampling Profiler, profiles no longer include legacy profile data.
            console.assert(profileData || InspectorBackend.hasCommand("Timeline.setInstruments"));
            return new WI.ScriptTimelineRecord(WI.ScriptTimelineRecord.EventType.ConsoleProfileRecorded, startTime, endTime, callFrames, sourceCodeLocation, recordPayload.data.title, profileData);

        case InspectorBackend.Enum.Timeline.EventType.TimerFire:
        case InspectorBackend.Enum.Timeline.EventType.EventDispatch:
        case InspectorBackend.Enum.Timeline.EventType.FireAnimationFrame:
        case InspectorBackend.Enum.Timeline.EventType.ObserverCallback:
            // These are handled when we see the child FunctionCall or EvaluateScript.
            break;

        case InspectorBackend.Enum.Timeline.EventType.FunctionCall:
            // FunctionCall always happens as a child of another record, and since the FunctionCall record
            // has useful info we just make the timeline record here (combining the data from both records).
            if (!parentRecordPayload) {
                console.warn("Unexpectedly received a FunctionCall timeline record without a parent record");
                break;
            }

            if (!sourceCodeLocation) {
                var mainFrame = WI.networkManager.mainFrame;
                var scriptResource = mainFrame.url === recordPayload.data.scriptName ? mainFrame.mainResource : mainFrame.resourceForURL(recordPayload.data.scriptName, true);
                if (scriptResource) {
                    // The lineNumber is 1-based, but we expect 0-based.
                    let lineNumber = recordPayload.data.scriptLine - 1;
                    let columnNumber = "scriptColumn" in recordPayload.data ? recordPayload.data.scriptColumn - 1 : 0;
                    sourceCodeLocation = scriptResource.createSourceCodeLocation(lineNumber, columnNumber);
                }
            }

            var profileData = recordPayload.data.profile;

            var record;
            switch (parentRecordPayload.type) {
            case InspectorBackend.Enum.Timeline.EventType.TimerFire:
                record = new WI.ScriptTimelineRecord(WI.ScriptTimelineRecord.EventType.TimerFired, startTime, endTime, callFrames, sourceCodeLocation, parentRecordPayload.data.timerId, profileData);
                break;
            case InspectorBackend.Enum.Timeline.EventType.EventDispatch:
                record = new WI.ScriptTimelineRecord(WI.ScriptTimelineRecord.EventType.EventDispatched, startTime, endTime, callFrames, sourceCodeLocation, parentRecordPayload.data.type, profileData, parentRecordPayload.data);
                break;
            case InspectorBackend.Enum.Timeline.EventType.ObserverCallback:
                record = new WI.ScriptTimelineRecord(WI.ScriptTimelineRecord.EventType.ObserverCallback, startTime, endTime, callFrames, sourceCodeLocation, parentRecordPayload.data.type, profileData);
                break;
            case InspectorBackend.Enum.Timeline.EventType.FireAnimationFrame:
                record = new WI.ScriptTimelineRecord(WI.ScriptTimelineRecord.EventType.AnimationFrameFired, startTime, endTime, callFrames, sourceCodeLocation, parentRecordPayload.data.id, profileData);
                break;
            case InspectorBackend.Enum.Timeline.EventType.FunctionCall:
                record = new WI.ScriptTimelineRecord(WI.ScriptTimelineRecord.EventType.ScriptEvaluated, startTime, endTime, callFrames, sourceCodeLocation, parentRecordPayload.data.id, profileData);
                break;
            case InspectorBackend.Enum.Timeline.EventType.RenderingFrame:
                record = new WI.ScriptTimelineRecord(WI.ScriptTimelineRecord.EventType.ScriptEvaluated, startTime, endTime, callFrames, sourceCodeLocation, parentRecordPayload.data.id, profileData);
                break;

            default:
                console.assert(false, "Missed FunctionCall embedded inside of: " + parentRecordPayload.type);
                break;
            }

            if (record) {
                this._webTimelineScriptRecordsExpectingScriptProfilerEvents.push(record);
                return record;
            }
            break;

        case InspectorBackend.Enum.Timeline.EventType.ProbeSample:
            // Pass the startTime as the endTime since this record type has no duration.
            sourceCodeLocation = WI.debuggerManager.probeForIdentifier(recordPayload.data.probeId).breakpoint.sourceCodeLocation;
            return new WI.ScriptTimelineRecord(WI.ScriptTimelineRecord.EventType.ProbeSampleRecorded, startTime, startTime, callFrames, sourceCodeLocation, recordPayload.data.probeId);

        case InspectorBackend.Enum.Timeline.EventType.TimerInstall:
            console.assert(isNaN(endTime));

            // Pass the startTime as the endTime since this record type has no duration.
            var timerDetails = {timerId: recordPayload.data.timerId, timeout: recordPayload.data.timeout, repeating: !recordPayload.data.singleShot};
            return new WI.ScriptTimelineRecord(WI.ScriptTimelineRecord.EventType.TimerInstalled, startTime, startTime, callFrames, sourceCodeLocation, timerDetails);

        case InspectorBackend.Enum.Timeline.EventType.TimerRemove:
            console.assert(isNaN(endTime));

            // Pass the startTime as the endTime since this record type has no duration.
            return new WI.ScriptTimelineRecord(WI.ScriptTimelineRecord.EventType.TimerRemoved, startTime, startTime, callFrames, sourceCodeLocation, recordPayload.data.timerId);

        case InspectorBackend.Enum.Timeline.EventType.RequestAnimationFrame:
            console.assert(isNaN(endTime));

            // Pass the startTime as the endTime since this record type has no duration.
            return new WI.ScriptTimelineRecord(WI.ScriptTimelineRecord.EventType.AnimationFrameRequested, startTime, startTime, callFrames, sourceCodeLocation, recordPayload.data.id);

        case InspectorBackend.Enum.Timeline.EventType.CancelAnimationFrame:
            console.assert(isNaN(endTime));

            // Pass the startTime as the endTime since this record type has no duration.
            return new WI.ScriptTimelineRecord(WI.ScriptTimelineRecord.EventType.AnimationFrameCanceled, startTime, startTime, callFrames, sourceCodeLocation, recordPayload.data.id);

        default:
            console.error("Missing handling of Timeline Event Type: " + recordPayload.type);
        }

        return null;
    }

    _processEvent(recordPayload, parentRecordPayload)
    {
        console.assert(this.isCapturing());

        switch (recordPayload.type) {
        case InspectorBackend.Enum.Timeline.EventType.TimeStamp:
            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;

        case InspectorBackend.Enum.Timeline.EventType.Time:
        case InspectorBackend.Enum.Timeline.EventType.TimeEnd:
            // FIXME: <https://webkit.org/b/150690> Web Inspector: Show console.time/timeEnd ranges in Timeline
            // FIXME: Make use of "message" payload properties.
            break;

        default:
            return this._processRecord(recordPayload, parentRecordPayload);
        }

        return null;
    }

    _loadNewRecording()
    {
        if (this._activeRecording && this._activeRecording.isEmpty())
            return;

        let instruments = this.enabledTimelineTypes.map((type) => WI.Instrument.createForTimelineType(type));
        let identifier = this._nextRecordingIdentifier++;
        let newRecording = new WI.TimelineRecording(identifier, WI.UIString("Timeline Recording %d").format(identifier), instruments);

        this._recordings.push(newRecording);
        this.dispatchEventToListeners(WI.TimelineManager.Event.RecordingCreated, {recording: newRecording});

        if (this._capturingState === TimelineManager.CapturingState.Starting || this._capturingState === TimelineManager.CapturingState.Active)
            this.stopCapturing();

        var oldRecording = this._activeRecording;
        if (oldRecording)
            oldRecording.unloaded();

        this._activeRecording = newRecording;

        // COMPATIBILITY (iOS 8): When using Legacy timestamps, a navigation will have computed
        // the main resource's will send request timestamp in terms of the last page's base timestamp.
        // Now that we have navigated, we should reset the legacy base timestamp and the
        // will send request timestamp for the new main resource. This way, all new timeline
        // records will be computed relative to the new navigation.
        if (this._mainResourceForAutoCapturing && WI.TimelineRecording.isLegacy) {
            console.assert(this._mainResourceForAutoCapturing.originalRequestWillBeSentTimestamp);
            this._activeRecording.setLegacyBaseTimestamp(this._mainResourceForAutoCapturing.originalRequestWillBeSentTimestamp);
            this._mainResourceForAutoCapturing._requestSentTimestamp = 0;
        }

        this.dispatchEventToListeners(WI.TimelineManager.Event.RecordingLoaded, {oldRecording});
    }

    _callFramesFromPayload(payload)
    {
        if (!payload)
            return null;

        return payload.map((x) => WI.CallFrame.fromPayload(WI.assumingMainTarget(), x));
    }

    _addRecord(record)
    {
        this._activeRecording.addRecord(record);

        // Only worry about dead time after the load event.
        if (WI.networkManager.mainFrame && isNaN(WI.networkManager.mainFrame.loadEventTimestamp))
            this._resetAutoRecordingDeadTimeTimeout();
    }

    _attemptAutoCapturingForFrame(frame)
    {
        if (!this._autoCaptureOnPageLoad)
            return false;

        if (!frame.isMainFrame())
            return false;

        if (!InspectorBackend.hasDomain("Timeline"))
            return false;

        // COMPATIBILITY (iOS 9): Timeline.setAutoCaptureEnabled did not exist.
        // Perform auto capture in the frontend.
        if (!InspectorBackend.hasCommand("Timeline.setAutoCaptureEnabled"))
            return this._legacyAttemptStartAutoCapturingForFrame(frame);

        if (!this._shouldSetAutoCapturingMainResource)
            return false;

        console.assert(this.isCapturing(), "We saw autoCaptureStarted so we should already be capturing");

        let mainResource = frame.provisionalMainResource || frame.mainResource;
        if (mainResource === this._mainResourceForAutoCapturing)
            return false;

        let oldMainResource = frame.mainResource || null;
        this._isCapturingPageReload = oldMainResource !== null && oldMainResource.url === mainResource.url;

        this._mainResourceForAutoCapturing = mainResource;

        this._addRecord(new WI.ResourceTimelineRecord(mainResource));

        this._resetAutoRecordingMaxTimeTimeout();

        this._shouldSetAutoCapturingMainResource = false;

        return true;
    }

    _legacyAttemptStartAutoCapturingForFrame(frame)
    {
        if (this.isCapturing() && !this._mainResourceForAutoCapturing)
            return false;

        let mainResource = frame.provisionalMainResource || frame.mainResource;
        if (mainResource === this._mainResourceForAutoCapturing)
            return false;

        let oldMainResource = frame.mainResource || null;
        this._isCapturingPageReload = oldMainResource !== null && oldMainResource.url === mainResource.url;

        if (this._capturingState === TimelineManager.CapturingState.Starting || this._capturingState === TimelineManager.CapturingState.Active)
            this.stopCapturing();

        this._mainResourceForAutoCapturing = mainResource;

        this._loadNewRecording();

        this.startCapturing();

        this._addRecord(new WI.ResourceTimelineRecord(mainResource));

        this._resetAutoRecordingMaxTimeTimeout();

        return true;
    }

    _stopAutoRecordingSoon()
    {
        if (!WI.settings.timelinesAutoStop.value)
            return;

        // Only auto stop when auto capturing.
        if (!this.isCapturing() || !this._mainResourceForAutoCapturing)
            return;

        if (this._stopCapturingTimeout)
            clearTimeout(this._stopCapturingTimeout);
        this._stopCapturingTimeout = setTimeout(this._boundStopCapturing, WI.TimelineManager.MaximumAutoRecordDurationAfterLoadEvent);
    }

    _resetAutoRecordingMaxTimeTimeout()
    {
        if (!WI.settings.timelinesAutoStop.value)
            return;

        if (this._stopCapturingTimeout)
            clearTimeout(this._stopCapturingTimeout);
        this._stopCapturingTimeout = setTimeout(this._boundStopCapturing, WI.TimelineManager.MaximumAutoRecordDuration);
    }

    _resetAutoRecordingDeadTimeTimeout()
    {
        if (!WI.settings.timelinesAutoStop.value)
            return;

        // Only monitor dead time when auto capturing.
        if (!this.isCapturing() || !this._mainResourceForAutoCapturing)
            return;

        // Avoid unnecessary churning of timeout identifier by not tickling until 10ms have passed.
        let now = Date.now();
        if (now <= this._lastDeadTimeTickle)
            return;
        this._lastDeadTimeTickle = now + 10;

        if (this._deadTimeTimeout)
            clearTimeout(this._deadTimeTimeout);
        this._deadTimeTimeout = setTimeout(this._boundStopCapturing, WI.TimelineManager.DeadTimeRequiredToStopAutoRecordingEarly);
    }

    _provisionalLoadStarted(event)
    {
        if (!this._enabled)
            return;

        this._attemptAutoCapturingForFrame(event.target);
    }

    _mainResourceDidChange(event)
    {
        if (!this._enabled)
            return;

        // 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;

        let frame = event.target;

        // When performing a page transition start a recording once the main resource changes.
        // We start a legacy capture because the backend wasn't available to automatically
        // initiate the capture, so the frontend must start the capture.
        if (this._transitioningPageTarget) {
            this._transitioningPageTarget = false;
            if (this._autoCaptureOnPageLoad)
                this._legacyAttemptStartAutoCapturingForFrame(frame);
            return;
        }

        if (this._attemptAutoCapturingForFrame(frame))
            return;

        if (!this.isCapturing())
            return;

        let mainResource = frame.mainResource;
        if (mainResource === this._mainResourceForAutoCapturing)
            return;

        this._addRecord(new WI.ResourceTimelineRecord(mainResource));
    }

    _resourceWasAdded(event)
    {
        if (!this._enabled)
            return;

        // 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;

        this._addRecord(new WI.ResourceTimelineRecord(event.data.resource));
    }

    _garbageCollected(event)
    {
        if (!this._enabled)
            return;

        let {collection} = event.data;
        this._addRecord(new WI.ScriptTimelineRecord(WI.ScriptTimelineRecord.EventType.GarbageCollected, collection.startTime, collection.endTime, null, null, collection));
    }

    _memoryPressure(event)
    {
        if (!this._enabled)
            return;

        this._activeRecording.addMemoryPressureEvent(event.data.memoryPressureEvent);
    }

    _handleTimelinesAutoStopSettingChanged(event)
    {
        if (WI.settings.timelinesAutoStop.value) {
            if (this._mainResourceForAutoCapturing && !isNaN(this._mainResourceForAutoCapturing.parentFrame.loadEventTimestamp))
                this._stopAutoRecordingSoon();
            else
                this._resetAutoRecordingMaxTimeTimeout();
            this._resetAutoRecordingDeadTimeTimeout();
        } else
            this.relaxAutoStop();
    }

    _scriptProfilerTypeToScriptTimelineRecordType(type)
    {
        switch (type) {
        case InspectorBackend.Enum.ScriptProfiler.EventType.API:
            return WI.ScriptTimelineRecord.EventType.APIScriptEvaluated;
        case InspectorBackend.Enum.ScriptProfiler.EventType.Microtask:
            return WI.ScriptTimelineRecord.EventType.MicrotaskDispatched;
        case InspectorBackend.Enum.ScriptProfiler.EventType.Other:
            return WI.ScriptTimelineRecord.EventType.ScriptEvaluated;
        }
    }

    _mergeScriptProfileRecords()
    {
        let nextRecord = function(list) { return list.shift() || null; };
        let nextWebTimelineRecord = nextRecord.bind(null, this._webTimelineScriptRecordsExpectingScriptProfilerEvents);
        let nextScriptProfilerRecord = nextRecord.bind(null, this._scriptProfilerRecords);
        let recordEnclosesRecord = function(record1, record2) {
            return record1.startTime <= record2.startTime && record1.endTime >= record2.endTime;
        };

        let webRecord = nextWebTimelineRecord();
        let profilerRecord = nextScriptProfilerRecord();

        while (webRecord && profilerRecord) {
            // Skip web records with parent web records. For example an EvaluateScript with an EvaluateScript parent.
            if (webRecord.parent instanceof WI.ScriptTimelineRecord) {
                console.assert(recordEnclosesRecord(webRecord.parent, webRecord), "Timeline Record incorrectly wrapping another Timeline Record");
                webRecord = nextWebTimelineRecord();
                continue;
            }

            // Normal case of a Web record wrapping a Script record.
            if (recordEnclosesRecord(webRecord, profilerRecord)) {
                webRecord.profilePayload = profilerRecord.profilePayload;
                profilerRecord = nextScriptProfilerRecord();

                // If there are more script profile records in the same time interval, add them
                // as individual script evaluated records with profiles. This can happen with
                // web microtask checkpoints that are technically inside of other web records.
                // FIXME: <https://webkit.org/b/152903> Web Inspector: Timeline Cleanup: Better Timeline Record for Microtask Checkpoints
                while (profilerRecord && recordEnclosesRecord(webRecord, profilerRecord)) {
                    this._addRecord(profilerRecord);
                    profilerRecord = nextScriptProfilerRecord();
                }

                webRecord = nextWebTimelineRecord();
                continue;
            }

            // Profiler Record is entirely after the Web Record. This would mean an empty web record.
            if (profilerRecord.startTime > webRecord.endTime) {
                console.warn("Unexpected case of a Timeline record not containing a ScriptProfiler event and profile data");
                webRecord = nextWebTimelineRecord();
                continue;
            }

            // Non-wrapped profiler record.
            console.warn("Unexpected case of a ScriptProfiler event not being contained by a Timeline record");
            this._addRecord(profilerRecord);
            profilerRecord = nextScriptProfilerRecord();
        }

        // Skipping the remaining ScriptProfiler events to match the current UI for handling Timeline records.
        // However, the remaining ScriptProfiler records are valid and could be shown.
        // FIXME: <https://webkit.org/b/152904> Web Inspector: Timeline UI should keep up with processing all incoming records
    }

    _updateAutoCaptureInstruments(targets)
    {
        console.assert(this._enabled);

        let enabledTimelineTypes = this.enabledTimelineTypes;

        for (let target of targets) {
            if (!target.hasCommand("Timeline.setInstruments"))
                continue;

            let instrumentSet = new Set;
            for (let timelineType of enabledTimelineTypes) {
                switch (timelineType) {
                case WI.TimelineRecord.Type.Script:
                    instrumentSet.add(InspectorBackend.Enum.Timeline.Instrument.ScriptProfiler);
                    break;
                case WI.TimelineRecord.Type.HeapAllocations:
                    instrumentSet.add(InspectorBackend.Enum.Timeline.Instrument.Heap);
                    break;
                case WI.TimelineRecord.Type.Network:
                case WI.TimelineRecord.Type.RenderingFrame:
                case WI.TimelineRecord.Type.Layout:
                case WI.TimelineRecord.Type.Media:
                    instrumentSet.add(InspectorBackend.Enum.Timeline.Instrument.Timeline);
                    break;
                case WI.TimelineRecord.Type.CPU:
                    instrumentSet.add(InspectorBackend.Enum.Timeline.Instrument.CPU);
                    break;
                case WI.TimelineRecord.Type.Memory:
                    instrumentSet.add(InspectorBackend.Enum.Timeline.Instrument.Memory);
                    break;
                }
            }

            target.TimelineAgent.setInstruments(Array.from(instrumentSet));
        }
    }

    _handleDOMNodeDidFireEvent(event)
    {
        if (!this._enabled)
            return;

        let {domEvent} = event.data;

        this._addRecord(new WI.MediaTimelineRecord(WI.MediaTimelineRecord.EventType.DOMEvent, domEvent.timestamp, {
            domNode: event.target,
            domEvent,
        }));
    }

    _handleDOMNodePowerEfficientPlaybackStateChanged(event)
    {
        if (!this._enabled)
            return;

        let {timestamp, isPowerEfficient} = event.data;

        this._addRecord(new WI.MediaTimelineRecord(WI.MediaTimelineRecord.EventType.PowerEfficientPlaybackStateChanged, timestamp, {
            domNode: event.target,
            isPowerEfficient,
        }));
    }
};

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",
};

WI.TimelineManager.MaximumAutoRecordDuration = 90000; // 90 seconds
WI.TimelineManager.MaximumAutoRecordDurationAfterLoadEvent = 10000; // 10 seconds
WI.TimelineManager.DeadTimeRequiredToStopAutoRecordingEarly = 2000; // 2 seconds
