Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(254)

Side by Side Diff: device/vr/vr_device_manager.cc

Issue 2494733002: Reland of mojo VR interface simpified. (Closed)
Patch Set: Fix Werror Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « device/vr/vr_device_manager.h ('k') | device/vr/vr_device_manager_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "device/vr/vr_device_manager.h" 5 #include "device/vr/vr_device_manager.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/memory/ptr_util.h" 10 #include "base/memory/ptr_util.h"
11 #include "base/memory/singleton.h" 11 #include "base/memory/singleton.h"
12 #include "build/build_config.h" 12 #include "build/build_config.h"
13 13
14 #if defined(OS_ANDROID) 14 #if defined(OS_ANDROID)
15 #include "device/vr/android/gvr/gvr_device_provider.h" 15 #include "device/vr/android/gvr/gvr_device_provider.h"
16 #endif 16 #endif
17 17
18 namespace device { 18 namespace device {
19 19
20 namespace { 20 namespace {
21 VRDeviceManager* g_vr_device_manager = nullptr; 21 VRDeviceManager* g_vr_device_manager = nullptr;
22 } 22 }
23 23
24 VRDeviceManager::VRDeviceManager() 24 VRDeviceManager::VRDeviceManager()
25 : vr_initialized_(false), 25 : vr_initialized_(false),
26 presenting_service_(nullptr),
27 presenting_device_(nullptr),
28 keep_alive_(false), 26 keep_alive_(false),
29 has_scheduled_poll_(false) { 27 has_scheduled_poll_(false) {
30 // Register VRDeviceProviders for the current platform 28 // Register VRDeviceProviders for the current platform
31 #if defined(OS_ANDROID) 29 #if defined(OS_ANDROID)
32 RegisterProvider(base::WrapUnique(new GvrDeviceProvider())); 30 RegisterProvider(base::WrapUnique(new GvrDeviceProvider()));
33 #endif 31 #endif
34 } 32 }
35 33
36 VRDeviceManager::VRDeviceManager(std::unique_ptr<VRDeviceProvider> provider) 34 VRDeviceManager::VRDeviceManager(std::unique_ptr<VRDeviceProvider> provider)
37 : vr_initialized_(false), 35 : vr_initialized_(false),
38 presenting_service_(nullptr),
39 presenting_device_(nullptr),
40 keep_alive_(true), 36 keep_alive_(true),
41 has_scheduled_poll_(false) { 37 has_scheduled_poll_(false) {
42 thread_checker_.DetachFromThread(); 38 thread_checker_.DetachFromThread();
43 RegisterProvider(std::move(provider)); 39 RegisterProvider(std::move(provider));
44 SetInstance(this); 40 SetInstance(this);
45 } 41 }
46 42
47 VRDeviceManager::~VRDeviceManager() { 43 VRDeviceManager::~VRDeviceManager() {
48 DCHECK(thread_checker_.CalledOnValidThread()); 44 DCHECK(thread_checker_.CalledOnValidThread());
49 StopSchedulingPollEvents(); 45 StopSchedulingPollEvents();
50 g_vr_device_manager = nullptr; 46 g_vr_device_manager = nullptr;
51 } 47 }
52 48
53 VRDeviceManager* VRDeviceManager::GetInstance() { 49 VRDeviceManager* VRDeviceManager::GetInstance() {
54 if (!g_vr_device_manager) 50 if (!g_vr_device_manager)
55 g_vr_device_manager = new VRDeviceManager(); 51 g_vr_device_manager = new VRDeviceManager();
56 return g_vr_device_manager; 52 return g_vr_device_manager;
57 } 53 }
58 54
59 // Returns the requested device with the requested id if the specified service
60 // is allowed to access it.
61 VRDevice* VRDeviceManager::GetAllowedDevice(VRServiceImpl* service,
62 unsigned int index) {
63 VRDeviceManager* device_manager = GetInstance();
64
65 // If another service is presenting to the requested device don't allow other
66 // services to access it. That could potentially allow them to spy on
67 // where the user is looking on another page, spam another application with
68 // pose resets, etc.
69 if (device_manager->presenting_service_ &&
70 device_manager->presenting_service_ != service) {
71 if (device_manager->presenting_device_ &&
72 device_manager->presenting_device_->id() == index)
73 return nullptr;
74 }
75
76 return device_manager->GetDevice(index);
77 }
78
79 void VRDeviceManager::SetInstance(VRDeviceManager* instance) { 55 void VRDeviceManager::SetInstance(VRDeviceManager* instance) {
80 // Unit tests can create multiple instances but only one should exist at any 56 // Unit tests can create multiple instances but only one should exist at any
81 // given time so g_vr_device_manager should only go from nullptr to 57 // given time so g_vr_device_manager should only go from nullptr to
82 // non-nullptr and vica versa. 58 // non-nullptr and vica versa.
83 CHECK_NE(!!instance, !!g_vr_device_manager); 59 CHECK_NE(!!instance, !!g_vr_device_manager);
84 g_vr_device_manager = instance; 60 g_vr_device_manager = instance;
85 } 61 }
86 62
87 bool VRDeviceManager::HasInstance() { 63 bool VRDeviceManager::HasInstance() {
88 // For testing. Checks to see if a VRDeviceManager instance is active. 64 // For testing. Checks to see if a VRDeviceManager instance is active.
89 return !!g_vr_device_manager; 65 return !!g_vr_device_manager;
90 } 66 }
91 67
92 void VRDeviceManager::AddService(VRServiceImpl* service) { 68 void VRDeviceManager::AddService(VRServiceImpl* service) {
69 // Loop through any currently active devices and send Connected messages to
70 // the service. Future devices that come online will send a Connected message
71 // when they are created.
72 GetVRDevices(service);
73
93 services_.push_back(service); 74 services_.push_back(service);
94
95 // Ensure that the device providers are initialized
96 InitializeProviders();
97 } 75 }
98 76
99 void VRDeviceManager::RemoveService(VRServiceImpl* service) { 77 void VRDeviceManager::RemoveService(VRServiceImpl* service) {
100 services_.erase(std::remove(services_.begin(), services_.end(), service), 78 services_.erase(std::remove(services_.begin(), services_.end(), service),
101 services_.end()); 79 services_.end());
102 80
103 if (service == presenting_service_) { 81 for (auto device : devices_) {
104 presenting_device_->ExitPresent(); 82 device.second->RemoveService(service);
105
106 presenting_service_ = nullptr;
107 presenting_device_ = nullptr;
108 } 83 }
109 84
110 if (services_.empty() && !keep_alive_) { 85 if (services_.empty() && !keep_alive_) {
111 // Delete the device manager when it has no active connections. 86 // Delete the device manager when it has no active connections.
112 delete g_vr_device_manager; 87 delete g_vr_device_manager;
113 } 88 }
114 } 89 }
115 90
116 mojo::Array<VRDisplayPtr> VRDeviceManager::GetVRDevices() { 91 bool VRDeviceManager::GetVRDevices(VRServiceImpl* service) {
117 DCHECK(thread_checker_.CalledOnValidThread()); 92 DCHECK(thread_checker_.CalledOnValidThread());
118 93
119 InitializeProviders(); 94 InitializeProviders();
120 95
121 std::vector<VRDevice*> devices; 96 std::vector<VRDevice*> devices;
122 for (const auto& provider : providers_) 97 for (const auto& provider : providers_)
123 provider->GetDevices(&devices); 98 provider->GetDevices(&devices);
124 99
125 mojo::Array<VRDisplayPtr> out_devices; 100 if (devices.empty())
101 return false;
102
126 for (auto* device : devices) { 103 for (auto* device : devices) {
127 if (device->id() == VR_DEVICE_LAST_ID) 104 if (device->id() == VR_DEVICE_LAST_ID)
128 continue; 105 continue;
129 106
130 if (devices_.find(device->id()) == devices_.end()) 107 if (devices_.find(device->id()) == devices_.end())
131 devices_[device->id()] = device; 108 devices_[device->id()] = device;
132 109
133 VRDisplayPtr vr_device_info = device->GetVRDevice(); 110 device->AddService(service);
134 if (vr_device_info.is_null())
135 continue;
136
137 // GetVRDevice should always set the index of the VRDisplay to its own id.
138 DCHECK(vr_device_info->index == device->id());
139
140 out_devices.push_back(std::move(vr_device_info));
141 } 111 }
142 112
143 return out_devices; 113 return true;
114 }
115
116 unsigned int VRDeviceManager::GetNumberOfConnectedDevices() {
117 DCHECK(thread_checker_.CalledOnValidThread());
118
119 return static_cast<unsigned int>(devices_.size());
144 } 120 }
145 121
146 VRDevice* VRDeviceManager::GetDevice(unsigned int index) { 122 VRDevice* VRDeviceManager::GetDevice(unsigned int index) {
147 DCHECK(thread_checker_.CalledOnValidThread()); 123 DCHECK(thread_checker_.CalledOnValidThread());
148 124
149 if (index == 0) { 125 if (index == 0) {
150 return NULL; 126 return NULL;
151 } 127 }
152 128
153 DeviceMap::iterator iter = devices_.find(index); 129 DeviceMap::iterator iter = devices_.find(index);
154 if (iter == devices_.end()) { 130 if (iter == devices_.end()) {
155 return nullptr; 131 return nullptr;
156 } 132 }
157 return iter->second; 133 return iter->second;
158 } 134 }
159 135
160 // These dispatchers must use Clone() instead of std::move to ensure that
161 // if there are multiple registered services they all get a copy of the data.
162 void VRDeviceManager::OnDeviceChanged(VRDisplayPtr device) {
163 for (const auto& service : services_)
164 service->client()->OnDisplayChanged(device.Clone());
165 }
166
167 bool VRDeviceManager::RequestPresent(VRServiceImpl* service,
168 unsigned int index,
169 bool secure_origin) {
170 // Is anything presenting currently?
171 if (presenting_service_) {
172 // Should never have a presenting service without a presenting device.
173 DCHECK(presenting_device_);
174
175 // Fail if the currently presenting service is not the one making the
176 // request.
177 if (presenting_service_ != service)
178 return false;
179
180 // If we are switching presentation from the currently presenting service to
181 // a new device stop presening to the previous one.
182 if (presenting_device_->id() != index) {
183 // Tell the device to stop presenting.
184 presenting_device_->ExitPresent();
185
186 // Only the presenting service needs to be notified that presentation is
187 // ending on the previous device.
188 presenting_service_->client()->OnExitPresent(presenting_device_->id());
189 presenting_device_ = nullptr;
190 }
191
192 presenting_service_ = nullptr;
193 }
194
195 VRDevice* requested_device = GetDevice(index);
196 // Can't present to a device that doesn't exist.
197 if (!requested_device)
198 return false;
199
200 // Attempt to begin presenting to this device. This could fail for any number
201 // of device-specific reasons.
202 if (!requested_device->RequestPresent(secure_origin))
203 return false;
204
205 // Successfully began presenting!
206 presenting_service_ = service;
207 presenting_device_ = requested_device;
208
209 return true;
210 }
211
212 void VRDeviceManager::ExitPresent(VRServiceImpl* service, unsigned int index) {
213 // Don't allow services other than the currently presenting one to exit
214 // presentation.
215 if (presenting_service_ != service)
216 return;
217
218 // Should never have a presenting service without a presenting device.
219 DCHECK(presenting_device_);
220
221 // Fail if the specified device is not currently presenting.
222 if (presenting_device_->id() != index)
223 return;
224
225 // Tell the client we're done. This must happen before the device's
226 // ExitPresent to avoid invalid mojo state.
227 if (presenting_service_->client()) {
228 presenting_service_->client()->OnExitPresent(index);
229 }
230
231 // Tell the device to stop presenting.
232 presenting_device_->ExitPresent();
233
234 // Clear the presenting service and device.
235 presenting_service_ = nullptr;
236 presenting_device_ = nullptr;
237 }
238
239 void VRDeviceManager::SubmitFrame(VRServiceImpl* service,
240 unsigned int index,
241 VRPosePtr pose) {
242 // Don't allow services other than the currently presenting one to submit any
243 // frames.
244 if (presenting_service_ != service)
245 return;
246
247 // Should never have a presenting service without a presenting device.
248 DCHECK(presenting_device_);
249
250 // Don't submit frames to devices other than the currently presenting one.
251 if (presenting_device_->id() != index)
252 return;
253
254 presenting_device_->SubmitFrame(std::move(pose));
255 }
256
257 void VRDeviceManager::OnDeviceConnectionStatusChanged(VRDevice* device,
258 bool is_connected) {
259 if (is_connected) {
260 VRDisplayPtr vr_device_info = device->GetVRDevice();
261 if (vr_device_info.is_null())
262 return;
263
264 vr_device_info->index = device->id();
265
266 for (const auto& service : services_)
267 service->client()->OnDisplayConnected(vr_device_info.Clone());
268 } else {
269 for (const auto& service : services_)
270 service->client()->OnDisplayDisconnected(device->id());
271 }
272 }
273
274 void VRDeviceManager::OnPresentEnded(VRDevice* device) {
275 // Ensure the presenting device is the one that we've been requested to stop.
276 if (!presenting_device_ || presenting_device_ != device)
277 return;
278
279 // Should never have a presenting device without a presenting service.
280 DCHECK(presenting_service_);
281
282 // Notify the presenting service that it's been forced to end presentation.
283 presenting_service_->client()->OnExitPresent(device->id());
284
285 // Clear the presenting service and device.
286 presenting_service_ = nullptr;
287 presenting_device_ = nullptr;
288 }
289
290 void VRDeviceManager::InitializeProviders() { 136 void VRDeviceManager::InitializeProviders() {
291 if (vr_initialized_) { 137 if (vr_initialized_) {
292 return; 138 return;
293 } 139 }
294 140
295 for (const auto& provider : providers_) { 141 for (const auto& provider : providers_) {
296 provider->SetClient(this);
297 provider->Initialize(); 142 provider->Initialize();
298 } 143 }
299 144
300 vr_initialized_ = true; 145 vr_initialized_ = true;
301 } 146 }
302 147
303 void VRDeviceManager::RegisterProvider( 148 void VRDeviceManager::RegisterProvider(
304 std::unique_ptr<VRDeviceProvider> provider) { 149 std::unique_ptr<VRDeviceProvider> provider) {
305 providers_.push_back(make_linked_ptr(provider.release())); 150 providers_.push_back(make_linked_ptr(provider.release()));
306 } 151 }
(...skipping 12 matching lines...) Expand all
319 for (const auto& provider : providers_) 164 for (const auto& provider : providers_)
320 provider->PollEvents(); 165 provider->PollEvents();
321 } 166 }
322 167
323 void VRDeviceManager::StopSchedulingPollEvents() { 168 void VRDeviceManager::StopSchedulingPollEvents() {
324 if (has_scheduled_poll_) 169 if (has_scheduled_poll_)
325 timer_.Stop(); 170 timer_.Stop();
326 } 171 }
327 172
328 } // namespace device 173 } // namespace device
OLDNEW
« no previous file with comments | « device/vr/vr_device_manager.h ('k') | device/vr/vr_device_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698