| Index: device/vr/vr_device_manager.cc
|
| diff --git a/device/vr/vr_device_manager.cc b/device/vr/vr_device_manager.cc
|
| index b774ad248b762c7018e36f3040eded2d48ba6e7d..6164efa5872dc403646fba36e60e760828d5e2db 100644
|
| --- a/device/vr/vr_device_manager.cc
|
| +++ b/device/vr/vr_device_manager.cc
|
| @@ -22,7 +22,11 @@ VRDeviceManager* g_vr_device_manager = nullptr;
|
| }
|
|
|
| VRDeviceManager::VRDeviceManager()
|
| - : vr_initialized_(false), keep_alive_(false), has_scheduled_poll_(false) {
|
| + : vr_initialized_(false),
|
| + presenting_service_(nullptr),
|
| + presenting_device_(nullptr),
|
| + keep_alive_(false),
|
| + has_scheduled_poll_(false) {
|
| // Register VRDeviceProviders for the current platform
|
| #if defined(OS_ANDROID)
|
| RegisterProvider(base::WrapUnique(new GvrDeviceProvider()));
|
| @@ -30,7 +34,11 @@ VRDeviceManager::VRDeviceManager()
|
| }
|
|
|
| VRDeviceManager::VRDeviceManager(std::unique_ptr<VRDeviceProvider> provider)
|
| - : vr_initialized_(false), keep_alive_(true), has_scheduled_poll_(false) {
|
| + : vr_initialized_(false),
|
| + presenting_service_(nullptr),
|
| + presenting_device_(nullptr),
|
| + keep_alive_(true),
|
| + has_scheduled_poll_(false) {
|
| thread_checker_.DetachFromThread();
|
| RegisterProvider(std::move(provider));
|
| SetInstance(this);
|
| @@ -48,6 +56,26 @@ VRDeviceManager* VRDeviceManager::GetInstance() {
|
| 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
|
| @@ -72,6 +100,13 @@ void VRDeviceManager::RemoveService(VRServiceImpl* service) {
|
| 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;
|
| @@ -127,6 +162,90 @@ void VRDeviceManager::OnDeviceChanged(VRDisplayPtr device) {
|
| service->client()->OnDisplayChanged(device.Clone());
|
| }
|
|
|
| +bool VRDeviceManager::RequestPresent(VRServiceImpl* service,
|
| + unsigned int index) {
|
| + // Is anything presenting currently?
|
| + if (presenting_service_) {
|
| + // Should never have a presenting service without a presenting device.
|
| + DCHECK(presenting_device_);
|
| +
|
| + // Fail if the currently presenting service is not the one making the
|
| + // request.
|
| + if (presenting_service_ != service)
|
| + return false;
|
| +
|
| + // If we are switching presentation from the currently presenting service to
|
| + // a new device stop presening to the previous one.
|
| + if (presenting_device_->id() != index) {
|
| + // Tell the device to stop presenting.
|
| + presenting_device_->ExitPresent();
|
| +
|
| + // Only the presenting service needs to be notified that presentation is
|
| + // ending on the previous device.
|
| + presenting_service_->client()->OnExitPresent(presenting_device_->id());
|
| + presenting_device_ = nullptr;
|
| + }
|
| +
|
| + presenting_service_ = nullptr;
|
| + }
|
| +
|
| + VRDevice* requested_device = GetDevice(index);
|
| + // Can't present to a device that doesn't exist.
|
| + if (!requested_device)
|
| + return false;
|
| +
|
| + // Attempt to begin presenting to this device. This could fail for any number
|
| + // of device-specific reasons.
|
| + if (!requested_device->RequestPresent())
|
| + return false;
|
| +
|
| + // Successfully began presenting!
|
| + presenting_service_ = service;
|
| + presenting_device_ = requested_device;
|
| +
|
| + return true;
|
| +}
|
| +
|
| +void VRDeviceManager::ExitPresent(VRServiceImpl* service, unsigned int index) {
|
| + // Don't allow services other than the currently presenting one to exit
|
| + // presentation.
|
| + if (presenting_service_ != service)
|
| + return;
|
| +
|
| + // Should never have a presenting service without a presenting device.
|
| + DCHECK(presenting_device_);
|
| +
|
| + // Fail if the specified device is not currently presenting.
|
| + if (presenting_device_->id() != index)
|
| + return;
|
| +
|
| + // Tell the device to stop presenting.
|
| + presenting_device_->ExitPresent();
|
| + presenting_service_->client()->OnExitPresent(index);
|
| +
|
| + // Clear the presenting service and device.
|
| + presenting_service_ = nullptr;
|
| + presenting_device_ = nullptr;
|
| +}
|
| +
|
| +void VRDeviceManager::SubmitFrame(VRServiceImpl* service,
|
| + unsigned int index,
|
| + VRPosePtr pose) {
|
| + // Don't allow services other than the currently presenting one to submit any
|
| + // frames.
|
| + if (presenting_service_ != service)
|
| + return;
|
| +
|
| + // Should never have a presenting service without a presenting device.
|
| + DCHECK(presenting_device_);
|
| +
|
| + // Don't submit frames to devices other than the currently presenting one.
|
| + if (presenting_device_->id() != index)
|
| + return;
|
| +
|
| + presenting_device_->SubmitFrame(std::move(pose));
|
| +}
|
| +
|
| void VRDeviceManager::InitializeProviders() {
|
| if (vr_initialized_) {
|
| return;
|
|
|