OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "content/browser/renderer_host/media/media_stream_manager.h" | 5 #include "content/browser/renderer_host/media/media_stream_manager.h" |
6 | 6 |
7 #include <list> | 7 #include <list> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
(...skipping 29 matching lines...) Expand all Loading... |
40 for (size_t i = 0; i < label.size(); ++i) { | 40 for (size_t i = 0; i < label.size(); ++i) { |
41 int random_char = base::RandGenerator(sizeof(kAlphabet) - 1); | 41 int random_char = base::RandGenerator(sizeof(kAlphabet) - 1); |
42 label[i] = kAlphabet[random_char]; | 42 label[i] = kAlphabet[random_char]; |
43 } | 43 } |
44 return label; | 44 return label; |
45 } | 45 } |
46 | 46 |
47 // Helper to verify if a media stream type is part of options or not. | 47 // Helper to verify if a media stream type is part of options or not. |
48 static bool Requested(const StreamOptions& options, | 48 static bool Requested(const StreamOptions& options, |
49 MediaStreamType stream_type) { | 49 MediaStreamType stream_type) { |
50 return (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE && | 50 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE && |
51 options.video) || | 51 options.video) { |
52 (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE && | 52 return true; |
53 options.audio); | 53 } else if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE && |
| 54 options.audio) { |
| 55 return true; |
| 56 } |
| 57 return false; |
54 } | 58 } |
55 | 59 |
56 DeviceThread::DeviceThread(const char* name) | 60 DeviceThread::DeviceThread(const char* name) |
57 : base::Thread(name) { | 61 : base::Thread(name) { |
58 } | 62 } |
59 | 63 |
60 DeviceThread::~DeviceThread() { | 64 DeviceThread::~DeviceThread() { |
61 Stop(); | 65 Stop(); |
62 } | 66 } |
63 | 67 |
64 void DeviceThread::Init() { | 68 void DeviceThread::Init() { |
65 using base::win::ScopedCOMInitializer; | 69 using base::win::ScopedCOMInitializer; |
66 // Enter the multi-threaded apartment. | 70 // Enter the multi-threaded apartment. |
67 com_initializer_.reset(new ScopedCOMInitializer(ScopedCOMInitializer::kMTA)); | 71 com_initializer_.reset(new ScopedCOMInitializer(ScopedCOMInitializer::kMTA)); |
68 } | 72 } |
69 | 73 |
70 void DeviceThread::CleanUp() { | 74 void DeviceThread::CleanUp() { |
71 com_initializer_.reset(); | 75 com_initializer_.reset(); |
72 } | 76 } |
73 | 77 |
74 // TODO(xians): Merge DeviceRequest with MediaStreamRequest. | 78 // TODO(xians): Merge DeviceRequest with MediaStreamRequest. |
75 struct MediaStreamManager::DeviceRequest { | 79 struct MediaStreamManager::DeviceRequest { |
76 enum RequestState { | 80 enum RequestState { |
77 STATE_NOT_REQUESTED = 0, | 81 kNotRequested = 0, |
78 STATE_REQUESTED, | 82 kRequested, |
79 STATE_PENDING_APPROVAL, | 83 kPendingApproval, |
80 STATE_OPENING, | 84 kOpening, |
81 STATE_DONE, | 85 kDone, |
82 STATE_ERROR | 86 kError |
83 }; | 87 }; |
84 | 88 |
85 enum RequestType { | 89 enum RequestType { |
86 GENERATE_STREAM = 0, | 90 kGenerateStream = 0, |
87 ENUMERATE_DEVICES, | 91 kEnumerateDevices, |
88 OPEN_DEVICE | 92 kOpenDevice |
89 }; | 93 }; |
90 | 94 |
91 DeviceRequest() | 95 DeviceRequest() |
92 : requester(NULL), | 96 : requester(NULL), |
93 state(content::NUM_MEDIA_STREAM_DEVICE_TYPES, STATE_NOT_REQUESTED), | 97 state(content::NUM_MEDIA_STREAM_DEVICE_TYPES, kNotRequested), |
94 type(GENERATE_STREAM), | 98 type(kGenerateStream), |
95 render_process_id(-1), | 99 render_process_id(-1), |
96 render_view_id(-1) { | 100 render_view_id(-1) { |
97 options.audio = false; | 101 options.audio = false; |
98 options.video = false; | 102 options.video = false; |
99 } | 103 } |
100 | 104 |
101 DeviceRequest(MediaStreamRequester* requester, | 105 DeviceRequest(MediaStreamRequester* requester, |
102 const StreamOptions& request_options, | 106 const StreamOptions& request_options, |
103 int render_process_id, | 107 int render_process_id, |
104 int render_view_id, | 108 int render_view_id, |
105 const GURL& request_security_origin) | 109 const GURL& request_security_origin) |
106 : requester(requester), | 110 : requester(requester), |
107 options(request_options), | 111 options(request_options), |
108 state(content::NUM_MEDIA_STREAM_DEVICE_TYPES, STATE_NOT_REQUESTED), | 112 state(content::NUM_MEDIA_STREAM_DEVICE_TYPES, kNotRequested), |
109 type(GENERATE_STREAM), | 113 type(kGenerateStream), |
110 render_process_id(render_process_id), | 114 render_process_id(render_process_id), |
111 render_view_id(render_view_id), | 115 render_view_id(render_view_id), |
112 security_origin(request_security_origin) { | 116 security_origin(request_security_origin) { |
113 DCHECK(requester); | 117 DCHECK(requester); |
114 } | 118 } |
115 | 119 |
116 ~DeviceRequest() {} | 120 ~DeviceRequest() {} |
117 | 121 |
118 MediaStreamRequester* requester; | 122 MediaStreamRequester* requester; |
119 StreamOptions options; | 123 StreamOptions options; |
120 std::vector<RequestState> state; | 124 std::vector<RequestState> state; |
121 RequestType type; | 125 RequestType type; |
122 int render_process_id; | 126 int render_process_id; |
123 int render_view_id; | 127 int render_view_id; |
124 GURL security_origin; | 128 GURL security_origin; |
125 std::string requested_device_id; | 129 std::string requested_device_id; |
126 StreamDeviceInfoArray audio_devices; | 130 StreamDeviceInfoArray audio_devices; |
127 StreamDeviceInfoArray video_devices; | 131 StreamDeviceInfoArray video_devices; |
128 }; | 132 }; |
129 | 133 |
130 MediaStreamManager::EnumerationCache::EnumerationCache() | |
131 : valid(false) { | |
132 } | |
133 | |
134 MediaStreamManager::EnumerationCache::~EnumerationCache() { | |
135 } | |
136 | |
137 MediaStreamManager::MediaStreamManager( | 134 MediaStreamManager::MediaStreamManager( |
138 AudioInputDeviceManager* audio_input_device_manager, | 135 AudioInputDeviceManager* audio_input_device_manager, |
139 VideoCaptureManager* video_capture_manager) | 136 VideoCaptureManager* video_capture_manager) |
140 : ALLOW_THIS_IN_INITIALIZER_LIST( | 137 : ALLOW_THIS_IN_INITIALIZER_LIST( |
141 device_settings_(new MediaStreamDeviceSettings(this))), | 138 device_settings_(new MediaStreamDeviceSettings(this))), |
142 audio_input_device_manager_(audio_input_device_manager), | 139 audio_input_device_manager_(audio_input_device_manager), |
143 video_capture_manager_(video_capture_manager), | 140 video_capture_manager_(video_capture_manager), |
144 monitoring_started_(false), | 141 enumeration_in_progress_(content::NUM_MEDIA_STREAM_DEVICE_TYPES, false), |
145 io_loop_(NULL) { | 142 io_loop_(NULL) { |
146 memset(active_enumeration_ref_count_, 0, | |
147 sizeof(active_enumeration_ref_count_)); | |
148 } | 143 } |
149 | 144 |
150 MediaStreamManager::~MediaStreamManager() { | 145 MediaStreamManager::~MediaStreamManager() { |
151 DCHECK(requests_.empty()); | 146 DCHECK(requests_.empty()); |
152 DCHECK(!device_thread_.get()); | 147 DCHECK(!device_thread_.get()); |
153 DCHECK(!io_loop_); | 148 DCHECK(!io_loop_); |
154 } | 149 } |
155 | 150 |
156 VideoCaptureManager* MediaStreamManager::video_capture_manager() { | 151 VideoCaptureManager* MediaStreamManager::video_capture_manager() { |
157 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 152 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
(...skipping 16 matching lines...) Expand all Loading... |
174 const GURL& security_origin, | 169 const GURL& security_origin, |
175 std::string* label) { | 170 std::string* label) { |
176 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 171 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
177 | 172 |
178 // Create a new request based on options. | 173 // Create a new request based on options. |
179 DeviceRequest new_request(requester, options, | 174 DeviceRequest new_request(requester, options, |
180 render_process_id, | 175 render_process_id, |
181 render_view_id, | 176 render_view_id, |
182 security_origin); | 177 security_origin); |
183 StartEnumeration(&new_request, label); | 178 StartEnumeration(&new_request, label); |
184 | |
185 // Get user confirmation to use capture devices. | |
186 // Need to make an asynchronous call to make sure the |requester| gets the | |
187 // |label| before it would receive any event. | |
188 BrowserThread::PostTask(BrowserThread::IO, | |
189 FROM_HERE, | |
190 base::Bind(&MediaStreamDeviceSettings::RequestCaptureDeviceUsage, | |
191 base::Unretained(device_settings_.get()), | |
192 *label, render_process_id, | |
193 render_view_id, options, | |
194 security_origin)); | |
195 } | 179 } |
196 | 180 |
197 void MediaStreamManager::CancelRequests(MediaStreamRequester* requester) { | 181 void MediaStreamManager::CancelRequests(MediaStreamRequester* requester) { |
198 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 182 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
199 DeviceRequests::iterator it = requests_.begin(); | 183 DeviceRequests::iterator it = requests_.begin(); |
200 while (it != requests_.end()) { | 184 while (it != requests_.end()) { |
201 if (it->second.requester == requester && !RequestDone(it->second)) { | 185 if (it->second.requester == requester && !RequestDone(it->second)) { |
202 // The request isn't complete, but there might be some devices already | 186 // The request isn't complete, but there might be some devices already |
203 // opened -> close them. | 187 // opened -> close them. |
204 DeviceRequest* request = &(it->second); | 188 DeviceRequest* request = &(it->second); |
205 if (request->state[content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE] == | 189 if (request->state[content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE] == |
206 DeviceRequest::STATE_OPENING) { | 190 DeviceRequest::kOpening) { |
207 for (StreamDeviceInfoArray::iterator it = | 191 for (StreamDeviceInfoArray::iterator it = |
208 request->audio_devices.begin(); it != request->audio_devices.end(); | 192 request->audio_devices.begin(); it != request->audio_devices.end(); |
209 ++it) { | 193 ++it) { |
210 audio_input_device_manager()->Close(it->session_id); | 194 audio_input_device_manager()->Close(it->session_id); |
211 } | 195 } |
212 } | 196 } |
213 if (request->state[content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE] == | 197 if (request->state[content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE] == |
214 DeviceRequest::STATE_OPENING) { | 198 DeviceRequest::kOpening) { |
215 for (StreamDeviceInfoArray::iterator it = | 199 for (StreamDeviceInfoArray::iterator it = |
216 request->video_devices.begin(); it != request->video_devices.end(); | 200 request->video_devices.begin(); it != request->video_devices.end(); |
217 ++it) { | 201 ++it) { |
218 video_capture_manager()->Close(it->session_id); | 202 video_capture_manager()->Close(it->session_id); |
219 } | 203 } |
220 } | 204 } |
221 requests_.erase(it++); | 205 requests_.erase(it++); |
222 } else { | 206 } else { |
223 ++it; | 207 ++it; |
224 } | 208 } |
225 } | 209 } |
226 } | 210 } |
227 | 211 |
228 void MediaStreamManager::CancelGenerateStream(const std::string& label) { | 212 void MediaStreamManager::CancelGenerateStream(const std::string& label) { |
229 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 213 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
230 | 214 |
231 DeviceRequests::iterator it = requests_.find(label); | 215 DeviceRequests::iterator it = requests_.find(label); |
232 if (it != requests_.end()) { | 216 if (it != requests_.end()) { |
233 // The request isn't complete. | 217 // The request isn't complete. |
234 if (!RequestDone(it->second)) { | 218 if (!RequestDone(it->second)) { |
235 DeviceRequest* request = &(it->second); | 219 DeviceRequest* request = &(it->second); |
236 if (request->state[content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE] == | 220 if (request->state[content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE] == |
237 DeviceRequest::STATE_OPENING) { | 221 DeviceRequest::kOpening) { |
238 for (StreamDeviceInfoArray::iterator it = | 222 for (StreamDeviceInfoArray::iterator it = |
239 request->audio_devices.begin(); it != request->audio_devices.end(); | 223 request->audio_devices.begin(); it != request->audio_devices.end(); |
240 ++it) { | 224 ++it) { |
241 audio_input_device_manager()->Close(it->session_id); | 225 audio_input_device_manager()->Close(it->session_id); |
242 } | 226 } |
243 } | 227 } |
244 if (request->state[content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE] == | 228 if (request->state[content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE] == |
245 DeviceRequest::STATE_OPENING) { | 229 DeviceRequest::kOpening) { |
246 for (StreamDeviceInfoArray::iterator it = | 230 for (StreamDeviceInfoArray::iterator it = |
247 request->video_devices.begin(); it != request->video_devices.end(); | 231 request->video_devices.begin(); it != request->video_devices.end(); |
248 ++it) { | 232 ++it) { |
249 video_capture_manager()->Close(it->session_id); | 233 video_capture_manager()->Close(it->session_id); |
250 } | 234 } |
251 } | 235 } |
252 requests_.erase(it); | 236 requests_.erase(it); |
253 } else { | 237 } else { |
254 StopGeneratedStream(label); | 238 StopGeneratedStream(label); |
255 } | 239 } |
256 device_settings_->RemovePendingCaptureRequest(label); | 240 device_settings_->RemovePendingCaptureRequest(label); |
257 } | 241 } |
258 } | 242 } |
259 | 243 |
260 void MediaStreamManager::StopGeneratedStream(const std::string& label) { | 244 void MediaStreamManager::StopGeneratedStream(const std::string& label) { |
261 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 245 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
262 // Find the request and close all open devices for the request. | 246 // Find the request and close all open devices for the request. |
263 DeviceRequests::iterator it = requests_.find(label); | 247 DeviceRequests::iterator it = requests_.find(label); |
264 if (it != requests_.end()) { | 248 if (it != requests_.end()) { |
265 if (it->second.type == DeviceRequest::ENUMERATE_DEVICES) { | |
266 StopEnumerateDevices(label); | |
267 return; | |
268 } | |
269 for (StreamDeviceInfoArray::iterator audio_it = | 249 for (StreamDeviceInfoArray::iterator audio_it = |
270 it->second.audio_devices.begin(); | 250 it->second.audio_devices.begin(); |
271 audio_it != it->second.audio_devices.end(); ++audio_it) { | 251 audio_it != it->second.audio_devices.end(); ++audio_it) { |
272 audio_input_device_manager()->Close(audio_it->session_id); | 252 audio_input_device_manager()->Close(audio_it->session_id); |
273 } | 253 } |
274 for (StreamDeviceInfoArray::iterator video_it = | 254 for (StreamDeviceInfoArray::iterator video_it = |
275 it->second.video_devices.begin(); | 255 it->second.video_devices.begin(); |
276 video_it != it->second.video_devices.end(); ++video_it) { | 256 video_it != it->second.video_devices.end(); ++video_it) { |
277 video_capture_manager()->Close(video_it->session_id); | 257 video_capture_manager()->Close(video_it->session_id); |
278 } | 258 } |
279 if (it->second.type == DeviceRequest::GENERATE_STREAM) { | 259 if (it->second.type == DeviceRequest::kGenerateStream) { |
280 NotifyObserverDevicesClosed(&(it->second)); | 260 NotifyObserverDevicesClosed(&(it->second)); |
281 } | 261 } |
282 requests_.erase(it); | 262 requests_.erase(it); |
| 263 return; |
283 } | 264 } |
284 } | 265 } |
285 | 266 |
286 void MediaStreamManager::EnumerateDevices( | 267 void MediaStreamManager::EnumerateDevices( |
287 MediaStreamRequester* requester, | 268 MediaStreamRequester* requester, |
288 int render_process_id, | 269 int render_process_id, |
289 int render_view_id, | 270 int render_view_id, |
290 MediaStreamType type, | 271 MediaStreamType type, |
291 const GURL& security_origin, | 272 const GURL& security_origin, |
292 std::string* label) { | 273 std::string* label) { |
293 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 274 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
294 DCHECK(type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE || | |
295 type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE); | |
296 | 275 |
297 // Create a new request. | 276 // Create a new request. |
298 StreamOptions options; | 277 StreamOptions options; |
299 EnumerationCache* cache = NULL; | 278 if (type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) |
300 if (type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { | |
301 options.audio = true; | 279 options.audio = true; |
302 cache = &audio_enumeration_cache_; | 280 else |
303 } else { | |
304 options.video = true; | 281 options.video = true; |
305 cache = &video_enumeration_cache_; | |
306 } | |
307 | 282 |
308 DeviceRequest new_request(requester, options, | 283 DeviceRequest new_request(requester, options, |
309 render_process_id, | 284 render_process_id, |
310 render_view_id, | 285 render_view_id, |
311 security_origin); | 286 security_origin); |
312 new_request.type = DeviceRequest::ENUMERATE_DEVICES; | 287 new_request.type = DeviceRequest::kEnumerateDevices; |
313 | 288 |
314 if (cache->valid) { | 289 StartEnumeration(&new_request, label); |
315 // Cached device list of this type exists. Just send it out. | |
316 new_request.state[type] = DeviceRequest::STATE_REQUESTED; | |
317 AddRequest(&new_request, label); | |
318 // Need to post a task since the requester won't have label till | |
319 // this function returns. | |
320 BrowserThread::PostTask(BrowserThread::IO, | |
321 FROM_HERE, | |
322 base::Bind(&MediaStreamManager::SendCachedDeviceList, | |
323 base::Unretained(this), cache, *label)); | |
324 } else { | |
325 StartEnumeration(&new_request, label); | |
326 StartMonitoring(); | |
327 } | |
328 } | |
329 | |
330 void MediaStreamManager::StopEnumerateDevices(const std::string& label) { | |
331 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
332 | |
333 DeviceRequests::iterator it = requests_.find(label); | |
334 if (it != requests_.end()) { | |
335 DCHECK_EQ(it->second.type, DeviceRequest::ENUMERATE_DEVICES); | |
336 requests_.erase(it); | |
337 if (!HasEnumerationRequest()) { | |
338 StopMonitoring(); | |
339 } | |
340 } | |
341 } | 290 } |
342 | 291 |
343 void MediaStreamManager::OpenDevice( | 292 void MediaStreamManager::OpenDevice( |
344 MediaStreamRequester* requester, | 293 MediaStreamRequester* requester, |
345 int render_process_id, | 294 int render_process_id, |
346 int render_view_id, | 295 int render_view_id, |
347 const std::string& device_id, | 296 const std::string& device_id, |
348 MediaStreamType type, | 297 MediaStreamType type, |
349 const GURL& security_origin, | 298 const GURL& security_origin, |
350 std::string* label) { | 299 std::string* label) { |
351 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 300 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
352 | 301 |
353 // Create a new request. | 302 // Create a new request. |
354 StreamOptions options; | 303 StreamOptions options; |
355 if (type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) | 304 if (type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) |
356 options.audio = true; | 305 options.audio = true; |
357 else | 306 else |
358 options.video = true; | 307 options.video = true; |
359 | 308 |
360 DeviceRequest new_request(requester, options, | 309 DeviceRequest new_request(requester, options, |
361 render_process_id, | 310 render_process_id, |
362 render_view_id, | 311 render_view_id, |
363 security_origin); | 312 security_origin); |
364 new_request.type = DeviceRequest::OPEN_DEVICE; | 313 new_request.type = DeviceRequest::kOpenDevice; |
365 new_request.requested_device_id = device_id; | 314 new_request.requested_device_id = device_id; |
366 | 315 |
367 StartEnumeration(&new_request, label); | 316 StartEnumeration(&new_request, label); |
368 } | 317 } |
369 | 318 |
370 void MediaStreamManager::SendCachedDeviceList( | |
371 EnumerationCache* cache, | |
372 const std::string& label) { | |
373 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
374 if (cache->valid) { | |
375 DeviceRequests::iterator it = requests_.find(label); | |
376 if (it != requests_.end()) { | |
377 it->second.requester->DevicesEnumerated(label, cache->devices); | |
378 } | |
379 } | |
380 } | |
381 | |
382 void MediaStreamManager::StartMonitoring() { | |
383 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
384 if (!monitoring_started_) { | |
385 monitoring_started_ = true; | |
386 base::SystemMonitor::Get()->AddDevicesChangedObserver(this); | |
387 } | |
388 } | |
389 | |
390 void MediaStreamManager::StopMonitoring() { | |
391 DCHECK_EQ(MessageLoop::current(), io_loop_); | |
392 if (monitoring_started_ && !HasEnumerationRequest()) { | |
393 base::SystemMonitor::Get()->RemoveDevicesChangedObserver(this); | |
394 monitoring_started_ = false; | |
395 ClearEnumerationCache(&audio_enumeration_cache_); | |
396 ClearEnumerationCache(&video_enumeration_cache_); | |
397 } | |
398 } | |
399 | |
400 void MediaStreamManager::ClearEnumerationCache(EnumerationCache* cache) { | |
401 DCHECK_EQ(MessageLoop::current(), io_loop_); | |
402 cache->valid = false; | |
403 } | |
404 | |
405 void MediaStreamManager::StartEnumeration( | 319 void MediaStreamManager::StartEnumeration( |
406 DeviceRequest* new_request, | 320 DeviceRequest* new_request, |
407 std::string* label) { | 321 std::string* label) { |
408 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 322 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
409 | 323 |
410 MediaStreamType stream_type = content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE; | 324 MediaStreamType stream_type = content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE; |
411 if (Requested(new_request->options, stream_type)) { | 325 if (Requested(new_request->options, stream_type)) { |
412 new_request->state[stream_type] = DeviceRequest::STATE_REQUESTED; | 326 new_request->state[stream_type] = DeviceRequest::kRequested; |
413 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0); | 327 if (!enumeration_in_progress_[stream_type]) { |
414 if (!active_enumeration_ref_count_[stream_type]) { | 328 enumeration_in_progress_[stream_type] = true; |
415 ++active_enumeration_ref_count_[stream_type]; | |
416 GetDeviceManager(stream_type)->EnumerateDevices(); | 329 GetDeviceManager(stream_type)->EnumerateDevices(); |
417 } | 330 } |
418 } | 331 } |
419 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE; | 332 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE; |
420 if (Requested(new_request->options, stream_type)) { | 333 if (Requested(new_request->options, stream_type)) { |
421 new_request->state[stream_type] = DeviceRequest::STATE_REQUESTED; | 334 new_request->state[stream_type] = DeviceRequest::kRequested; |
422 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0); | 335 if (!enumeration_in_progress_[stream_type]) { |
423 if (!active_enumeration_ref_count_[stream_type]) { | 336 enumeration_in_progress_[stream_type] = true; |
424 ++active_enumeration_ref_count_[stream_type]; | |
425 GetDeviceManager(stream_type)->EnumerateDevices(); | 337 GetDeviceManager(stream_type)->EnumerateDevices(); |
426 } | 338 } |
427 } | 339 } |
428 | 340 |
429 AddRequest(new_request, label); | |
430 } | |
431 | |
432 void MediaStreamManager::AddRequest( | |
433 DeviceRequest* new_request, | |
434 std::string* label) { | |
435 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
436 | |
437 // Create a label for this request and verify it is unique. | 341 // Create a label for this request and verify it is unique. |
438 std::string request_label; | 342 std::string request_label; |
439 do { | 343 do { |
440 request_label = RandomLabel(); | 344 request_label = RandomLabel(); |
441 } while (requests_.find(request_label) != requests_.end()); | 345 } while (requests_.find(request_label) != requests_.end()); |
442 | 346 |
443 requests_.insert(std::make_pair(request_label, *new_request)); | 347 requests_.insert(std::make_pair(request_label, *new_request)); |
444 | 348 |
| 349 // Get user confirmation to use capture devices. |
| 350 // Need to make an asynchronous call to make sure the |requester| gets the |
| 351 // |label| before it would receive any event. |
| 352 if (new_request->type == DeviceRequest::kGenerateStream) { |
| 353 BrowserThread::PostTask(BrowserThread::IO, |
| 354 FROM_HERE, |
| 355 base::Bind(&MediaStreamDeviceSettings::RequestCaptureDeviceUsage, |
| 356 base::Unretained(device_settings_.get()), |
| 357 request_label, new_request->render_process_id, |
| 358 new_request->render_view_id, new_request->options, |
| 359 new_request->security_origin)); |
| 360 } |
| 361 |
445 (*label) = request_label; | 362 (*label) = request_label; |
446 } | 363 } |
447 | 364 |
448 void MediaStreamManager::EnsureDeviceThreadAndListener() { | 365 void MediaStreamManager::EnsureDeviceThreadAndListener() { |
449 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 366 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
450 if (device_thread_.get()) | 367 if (device_thread_.get()) |
451 return; | 368 return; |
452 | 369 |
453 device_thread_.reset(new DeviceThread("MediaStreamDeviceThread")); | 370 device_thread_.reset(new DeviceThread("MediaStreamDeviceThread")); |
454 CHECK(device_thread_->Start()); | 371 CHECK(device_thread_->Start()); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
490 request = &(request_it->second); | 407 request = &(request_it->second); |
491 break; | 408 break; |
492 } | 409 } |
493 } | 410 } |
494 } | 411 } |
495 if (request == NULL) { | 412 if (request == NULL) { |
496 // The request doesn't exist. | 413 // The request doesn't exist. |
497 return; | 414 return; |
498 } | 415 } |
499 | 416 |
500 DCHECK_NE(request->state[stream_type], DeviceRequest::STATE_REQUESTED); | 417 DCHECK_NE(request->state[stream_type], DeviceRequest::kRequested); |
501 | 418 |
502 // Check if all devices for this stream type are opened. Update the state if | 419 // Check if all devices for this stream type are opened. Update the state if |
503 // they are. | 420 // they are. |
504 for (StreamDeviceInfoArray::iterator device_it = devices->begin(); | 421 for (StreamDeviceInfoArray::iterator device_it = devices->begin(); |
505 device_it != devices->end(); ++device_it) { | 422 device_it != devices->end(); ++device_it) { |
506 if (device_it->in_use == false) { | 423 if (device_it->in_use == false) { |
507 // Wait for more devices to be opened before we're done. | 424 // Wait for more devices to be opened before we're done. |
508 return; | 425 return; |
509 } | 426 } |
510 } | 427 } |
511 request->state[stream_type] = DeviceRequest::STATE_DONE; | 428 request->state[stream_type] = DeviceRequest::kDone; |
512 | 429 |
513 if (!RequestDone(*request)) { | 430 if (!RequestDone(*request)) { |
514 // This stream_type is done, but not the other type. | 431 // This stream_type is done, but not the other type. |
515 return; | 432 return; |
516 } | 433 } |
517 | 434 |
518 switch (request->type) { | 435 switch (request->type) { |
519 case DeviceRequest::OPEN_DEVICE: | 436 case DeviceRequest::kOpenDevice: |
520 request->requester->DeviceOpened(label, (*devices)[0]); | 437 request->requester->DeviceOpened(label, (*devices)[0]); |
521 break; | 438 break; |
522 case DeviceRequest::GENERATE_STREAM: | 439 case DeviceRequest::kGenerateStream: |
523 request->requester->StreamGenerated(label, request->audio_devices, | 440 request->requester->StreamGenerated(label, request->audio_devices, |
524 request->video_devices); | 441 request->video_devices); |
525 NotifyObserverDevicesOpened(request); | 442 NotifyObserverDevicesOpened(request); |
526 break; | 443 break; |
527 default: | 444 default: |
528 NOTREACHED(); | 445 NOTREACHED(); |
529 } | 446 } |
530 } | 447 } |
531 | 448 |
532 void MediaStreamManager::Closed(MediaStreamType stream_type, | 449 void MediaStreamManager::Closed(MediaStreamType stream_type, |
533 int capture_session_id) { | 450 int capture_session_id) { |
534 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 451 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
535 } | 452 } |
536 | 453 |
537 void MediaStreamManager::DevicesEnumerated( | 454 void MediaStreamManager::DevicesEnumerated( |
538 MediaStreamType stream_type, const StreamDeviceInfoArray& devices) { | 455 MediaStreamType stream_type, const StreamDeviceInfoArray& devices) { |
539 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 456 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
540 | 457 |
541 // Only cache device list when there is EnumerateDevices request, since | |
542 // other requests don't turn on device monitoring. | |
543 bool need_update_clients = false; | |
544 EnumerationCache* cache = | |
545 (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE ? | |
546 &audio_enumeration_cache_ : &video_enumeration_cache_); | |
547 if (HasEnumerationRequest(stream_type) && | |
548 (!cache->valid || | |
549 !std::equal(devices.begin(), devices.end(), cache->devices.begin(), | |
550 media_stream::StreamDeviceInfo::IsEqual))) { | |
551 cache->valid = true; | |
552 cache->devices = devices; | |
553 need_update_clients = true; | |
554 } | |
555 | |
556 // Publish the result for all requests waiting for device list(s). | 458 // Publish the result for all requests waiting for device list(s). |
557 // Find the requests waiting for this device list, store their labels and | 459 // Find the requests waiting for this device list, store their labels and |
558 // release the iterator before calling device settings. We might get a call | 460 // release the iterator before calling device settings. We might get a call |
559 // back from device_settings that will need to iterate through devices. | 461 // back from device_settings that will need to iterate through devices. |
560 std::list<std::string> label_list; | 462 std::list<std::string> label_list; |
561 for (DeviceRequests::iterator it = requests_.begin(); it != requests_.end(); | 463 for (DeviceRequests::iterator it = requests_.begin(); it != requests_.end(); |
562 ++it) { | 464 ++it) { |
563 if (it->second.state[stream_type] == DeviceRequest::STATE_REQUESTED && | 465 if (it->second.state[stream_type] == DeviceRequest::kRequested && |
564 Requested(it->second.options, stream_type)) { | 466 Requested(it->second.options, stream_type)) { |
565 if (it->second.type != DeviceRequest::ENUMERATE_DEVICES) | 467 it->second.state[stream_type] = DeviceRequest::kPendingApproval; |
566 it->second.state[stream_type] = DeviceRequest::STATE_PENDING_APPROVAL; | |
567 label_list.push_back(it->first); | 468 label_list.push_back(it->first); |
568 } | 469 } |
569 } | 470 } |
570 for (std::list<std::string>::iterator it = label_list.begin(); | 471 for (std::list<std::string>::iterator it = label_list.begin(); |
571 it != label_list.end(); ++it) { | 472 it != label_list.end(); ++it) { |
572 DeviceRequest& request = requests_[*it]; | 473 DeviceRequest& request = requests_[*it]; |
573 switch (request.type) { | 474 switch (request.type) { |
574 case DeviceRequest::ENUMERATE_DEVICES: | 475 case DeviceRequest::kEnumerateDevices: |
575 if (need_update_clients) | 476 request.requester->DevicesEnumerated(*it, devices); |
576 request.requester->DevicesEnumerated(*it, devices); | 477 requests_.erase(*it); |
577 break; | 478 break; |
578 case DeviceRequest::OPEN_DEVICE: | 479 case DeviceRequest::kOpenDevice: |
579 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin(); | 480 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin(); |
580 device_it != devices.end(); device_it++) { | 481 device_it != devices.end(); device_it++) { |
581 if (request.requested_device_id == device_it->device_id) { | 482 if (request.requested_device_id == device_it->device_id) { |
582 StreamDeviceInfo device = *device_it; | 483 StreamDeviceInfo device = *device_it; |
583 device.in_use = false; | 484 device.in_use = false; |
584 device.session_id = | 485 device.session_id = |
585 GetDeviceManager(device_it->stream_type)->Open(device); | 486 GetDeviceManager(device_it->stream_type)->Open(device); |
586 request.state[device_it->stream_type] = | 487 request.state[device_it->stream_type] = DeviceRequest::kOpening; |
587 DeviceRequest::STATE_OPENING; | |
588 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) | 488 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) |
589 request.audio_devices.push_back(device); | 489 request.audio_devices.push_back(device); |
590 else | 490 else |
591 request.video_devices.push_back(device); | 491 request.video_devices.push_back(device); |
592 break; | 492 break; |
593 } | 493 } |
594 } | 494 } |
595 break; | 495 break; |
596 default: | 496 default: |
597 BrowserThread::PostTask(BrowserThread::IO, | 497 BrowserThread::PostTask(BrowserThread::IO, |
598 FROM_HERE, | 498 FROM_HERE, |
599 base::Bind(&MediaStreamDeviceSettings::AvailableDevices, | 499 base::Bind(&MediaStreamDeviceSettings::AvailableDevices, |
600 base::Unretained(device_settings_.get()), | 500 base::Unretained(device_settings_.get()), |
601 *it, stream_type, devices)); | 501 *it, stream_type, devices)); |
602 } | 502 } |
603 } | 503 } |
604 label_list.clear(); | 504 label_list.clear(); |
605 --active_enumeration_ref_count_[stream_type]; | 505 enumeration_in_progress_[stream_type] = false; |
606 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0); | |
607 } | 506 } |
608 | 507 |
609 void MediaStreamManager::Error(MediaStreamType stream_type, | 508 void MediaStreamManager::Error(MediaStreamType stream_type, |
610 int capture_session_id, | 509 int capture_session_id, |
611 MediaStreamProviderError error) { | 510 MediaStreamProviderError error) { |
612 // Find the device for the error call. | 511 // Find the device for the error call. |
613 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 512 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
614 for (DeviceRequests::iterator it = requests_.begin(); it != requests_.end(); | 513 for (DeviceRequests::iterator it = requests_.begin(); it != requests_.end(); |
615 ++it) { | 514 ++it) { |
616 StreamDeviceInfoArray* devices = NULL; | 515 StreamDeviceInfoArray* devices = NULL; |
617 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { | 516 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { |
618 devices = &(it->second.audio_devices); | 517 devices = &(it->second.audio_devices); |
619 } else if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) { | 518 } else if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) { |
620 devices = &(it->second.video_devices); | 519 devices = &(it->second.video_devices); |
621 } else { | 520 } else { |
622 NOTREACHED(); | 521 NOTREACHED(); |
623 } | 522 } |
624 | 523 |
625 int device_idx = 0; | 524 int device_idx = 0; |
626 for (StreamDeviceInfoArray::iterator device_it = devices->begin(); | 525 for (StreamDeviceInfoArray::iterator device_it = devices->begin(); |
627 device_it != devices->end(); ++device_it, ++device_idx) { | 526 device_it != devices->end(); ++device_it, ++device_idx) { |
628 if (device_it->session_id == capture_session_id) { | 527 if (device_it->session_id == capture_session_id) { |
629 // We've found the failing device. Find the error case: | 528 // We've found the failing device. Find the error case: |
630 if (it->second.state[stream_type] == DeviceRequest::STATE_DONE) { | 529 if (it->second.state[stream_type] == DeviceRequest::kDone) { |
631 // 1. Already opened -> signal device failure and close device. | 530 // 1. Already opened -> signal device failure and close device. |
632 // Use device_idx to signal which of the devices encountered an | 531 // Use device_idx to signal which of the devices encountered an |
633 // error. | 532 // error. |
634 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { | 533 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { |
635 it->second.requester->AudioDeviceFailed(it->first, device_idx); | 534 it->second.requester->AudioDeviceFailed(it->first, device_idx); |
636 } else if (stream_type == | 535 } else if (stream_type == |
637 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) { | 536 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) { |
638 it->second.requester->VideoDeviceFailed(it->first, device_idx); | 537 it->second.requester->VideoDeviceFailed(it->first, device_idx); |
639 } | 538 } |
640 GetDeviceManager(stream_type)->Close(capture_session_id); | 539 GetDeviceManager(stream_type)->Close(capture_session_id); |
(...skipping 29 matching lines...) Expand all Loading... |
670 | 569 |
671 // Loop through all device types for this request. | 570 // Loop through all device types for this request. |
672 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin(); | 571 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin(); |
673 device_it != devices.end(); ++device_it) { | 572 device_it != devices.end(); ++device_it) { |
674 StreamDeviceInfo device_info = *device_it; | 573 StreamDeviceInfo device_info = *device_it; |
675 | 574 |
676 // Set in_use to false to be able to track if this device has been | 575 // Set in_use to false to be able to track if this device has been |
677 // opened. in_use might be true if the device type can be used in more | 576 // opened. in_use might be true if the device type can be used in more |
678 // than one session. | 577 // than one session. |
679 DCHECK_EQ(request_it->second.state[device_it->stream_type], | 578 DCHECK_EQ(request_it->second.state[device_it->stream_type], |
680 DeviceRequest::STATE_PENDING_APPROVAL); | 579 DeviceRequest::kPendingApproval); |
681 device_info.in_use = false; | 580 device_info.in_use = false; |
682 device_info.session_id = | 581 device_info.session_id = |
683 GetDeviceManager(device_info.stream_type)->Open(device_info); | 582 GetDeviceManager(device_info.stream_type)->Open(device_info); |
684 request_it->second.state[device_it->stream_type] = | 583 request_it->second.state[device_it->stream_type] = |
685 DeviceRequest::STATE_OPENING; | 584 DeviceRequest::kOpening; |
686 if (device_info.stream_type == | 585 if (device_info.stream_type == |
687 content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { | 586 content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { |
688 request_it->second.audio_devices.push_back(device_info); | 587 request_it->second.audio_devices.push_back(device_info); |
689 } else if (device_info.stream_type == | 588 } else if (device_info.stream_type == |
690 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) { | 589 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) { |
691 request_it->second.video_devices.push_back(device_info); | 590 request_it->second.video_devices.push_back(device_info); |
692 } else { | 591 } else { |
693 NOTREACHED(); | 592 NOTREACHED(); |
694 } | 593 } |
695 } | 594 } |
696 // Check if we received all stream types requested. | 595 // Check if we received all stream types requested. |
697 MediaStreamType stream_type = | 596 MediaStreamType stream_type = |
698 content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE; | 597 content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE; |
699 if (Requested(request_it->second.options, stream_type) && | 598 if (Requested(request_it->second.options, stream_type) && |
700 request_it->second.audio_devices.size() == 0) { | 599 request_it->second.audio_devices.size() == 0) { |
701 request_it->second.state[stream_type] = DeviceRequest::STATE_ERROR; | 600 request_it->second.state[stream_type] = DeviceRequest::kError; |
702 } | 601 } |
703 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE; | 602 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE; |
704 if (Requested(request_it->second.options, stream_type) && | 603 if (Requested(request_it->second.options, stream_type) && |
705 request_it->second.video_devices.size() == 0) { | 604 request_it->second.video_devices.size() == 0) { |
706 request_it->second.state[stream_type] = DeviceRequest::STATE_ERROR; | 605 request_it->second.state[stream_type] = DeviceRequest::kError; |
707 } | 606 } |
708 return; | 607 return; |
709 } | 608 } |
710 } | 609 } |
711 | 610 |
712 void MediaStreamManager::SettingsError(const std::string& label) { | 611 void MediaStreamManager::SettingsError(const std::string& label) { |
713 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 612 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
714 // Erase this request and report an error. | 613 // Erase this request and report an error. |
715 DeviceRequests::iterator it = requests_.find(label); | 614 DeviceRequests::iterator it = requests_.find(label); |
716 if (it != requests_.end()) { | 615 if (it != requests_.end()) { |
717 DCHECK_EQ(it->second.type, DeviceRequest::GENERATE_STREAM); | 616 DCHECK_EQ(it->second.type, DeviceRequest::kGenerateStream); |
718 it->second.requester->StreamGenerationFailed(label); | 617 it->second.requester->StreamGenerationFailed(label); |
719 requests_.erase(it); | 618 requests_.erase(it); |
720 return; | 619 return; |
721 } | 620 } |
722 } | 621 } |
723 | 622 |
724 void MediaStreamManager::UseFakeDevice() { | 623 void MediaStreamManager::UseFakeDevice() { |
725 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 624 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
726 video_capture_manager()->UseFakeDevice(); | 625 video_capture_manager()->UseFakeDevice(); |
727 device_settings_->UseFakeUI(); | 626 device_settings_->UseFakeUI(); |
728 } | 627 } |
729 | 628 |
730 void MediaStreamManager::WillDestroyCurrentMessageLoop() { | 629 void MediaStreamManager::WillDestroyCurrentMessageLoop() { |
731 DCHECK_EQ(MessageLoop::current(), io_loop_); | 630 DCHECK_EQ(MessageLoop::current(), io_loop_); |
732 DCHECK(requests_.empty()); | |
733 if (device_thread_.get()) { | 631 if (device_thread_.get()) { |
734 StopMonitoring(); | |
735 | |
736 video_capture_manager_->Unregister(); | 632 video_capture_manager_->Unregister(); |
737 audio_input_device_manager_->Unregister(); | 633 audio_input_device_manager_->Unregister(); |
738 device_thread_.reset(); | 634 device_thread_.reset(); |
739 } | 635 } |
740 | 636 |
741 audio_input_device_manager_ = NULL; | 637 audio_input_device_manager_ = NULL; |
742 video_capture_manager_ = NULL; | 638 video_capture_manager_ = NULL; |
743 io_loop_ = NULL; | 639 io_loop_ = NULL; |
744 device_settings_.reset(); | 640 device_settings_.reset(); |
745 } | 641 } |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
818 MediaStreamType stream_type) { | 714 MediaStreamType stream_type) { |
819 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) { | 715 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) { |
820 return video_capture_manager(); | 716 return video_capture_manager(); |
821 } else if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { | 717 } else if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { |
822 return audio_input_device_manager(); | 718 return audio_input_device_manager(); |
823 } | 719 } |
824 NOTREACHED(); | 720 NOTREACHED(); |
825 return NULL; | 721 return NULL; |
826 } | 722 } |
827 | 723 |
828 void MediaStreamManager::OnDevicesChanged( | |
829 base::SystemMonitor::DeviceType device_type) { | |
830 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
831 MediaStreamType stream_type; | |
832 EnumerationCache* cache; | |
833 if (device_type == base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE) { | |
834 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE; | |
835 cache = &audio_enumeration_cache_; | |
836 } else if (device_type == base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE) { | |
837 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE; | |
838 cache = &video_enumeration_cache_; | |
839 } else { | |
840 return; // Uninteresting device change. | |
841 } | |
842 | |
843 if (!HasEnumerationRequest(stream_type)) { | |
844 // There is no request for that type, No need to enumerate devices. | |
845 // Therefore, invalidate the cache of that type. | |
846 ClearEnumerationCache(cache); | |
847 return; | |
848 } | |
849 | |
850 // Always do enumeration even though some enumeration is in progress, | |
851 // because those enumeration commands could be sent before these devices | |
852 // change. | |
853 ++active_enumeration_ref_count_[stream_type]; | |
854 GetDeviceManager(stream_type)->EnumerateDevices(); | |
855 } | |
856 | |
857 bool MediaStreamManager::HasEnumerationRequest() { | |
858 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
859 for (DeviceRequests::iterator it = requests_.begin(); | |
860 it != requests_.end(); ++it) { | |
861 if (it->second.type == DeviceRequest::ENUMERATE_DEVICES) { | |
862 return true; | |
863 } | |
864 } | |
865 return false; | |
866 } | |
867 | |
868 bool MediaStreamManager::HasEnumerationRequest( | |
869 MediaStreamType stream_type) { | |
870 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
871 for (DeviceRequests::iterator it = requests_.begin(); | |
872 it != requests_.end(); ++it) { | |
873 if (it->second.type == DeviceRequest::ENUMERATE_DEVICES && | |
874 Requested(it->second.options, stream_type)) { | |
875 return true; | |
876 } | |
877 } | |
878 return false; | |
879 } | |
880 | |
881 } // namespace media_stream | 724 } // namespace media_stream |
OLD | NEW |