Prevent pages other than the one presenting from reading or reseting device pose.
diff --git a/device/vr/vr_device_manager.cc b/device/vr/vr_device_manager.cc
index a67153c..0b16cf6 100644
--- a/device/vr/vr_device_manager.cc
+++ b/device/vr/vr_device_manager.cc
@@ -75,6 +75,26 @@
return g_vr_device_manager;
}
+// Returns the requested device with the requested id if the specified service
+// is allowed to access it.
+VRDevice* VRDeviceManager::GetAllowedDevice(
+ VRServiceImpl* service, unsigned int index) {
+ VRDeviceManager* device_manager = GetInstance();
+
+ // If another service is presenting to the requested device don't allow other
+ // services to access it. That could potentially allow them to spy on
+ // where the user is looking on another page, spam another application with
+ // pose resets, etc.
+ if (device_manager->presenting_service_ &&
+ device_manager->presenting_service_ != service) {
+ if (device_manager->presenting_device_ &&
+ device_manager->presenting_device_->id() == index)
+ return nullptr;
+ }
+
+ return device_manager->GetDevice(index);
+}
+
void VRDeviceManager::SetInstance(VRDeviceManager* instance) {
// Unit tests can create multiple instances but only one should exist at any
// given time so g_vr_device_manager should only go from nullptr to
@@ -101,6 +121,13 @@
services_.erase(std::remove(services_.begin(), services_.end(), service),
services_.end());
+ if (service == presenting_service_) {
+ presenting_device_->ExitPresent();
+
+ presenting_service_ = nullptr;
+ presenting_device_ = nullptr;
+ }
+
if (services_.empty() && !keep_alive_) {
// Delete the device manager when it has no active connections.
// delete g_vr_device_manager;
@@ -205,7 +232,7 @@
// Tell the device to stop presenting.
presenting_device_->ExitPresent();
- presenting_service_->client()->OnExitPresent(presenting_device_->id());
+ presenting_service_->client()->OnExitPresent(index);
// Clear the presenting service and device.
presenting_service_ = nullptr;
diff --git a/device/vr/vr_device_manager.h b/device/vr/vr_device_manager.h
index f269fdb..cc3b5b0a 100644
--- a/device/vr/vr_device_manager.h
+++ b/device/vr/vr_device_manager.h
@@ -32,13 +32,15 @@
// Returns the VRDeviceManager singleton.
static VRDeviceManager* GetInstance();
+ // Gets a VRDevice instance if the specified service is allowed to access it.
+ static VRDevice* GetAllowedDevice(VRServiceImpl* service, unsigned int index);
+
// Adds a listener for device manager events. VRDeviceManager does not own
// this object.
void AddService(VRServiceImpl* service);
void RemoveService(VRServiceImpl* service);
DEVICE_VR_EXPORT mojo::Array<VRDisplayPtr> GetVRDevices();
- DEVICE_VR_EXPORT VRDevice* GetDevice(unsigned int index);
// Manage presentation to only allow a single service and device at a time.
bool RequestPresent(VRServiceImpl* service, unsigned int index);
@@ -65,6 +67,8 @@
DEVICE_VR_EXPORT explicit VRDeviceManager(
std::unique_ptr<VRDeviceProvider> provider);
+ VRDevice* GetDevice(unsigned int index);
+
static void SetInstance(VRDeviceManager* service);
static bool HasInstance();
diff --git a/device/vr/vr_service.mojom b/device/vr/vr_service.mojom
index 945d59c..1ef3d9e 100644
--- a/device/vr/vr_service.mojom
+++ b/device/vr/vr_service.mojom
@@ -74,7 +74,7 @@
GetDisplays() => (array<VRDisplay> displays);
[Sync]
- GetPose(uint32 index) => (VRPose pose);
+ GetPose(uint32 index) => (VRPose? pose);
ResetPose(uint32 index);
RequestPresent(uint32 index) => (bool success);
diff --git a/device/vr/vr_service_impl.cc b/device/vr/vr_service_impl.cc
index 3b70aeb..6881a60 100644
--- a/device/vr/vr_service_impl.cc
+++ b/device/vr/vr_service_impl.cc
@@ -48,8 +48,7 @@
}
void VRServiceImpl::GetPose(uint32_t index, const GetPoseCallback& callback) {
- VRDeviceManager* device_manager = VRDeviceManager::GetInstance();
- VRDevice* device = device_manager->GetDevice(index);
+ VRDevice* device = VRDeviceManager::GetAllowedDevice(this, index);
if (device) {
callback.Run(device->GetPose());
@@ -59,8 +58,7 @@
}
void VRServiceImpl::ResetPose(uint32_t index) {
- VRDeviceManager* device_manager = VRDeviceManager::GetInstance();
- VRDevice* device = device_manager->GetDevice(index);
+ VRDevice* device = VRDeviceManager::GetAllowedDevice(this, index);
if (device)
device->ResetPose();
}
@@ -84,8 +82,7 @@
void VRServiceImpl::UpdateLayerBounds(uint32_t index,
VRLayerBoundsPtr leftBounds,
VRLayerBoundsPtr rightBounds) {
- VRDeviceManager* device_manager = VRDeviceManager::GetInstance();
- VRDevice* device = device_manager->GetDevice(index);
+ VRDevice* device = VRDeviceManager::GetAllowedDevice(this, index);
if (device)
device->UpdateLayerBounds(std::move(leftBounds), std::move(rightBounds));
}