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

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

Issue 10912004: Begin adding support for tab mirroring via the MediaStream audio/video capturing (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: AudioManager injection into MediaStreamManager, consistent enum naming; per wjia@ comments. Also, … Created 8 years, 3 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 return (options.audio_type == stream_type ||
51 options.video) || 51 options.video_type == stream_type);
52 (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE &&
53 options.audio);
54 } 52 }
55 53
56 DeviceThread::DeviceThread(const char* name) 54 DeviceThread::DeviceThread(const char* name)
57 : base::Thread(name) { 55 : base::Thread(name) {
58 } 56 }
59 57
60 DeviceThread::~DeviceThread() { 58 DeviceThread::~DeviceThread() {
61 Stop(); 59 Stop();
62 } 60 }
63 61
(...skipping 19 matching lines...) Expand all
83 }; 81 };
84 82
85 enum RequestType { 83 enum RequestType {
86 GENERATE_STREAM = 0, 84 GENERATE_STREAM = 0,
87 ENUMERATE_DEVICES, 85 ENUMERATE_DEVICES,
88 OPEN_DEVICE 86 OPEN_DEVICE
89 }; 87 };
90 88
91 DeviceRequest() 89 DeviceRequest()
92 : requester(NULL), 90 : requester(NULL),
93 state(content::NUM_MEDIA_STREAM_DEVICE_TYPES, STATE_NOT_REQUESTED), 91 state(content::NUM_MEDIA_TYPES, STATE_NOT_REQUESTED),
94 type(GENERATE_STREAM), 92 type(GENERATE_STREAM),
95 render_process_id(-1), 93 render_process_id(-1),
96 render_view_id(-1) { 94 render_view_id(-1) {
97 options.audio = false;
98 options.video = false;
99 } 95 }
100 96
101 DeviceRequest(MediaStreamRequester* requester, 97 DeviceRequest(MediaStreamRequester* requester,
102 const StreamOptions& request_options, 98 const StreamOptions& request_options,
103 int render_process_id, 99 int render_process_id,
104 int render_view_id, 100 int render_view_id,
105 const GURL& request_security_origin) 101 const GURL& request_security_origin)
106 : requester(requester), 102 : requester(requester),
107 options(request_options), 103 options(request_options),
108 state(content::NUM_MEDIA_STREAM_DEVICE_TYPES, STATE_NOT_REQUESTED), 104 state(content::NUM_MEDIA_TYPES, STATE_NOT_REQUESTED),
109 type(GENERATE_STREAM), 105 type(GENERATE_STREAM),
110 render_process_id(render_process_id), 106 render_process_id(render_process_id),
111 render_view_id(render_view_id), 107 render_view_id(render_view_id),
112 security_origin(request_security_origin) { 108 security_origin(request_security_origin) {
113 DCHECK(requester); 109 DCHECK(requester);
114 } 110 }
115 111
116 ~DeviceRequest() {} 112 ~DeviceRequest() {}
117 113
118 MediaStreamRequester* requester; 114 MediaStreamRequester* requester;
119 StreamOptions options; 115 StreamOptions options;
120 std::vector<RequestState> state; 116 std::vector<RequestState> state;
121 RequestType type; 117 RequestType type;
122 int render_process_id; 118 int render_process_id;
123 int render_view_id; 119 int render_view_id;
124 GURL security_origin; 120 GURL security_origin;
125 std::string requested_device_id; 121 std::string requested_device_id;
126 StreamDeviceInfoArray audio_devices; 122 StreamDeviceInfoArray devices;
127 StreamDeviceInfoArray video_devices;
128 }; 123 };
129 124
130 MediaStreamManager::EnumerationCache::EnumerationCache() 125 MediaStreamManager::EnumerationCache::EnumerationCache()
131 : valid(false) { 126 : valid(false) {
132 } 127 }
133 128
134 MediaStreamManager::EnumerationCache::~EnumerationCache() { 129 MediaStreamManager::EnumerationCache::~EnumerationCache() {
135 } 130 }
136 131
137 MediaStreamManager::MediaStreamManager( 132 MediaStreamManager::MediaStreamManager(media::AudioManager* audio_manager)
138 AudioInputDeviceManager* audio_input_device_manager,
139 VideoCaptureManager* video_capture_manager)
140 : ALLOW_THIS_IN_INITIALIZER_LIST( 133 : ALLOW_THIS_IN_INITIALIZER_LIST(
141 device_settings_(new MediaStreamDeviceSettings(this))), 134 device_settings_(new MediaStreamDeviceSettings(this))),
142 audio_input_device_manager_(audio_input_device_manager), 135 audio_manager_(audio_manager),
143 video_capture_manager_(video_capture_manager),
144 monitoring_started_(false), 136 monitoring_started_(false),
145 io_loop_(NULL) { 137 io_loop_(NULL) {
138 DCHECK(audio_manager_);
146 memset(active_enumeration_ref_count_, 0, 139 memset(active_enumeration_ref_count_, 0,
147 sizeof(active_enumeration_ref_count_)); 140 sizeof(active_enumeration_ref_count_));
148 } 141 }
149 142
150 MediaStreamManager::~MediaStreamManager() { 143 MediaStreamManager::~MediaStreamManager() {
151 DCHECK(requests_.empty()); 144 DCHECK(requests_.empty());
152 DCHECK(!device_thread_.get()); 145 DCHECK(!device_thread_.get());
153 DCHECK(!io_loop_); 146 DCHECK(!io_loop_);
154 } 147 }
155 148
156 VideoCaptureManager* MediaStreamManager::video_capture_manager() {
157 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
158 DCHECK(video_capture_manager_);
159 EnsureDeviceThreadAndListener();
160 return video_capture_manager_;
161 }
162
163 AudioInputDeviceManager* MediaStreamManager::audio_input_device_manager() {
164 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
165 DCHECK(audio_input_device_manager_);
166 EnsureDeviceThreadAndListener();
167 return audio_input_device_manager_;
168 }
169
170 void MediaStreamManager::GenerateStream(MediaStreamRequester* requester, 149 void MediaStreamManager::GenerateStream(MediaStreamRequester* requester,
171 int render_process_id, 150 int render_process_id,
172 int render_view_id, 151 int render_view_id,
173 const StreamOptions& options, 152 const StreamOptions& options,
174 const GURL& security_origin, 153 const GURL& security_origin,
175 std::string* label) { 154 std::string* label) {
176 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 155 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
177 156
178 // Create a new request based on options. 157 // Create a new request based on options.
179 DeviceRequest new_request(requester, options, 158 DeviceRequest new_request(requester, options,
180 render_process_id, 159 render_process_id,
181 render_view_id, 160 render_view_id,
182 security_origin); 161 security_origin);
183 StartEnumeration(&new_request, label); 162 StartEnumeration(&new_request, label);
184 163
185 // Get user confirmation to use capture devices. 164 // Get user confirmation to use capture devices.
186 device_settings_->RequestCaptureDeviceUsage(*label, 165 device_settings_->RequestCaptureDeviceUsage(*label,
187 render_process_id, 166 render_process_id,
188 render_view_id, 167 render_view_id,
189 options, 168 options,
190 security_origin); 169 security_origin);
191 } 170 }
192 171
172 void MediaStreamManager::GenerateStreamForDevice(
173 MediaStreamRequester* requester, int render_process_id, int render_view_id,
174 const StreamOptions& options, const std::string& device_id,
175 const GURL& security_origin, std::string* label) {
176 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
177
178 // Create a new request based on options.
179 AddRequest(DeviceRequest(requester, options,
180 render_process_id, render_view_id,
181 security_origin),
182 label);
183 DeviceRequest& request = requests_[*label];
184
185 // Get user confirmation to use the capture device.
186 device_settings_->RequestCaptureDeviceUsage(*label,
187 render_process_id,
188 render_view_id,
189 options,
190 security_origin);
191 // TODO(miu): We should ask the device manager whether a device with id
192 // |device_id| actually exists. Note that no such MediaStreamProvider API for
193 // this currently exists. Also, we don't have a user-friendly device name for
194 // the infobar UI.
195 if (content::IsAudioMediaType(options.audio_type)) {
196 request.state[options.audio_type] = DeviceRequest::STATE_PENDING_APPROVAL;
197 device_settings_->AvailableDevices(
198 *label, options.audio_type, StreamDeviceInfoArray(
199 1, StreamDeviceInfo(options.audio_type, device_id, device_id,
200 false)));
201 }
202 if (content::IsVideoMediaType(options.video_type)) {
203 request.state[options.video_type] = DeviceRequest::STATE_PENDING_APPROVAL;
204 device_settings_->AvailableDevices(
205 *label, options.video_type, StreamDeviceInfoArray(
206 1, StreamDeviceInfo(options.video_type, device_id, device_id,
207 false)));
208 }
209 }
210
193 void MediaStreamManager::CancelGenerateStream(const std::string& label) { 211 void MediaStreamManager::CancelGenerateStream(const std::string& label) {
194 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 212 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
195 213
196 DeviceRequests::iterator it = requests_.find(label); 214 DeviceRequests::iterator it = requests_.find(label);
197 if (it != requests_.end()) { 215 if (it != requests_.end()) {
198 // The request isn't complete. 216 // The request isn't complete.
199 if (!RequestDone(it->second)) { 217 if (!RequestDone(it->second)) {
200 DeviceRequest* request = &(it->second); 218 DeviceRequest& request = it->second;
201 if (request->state[content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE] == 219 for (int i = content::MEDIA_NO_SERVICE + 1; i < content::NUM_MEDIA_TYPES;
202 DeviceRequest::STATE_OPENING) { 220 ++i) {
203 for (StreamDeviceInfoArray::iterator it = 221 const MediaStreamType stream_type = static_cast<MediaStreamType>(i);
204 request->audio_devices.begin(); it != request->audio_devices.end(); 222 if (request.state[stream_type] != DeviceRequest::STATE_OPENING) {
205 ++it) { 223 continue;
206 audio_input_device_manager()->Close(it->session_id);
207 } 224 }
208 } 225 for (StreamDeviceInfoArray::const_iterator device_it =
209 if (request->state[content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE] == 226 request.devices.begin();
210 DeviceRequest::STATE_OPENING) { 227 device_it != request.devices.end(); ++device_it) {
211 for (StreamDeviceInfoArray::iterator it = 228 if (device_it->stream_type == stream_type) {
212 request->video_devices.begin(); it != request->video_devices.end(); 229 GetDeviceManager(stream_type)->Close(device_it->session_id);
213 ++it) { 230 }
214 video_capture_manager()->Close(it->session_id);
215 } 231 }
216 } 232 }
217 requests_.erase(it); 233 requests_.erase(it);
218 } else { 234 } else {
219 StopGeneratedStream(label); 235 StopGeneratedStream(label);
220 } 236 }
221 device_settings_->RemovePendingCaptureRequest(label); 237 device_settings_->RemovePendingCaptureRequest(label);
222 } 238 }
223 } 239 }
224 240
225 void MediaStreamManager::StopGeneratedStream(const std::string& label) { 241 void MediaStreamManager::StopGeneratedStream(const std::string& label) {
226 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 242 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
227 // Find the request and close all open devices for the request. 243 // Find the request and close all open devices for the request.
228 DeviceRequests::iterator it = requests_.find(label); 244 DeviceRequests::iterator it = requests_.find(label);
229 if (it != requests_.end()) { 245 if (it != requests_.end()) {
230 if (it->second.type == DeviceRequest::ENUMERATE_DEVICES) { 246 if (it->second.type == DeviceRequest::ENUMERATE_DEVICES) {
231 StopEnumerateDevices(label); 247 StopEnumerateDevices(label);
232 return; 248 return;
233 } 249 }
234 for (StreamDeviceInfoArray::iterator audio_it = 250 for (StreamDeviceInfoArray::const_iterator device_it =
235 it->second.audio_devices.begin(); 251 it->second.devices.begin();
236 audio_it != it->second.audio_devices.end(); ++audio_it) { 252 device_it != it->second.devices.end(); ++device_it) {
237 audio_input_device_manager()->Close(audio_it->session_id); 253 GetDeviceManager(device_it->stream_type)->Close(device_it->session_id);
238 }
239 for (StreamDeviceInfoArray::iterator video_it =
240 it->second.video_devices.begin();
241 video_it != it->second.video_devices.end(); ++video_it) {
242 video_capture_manager()->Close(video_it->session_id);
243 } 254 }
244 if (it->second.type == DeviceRequest::GENERATE_STREAM && 255 if (it->second.type == DeviceRequest::GENERATE_STREAM &&
245 RequestDone(it->second)) { 256 RequestDone(it->second)) {
246 NotifyObserverDevicesClosed(&(it->second)); 257 NotifyObserverDevicesClosed(&(it->second));
247 } 258 }
248 requests_.erase(it); 259 requests_.erase(it);
249 } 260 }
250 } 261 }
251 262
252 void MediaStreamManager::EnumerateDevices( 263 void MediaStreamManager::EnumerateDevices(
253 MediaStreamRequester* requester, 264 MediaStreamRequester* requester,
254 int render_process_id, 265 int render_process_id,
255 int render_view_id, 266 int render_view_id,
256 MediaStreamType type, 267 MediaStreamType type,
257 const GURL& security_origin, 268 const GURL& security_origin,
258 std::string* label) { 269 std::string* label) {
259 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 270 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
260 DCHECK(type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE || 271 DCHECK(type == content::MEDIA_DEVICE_AUDIO_CAPTURE ||
261 type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE); 272 type == content::MEDIA_DEVICE_VIDEO_CAPTURE);
262 273
263 // Create a new request. 274 // Create a new request.
264 StreamOptions options; 275 StreamOptions options;
265 EnumerationCache* cache = NULL; 276 EnumerationCache* cache = NULL;
266 if (type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { 277 if (type == content::MEDIA_DEVICE_AUDIO_CAPTURE) {
267 options.audio = true; 278 options.audio_type = type;
268 cache = &audio_enumeration_cache_; 279 cache = &audio_enumeration_cache_;
280 } else if (type == content::MEDIA_DEVICE_VIDEO_CAPTURE) {
281 options.video_type = type;
282 cache = &video_enumeration_cache_;
269 } else { 283 } else {
270 options.video = true; 284 NOTREACHED();
271 cache = &video_enumeration_cache_; 285 return;
272 } 286 }
273 287
274 DeviceRequest new_request(requester, options, 288 DeviceRequest new_request(requester, options,
275 render_process_id, 289 render_process_id,
276 render_view_id, 290 render_view_id,
277 security_origin); 291 security_origin);
278 new_request.type = DeviceRequest::ENUMERATE_DEVICES; 292 new_request.type = DeviceRequest::ENUMERATE_DEVICES;
279 293
280 if (cache->valid) { 294 if (cache->valid) {
281 // Cached device list of this type exists. Just send it out. 295 // Cached device list of this type exists. Just send it out.
282 new_request.state[type] = DeviceRequest::STATE_REQUESTED; 296 new_request.state[type] = DeviceRequest::STATE_REQUESTED;
283 AddRequest(&new_request, label); 297 AddRequest(new_request, label);
284 // Need to post a task since the requester won't have label till 298 // Need to post a task since the requester won't have label till
285 // this function returns. 299 // this function returns.
286 BrowserThread::PostTask(BrowserThread::IO, 300 BrowserThread::PostTask(BrowserThread::IO,
287 FROM_HERE, 301 FROM_HERE,
288 base::Bind(&MediaStreamManager::SendCachedDeviceList, 302 base::Bind(&MediaStreamManager::SendCachedDeviceList,
289 base::Unretained(this), cache, *label)); 303 base::Unretained(this), cache, *label));
290 } else { 304 } else {
291 StartEnumeration(&new_request, label); 305 StartEnumeration(&new_request, label);
292 StartMonitoring(); 306 StartMonitoring();
293 } 307 }
(...skipping 14 matching lines...) Expand all
308 322
309 void MediaStreamManager::OpenDevice( 323 void MediaStreamManager::OpenDevice(
310 MediaStreamRequester* requester, 324 MediaStreamRequester* requester,
311 int render_process_id, 325 int render_process_id,
312 int render_view_id, 326 int render_view_id,
313 const std::string& device_id, 327 const std::string& device_id,
314 MediaStreamType type, 328 MediaStreamType type,
315 const GURL& security_origin, 329 const GURL& security_origin,
316 std::string* label) { 330 std::string* label) {
317 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 331 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
332 DCHECK(type == content::MEDIA_DEVICE_AUDIO_CAPTURE ||
333 type == content::MEDIA_DEVICE_VIDEO_CAPTURE);
318 334
319 // Create a new request. 335 // Create a new request.
320 StreamOptions options; 336 StreamOptions options;
321 if (type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) 337 if (content::IsAudioMediaType(type)) {
322 options.audio = true; 338 options.audio_type = type;
323 else 339 } else if (content::IsVideoMediaType(type)) {
324 options.video = true; 340 options.video_type = type;
341 } else {
342 NOTREACHED();
343 return;
344 }
325 345
326 DeviceRequest new_request(requester, options, 346 DeviceRequest new_request(requester, options,
327 render_process_id, 347 render_process_id,
328 render_view_id, 348 render_view_id,
329 security_origin); 349 security_origin);
330 new_request.type = DeviceRequest::OPEN_DEVICE; 350 new_request.type = DeviceRequest::OPEN_DEVICE;
331 new_request.requested_device_id = device_id; 351 new_request.requested_device_id = device_id;
332 352
333 StartEnumeration(&new_request, label); 353 StartEnumeration(&new_request, label);
334 } 354 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
366 void MediaStreamManager::ClearEnumerationCache(EnumerationCache* cache) { 386 void MediaStreamManager::ClearEnumerationCache(EnumerationCache* cache) {
367 DCHECK_EQ(MessageLoop::current(), io_loop_); 387 DCHECK_EQ(MessageLoop::current(), io_loop_);
368 cache->valid = false; 388 cache->valid = false;
369 } 389 }
370 390
371 void MediaStreamManager::StartEnumeration( 391 void MediaStreamManager::StartEnumeration(
372 DeviceRequest* new_request, 392 DeviceRequest* new_request,
373 std::string* label) { 393 std::string* label) {
374 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 394 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
375 395
376 MediaStreamType stream_type = content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE; 396 for (int i = content::MEDIA_NO_SERVICE + 1; i < content::NUM_MEDIA_TYPES;
377 if (Requested(new_request->options, stream_type)) { 397 ++i) {
378 new_request->state[stream_type] = DeviceRequest::STATE_REQUESTED; 398 const MediaStreamType stream_type = static_cast<MediaStreamType>(i);
379 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0); 399 if (Requested(new_request->options, stream_type)) {
380 if (!active_enumeration_ref_count_[stream_type]) { 400 new_request->state[stream_type] = DeviceRequest::STATE_REQUESTED;
381 ++active_enumeration_ref_count_[stream_type]; 401 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0);
382 GetDeviceManager(stream_type)->EnumerateDevices(); 402 if (active_enumeration_ref_count_[stream_type] == 0) {
383 } 403 ++active_enumeration_ref_count_[stream_type];
384 } 404 GetDeviceManager(stream_type)->EnumerateDevices();
385 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE; 405 }
386 if (Requested(new_request->options, stream_type)) {
387 new_request->state[stream_type] = DeviceRequest::STATE_REQUESTED;
388 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0);
389 if (!active_enumeration_ref_count_[stream_type]) {
390 ++active_enumeration_ref_count_[stream_type];
391 GetDeviceManager(stream_type)->EnumerateDevices();
392 } 406 }
393 } 407 }
394 408
395 AddRequest(new_request, label); 409 AddRequest(*new_request, label);
396 } 410 }
397 411
398 void MediaStreamManager::AddRequest( 412 void MediaStreamManager::AddRequest(
399 DeviceRequest* new_request, 413 const DeviceRequest& new_request,
400 std::string* label) { 414 std::string* label) {
401 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 415 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
402 416
403 // Create a label for this request and verify it is unique. 417 // Create a label for this request and verify it is unique.
404 std::string request_label; 418 std::string request_label;
405 do { 419 do {
406 request_label = RandomLabel(); 420 request_label = RandomLabel();
407 } while (requests_.find(request_label) != requests_.end()); 421 } while (requests_.find(request_label) != requests_.end());
408 422
409 requests_.insert(std::make_pair(request_label, *new_request)); 423 requests_.insert(std::make_pair(request_label, new_request));
410 424
411 (*label) = request_label; 425 (*label) = request_label;
412 } 426 }
413 427
414 void MediaStreamManager::EnsureDeviceThreadAndListener() { 428 void MediaStreamManager::EnsureDeviceManagerStarted(
429 MediaStreamType stream_type) {
415 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 430 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
416 if (device_thread_.get())
417 return;
418 431
419 device_thread_.reset(new DeviceThread("MediaStreamDeviceThread")); 432 if (!device_thread_.get()) {
420 CHECK(device_thread_->Start()); 433 device_thread_.reset(new DeviceThread("MediaStreamDeviceThread"));
434 CHECK(device_thread_->Start());
435 }
421 436
422 audio_input_device_manager_->Register(this, 437 if (!device_manager_[stream_type]) {
423 device_thread_->message_loop_proxy()); 438 switch (stream_type) {
424 video_capture_manager_->Register(this, device_thread_->message_loop_proxy()); 439 case content::MEDIA_DEVICE_AUDIO_CAPTURE:
440 case content::MEDIA_TAB_AUDIO_CAPTURE:
441 device_manager_[stream_type] =
442 new media_stream::AudioInputDeviceManager(audio_manager_,
443 stream_type);
444 break;
445 case content::MEDIA_DEVICE_VIDEO_CAPTURE:
446 case content::MEDIA_TAB_VIDEO_CAPTURE:
447 device_manager_[stream_type] =
448 new media_stream::VideoCaptureManager(stream_type);
449 break;
450 default:
451 LOG(FATAL) << "Cannot create device manager for invalid or "
452 << "unsupported MediaStreamType " << stream_type;
453 return;
454 }
455 device_manager_[stream_type]->Register(
456 this, device_thread_->message_loop_proxy());
457 }
425 458
426 // We want to be notified of IO message loop destruction to delete the thread 459 // We want to be notified of IO message loop destruction to delete the thread
427 // and the device managers. 460 // and the device managers.
428 io_loop_ = MessageLoop::current(); 461 if (!io_loop_) {
429 io_loop_->AddDestructionObserver(this); 462 io_loop_ = MessageLoop::current();
463 io_loop_->AddDestructionObserver(this);
464 }
430 } 465 }
431 466
432 void MediaStreamManager::Opened(MediaStreamType stream_type, 467 void MediaStreamManager::Opened(MediaStreamType stream_type,
433 int capture_session_id) { 468 int capture_session_id) {
434 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 469 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
435 470
436 // Find the request containing this device and mark it as used. 471 // Find the request containing this device and mark it as used.
437 DeviceRequest* request = NULL; 472 DeviceRequest* request = NULL;
438 StreamDeviceInfoArray* devices = NULL; 473 StreamDeviceInfoArray* devices = NULL;
439 std::string label; 474 std::string label;
440 for (DeviceRequests::iterator request_it = requests_.begin(); 475 for (DeviceRequests::iterator request_it = requests_.begin();
441 request_it != requests_.end() && request == NULL; ++request_it) { 476 request_it != requests_.end() && request == NULL; ++request_it) {
442 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { 477 devices = &(request_it->second.devices);
443 devices = &(request_it->second.audio_devices);
444 } else if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) {
445 devices = &(request_it->second.video_devices);
446 } else {
447 NOTREACHED();
448 }
449
450 for (StreamDeviceInfoArray::iterator device_it = devices->begin(); 478 for (StreamDeviceInfoArray::iterator device_it = devices->begin();
451 device_it != devices->end(); ++device_it) { 479 device_it != devices->end(); ++device_it) {
452 if (device_it->session_id == capture_session_id) { 480 if (device_it->stream_type == stream_type &&
481 device_it->session_id == capture_session_id) {
453 // We've found the request. 482 // We've found the request.
454 device_it->in_use = true; 483 device_it->in_use = true;
455 label = request_it->first; 484 label = request_it->first;
456 request = &(request_it->second); 485 request = &(request_it->second);
457 break; 486 break;
458 } 487 }
459 } 488 }
460 } 489 }
461 if (request == NULL) { 490 if (request == NULL) {
462 // The request doesn't exist. 491 // The request doesn't exist.
463 return; 492 return;
464 } 493 }
465 494
466 DCHECK_NE(request->state[stream_type], DeviceRequest::STATE_REQUESTED); 495 DCHECK_NE(request->state[stream_type], DeviceRequest::STATE_REQUESTED);
467 496
468 // Check if all devices for this stream type are opened. Update the state if 497 // Check if all devices for this stream type are opened. Update the state if
469 // they are. 498 // they are.
470 for (StreamDeviceInfoArray::iterator device_it = devices->begin(); 499 for (StreamDeviceInfoArray::iterator device_it = devices->begin();
471 device_it != devices->end(); ++device_it) { 500 device_it != devices->end(); ++device_it) {
501 if (device_it->stream_type != stream_type) {
502 continue;
503 }
472 if (device_it->in_use == false) { 504 if (device_it->in_use == false) {
473 // Wait for more devices to be opened before we're done. 505 // Wait for more devices to be opened before we're done.
474 return; 506 return;
475 } 507 }
476 } 508 }
477 request->state[stream_type] = DeviceRequest::STATE_DONE; 509 request->state[stream_type] = DeviceRequest::STATE_DONE;
478 510
479 if (!RequestDone(*request)) { 511 if (!RequestDone(*request)) {
480 // This stream_type is done, but not the other type. 512 // This stream_type is done, but not the other type.
481 return; 513 return;
482 } 514 }
483 515
484 switch (request->type) { 516 switch (request->type) {
485 case DeviceRequest::OPEN_DEVICE: 517 case DeviceRequest::OPEN_DEVICE:
486 request->requester->DeviceOpened(label, (*devices)[0]); 518 request->requester->DeviceOpened(label, devices->front());
487 break; 519 break;
488 case DeviceRequest::GENERATE_STREAM: 520 case DeviceRequest::GENERATE_STREAM: {
489 request->requester->StreamGenerated(label, request->audio_devices, 521 // Partition the array of devices into audio vs video.
490 request->video_devices); 522 StreamDeviceInfoArray audio_devices, video_devices;
523 for (StreamDeviceInfoArray::const_iterator device_it = devices->begin();
524 device_it != devices->end(); ++device_it) {
525 if (content::IsAudioMediaType(device_it->stream_type)) {
526 audio_devices.push_back(*device_it);
527 } else if (content::IsVideoMediaType(device_it->stream_type)) {
528 video_devices.push_back(*device_it);
529 } else {
530 NOTREACHED();
531 }
532 }
533
534 request->requester->StreamGenerated(label, audio_devices, video_devices);
491 NotifyObserverDevicesOpened(request); 535 NotifyObserverDevicesOpened(request);
492 break; 536 break;
537 }
493 default: 538 default:
494 NOTREACHED(); 539 NOTREACHED();
540 break;
495 } 541 }
496 } 542 }
497 543
498 void MediaStreamManager::Closed(MediaStreamType stream_type, 544 void MediaStreamManager::Closed(MediaStreamType stream_type,
499 int capture_session_id) { 545 int capture_session_id) {
500 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 546 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
501 } 547 }
502 548
503 void MediaStreamManager::DevicesEnumerated( 549 void MediaStreamManager::DevicesEnumerated(
504 MediaStreamType stream_type, const StreamDeviceInfoArray& devices) { 550 MediaStreamType stream_type, const StreamDeviceInfoArray& devices) {
505 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 551 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
506 552
507 // Only cache device list when there is EnumerateDevices request, since 553 // Only cache the device list when there is an EnumerateDevices request, since
508 // other requests don't turn on device monitoring. 554 // other requests don't turn on device monitoring.
509 bool need_update_clients = false; 555 bool need_update_clients = false;
510 EnumerationCache* cache = 556 EnumerationCache* cache =
511 (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE ? 557 (stream_type == content::MEDIA_DEVICE_AUDIO_CAPTURE ?
512 &audio_enumeration_cache_ : &video_enumeration_cache_); 558 &audio_enumeration_cache_ : &video_enumeration_cache_);
513 if (HasEnumerationRequest(stream_type) && 559 if (HasEnumerationRequest(stream_type) &&
514 (!cache->valid || 560 (!cache->valid ||
515 devices.size() != cache->devices.size() || 561 devices.size() != cache->devices.size() ||
516 !std::equal(devices.begin(), devices.end(), cache->devices.begin(), 562 !std::equal(devices.begin(), devices.end(), cache->devices.begin(),
517 media_stream::StreamDeviceInfo::IsEqual))) { 563 media_stream::StreamDeviceInfo::IsEqual))) {
518 cache->valid = true; 564 cache->valid = true;
519 cache->devices = devices; 565 cache->devices = devices;
520 need_update_clients = true; 566 need_update_clients = true;
521 } 567 }
(...skipping 14 matching lines...) Expand all
536 } 582 }
537 for (std::list<std::string>::iterator it = label_list.begin(); 583 for (std::list<std::string>::iterator it = label_list.begin();
538 it != label_list.end(); ++it) { 584 it != label_list.end(); ++it) {
539 DeviceRequest& request = requests_[*it]; 585 DeviceRequest& request = requests_[*it];
540 switch (request.type) { 586 switch (request.type) {
541 case DeviceRequest::ENUMERATE_DEVICES: 587 case DeviceRequest::ENUMERATE_DEVICES:
542 if (need_update_clients) 588 if (need_update_clients)
543 request.requester->DevicesEnumerated(*it, devices); 589 request.requester->DevicesEnumerated(*it, devices);
544 break; 590 break;
545 case DeviceRequest::OPEN_DEVICE: 591 case DeviceRequest::OPEN_DEVICE:
592 DCHECK(!request.requested_device_id.empty());
546 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin(); 593 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin();
547 device_it != devices.end(); device_it++) { 594 device_it != devices.end(); ++device_it) {
548 if (request.requested_device_id == device_it->device_id) { 595 if (request.requested_device_id == device_it->device_id) {
549 StreamDeviceInfo device = *device_it; 596 StreamDeviceInfo device = *device_it;
550 device.in_use = false; 597 device.in_use = false;
551 device.session_id = 598 device.session_id =
552 GetDeviceManager(device_it->stream_type)->Open(device); 599 GetDeviceManager(device_it->stream_type)->Open(device);
553 request.state[device_it->stream_type] = 600 request.state[device_it->stream_type] =
554 DeviceRequest::STATE_OPENING; 601 DeviceRequest::STATE_OPENING;
555 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) 602 request.devices.push_back(device);
556 request.audio_devices.push_back(device);
557 else
558 request.video_devices.push_back(device);
559 break; 603 break;
560 } 604 }
561 } 605 }
562 break; 606 break;
563 default: 607 default:
564 device_settings_->AvailableDevices(*it, stream_type, devices); 608 device_settings_->AvailableDevices(*it, stream_type, devices);
609 break;
565 } 610 }
566 } 611 }
567 label_list.clear(); 612 label_list.clear();
568 --active_enumeration_ref_count_[stream_type]; 613 --active_enumeration_ref_count_[stream_type];
569 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0); 614 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0);
570 } 615 }
571 616
572 void MediaStreamManager::Error(MediaStreamType stream_type, 617 void MediaStreamManager::Error(MediaStreamType stream_type,
573 int capture_session_id, 618 int capture_session_id,
574 MediaStreamProviderError error) { 619 MediaStreamProviderError error) {
575 // Find the device for the error call. 620 // Find the device for the error call.
576 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 621 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
622
577 for (DeviceRequests::iterator it = requests_.begin(); it != requests_.end(); 623 for (DeviceRequests::iterator it = requests_.begin(); it != requests_.end();
578 ++it) { 624 ++it) {
579 StreamDeviceInfoArray* devices = NULL; 625 StreamDeviceInfoArray& devices = it->second.devices;
580 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) {
581 devices = &(it->second.audio_devices);
582 } else if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) {
583 devices = &(it->second.video_devices);
584 } else {
585 NOTREACHED();
586 }
587 626
588 int device_idx = 0; 627 int audio_device_idx = -1;
589 for (StreamDeviceInfoArray::iterator device_it = devices->begin(); 628 int video_device_idx = -1;
590 device_it != devices->end(); ++device_it, ++device_idx) { 629 for (StreamDeviceInfoArray::iterator device_it = devices.begin();
591 if (device_it->session_id == capture_session_id) { 630 device_it != devices.end(); ++device_it) {
592 // We've found the failing device. Find the error case: 631 if (content::IsAudioMediaType(device_it->stream_type)) {
593 if (it->second.state[stream_type] == DeviceRequest::STATE_DONE) { 632 ++audio_device_idx;
594 // 1. Already opened -> signal device failure and close device. 633 } else if (content::IsVideoMediaType(device_it->stream_type)) {
595 // Use device_idx to signal which of the devices encountered an 634 ++video_device_idx;
596 // error. 635 } else {
597 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { 636 NOTREACHED();
598 it->second.requester->AudioDeviceFailed(it->first, device_idx); 637 continue;
599 } else if (stream_type == 638 }
600 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) { 639 if (device_it->stream_type != stream_type ||
601 it->second.requester->VideoDeviceFailed(it->first, device_idx); 640 device_it->session_id != capture_session_id) {
602 } 641 continue;
603 GetDeviceManager(stream_type)->Close(capture_session_id); 642 }
604 // We don't erase the devices here so that we can update the UI 643 // We've found the failing device. Find the error case:
605 // properly in StopGeneratedStream(). 644 if (it->second.state[stream_type] == DeviceRequest::STATE_DONE) {
606 it->second.state[stream_type] = DeviceRequest::STATE_ERROR; 645 // 1. Already opened -> signal device failure and close device.
646 // Use device_idx to signal which of the devices encountered an
647 // error.
648 if (content::IsAudioMediaType(stream_type)) {
649 it->second.requester->AudioDeviceFailed(it->first, audio_device_idx);
650 } else if (content::IsVideoMediaType(stream_type)) {
651 it->second.requester->VideoDeviceFailed(it->first, video_device_idx);
607 } else { 652 } else {
608 // Request is not done, devices are not opened in this case. 653 NOTREACHED();
609 if ((it->second.audio_devices.size() + 654 return;
610 it->second.video_devices.size()) <= 1) {
611 // 2. Device not opened and no other devices for this request ->
612 // signal stream error and remove the request.
613 it->second.requester->StreamGenerationFailed(it->first);
614 requests_.erase(it);
615 } else {
616 // 3. Not opened but other devices exists for this request -> remove
617 // device from list, but don't signal an error.
618 devices->erase(device_it);
619 }
620 } 655 }
621 return; 656 GetDeviceManager(stream_type)->Close(capture_session_id);
657 // We don't erase the devices here so that we can update the UI
658 // properly in StopGeneratedStream().
659 it->second.state[stream_type] = DeviceRequest::STATE_ERROR;
660 } else {
661 // Request is not done, devices are not opened in this case.
662 if (devices.size() <= 1) {
663 // 2. Device not opened and no other devices for this request ->
664 // signal stream error and remove the request.
665 it->second.requester->StreamGenerationFailed(it->first);
666 requests_.erase(it);
667 } else {
668 // 3. Not opened but other devices exists for this request -> remove
669 // device from list, but don't signal an error.
670 devices.erase(device_it); // NOTE: This invalidates device_it!
671 }
622 } 672 }
673 return;
623 } 674 }
624 } 675 }
625 } 676 }
626 677
627 void MediaStreamManager::DevicesAccepted(const std::string& label, 678 void MediaStreamManager::DevicesAccepted(const std::string& label,
628 const StreamDeviceInfoArray& devices) { 679 const StreamDeviceInfoArray& devices) {
629 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 680 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
630 DeviceRequests::iterator request_it = requests_.find(label); 681 DeviceRequests::iterator request_it = requests_.find(label);
631 if (request_it != requests_.end()) { 682 if (request_it == requests_.end()) {
632 if (devices.empty()) { 683 return;
633 // No available devices or user didn't accept device usage. 684 }
634 request_it->second.requester->StreamGenerationFailed(request_it->first); 685
635 requests_.erase(request_it); 686 DeviceRequest& request = request_it->second;
636 return; 687
688 if (devices.empty()) {
689 // No available devices or user didn't accept device usage.
690 request.requester->StreamGenerationFailed(request_it->first);
691 requests_.erase(request_it);
692 return;
693 }
694
695 // Process all newly-accepted devices for this request.
696 bool found_audio = false, found_video = false;
697 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin();
698 device_it != devices.end(); ++device_it) {
699 StreamDeviceInfo device_info = *device_it; // Make a copy.
700
701 // Set in_use to false to be able to track if this device has been
702 // opened. in_use might be true if the device type can be used in more
703 // than one session.
704 DCHECK_EQ(request.state[device_it->stream_type],
705 DeviceRequest::STATE_PENDING_APPROVAL);
706 device_info.in_use = false;
707 device_info.session_id =
708 GetDeviceManager(device_info.stream_type)->Open(device_info);
709 request.state[device_it->stream_type] = DeviceRequest::STATE_OPENING;
710 request.devices.push_back(device_info);
711
712 if (device_info.stream_type == request.options.audio_type) {
713 found_audio = true;
714 } else if (device_info.stream_type == request.options.video_type) {
715 found_video = true;
637 } 716 }
717 }
638 718
639 // Loop through all device types for this request. 719 // Check whether we've received all stream types requested.
640 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin(); 720 if (request.options.audio_type != content::MEDIA_NO_SERVICE &&
641 device_it != devices.end(); ++device_it) { 721 !found_audio) {
642 StreamDeviceInfo device_info = *device_it; 722 request.state[request.options.audio_type] = DeviceRequest::STATE_ERROR;
643 723 }
644 // Set in_use to false to be able to track if this device has been 724 if (request.options.video_type != content::MEDIA_NO_SERVICE &&
645 // opened. in_use might be true if the device type can be used in more 725 !found_video) {
646 // than one session. 726 request.state[request.options.video_type] = DeviceRequest::STATE_ERROR;
647 DCHECK_EQ(request_it->second.state[device_it->stream_type],
648 DeviceRequest::STATE_PENDING_APPROVAL);
649 device_info.in_use = false;
650 device_info.session_id =
651 GetDeviceManager(device_info.stream_type)->Open(device_info);
652 request_it->second.state[device_it->stream_type] =
653 DeviceRequest::STATE_OPENING;
654 if (device_info.stream_type ==
655 content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) {
656 request_it->second.audio_devices.push_back(device_info);
657 } else if (device_info.stream_type ==
658 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) {
659 request_it->second.video_devices.push_back(device_info);
660 } else {
661 NOTREACHED();
662 }
663 }
664 // Check if we received all stream types requested.
665 MediaStreamType stream_type =
666 content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE;
667 if (Requested(request_it->second.options, stream_type) &&
668 request_it->second.audio_devices.size() == 0) {
669 request_it->second.state[stream_type] = DeviceRequest::STATE_ERROR;
670 }
671 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE;
672 if (Requested(request_it->second.options, stream_type) &&
673 request_it->second.video_devices.size() == 0) {
674 request_it->second.state[stream_type] = DeviceRequest::STATE_ERROR;
675 }
676 return;
677 } 727 }
678 } 728 }
679 729
680 void MediaStreamManager::SettingsError(const std::string& label) { 730 void MediaStreamManager::SettingsError(const std::string& label) {
681 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 731 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
682 // Erase this request and report an error. 732 // Erase this request and report an error.
683 DeviceRequests::iterator it = requests_.find(label); 733 DeviceRequests::iterator it = requests_.find(label);
684 if (it != requests_.end()) { 734 if (it != requests_.end()) {
685 DCHECK_EQ(it->second.type, DeviceRequest::GENERATE_STREAM); 735 DCHECK_EQ(it->second.type, DeviceRequest::GENERATE_STREAM);
686 it->second.requester->StreamGenerationFailed(label); 736 it->second.requester->StreamGenerationFailed(label);
687 requests_.erase(it); 737 requests_.erase(it);
688 return; 738 return;
689 } 739 }
690 } 740 }
691 741
692 void MediaStreamManager::UseFakeDevice() { 742 void MediaStreamManager::UseFakeDevice() {
693 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 743 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
694 video_capture_manager()->UseFakeDevice(); 744 for (int i = content::MEDIA_NO_SERVICE + 1; i < content::NUM_MEDIA_TYPES;
745 ++i) {
746 const MediaStreamType stream_type = static_cast<MediaStreamType>(i);
747 if (content::IsVideoMediaType(stream_type)) {
748 GetVideoCaptureManager(stream_type)->UseFakeDevice();
749 }
750 }
695 device_settings_->UseFakeUI(); 751 device_settings_->UseFakeUI();
696 } 752 }
697 753
698 void MediaStreamManager::WillDestroyCurrentMessageLoop() { 754 void MediaStreamManager::WillDestroyCurrentMessageLoop() {
699 DCHECK_EQ(MessageLoop::current(), io_loop_); 755 DCHECK_EQ(MessageLoop::current(), io_loop_);
700 DCHECK(requests_.empty()); 756 DCHECK(requests_.empty());
701 if (device_thread_.get()) { 757 if (device_thread_.get()) {
702 StopMonitoring(); 758 StopMonitoring();
703 759
704 video_capture_manager_->Unregister(); 760 for (int i = content::MEDIA_NO_SERVICE + 1; i < content::NUM_MEDIA_TYPES;
705 audio_input_device_manager_->Unregister(); 761 ++i) {
762 if (device_manager_[i]) {
763 device_manager_[i]->Unregister();
764 }
765 }
766
706 device_thread_.reset(); 767 device_thread_.reset();
707 } 768 }
708 769
709 audio_input_device_manager_ = NULL; 770 for (int i = content::MEDIA_NO_SERVICE + 1; i < content::NUM_MEDIA_TYPES;
710 video_capture_manager_ = NULL; 771 ++i) {
772 device_manager_[i] = NULL;
773 }
711 io_loop_ = NULL; 774 io_loop_ = NULL;
712 device_settings_.reset(); 775 device_settings_.reset();
713 } 776 }
714 777
715 void MediaStreamManager::NotifyObserverDevicesOpened(DeviceRequest* request) { 778 void MediaStreamManager::NotifyObserverDevicesOpened(DeviceRequest* request) {
716 content::MediaObserver* media_observer = 779 content::MediaObserver* media_observer =
717 content::GetContentClient()->browser()->GetMediaObserver(); 780 content::GetContentClient()->browser()->GetMediaObserver();
718 content::MediaStreamDevices opened_devices; 781 content::MediaStreamDevices opened_devices;
719 DevicesFromRequest(request, &opened_devices); 782 DevicesFromRequest(request, &opened_devices);
720 DCHECK(!opened_devices.empty()); 783 DCHECK(!opened_devices.empty());
721 media_observer->OnCaptureDevicesOpened(request->render_process_id, 784 media_observer->OnCaptureDevicesOpened(request->render_process_id,
722 request->render_view_id, 785 request->render_view_id,
723 opened_devices); 786 opened_devices);
724 } 787 }
725 788
726 void MediaStreamManager::NotifyObserverDevicesClosed(DeviceRequest* request) { 789 void MediaStreamManager::NotifyObserverDevicesClosed(DeviceRequest* request) {
727 content::MediaObserver* media_observer = 790 content::MediaObserver* media_observer =
728 content::GetContentClient()->browser()->GetMediaObserver(); 791 content::GetContentClient()->browser()->GetMediaObserver();
729 content::MediaStreamDevices closed_devices; 792 content::MediaStreamDevices closed_devices;
730 DevicesFromRequest(request, &closed_devices); 793 DevicesFromRequest(request, &closed_devices);
731 if (closed_devices.empty()) 794 if (closed_devices.empty())
732 return; 795 return;
733 media_observer->OnCaptureDevicesClosed(request->render_process_id, 796 media_observer->OnCaptureDevicesClosed(request->render_process_id,
734 request->render_view_id, 797 request->render_view_id,
735 closed_devices); 798 closed_devices);
736 } 799 }
737 800
738 void MediaStreamManager::DevicesFromRequest( 801 void MediaStreamManager::DevicesFromRequest(
739 DeviceRequest* request, content::MediaStreamDevices* devices) { 802 DeviceRequest* request, content::MediaStreamDevices* devices) {
740 StreamDeviceInfoArray::const_iterator it = request->audio_devices.begin(); 803 for (StreamDeviceInfoArray::const_iterator it = request->devices.begin();
741 for (; it != request->audio_devices.end(); ++it) { 804 it != request->devices.end(); ++it) {
742 devices->push_back( 805 devices->push_back(content::MediaStreamDevice(
743 content::MediaStreamDevice( 806 it->stream_type, it->device_id, it->name));
744 content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE,
745 it->device_id,
746 it->name));
747 }
748 for (it = request->video_devices.begin(); it != request->video_devices.end();
749 ++it) {
750 devices->push_back(
751 content::MediaStreamDevice(
752 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE,
753 it->device_id,
754 it->name));
755 } 807 }
756 } 808 }
757 809
758 bool MediaStreamManager::RequestDone(const DeviceRequest& request) const { 810 bool MediaStreamManager::RequestDone(const DeviceRequest& request) const {
759 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 811 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
760 // Check if all devices are opened.
761 MediaStreamType stream_type = content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE;
762 if (Requested(request.options, stream_type)) {
763 if (request.state[stream_type] != DeviceRequest::STATE_DONE &&
764 request.state[stream_type] != DeviceRequest::STATE_ERROR) {
765 return false;
766 }
767 812
768 for (StreamDeviceInfoArray::const_iterator it = 813 const bool requested_audio =
769 request.audio_devices.begin(); it != request.audio_devices.end(); 814 content::IsAudioMediaType(request.options.audio_type);
770 ++it) { 815 const bool requested_video =
771 if (it->in_use == false) { 816 content::IsVideoMediaType(request.options.video_type);
772 return false; 817
773 } 818 const bool audio_done =
774 } 819 !requested_audio ||
820 request.state[request.options.audio_type] == DeviceRequest::STATE_DONE ||
821 request.state[request.options.audio_type] == DeviceRequest::STATE_ERROR;
822 if (!audio_done) {
823 return false;
775 } 824 }
776 825
777 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE; 826 const bool video_done =
778 if (Requested(request.options, stream_type)) { 827 !requested_video ||
779 if (request.state[stream_type] != DeviceRequest::STATE_DONE && 828 request.state[request.options.video_type] == DeviceRequest::STATE_DONE ||
780 request.state[stream_type] != DeviceRequest::STATE_ERROR) { 829 request.state[request.options.video_type] == DeviceRequest::STATE_ERROR;
830 if (!video_done) {
831 return false;
832 }
833
834 for (StreamDeviceInfoArray::const_iterator it = request.devices.begin();
835 it != request.devices.end(); ++it) {
836 if (it->in_use == false) {
781 return false; 837 return false;
782 } 838 }
783
784 for (StreamDeviceInfoArray::const_iterator it =
785 request.video_devices.begin(); it != request.video_devices.end();
786 ++it) {
787 if (it->in_use == false) {
788 return false;
789 }
790 }
791 } 839 }
792 840
793 return true; 841 return true;
794 } 842 }
795 843
796 // Called to get media capture device manager of specified type.
797 MediaStreamProvider* MediaStreamManager::GetDeviceManager( 844 MediaStreamProvider* MediaStreamManager::GetDeviceManager(
798 MediaStreamType stream_type) { 845 MediaStreamType stream_type) {
799 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) { 846 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
800 return video_capture_manager(); 847 EnsureDeviceManagerStarted(stream_type);
801 } else if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { 848 return device_manager_[stream_type];
802 return audio_input_device_manager(); 849 }
803 } 850
804 NOTREACHED(); 851 VideoCaptureManager* MediaStreamManager::GetVideoCaptureManager(
805 return NULL; 852 MediaStreamType stream_type) {
853 DCHECK(content::IsVideoMediaType(stream_type));
854 return reinterpret_cast<VideoCaptureManager*>(GetDeviceManager(stream_type));
855 }
856
857 AudioInputDeviceManager* MediaStreamManager::GetAudioInputDeviceManager(
858 MediaStreamType stream_type) {
859 DCHECK(content::IsAudioMediaType(stream_type));
860 return reinterpret_cast<AudioInputDeviceManager*>(
861 GetDeviceManager(stream_type));
806 } 862 }
807 863
808 void MediaStreamManager::OnDevicesChanged( 864 void MediaStreamManager::OnDevicesChanged(
809 base::SystemMonitor::DeviceType device_type) { 865 base::SystemMonitor::DeviceType device_type) {
810 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 866 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
867
868 // NOTE: This method is only called in response to physical audio/video device
869 // changes (from the operating system).
870
811 MediaStreamType stream_type; 871 MediaStreamType stream_type;
812 EnumerationCache* cache; 872 EnumerationCache* cache;
813 if (device_type == base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE) { 873 if (device_type == base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE) {
814 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE; 874 stream_type = content::MEDIA_DEVICE_AUDIO_CAPTURE;
815 cache = &audio_enumeration_cache_; 875 cache = &audio_enumeration_cache_;
816 } else if (device_type == base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE) { 876 } else if (device_type == base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE) {
817 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE; 877 stream_type = content::MEDIA_DEVICE_VIDEO_CAPTURE;
818 cache = &video_enumeration_cache_; 878 cache = &video_enumeration_cache_;
819 } else { 879 } else {
820 return; // Uninteresting device change. 880 return; // Uninteresting device change.
821 } 881 }
822 882
823 if (!HasEnumerationRequest(stream_type)) { 883 if (!HasEnumerationRequest(stream_type)) {
824 // There is no request for that type, No need to enumerate devices. 884 // There is no request for that type, No need to enumerate devices.
825 // Therefore, invalidate the cache of that type. 885 // Therefore, invalidate the cache of that type.
826 ClearEnumerationCache(cache); 886 ClearEnumerationCache(cache);
827 return; 887 return;
(...skipping 24 matching lines...) Expand all
852 it != requests_.end(); ++it) { 912 it != requests_.end(); ++it) {
853 if (it->second.type == DeviceRequest::ENUMERATE_DEVICES && 913 if (it->second.type == DeviceRequest::ENUMERATE_DEVICES &&
854 Requested(it->second.options, stream_type)) { 914 Requested(it->second.options, stream_type)) {
855 return true; 915 return true;
856 } 916 }
857 } 917 }
858 return false; 918 return false;
859 } 919 }
860 920
861 } // namespace media_stream 921 } // namespace media_stream
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698