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

Side by Side Diff: content/browser/renderer_host/media/media_stream_manager.cc

Issue 10834232: Revert 150491 - refactor EnumerateDevices to make it a persistent request. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 4 months 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 | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « content/browser/renderer_host/media/media_stream_manager.h ('k') | content/common/media/media_stream_messages.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698