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

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

Powered by Google App Engine
This is Rietveld 408576698