void InspectorReplayAgent::insertSessionSegment(ErrorString& errorString, Inspector::Protocol::Replay::SessionIdentifier sessionIdentifier, SegmentIdentifier segmentIdentifier, int segmentIndex)
{
    ASSERT_ARG(sessionIdentifier, sessionIdentifier > 0);
    ASSERT_ARG(segmentIdentifier, segmentIdentifier > 0);
    ASSERT_ARG(segmentIndex, segmentIndex >= 0);

    RefPtr<ReplaySession> session = findSession(errorString, sessionIdentifier);
    RefPtr<ReplaySessionSegment> segment = findSegment(errorString, segmentIdentifier);

    if (!session || !segment)
        return;

    if (static_cast<size_t>(segmentIndex) > session->size()) {
        errorString = ASCIILiteral("Invalid segment index.");
        return;
    }

    if (session == m_page.replayController().loadedSession() && sessionState() != WebCore::SessionState::Inactive) {
        errorString = ASCIILiteral("Can't modify a loaded session unless the session is inactive.");
        return;
    }

    session->insertSegment(segmentIndex, WTF::move(segment));
    sessionModified(WTF::move(session));
}
void InspectorReplayAgent::cancelPlayback(ErrorString& errorString)
{
    if (sessionState() == WebCore::SessionState::Capturing) {
        errorString = ASCIILiteral("Can't cancel playback if capture is in progress.");
        return;
    }

    m_page.replayController().cancelPlayback();
}
void InspectorReplayAgent::replayToCompletion(ErrorString& errorString, bool fastReplay)
{
    if (sessionState() == WebCore::SessionState::Capturing) {
        errorString = ASCIILiteral("Can't start replay while capture is in progress.");
        return;
    }

    m_page.replayController().replayToCompletion((fastReplay) ? DispatchSpeed::FastForward : DispatchSpeed::RealTime);
}
void InspectorReplayAgent::pausePlayback(ErrorString& errorString)
{
    if (sessionState() != WebCore::SessionState::Replaying) {
        errorString = ASCIILiteral("Can't pause playback if playback is not in progress.");
        return;
    }

    m_page.replayController().pausePlayback();
}
void InspectorReplayAgent::stopCapturing(ErrorString& errorString)
{
    if (sessionState() != WebCore::SessionState::Capturing) {
        errorString = ASCIILiteral("Can't stop capturing if capture is not in progress.");
        return;
    }

    m_page.replayController().stopCapturing();
}
void InspectorReplayAgent::startCapturing(ErrorString& errorString)
{
    if (sessionState() != WebCore::SessionState::Inactive) {
        errorString = ASCIILiteral("Can't start capturing if the session is already capturing or replaying.");
        return;
    }

    m_page.replayController().startCapturing();
}
void MonolithicApplication::startInternalCore()
{
    if (!_internalInitDone) {
        _internal->init();
        _internalInitDone = true;
    }
    Core *core = Core::instance();
    CoreConnection *connection = Client::coreConnection();
    connect(connection, SIGNAL(connectToInternalCore(InternalPeer*)), core, SLOT(setupInternalClientSession(InternalPeer*)));
    connect(core, SIGNAL(sessionState(QVariant)), connection, SLOT(internalSessionStateReceived(QVariant)));
}
void InspectorReplayAgent::didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*)
{
    m_instrumentingAgents.setInspectorReplayAgent(this);
    ASSERT(sessionState() == WebCore::SessionState::Inactive);

    // Keep track of the (default) session currently loaded by ReplayController,
    // and any segments within the session.
    RefPtr<ReplaySession> session = m_page.replayController().loadedSession();
    m_sessionsMap.add(session->identifier(), session);

    for (auto& segment : *session)
        m_segmentsMap.add(segment->identifier(), segment);
}
void InspectorReplayAgent::switchSession(ErrorString& errorString, Inspector::Protocol::Replay::SessionIdentifier identifier)
{
    ASSERT_ARG(identifier, identifier > 0);

    if (sessionState() != WebCore::SessionState::Inactive) {
        errorString = ASCIILiteral("Can't switch sessions unless the session is neither capturing or replaying.");
        return;
    }

    RefPtr<ReplaySession> session = findSession(errorString, identifier);
    if (!session)
        return;

    m_page.replayController().switchSession(WTF::move(session));
}
void InspectorReplayAgent::didCreateFrontendAndBackend(InspectorFrontendChannel* frontendChannel, InspectorBackendDispatcher* backendDispatcher)
{
    m_frontendDispatcher = std::make_unique<InspectorReplayFrontendDispatcher>(frontendChannel);
    m_backendDispatcher = InspectorReplayBackendDispatcher::create(backendDispatcher, this);

    m_instrumentingAgents->setInspectorReplayAgent(this);
    ASSERT(sessionState() == WebCore::SessionState::Inactive);

    // Keep track of the (default) session currently loaded by ReplayController,
    // and any segments within the session.
    RefPtr<ReplaySession> session = m_page.replayController().loadedSession();
    m_sessionsMap.add(session->identifier(), session);

    for (auto it = session->begin(); it != session->end(); ++it)
        m_segmentsMap.add((*it)->identifier(), *it);
}
void InspectorReplayAgent::replayToPosition(ErrorString& errorString, const InspectorObject& positionObject, bool fastReplay)
{
    ReplayPosition position;
    if (!positionObject.getInteger(ASCIILiteral("segmentOffset"), position.segmentOffset)) {
        errorString = ASCIILiteral("Couldn't decode ReplayPosition segment offset provided to ReplayAgent.replayToPosition.");
        return;
    }

    if (!positionObject.getInteger(ASCIILiteral("inputOffset"), position.inputOffset)) {
        errorString = ASCIILiteral("Couldn't decode ReplayPosition input offset provided to ReplayAgent.replayToPosition.");
        return;
    }

    if (sessionState() == WebCore::SessionState::Capturing) {
        errorString = ASCIILiteral("Can't start replay while capture is in progress.");
        return;
    }

    m_page.replayController().replayToPosition(position, (fastReplay) ? DispatchSpeed::FastForward : DispatchSpeed::RealTime);
}
void InspectorReplayAgent::removeSessionSegment(ErrorString* errorString, Inspector::Protocol::Replay::SessionIdentifier identifier, int segmentIndex)
{
    ASSERT(identifier > 0);
    ASSERT(segmentIndex >= 0);

    RefPtr<ReplaySession> session = findSession(errorString, identifier);

    if (!session)
        return;

    if (static_cast<size_t>(segmentIndex) >= session->size()) {
        *errorString = ASCIILiteral("Invalid segment index.");
        return;
    }

    if (session == m_page.replayController().loadedSession() && sessionState() != WebCore::SessionState::Inactive) {
        *errorString = ASCIILiteral("Can't modify a loaded session unless the session is inactive.");
        return;
    }

    session->removeSegment(segmentIndex);
    sessionModified(session);
}
void InspectorReplayAgent::willDispatchEvent(const Event& event, Frame* frame)
{
    if (sessionState() != WebCore::SessionState::Inactive)
        m_page.replayController().willDispatchEvent(event, frame);
}
void InspectorReplayAgent::frameDetached(Frame& frame)
{
    if (sessionState() != WebCore::SessionState::Inactive)
        m_page.replayController().frameDetached(frame);
}
void InspectorReplayAgent::frameNavigated(DocumentLoader* loader)
{
    if (sessionState() != WebCore::SessionState::Inactive)
        m_page.replayController().frameNavigated(loader);
}