Bug 1254776 - VRDisplay.requestPresent must succeed only when called from a user-gesture or trusted event,r=qdot

MozReview-Commit-ID: 4BugtHPRekG
This commit is contained in:
Kearwood Gilbert 2017-03-07 16:04:12 -08:00
parent 5728cb6576
commit 407247f33d
5 changed files with 24 additions and 4 deletions

View File

@ -12,7 +12,9 @@
#include "mozilla/dom/VRDisplay.h"
#include "mozilla/HoldDropJSObjects.h"
#include "mozilla/dom/VRDisplayBinding.h"
#include "mozilla/EventStateManager.h"
#include "Navigator.h"
#include "gfxPrefs.h"
#include "gfxVR.h"
#include "VRDisplayClient.h"
#include "VRManagerChild.h"
@ -450,7 +452,9 @@ VRDisplay::ResetPose()
}
already_AddRefed<Promise>
VRDisplay::RequestPresent(const nsTArray<VRLayer>& aLayers, ErrorResult& aRv)
VRDisplay::RequestPresent(const nsTArray<VRLayer>& aLayers,
CallerType aCallerType,
ErrorResult& aRv)
{
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
if (!global) {
@ -464,7 +468,15 @@ VRDisplay::RequestPresent(const nsTArray<VRLayer>& aLayers, ErrorResult& aRv)
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
NS_ENSURE_TRUE(obs, nullptr);
if (!IsPresenting() && IsAnyPresenting()) {
if (!EventStateManager::IsHandlingUserInput() &&
aCallerType != CallerType::System &&
gfxPrefs::VRRequireGesture()) {
// The WebVR API states that if called outside of a user gesture, the
// promise must be rejected. We allow VR presentations to start within
// trusted events such as vrdisplayactivate, which triggers in response to
// HMD proximity sensors and when navigating within a VR presentation.
promise->MaybeRejectWithUndefined();
} else if (!IsPresenting() && IsAnyPresenting()) {
// Only one presentation allowed per VRDisplay
// on a first-come-first-serve basis.
// If this Javascript context is presenting, then we can replace our

View File

@ -324,7 +324,9 @@ public:
mDepthFar = aDepthFar;
}
already_AddRefed<Promise> RequestPresent(const nsTArray<VRLayer>& aLayers, ErrorResult& aRv);
already_AddRefed<Promise> RequestPresent(const nsTArray<VRLayer>& aLayers,
CallerType aCallerType,
ErrorResult& aRv);
already_AddRefed<Promise> ExitPresent(ErrorResult& aRv);
void GetLayers(nsTArray<VRLayer>& result);
void SubmitFrame();

View File

@ -264,7 +264,7 @@ interface VRDisplay : EventTarget {
* Begin presenting to the VRDisplay. Must be called in response to a user gesture.
* Repeat calls while already presenting will update the VRLayers being displayed.
*/
[Throws] Promise<void> requestPresent(sequence<VRLayer> layers);
[Throws, NeedsCallerType] Promise<void> requestPresent(sequence<VRLayer> layers);
/**
* Stops presenting to the VRDisplay.

View File

@ -325,6 +325,7 @@ private:
DECL_GFX_PREF(Once, "dom.vr.openvr.enabled", VROpenVREnabled, bool, false);
DECL_GFX_PREF(Once, "dom.vr.osvr.enabled", VROSVREnabled, bool, false);
DECL_GFX_PREF(Live, "dom.vr.poseprediction.enabled", VRPosePredictionEnabled, bool, false);
DECL_GFX_PREF(Once, "dom.vr.require-gesture", VRRequireGesture, bool, true);
DECL_GFX_PREF(Live, "dom.vr.puppet.enabled", VRPuppetEnabled, bool, false);
DECL_GFX_PREF(Live, "dom.w3c_pointer_events.enabled", PointerEventsEnabled, bool, false);
DECL_GFX_PREF(Live, "dom.w3c_touch_events.enabled", TouchEventsEnabled, int32_t, 0);

View File

@ -5033,6 +5033,11 @@ pref("dom.vr.openvr.enabled", false);
// Oculus Rift on SDK 0.8 or greater. It is disabled by default for now due to
// frame uniformity issues with e10s.
pref("dom.vr.poseprediction.enabled", false);
// Starting VR presentation is only allowed within a user gesture or event such
// as VRDisplayActivate triggered by the system. dom.vr.require-gesture allows
// this requirement to be disabled for special cases such as during automated
// tests or in a headless kiosk system.
pref("dom.vr.require-gesture", true);
// path to openvr DLL
pref("gfx.vr.openvr-runtime", "");
// path to OSVR DLLs