/*
 * Copyright (C) 2020 Igalia S.L. 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.
 */

#include "config.h"
#include "WebXRSession.h"

#if ENABLE(WEBXR)

#include "Document.h"
#include "EventNames.h"
#include "JSWebXRReferenceSpace.h"
#include "WebXRBoundedReferenceSpace.h"
#include "WebXRFrame.h"
#include "WebXRSystem.h"
#include "WebXRView.h"
#include "XRFrameRequestCallback.h"
#include "XRRenderStateInit.h"
#include "XRSessionEvent.h"
#include <wtf/IsoMallocInlines.h>
#include <wtf/RefPtr.h>

namespace WebCore {

WTF_MAKE_ISO_ALLOCATED_IMPL(WebXRSession);

Ref<WebXRSession> WebXRSession::create(Document& document, WebXRSystem& system, XRSessionMode mode, PlatformXR::Device& device, FeatureList&& requestedFeatures)
{
    return adoptRef(*new WebXRSession(document, system, mode, device, WTFMove(requestedFeatures)));
}

WebXRSession::WebXRSession(Document& document, WebXRSystem& system, XRSessionMode mode, PlatformXR::Device& device, FeatureList&& requestedFeatures)
    : ActiveDOMObject(&document)
    , m_inputSources(WebXRInputSourceArray::create(*this))
    , m_xrSystem(system)
    , m_mode(mode)
    , m_device(makeWeakPtr(device))
    , m_requestedFeatures(WTFMove(requestedFeatures))
    , m_activeRenderState(WebXRRenderState::create(mode))
    , m_viewerReferenceSpace(makeUnique<WebXRViewerSpace>(document, *this))
    , m_timeOrigin(MonotonicTime::now())
    , m_views(device.views(mode))
{
    m_device->setTrackingAndRenderingClient(makeWeakPtr(*this));
    m_device->initializeTrackingAndRendering(mode);

    // https://immersive-web.github.io/webxr/#ref-for-dom-xrreferencespacetype-viewer%E2%91%A2
    // Every session MUST support viewer XRReferenceSpaces.
    m_device->initializeReferenceSpace(XRReferenceSpaceType::Viewer);

    suspendIfNeeded();
}

WebXRSession::~WebXRSession()
{
    if (!m_ended && m_device)
        m_device->shutDownTrackingAndRendering();
}

XREnvironmentBlendMode WebXRSession::environmentBlendMode() const
{
    return m_environmentBlendMode;
}

XRInteractionMode WebXRSession::interactionMode() const
{
    return m_interactionMode;
}

XRVisibilityState WebXRSession::visibilityState() const
{
    return m_visibilityState;
}

const WebXRRenderState& WebXRSession::renderState() const
{
    return *m_activeRenderState;
}

const WebXRInputSourceArray& WebXRSession::inputSources() const
{
    return m_inputSources;
}

static bool isImmersive(XRSessionMode mode)
{
    return mode == XRSessionMode::ImmersiveAr || mode == XRSessionMode::ImmersiveVr;
}

// https://immersive-web.github.io/webxr/#dom-xrsession-updaterenderstate
ExceptionOr<void> WebXRSession::updateRenderState(const XRRenderStateInit& newState)
{
    // 1. Let session be this.
    // 2. If session's ended value is true, throw an InvalidStateError and abort these steps.
    if (m_ended)
        return Exception { InvalidStateError };

    // 3. If newState's baseLayer was created with an XRSession other than session,
    //    throw an InvalidStateError and abort these steps.
    if (newState.baseLayer && &newState.baseLayer->session() != this)
        return Exception { InvalidStateError };

    // 4. If newState's inlineVerticalFieldOfView is set and session is an immersive session,
    //    throw an InvalidStateError and abort these steps.
    if (newState.inlineVerticalFieldOfView && isImmersive(m_mode))
        return Exception { InvalidStateError };

    // 5. If none of newState's depthNear, depthFar, inlineVerticalFieldOfView, baseLayer,
    //    layers are set, abort these steps.
    if (!newState.depthNear && !newState.depthFar && !newState.inlineVerticalFieldOfView && !newState.baseLayer && !newState.layers)
        return { };

    // 6. Run update the pending layers state with session and newState.
    // https://immersive-web.github.io/webxr/#update-the-pending-layers-state
    if (newState.layers)
        return Exception { NotSupportedError };

    // 7. Let activeState be session's active render state.
    // 8. If session's pending render state is null, set it to a copy of activeState.
    if (!m_pendingRenderState)
        m_pendingRenderState = m_activeRenderState->clone();

    // 9. If newState's depthNear value is set, set session's pending render state's depthNear to newState's depthNear.
    if (newState.depthNear)
        m_pendingRenderState->setDepthNear(newState.depthNear.value());

    // 10. If newState's depthFar value is set, set session's pending render state's depthFar to newState's depthFar.
    if (newState.depthFar)
        m_pendingRenderState->setDepthFar(newState.depthFar.value());

    // 11. If newState's inlineVerticalFieldOfView is set, set session's pending render state's inlineVerticalFieldOfView
    //     to newState's inlineVerticalFieldOfView.
    if (newState.inlineVerticalFieldOfView)
        m_pendingRenderState->setInlineVerticalFieldOfView(newState.inlineVerticalFieldOfView.value());

    // 12. If newState's baseLayer is set, set session's pending render state's baseLayer to newState's baseLayer.
    if (newState.baseLayer)
        m_pendingRenderState->setBaseLayer(newState.baseLayer.get());

    return { };
}

// https://immersive-web.github.io/webxr/#reference-space-is-supported
bool WebXRSession::referenceSpaceIsSupported(XRReferenceSpaceType type) const
{
    // 1. If type is not contained in session’s XR device's list of enabled features for mode return false.
    if (!m_requestedFeatures.contains(type))
        return false;

    // 2. If type is viewer, return true.
    if (type == XRReferenceSpaceType::Viewer)
        return true;

    bool isImmersiveSession = isImmersive(m_mode);
    if (type == XRReferenceSpaceType::Local || type == XRReferenceSpaceType::LocalFloor) {
        // 3. If type is local or local-floor, and session is an immersive session, return true.
        if (isImmersiveSession)
            return true;

        // 4. If type is local or local-floor, and the XR device supports reporting orientation data, return true.
        if (m_device->supportsOrientationTracking())
            return true;
    }

    // 5. If type is bounded-floor and session is an immersive session, return the result of whether bounded
    //    reference spaces are supported by the XR device.
    // https://immersive-web.github.io/webxr/#bounded-reference-spaces-are-supported
    // TODO: add API to PlatformXR::Device
    if (type == XRReferenceSpaceType::BoundedFloor && isImmersiveSession)
        return true;

    // 6. If type is unbounded, session is an immersive session, and the XR device supports stable tracking
    //    near the user over an unlimited distance, return true.
    // TODO: add API to PlatformXR::Device to check stable tracking over unlimited distance.
    if (type == XRReferenceSpaceType::Unbounded && isImmersiveSession)
        return true;

    // 7. Return false.
    return false;
}

// https://immersive-web.github.io/webxr/#dom-xrsession-requestreferencespace
void WebXRSession::requestReferenceSpace(XRReferenceSpaceType type, RequestReferenceSpacePromise&& promise)
{
    if (!scriptExecutionContext()) {
        promise.reject(Exception { InvalidStateError });
        return;
    }

    // 1. Let promise be a new Promise.
    // 2. Run the following steps in parallel:
    scriptExecutionContext()->postTask([this, weakThis = makeWeakPtr(*this), promise = WTFMove(promise), type](auto&) mutable {
        if (!weakThis)
            return;
        // 2.1. If the result of running reference space is supported for type and session is false, queue a task to reject promise
        // with a NotSupportedError and abort these steps.
        if (!referenceSpaceIsSupported(type)) {
            queueTaskKeepingObjectAlive(*this, TaskSource::WebXR, [promise = WTFMove(promise)]() mutable {
                promise.reject(Exception { NotSupportedError });
            });
            return;
        }
        // 2.2. Set up any platform resources required to track reference spaces of type type.
        m_device->initializeReferenceSpace(type);

        // 2.3. Queue a task to run the following steps:
        queueTaskKeepingObjectAlive(*this, TaskSource::WebXR, [this, type, promise = WTFMove(promise)]() mutable {
            if (!scriptExecutionContext()) {
                promise.reject(Exception { InvalidStateError });
                return;
            }
            auto& document = downcast<Document>(*scriptExecutionContext());
            // 2.4. Create a reference space, referenceSpace, with type and session.
            // https://immersive-web.github.io/webxr/#create-a-reference-space
            RefPtr<WebXRReferenceSpace> referenceSpace;
            if (type == XRReferenceSpaceType::BoundedFloor)
                referenceSpace = WebXRBoundedReferenceSpace::create(document, Ref { *this }, type);
            else
                referenceSpace = WebXRReferenceSpace::create(document, Ref { *this }, type);

            // 2.5. Resolve promise with referenceSpace.
            promise.resolve(referenceSpace.releaseNonNull());
        });
    });
}

// https://immersive-web.github.io/webxr/#dom-xrsession-requestanimationframe
unsigned WebXRSession::requestAnimationFrame(Ref<XRFrameRequestCallback>&& callback)
{
    // Ignore any new frame requests once the session is ended.
    if (m_ended)
        return 0;

    // 1. Let session be the target XRSession object.
    // 2. Increment session's animation frame callback identifier by one.
    unsigned newId = m_nextCallbackId++;

    // 3. Append callback to session's list of animation frame callbacks, associated with session's
    // animation frame callback identifier's current value.
    callback->setCallbackId(newId);
    m_callbacks.append(WTFMove(callback));

    // Script can add multiple requestAnimationFrame callbacks but we should only request a device frame once.
    // When requestAnimationFrame is called during processing RAF callbacks the next requestFrame is scheduled
    // at the end of WebXRSession::onFrame() to prevent requesting a new frame before the current one has ended.
    if (m_callbacks.size() == 1)
        requestFrame();

    // 4. Return session's animation frame callback identifier's current value.
    return newId;
}

// https://immersive-web.github.io/webxr/#dom-xrsession-cancelanimationframe
void WebXRSession::cancelAnimationFrame(unsigned callbackId)
{
    // 1. Let session be the target XRSession object.
    // 2. Find the entry in session's list of animation frame callbacks or session's list of
    //    currently running animation frame callbacks that is associated with the value handle.
    // 3. If there is such an entry, set its cancelled boolean to true and remove it from
    //    session's list of animation frame callbacks.
    size_t position = m_callbacks.findMatching([callbackId] (auto& item) {
        return item->callbackId() == callbackId;
    });

    if (position != notFound) {
        m_callbacks[position]->setFiredOrCancelled();
        return;
    }
}

// https://immersive-web.github.io/webxr/#native-webgl-framebuffer-resolution
IntSize WebXRSession::nativeWebGLFramebufferResolution() const
{
    if (m_mode == XRSessionMode::Inline) {
        // FIXME: replace the conditional by ASSERTs once we properly initialize the outputCanvas.
        return m_activeRenderState && m_activeRenderState->outputCanvas() ? m_activeRenderState->outputCanvas()->size() : IntSize(1, 1);
    }

    return recommendedWebGLFramebufferResolution();
}

// https://immersive-web.github.io/webxr/#recommended-webgl-framebuffer-resolution
IntSize WebXRSession::recommendedWebGLFramebufferResolution() const
{
    ASSERT(m_device);
    return m_device->recommendedResolution(m_mode);
}

// https://immersive-web.github.io/webxr/#view-viewport-modifiable
bool WebXRSession::supportsViewportScaling() const
{
    ASSERT(m_device);
    // Only immersive sessions support viewport scaling.
    return m_mode == XRSessionMode::ImmersiveVr && m_device->supportsViewportScaling();
}

bool WebXRSession::isPositionEmulated() const
{
    return m_frameData.isPositionEmulated || !m_frameData.isPositionValid;
}

// https://immersive-web.github.io/webxr/#shut-down-the-session
void WebXRSession::shutdown(InitiatedBySystem initiatedBySystem)
{
    Ref protectedThis { *this };

    if (m_ended) {
        // This method was called earlier with initiatedBySystem=No when the
        // session termination was requested manually via XRSession.end(). When
        // the system has completed the shutdown, this method is now called again
        // with initiatedBySystem=Yes to do the final cleanup.
        if (initiatedBySystem == InitiatedBySystem::Yes)
            didCompleteShutdown();
        return;
    }

    // 1. Let session be the target XRSession object.
    // 2. Set session's ended value to true.
    m_ended = true;

    // 3. If the active immersive session is equal to session, set the active immersive session to null.
    // 4. Remove session from the list of inline sessions.
    m_xrSystem.sessionEnded(*this);

    m_inputSources->clear();

    if (initiatedBySystem == InitiatedBySystem::Yes) {
        // If we get here, the session termination was triggered by the system rather than
        // via XRSession.end(). Since the system has completed the session shutdown, we can
        // immediately do the final cleanup.
        didCompleteShutdown();
        return;
    }

    // TODO: complete the implementation
    // 5. Reject any outstanding promises returned by session with an InvalidStateError, except for any promises returned by end().
    // 6. If no other features of the user agent are actively using them, perform the necessary platform-specific steps to shut down the device's tracking and rendering capabilities. This MUST include:
    //  6.1. Releasing exclusive access to the XR device if session is an immersive session.
    //  6.2. Deallocating any graphics resources acquired by session for presentation to the XR device.
    //  6.3. Putting the XR device in a state such that a different source may be able to initiate a session with the same device if session is an immersive session.
    if (m_device)
        m_device->shutDownTrackingAndRendering();

    // If device will not report shutdown completion via the TrackingAndRenderingClient,
    // complete the shutdown cleanup here.
    if (!m_device || !m_device->supportsSessionShutdownNotification())
        didCompleteShutdown();
}

void WebXRSession::didCompleteShutdown()
{
    if (m_device)
        m_device->setTrackingAndRenderingClient(nullptr);

    // Resolve end promise from XRSession::end()
    if (m_endPromise) {
        m_endPromise->resolve();
        m_endPromise = std::nullopt;
    }

    // From https://immersive-web.github.io/webxr/#shut-down-the-session
    // 7. Queue a task that fires an XRSessionEvent named end on session.
    auto event = XRSessionEvent::create(eventNames().endEvent, { makeRefPtr(*this) });
    queueTaskToDispatchEvent(*this, TaskSource::WebXR, WTFMove(event));
}

// https://immersive-web.github.io/webxr/#dom-xrsession-end
ExceptionOr<void> WebXRSession::end(EndPromise&& promise)
{
    // The shutdown() call below might remove the sole reference to session
    // that could exist (the XRSystem owns the sessions) so let's protect this.
    Ref protectedThis { *this };

    if (m_ended)
        return Exception { InvalidStateError, "Cannot end a session more than once"_s };

    ASSERT(!m_endPromise);
    m_endPromise = WTFMove(promise);

    // 1. Let promise be a new Promise.
    // 2. Shut down the target XRSession object.
    shutdown(InitiatedBySystem::No);

    // 3. Queue a task to perform the following steps:
    // 3.1 Wait until any platform-specific steps related to shutting down the session have completed.
    // 3.2 Resolve promise.
    // 4. Return promise.
    return { };
}

const char* WebXRSession::activeDOMObjectName() const
{
    return "XRSession";
}

void WebXRSession::stop()
{
}

void WebXRSession::sessionDidInitializeInputSources(Vector<PlatformXR::Device::FrameData::InputSource>&& inputSources)
{
    // https://immersive-web.github.io/webxr/#dom-xrsystem-requestsession
    // 5.4.11 Queue a task to perform the following steps: NOTE: These steps ensure that initial inputsourceschange
    // events occur after the initial session is resolved.
    queueTaskKeepingObjectAlive(*this, TaskSource::WebXR, [this, inputSources = WTFMove(inputSources)]() mutable {
        //  1. Set session's promise resolved flag to true.
        m_inputInitialized = true;
        //  2. Let sources be any existing input sources attached to session.
        //  3. If sources is non-empty, perform the following steps:
        if (!inputSources.isEmpty()) {
            auto timestamp = (MonotonicTime::now() - m_timeOrigin).milliseconds();
            //  3.1. Set session's list of active XR input sources to sources.
            //  3.2. Fire an XRInputSourcesChangeEvent named inputsourceschange on session with added set to sources.
            //  Note: 3.1 and 3.2 steps are handled inside the update() call.
            m_inputSources->update(timestamp, inputSources);
        }
    });
}

void WebXRSession::sessionDidEnd()
{
    // This can be called as a result of finishing the shutdown initiated
    // from XRSession::end(), or session termination triggered by the system.
    shutdown(InitiatedBySystem::Yes);
}

void WebXRSession::applyPendingRenderState()
{
    // https: //immersive-web.github.io/webxr/#apply-the-pending-render-state
    // 1. Let activeState be session’s active render state.
    // 2. Let newState be session’s pending render state.
    // 3. Set session’s pending render state to null.
    auto newState = m_pendingRenderState;
    ASSERT(newState);

    // 4. Let oldBaseLayer be activeState’s baseLayer.
    // 5. Let oldLayers be activeState’s layers.
    // FIXME: those are only needed for step 6.2.

    // 6.1 Set activeState to newState.
    m_activeRenderState = newState;

    // 6.2 If oldBaseLayer is not equal to activeState’s baseLayer, oldLayers is not equal to activeState’s layers, or the dimensions of any of the layers have changed, update the viewports for session.
    // FIXME: implement this.

    // 6.3 If activeState’s inlineVerticalFieldOfView is less than session’s minimum inline field of view set activeState’s inlineVerticalFieldOfView to session’s minimum inline field of view.
    if (m_activeRenderState->inlineVerticalFieldOfView() < m_minimumInlineFOV)
        m_activeRenderState->setInlineVerticalFieldOfView(m_minimumInlineFOV);

    // 6.4 If activeState’s inlineVerticalFieldOfView is greater than session’s maximum inline field of view set activeState’s inlineVerticalFieldOfView to session’s maximum inline field of view.
    if (m_activeRenderState->inlineVerticalFieldOfView() > m_maximumInlineFOV)
        m_activeRenderState->setInlineVerticalFieldOfView(m_maximumInlineFOV);

    // 6.5 If activeState’s depthNear is less than session’s minimum near clip plane set activeState’s depthNear to session’s minimum near clip plane.
    if (m_activeRenderState->depthNear() < m_minimumNearClipPlane)
        m_activeRenderState->setDepthNear(m_minimumNearClipPlane);

    // 6.6 If activeState’s depthFar is greater than session’s maximum far clip plane set activeState’s depthFar to session’s maximum far clip plane.
    if (m_activeRenderState->depthFar() > m_maximumFarClipPlane)
        m_activeRenderState->setDepthFar(m_maximumFarClipPlane);

    // 6.7 Let baseLayer be activeState’s baseLayer.
    auto baseLayer = m_activeRenderState->baseLayer();

    // 6.8 Set activeState’s composition enabled and output canvas as follows:
    if (m_mode == XRSessionMode::Inline && is<WebXRWebGLLayer>(baseLayer) && !baseLayer->isCompositionEnabled()) {
        m_activeRenderState->setCompositionEnabled(false);
        m_activeRenderState->setOutputCanvas(baseLayer->canvas());
    } else {
        m_activeRenderState->setCompositionEnabled(true);
        m_activeRenderState->setOutputCanvas(nullptr);
    }
}

// https://immersive-web.github.io/webxr/#should-be-rendered
bool WebXRSession::frameShouldBeRendered() const
{
    if (!m_activeRenderState->baseLayer())
        return false;
    if (m_mode == XRSessionMode::Inline && !m_activeRenderState->outputCanvas())
        return false;
    return true;
}

void WebXRSession::requestFrame()
{
    m_device->requestFrame([this, protectedThis = Ref { *this }](auto&& frameData) {
        onFrame(WTFMove(frameData));
    });
}

void WebXRSession::onFrame(PlatformXR::Device::FrameData&& frameData)
{
    ASSERT(isMainThread());

    if (m_ended)
        return;

    // Queue a task to perform the following steps.
    queueTaskKeepingObjectAlive(*this, TaskSource::WebXR, [this, frameData = WTFMove(frameData)]() mutable {
        if (m_ended)
            return;

        m_frameData = WTFMove(frameData);
        //  1.Let now be the current high resolution time.
        auto now = (MonotonicTime::now() - m_timeOrigin).milliseconds();

        auto frame = WebXRFrame::create(*this, WebXRFrame::IsAnimationFrame::Yes);
        //  2.Let frame be session’s animation frame.
        //  3.Set frame’s time to frameTime.
        frame->setTime(static_cast<DOMHighResTimeStamp>(m_frameData.predictedDisplayTime));

        // 4. For each view in list of views, set view’s viewport modifiable flag to true.
        // 5. If the active flag of any view in the list of views has changed since the last XR animation frame, update the viewports.
        // FIXME: implement.

        // FIXME: I moved step 7 before 6 because of https://github.com/immersive-web/webxr/issues/1164
        // 7.If session’s pending render state is not null, apply the pending render state.
        if (m_pendingRenderState)
            applyPendingRenderState();

        // 6. If the frame should be rendered for session:
        if (frameShouldBeRendered() && m_frameData.shouldRender) {
            // Prepare all layers for render
            if (m_mode == XRSessionMode::ImmersiveVr && m_activeRenderState->baseLayer())
                m_activeRenderState->baseLayer()->startFrame(m_frameData);

            // 6.1.Set session’s list of currently running animation frame callbacks to be session’s list of animation frame callbacks.
            // 6.2.Set session’s list of animation frame callbacks to the empty list.
            auto callbacks = m_callbacks;

            // 6.3.Set frame’s active boolean to true.
            frame->setActive(true);

            // 6.4.Apply frame updates for frame.
            if (m_inputInitialized)
                m_inputSources->update(now, m_frameData.inputSources);

            // 6.5.For each entry in session’s list of currently running animation frame callbacks, in order:
            for (auto& callback : callbacks) {
                //  6.6.If the entry’s cancelled boolean is true, continue to the next entry.
                if (callback->isFiredOrCancelled())
                    continue;
                callback->setFiredOrCancelled();
                //  6.7.Invoke the Web IDL callback function for entry, passing now and frame as the arguments
                callback->handleEvent(now, frame.get());

                //  6.8.If an exception is thrown, report the exception.
            }
            // 6.9.Set session’s list of currently running animation frame callbacks to the empty list.
            m_callbacks.removeAllMatching([](auto& callback) {
                return callback->isFiredOrCancelled();
            });

            // 6.10.Set frame’s active boolean to false.
            // If the session is ended, m_animationFrame->setActive false is set in shutdown().
            frame->setActive(false);


            // Submit current frame layers to the device.
            Vector<PlatformXR::Device::Layer> frameLayers;
            if (m_mode == XRSessionMode::ImmersiveVr && m_activeRenderState->baseLayer())
                frameLayers.append(m_activeRenderState->baseLayer()->endFrame());

            m_device->submitFrame(WTFMove(frameLayers));
        }

        if (!m_callbacks.isEmpty())
            requestFrame();

    });
}

// https://immersive-web.github.io/webxr/#poses-may-be-reported
bool WebXRSession::posesCanBeReported(const Document& document) const
{
    // 1. If session’s relevant global object is not the current global object, return false.
    auto* sessionDocument = downcast<Document>(scriptExecutionContext());
    if (!sessionDocument || sessionDocument->domWindow() != document.domWindow())
        return false;

    // 2. If session's visibilityState in not "visible", return false.
    if (m_visibilityState != XRVisibilityState::Visible)
        return false;

    // 5. Determine if the pose data can be returned as follows:
    // The procedure in the specs tries to ensure that we apply measures to
    // prevent fingerprintint in pose data and return false in case we don't.
    // We're going to apply them so let's just return true.
    return true;
}

} // namespace WebCore

#endif // ENABLE(WEBXR)
