/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef mozilla_dom_XRsystem_h_ #define mozilla_dom_XRsystem_h_ #include "mozilla/DOMEventTargetHelper.h" #include "mozilla/dom/WebXRBinding.h" #include "nsContentPermissionHelper.h" #include "VRManagerChild.h" #include "gfxVR.h" namespace mozilla::dom { struct XRSessionCreationOptions; class IsSessionSupportedRequest { public: IsSessionSupportedRequest(XRSessionMode aSessionMode, Promise* aPromise) : mPromise(aPromise), mSessionMode(aSessionMode) {} NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(IsSessionSupportedRequest) NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(IsSessionSupportedRequest) RefPtr mPromise; XRSessionMode GetSessionMode() const; private: ~IsSessionSupportedRequest() = default; XRSessionMode mSessionMode; }; class RequestSessionRequest { public: RequestSessionRequest( XRSessionMode aSessionMode, uint32_t aPresentationGroup, Promise* aPromise, const nsTArray& aRequiredReferenceSpaceTypes, const nsTArray& aOptionalReferenceSpaceTypes); NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(RequestSessionRequest) NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(RequestSessionRequest) RefPtr mPromise; bool ResolveSupport( const gfx::VRDisplayClient* aDisplay, nsTArray& aEnabledReferenceSpaceTypes) const; bool IsImmersive() const; bool WantsHardware() const; bool NeedsHardware() const; XRSessionMode GetSessionMode() const; uint32_t GetPresentationGroup() const; private: ~RequestSessionRequest() = default; XRSessionMode mSessionMode; uint32_t mPresentationGroup; nsTArray mRequiredReferenceSpaceTypes; nsTArray mOptionalReferenceSpaceTypes; }; class XRRequestSessionPermissionRequest final : public ContentPermissionRequestBase { public: NS_DECL_ISUPPORTS_INHERITED NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(XRRequestSessionPermissionRequest, ContentPermissionRequestBase) // nsIContentPermissionRequest NS_IMETHOD Cancel(void) override; NS_IMETHOD Allow(JS::Handle choices) override; using AllowCallback = std::function; using AllowAnySiteCallback = std::function; using CancelCallback = std::function; static already_AddRefed Create( nsPIDOMWindowInner* aWindow, AllowCallback&& aAllowCallback, AllowAnySiteCallback&& aAllowAnySiteCallback, CancelCallback&& aCancelCallback); using AutoGrantDelayPromise = MozPromise; RefPtr MaybeDelayAutomaticGrants(); private: XRRequestSessionPermissionRequest( nsPIDOMWindowInner* aWindow, nsIPrincipal* aNodePrincipal, AllowCallback&& aAllowCallback, AllowAnySiteCallback&& aAllowAnySiteCallback, CancelCallback&& aCancelCallback); ~XRRequestSessionPermissionRequest(); AllowCallback mAllowCallback; AllowAnySiteCallback mAllowAnySiteCallback; CancelCallback mCancelCallback; nsTArray mPermissionRequests; bool mCallbackCalled; }; class XRSystem final : public DOMEventTargetHelper, public gfx::VRManagerEventObserver { public: NS_DECL_ISUPPORTS_INHERITED NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(XRSystem, DOMEventTargetHelper) void Shutdown(); void SessionEnded(XRSession* aSession); bool FeaturePolicyBlocked() const; bool OnXRPermissionRequestAllow(); void OnXRPermissionRequestCancel(); bool HasActiveImmersiveSession() const; // WebIDL Boilerplate static already_AddRefed Create(nsPIDOMWindowInner* aWindow); JSObject* WrapObject(JSContext* aCx, JS::Handle aGivenProto) override; // WebIDL Members already_AddRefed IsSessionSupported(XRSessionMode aMode, ErrorResult& aRv); already_AddRefed RequestSession(JSContext* aCx, XRSessionMode aMode, const XRSessionInit& aOptions, CallerType aCallerType, ErrorResult& aRv); IMPL_EVENT_HANDLER(devicechange); // VRManagerEventObserver interface void NotifyVRDisplayMounted(uint32_t aDisplayID) override; void NotifyVRDisplayUnmounted(uint32_t aDisplayID) override; void NotifyVRDisplayConnect(uint32_t aDisplayID) override; void NotifyVRDisplayDisconnect(uint32_t aDisplayID) override; void NotifyVRDisplayPresentChange(uint32_t aDisplayID) override; void NotifyPresentationGenerationChanged(uint32_t aDisplayID) override; void NotifyEnumerationCompleted() override; void NotifyDetectRuntimesCompleted() override; bool GetStopActivityStatus() const override; private: explicit XRSystem(nsPIDOMWindowInner* aWindow); virtual ~XRSystem() = default; void ResolveIsSessionSupportedRequests(); void ProcessSessionRequestsWaitingForRuntimeDetection(); bool CancelHardwareRequest(RequestSessionRequest* aRequest); void QueueSessionRequestWithEnumeration(RequestSessionRequest* aRequest); void QueueSessionRequestWithoutEnumeration(RequestSessionRequest* aRequest); void ResolveSessionRequestsWithoutHardware(); void ResolveSessionRequests( nsTArray>& aRequests, const nsTArray>& aDisplays); bool mShuttingDown; // https://immersive-web.github.io/webxr/#pending-immersive-session bool mPendingImmersiveSession; // https://immersive-web.github.io/webxr/#active-immersive-session RefPtr mActiveImmersiveSession; // https://immersive-web.github.io/webxr/#list-of-inline-sessions nsTArray> mInlineSessions; bool mEnumerationInFlight; nsTArray> mIsSessionSupportedRequests; nsTArray> mRequestSessionRequestsWithoutHardware; nsTArray> mRequestSessionRequestsWaitingForRuntimeDetection; nsTArray> mRequestSessionRequestsWaitingForEnumeration; }; } // namespace mozilla::dom #endif // mozilla_dom_XRsystem_h_