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

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: Add CONTENT_EXPORT to resolve linker issues on components builds. Also, IWYU. 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 23 matching lines...) Expand all
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_STREAM_DEVICE_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_STREAM_DEVICE_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_STREAM_DEVICE_TYPE_NO_SERVICE + 1;
202 DeviceRequest::STATE_OPENING) { 180 i < content::NUM_MEDIA_STREAM_DEVICE_TYPES; ++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::iterator device_it =
no longer working on chromium 2012/08/31 13:38:23 nit, const_iterator
miu 2012/09/01 01:32:00 Done.
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::iterator device_it = it->second.devices.begin();
no longer working on chromium 2012/08/31 13:38:23 nit, const_iterator
miu 2012/09/01 01:32:00 Done.
235 it->second.audio_devices.begin(); 211 device_it != it->second.devices.end(); ++device_it) {
236 audio_it != it->second.audio_devices.end(); ++audio_it) { 212 GetDeviceManager(device_it->stream_type)->Close(device_it->session_id);
237 audio_input_device_manager()->Close(audio_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 } 213 }
244 if (it->second.type == DeviceRequest::GENERATE_STREAM && 214 if (it->second.type == DeviceRequest::GENERATE_STREAM &&
245 RequestDone(it->second)) { 215 RequestDone(it->second)) {
246 NotifyObserverDevicesClosed(&(it->second)); 216 NotifyObserverDevicesClosed(&(it->second));
247 } 217 }
248 requests_.erase(it); 218 requests_.erase(it);
249 } 219 }
250 } 220 }
251 221
252 void MediaStreamManager::EnumerateDevices( 222 void MediaStreamManager::EnumerateDevices(
253 MediaStreamRequester* requester, 223 MediaStreamRequester* requester,
254 int render_process_id, 224 int render_process_id,
255 int render_view_id, 225 int render_view_id,
256 MediaStreamType type, 226 MediaStreamType type,
257 const GURL& security_origin, 227 const GURL& security_origin,
258 std::string* label) { 228 std::string* label) {
259 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 229 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
260 DCHECK(type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE || 230 DCHECK_LT(content::MEDIA_STREAM_DEVICE_TYPE_NO_SERVICE, type);
261 type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE); 231 DCHECK_GT(content::NUM_MEDIA_STREAM_DEVICE_TYPES, type);
262 232
263 // Create a new request. 233 // Create a new request.
264 StreamOptions options; 234 StreamOptions options;
265 EnumerationCache* cache = NULL; 235 EnumerationCache* cache;
266 if (type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { 236 if (type == content::MEDIA_STREAM_DEVICE_TYPE_USER_AUDIO_CAPTURE) {
267 options.audio = true; 237 options.audio_type = type;
268 cache = &audio_enumeration_cache_; 238 cache = &user_audio_enumeration_cache_;
239 } else if (type == content::MEDIA_STREAM_DEVICE_TYPE_USER_VIDEO_CAPTURE) {
240 options.video_type = type;
241 cache = &user_video_enumeration_cache_;
269 } else { 242 } else {
270 options.video = true; 243 if (content::IsAudioMediaStreamDeviceType(type)) {
271 cache = &video_enumeration_cache_; 244 options.audio_type = type;
245 } else if (content::IsVideoMediaStreamDeviceType(type)) {
246 options.video_type = type;
247 }
248 cache = NULL;
272 } 249 }
273 250
274 DeviceRequest new_request(requester, options, 251 DeviceRequest new_request(requester, options,
275 render_process_id, 252 render_process_id,
276 render_view_id, 253 render_view_id,
277 security_origin); 254 security_origin);
278 new_request.type = DeviceRequest::ENUMERATE_DEVICES; 255 new_request.type = DeviceRequest::ENUMERATE_DEVICES;
279 256
280 if (cache->valid) { 257 if (cache && cache->valid) {
281 // Cached device list of this type exists. Just send it out. 258 // Cached device list of this type exists. Just send it out.
282 new_request.state[type] = DeviceRequest::STATE_REQUESTED; 259 new_request.state[type] = DeviceRequest::STATE_REQUESTED;
283 AddRequest(&new_request, label); 260 AddRequest(&new_request, label);
284 // Need to post a task since the requester won't have label till 261 // Need to post a task since the requester won't have label till
285 // this function returns. 262 // this function returns.
286 BrowserThread::PostTask(BrowserThread::IO, 263 BrowserThread::PostTask(BrowserThread::IO,
287 FROM_HERE, 264 FROM_HERE,
288 base::Bind(&MediaStreamManager::SendCachedDeviceList, 265 base::Bind(&MediaStreamManager::SendCachedDeviceList,
289 base::Unretained(this), cache, *label)); 266 base::Unretained(this), cache, *label));
290 } else { 267 } else {
291 StartEnumeration(&new_request, label); 268 StartEnumeration(&new_request, label);
292 StartMonitoring(); 269 if (cache) {
270 StartMonitoring();
271 }
293 } 272 }
294 } 273 }
295 274
296 void MediaStreamManager::StopEnumerateDevices(const std::string& label) { 275 void MediaStreamManager::StopEnumerateDevices(const std::string& label) {
297 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 276 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
298 277
299 DeviceRequests::iterator it = requests_.find(label); 278 DeviceRequests::iterator it = requests_.find(label);
300 if (it != requests_.end()) { 279 if (it != requests_.end()) {
301 DCHECK_EQ(it->second.type, DeviceRequest::ENUMERATE_DEVICES); 280 DCHECK_EQ(it->second.type, DeviceRequest::ENUMERATE_DEVICES);
302 requests_.erase(it); 281 requests_.erase(it);
303 if (!HasEnumerationRequest()) { 282 if (!HasEnumerationRequest()) {
304 StopMonitoring(); 283 StopMonitoring();
305 } 284 }
306 } 285 }
307 } 286 }
308 287
309 void MediaStreamManager::OpenDevice( 288 void MediaStreamManager::OpenDevice(
310 MediaStreamRequester* requester, 289 MediaStreamRequester* requester,
311 int render_process_id, 290 int render_process_id,
312 int render_view_id, 291 int render_view_id,
313 const std::string& device_id, 292 const std::string& device_id,
314 MediaStreamType type, 293 MediaStreamType type,
315 const GURL& security_origin, 294 const GURL& security_origin,
316 std::string* label) { 295 std::string* label) {
317 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 296 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
318 297
319 // Create a new request. 298 // Create a new request.
320 StreamOptions options; 299 StreamOptions options;
321 if (type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) 300 if (content::IsAudioMediaStreamDeviceType(type)) {
322 options.audio = true; 301 options.audio_type = type;
323 else 302 } else if (content::IsVideoMediaStreamDeviceType(type)) {
324 options.video = true; 303 options.video_type = type;
304 } else {
305 LOG(FATAL) << "Cannot handle request for MediaStreamType " << type;
306 return;
307 }
308 options.opt_device_id = device_id;
325 309
326 DeviceRequest new_request(requester, options, 310 DeviceRequest new_request(requester, options,
327 render_process_id, 311 render_process_id,
328 render_view_id, 312 render_view_id,
329 security_origin); 313 security_origin);
330 new_request.type = DeviceRequest::OPEN_DEVICE; 314 new_request.type = DeviceRequest::OPEN_DEVICE;
331 new_request.requested_device_id = device_id;
332 315
333 StartEnumeration(&new_request, label); 316 StartEnumeration(&new_request, label);
334 } 317 }
335 318
336 void MediaStreamManager::SendCachedDeviceList( 319 void MediaStreamManager::SendCachedDeviceList(
337 EnumerationCache* cache, 320 EnumerationCache* cache,
338 const std::string& label) { 321 const std::string& label) {
339 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 322 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
340 if (cache->valid) { 323 if (cache->valid) {
341 DeviceRequests::iterator it = requests_.find(label); 324 DeviceRequests::iterator it = requests_.find(label);
342 if (it != requests_.end()) { 325 if (it != requests_.end()) {
343 it->second.requester->DevicesEnumerated(label, cache->devices); 326 it->second.requester->DevicesEnumerated(label, cache->devices);
344 } 327 }
345 } 328 }
346 } 329 }
347 330
348 void MediaStreamManager::StartMonitoring() { 331 void MediaStreamManager::StartMonitoring() {
349 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 332 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
350 if (!monitoring_started_) { 333 if (!monitoring_started_) {
351 monitoring_started_ = true; 334 monitoring_started_ = true;
352 base::SystemMonitor::Get()->AddDevicesChangedObserver(this); 335 base::SystemMonitor::Get()->AddDevicesChangedObserver(this);
353 } 336 }
354 } 337 }
355 338
356 void MediaStreamManager::StopMonitoring() { 339 void MediaStreamManager::StopMonitoring() {
357 DCHECK_EQ(MessageLoop::current(), io_loop_); 340 DCHECK_EQ(MessageLoop::current(), io_loop_);
358 if (monitoring_started_ && !HasEnumerationRequest()) { 341 if (monitoring_started_ && !HasEnumerationRequest()) {
359 base::SystemMonitor::Get()->RemoveDevicesChangedObserver(this); 342 base::SystemMonitor::Get()->RemoveDevicesChangedObserver(this);
360 monitoring_started_ = false; 343 monitoring_started_ = false;
361 ClearEnumerationCache(&audio_enumeration_cache_); 344 ClearEnumerationCache(&user_audio_enumeration_cache_);
362 ClearEnumerationCache(&video_enumeration_cache_); 345 ClearEnumerationCache(&user_video_enumeration_cache_);
363 } 346 }
364 } 347 }
365 348
366 void MediaStreamManager::ClearEnumerationCache(EnumerationCache* cache) { 349 void MediaStreamManager::ClearEnumerationCache(EnumerationCache* cache) {
367 DCHECK_EQ(MessageLoop::current(), io_loop_); 350 DCHECK_EQ(MessageLoop::current(), io_loop_);
368 cache->valid = false; 351 cache->valid = false;
369 } 352 }
370 353
371 void MediaStreamManager::StartEnumeration( 354 void MediaStreamManager::StartEnumeration(
372 DeviceRequest* new_request, 355 DeviceRequest* new_request,
373 std::string* label) { 356 std::string* label) {
374 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 357 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
375 358
376 MediaStreamType stream_type = content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE; 359 for (int i = content::MEDIA_STREAM_DEVICE_TYPE_NO_SERVICE + 1;
377 if (Requested(new_request->options, stream_type)) { 360 i < content::NUM_MEDIA_STREAM_DEVICE_TYPES; ++i) {
378 new_request->state[stream_type] = DeviceRequest::STATE_REQUESTED; 361 const MediaStreamType stream_type = static_cast<MediaStreamType>(i);
379 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0); 362 if (Requested(new_request->options, stream_type)) {
380 if (!active_enumeration_ref_count_[stream_type]) { 363 new_request->state[stream_type] = DeviceRequest::STATE_REQUESTED;
381 ++active_enumeration_ref_count_[stream_type]; 364 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0);
382 GetDeviceManager(stream_type)->EnumerateDevices(); 365 if (active_enumeration_ref_count_[stream_type] == 0) {
383 } 366 ++active_enumeration_ref_count_[stream_type];
384 } 367 GetDeviceManager(stream_type)->EnumerateDevices();
385 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE; 368 }
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 } 369 }
393 } 370 }
394 371
395 AddRequest(new_request, label); 372 AddRequest(new_request, label);
396 } 373 }
397 374
398 void MediaStreamManager::AddRequest( 375 void MediaStreamManager::AddRequest(
399 DeviceRequest* new_request, 376 DeviceRequest* new_request,
400 std::string* label) { 377 std::string* label) {
401 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 378 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
402 379
403 // Create a label for this request and verify it is unique. 380 // Create a label for this request and verify it is unique.
404 std::string request_label; 381 std::string request_label;
405 do { 382 do {
406 request_label = RandomLabel(); 383 request_label = RandomLabel();
407 } while (requests_.find(request_label) != requests_.end()); 384 } while (requests_.find(request_label) != requests_.end());
408 385
409 requests_.insert(std::make_pair(request_label, *new_request)); 386 requests_.insert(std::make_pair(request_label, *new_request));
410 387
411 (*label) = request_label; 388 (*label) = request_label;
412 } 389 }
413 390
414 void MediaStreamManager::EnsureDeviceThreadAndListener() { 391 void MediaStreamManager::EnsureDeviceManagerStarted(
392 MediaStreamType stream_type) {
415 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 393 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
416 if (device_thread_.get())
417 return;
418 394
419 device_thread_.reset(new DeviceThread("MediaStreamDeviceThread")); 395 if (!device_thread_.get()) {
420 CHECK(device_thread_->Start()); 396 device_thread_.reset(new DeviceThread("MediaStreamDeviceThread"));
397 CHECK(device_thread_->Start());
398 }
421 399
422 audio_input_device_manager_->Register(this, 400 if (!audio_manager_) {
423 device_thread_->message_loop_proxy()); 401 audio_manager_ = content::BrowserMainLoop::GetAudioManager();
no longer working on chromium 2012/08/31 13:38:23 put this to the switch. So that video device unitt
miu 2012/09/01 01:32:00 Done.
424 video_capture_manager_->Register(this, device_thread_->message_loop_proxy()); 402 }
403
404 if (!device_manager_[stream_type].get()) {
no longer working on chromium 2012/08/31 13:38:23 nit, we don't need .get() here.
miu 2012/09/01 01:32:00 Done.
405 switch (stream_type) {
406 case content::MEDIA_STREAM_DEVICE_TYPE_USER_AUDIO_CAPTURE:
407 case content::MEDIA_STREAM_DEVICE_TYPE_TAB_AUDIO_CAPTURE:
408 device_manager_[stream_type] =
409 new media_stream::AudioInputDeviceManager(audio_manager_,
410 stream_type);
411 break;
412 case content::MEDIA_STREAM_DEVICE_TYPE_USER_VIDEO_CAPTURE:
413 case content::MEDIA_STREAM_DEVICE_TYPE_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]->
423 Register(this, device_thread_->message_loop_proxy());
no longer working on chromium 2012/08/31 13:38:23 nit, device_manager_[stream_type]->Register(
miu 2012/09/01 01:32:00 Done.
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::iterator device_it = devices->begin();
no longer working on chromium 2012/08/31 13:38:23 nit, const
miu 2012/09/01 01:32:00 Done.
486 device_it != devices->end(); ++device_it) {
487 if (content::IsAudioMediaStreamDeviceType(device_it->stream_type)) {
488 audio_devices.push_back(*device_it);
489 } else if (content::IsVideoMediaStreamDeviceType(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::IsAudioMediaStreamDeviceType(stream_type)) {
499 request->requester->DeviceOpened(label, audio_devices.front());
500 } else if (content::IsVideoMediaStreamDeviceType(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 a EnumerateDevices request, since
no longer working on chromium 2012/08/31 13:38:23 nit, an EnumerateDevices request
miu 2012/09/01 01:32:00 Done.
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_STREAM_DEVICE_TYPE_USER_AUDIO_CAPTURE) {
530 cache = &user_audio_enumeration_cache_;
531 } else if (stream_type ==
532 content::MEDIA_STREAM_DEVICE_TYPE_USER_VIDEO_CAPTURE) {
533 cache = &user_video_enumeration_cache_;
534 } else {
535 cache = NULL;
536 }
509 bool need_update_clients = false; 537 bool need_update_clients = false;
510 EnumerationCache* cache = 538 if (cache &&
511 (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE ? 539 HasEnumerationRequest(stream_type) &&
512 &audio_enumeration_cache_ : &video_enumeration_cache_);
513 if (HasEnumerationRequest(stream_type) &&
514 (!cache->valid || 540 (!cache->valid ||
515 devices.size() != cache->devices.size() || 541 devices.size() != cache->devices.size() ||
516 !std::equal(devices.begin(), devices.end(), cache->devices.begin(), 542 !std::equal(devices.begin(), devices.end(), cache->devices.begin(),
517 media_stream::StreamDeviceInfo::IsEqual))) { 543 media_stream::StreamDeviceInfo::IsEqual))) {
518 cache->valid = true; 544 cache->valid = true;
519 cache->devices = devices; 545 cache->devices = devices;
520 need_update_clients = true; 546 need_update_clients = true;
547 } else {
548 need_update_clients = (cache == NULL);
no longer working on chromium 2012/08/31 13:38:23 I am not familiar with this part of code, Wei, cou
miu 2012/09/01 01:32:00 I've added a comment to clarify this line of code,
521 } 549 }
522 550
523 // Publish the result for all requests waiting for device list(s). 551 // Publish the result for all requests waiting for device list(s).
524 // Find the requests waiting for this device list, store their labels and 552 // 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 553 // release the iterator before calling device settings. We might get a call
526 // back from device_settings that will need to iterate through devices. 554 // back from device_settings that will need to iterate through devices.
527 std::list<std::string> label_list; 555 std::list<std::string> label_list;
528 for (DeviceRequests::iterator it = requests_.begin(); it != requests_.end(); 556 for (DeviceRequests::iterator it = requests_.begin(); it != requests_.end();
529 ++it) { 557 ++it) {
530 if (it->second.state[stream_type] == DeviceRequest::STATE_REQUESTED && 558 if (it->second.state[stream_type] == DeviceRequest::STATE_REQUESTED &&
531 Requested(it->second.options, stream_type)) { 559 Requested(it->second.options, stream_type)) {
532 if (it->second.type != DeviceRequest::ENUMERATE_DEVICES) 560 if (it->second.type != DeviceRequest::ENUMERATE_DEVICES)
533 it->second.state[stream_type] = DeviceRequest::STATE_PENDING_APPROVAL; 561 it->second.state[stream_type] = DeviceRequest::STATE_PENDING_APPROVAL;
534 label_list.push_back(it->first); 562 label_list.push_back(it->first);
535 } 563 }
536 } 564 }
537 for (std::list<std::string>::iterator it = label_list.begin(); 565 for (std::list<std::string>::iterator it = label_list.begin();
538 it != label_list.end(); ++it) { 566 it != label_list.end(); ++it) {
539 DeviceRequest& request = requests_[*it]; 567 DeviceRequest& request = requests_[*it];
568
569 // If one specific device has been requested, prune all other devices out.
570 StreamDeviceInfoArray tmp;
571 const StreamDeviceInfoArray* pruned_devices;
572 if (request.options.opt_device_id.empty()) {
573 pruned_devices = &devices;
574 } else {
575 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin();
576 device_it != devices.end(); ++device_it) {
577 if (device_it->device_id == request.options.opt_device_id) {
578 tmp.push_back(*device_it);
579 }
580 }
581 pruned_devices = &tmp;
582 }
583
540 switch (request.type) { 584 switch (request.type) {
541 case DeviceRequest::ENUMERATE_DEVICES: 585 case DeviceRequest::ENUMERATE_DEVICES:
542 if (need_update_clients) 586 if (need_update_clients)
543 request.requester->DevicesEnumerated(*it, devices); 587 request.requester->DevicesEnumerated(*it, *pruned_devices);
544 break; 588 break;
545 case DeviceRequest::OPEN_DEVICE: 589 case DeviceRequest::OPEN_DEVICE:
546 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin(); 590 if (!pruned_devices->empty()) {
547 device_it != devices.end(); device_it++) { 591 StreamDeviceInfo device = pruned_devices->front();
548 if (request.requested_device_id == device_it->device_id) { 592 DCHECK_EQ(request.options.opt_device_id, device.device_id);
no longer working on chromium 2012/08/31 13:38:23 Do you know if we get hit this DCHECK if request.o
miu 2012/09/01 01:32:00 It can never be true for OPEN_DEVICE requests. I'
549 StreamDeviceInfo device = *device_it; 593 device.in_use = false;
550 device.in_use = false; 594 device.session_id =
551 device.session_id = 595 GetDeviceManager(device.stream_type)->Open(device);
552 GetDeviceManager(device_it->stream_type)->Open(device); 596 request.state[device.stream_type] = DeviceRequest::STATE_OPENING;
553 request.state[device_it->stream_type] = 597 request.devices.push_back(device);
554 DeviceRequest::STATE_OPENING;
555 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE)
556 request.audio_devices.push_back(device);
557 else
558 request.video_devices.push_back(device);
559 break;
560 }
561 } 598 }
562 break; 599 break;
563 default: 600 default:
564 device_settings_->AvailableDevices(*it, stream_type, devices); 601 device_settings_->AvailableDevices(*it, stream_type, *pruned_devices);
602 break;
565 } 603 }
566 } 604 }
567 label_list.clear(); 605 label_list.clear();
568 --active_enumeration_ref_count_[stream_type]; 606 --active_enumeration_ref_count_[stream_type];
569 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0); 607 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0);
570 } 608 }
571 609
572 void MediaStreamManager::Error(MediaStreamType stream_type, 610 void MediaStreamManager::Error(MediaStreamType stream_type,
573 int capture_session_id, 611 int capture_session_id,
574 MediaStreamProviderError error) { 612 MediaStreamProviderError error) {
575 // Find the device for the error call. 613 // Find the device for the error call.
576 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 614 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
615
577 for (DeviceRequests::iterator it = requests_.begin(); it != requests_.end(); 616 for (DeviceRequests::iterator it = requests_.begin(); it != requests_.end();
578 ++it) { 617 ++it) {
579 StreamDeviceInfoArray* devices = NULL; 618 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 619
588 int device_idx = 0; 620 int audio_device_idx = -1;
589 for (StreamDeviceInfoArray::iterator device_it = devices->begin(); 621 int video_device_idx = -1;
590 device_it != devices->end(); ++device_it, ++device_idx) { 622 for (StreamDeviceInfoArray::iterator device_it = devices.begin();
591 if (device_it->session_id == capture_session_id) { 623 device_it != devices.end(); ++device_it) {
592 // We've found the failing device. Find the error case: 624 if (content::IsAudioMediaStreamDeviceType(device_it->stream_type)) {
593 if (it->second.state[stream_type] == DeviceRequest::STATE_DONE) { 625 ++audio_device_idx;
594 // 1. Already opened -> signal device failure and close device. 626 } else if (content::IsVideoMediaStreamDeviceType(
595 // Use device_idx to signal which of the devices encountered an 627 device_it->stream_type)) {
596 // error. 628 ++video_device_idx;
597 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { 629 } else {
598 it->second.requester->AudioDeviceFailed(it->first, device_idx); 630 NOTREACHED();
599 } else if (stream_type == 631 continue;
600 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) { 632 }
601 it->second.requester->VideoDeviceFailed(it->first, device_idx); 633 if (device_it->stream_type != stream_type ||
602 } 634 device_it->session_id != capture_session_id) {
603 GetDeviceManager(stream_type)->Close(capture_session_id); 635 continue;
604 // We don't erase the devices here so that we can update the UI 636 }
605 // properly in StopGeneratedStream(). 637 // We've found the failing device. Find the error case:
606 it->second.state[stream_type] = DeviceRequest::STATE_ERROR; 638 if (it->second.state[stream_type] == DeviceRequest::STATE_DONE) {
639 // 1. Already opened -> signal device failure and close device.
640 // Use device_idx to signal which of the devices encountered an
641 // error.
642 if (content::IsAudioMediaStreamDeviceType(stream_type)) {
643 it->second.requester->AudioDeviceFailed(it->first, audio_device_idx);
644 } else if (content::IsVideoMediaStreamDeviceType(stream_type)) {
645 it->second.requester->VideoDeviceFailed(it->first, video_device_idx);
607 } else { 646 } else {
608 // Request is not done, devices are not opened in this case. 647 NOTREACHED();
609 if ((it->second.audio_devices.size() + 648 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 } 649 }
621 return; 650 GetDeviceManager(stream_type)->Close(capture_session_id);
651 // We don't erase the devices here so that we can update the UI
652 // properly in StopGeneratedStream().
653 it->second.state[stream_type] = DeviceRequest::STATE_ERROR;
654 } else {
655 // Request is not done, devices are not opened in this case.
656 if (devices.size() <= 1) {
657 // 2. Device not opened and no other devices for this request ->
658 // signal stream error and remove the request.
659 it->second.requester->StreamGenerationFailed(it->first);
660 requests_.erase(it);
661 } else {
662 // 3. Not opened but other devices exists for this request -> remove
663 // device from list, but don't signal an error.
664 devices.erase(device_it);
665 }
622 } 666 }
667 return;
623 } 668 }
624 } 669 }
625 } 670 }
626 671
627 void MediaStreamManager::DevicesAccepted(const std::string& label, 672 void MediaStreamManager::DevicesAccepted(const std::string& label,
628 const StreamDeviceInfoArray& devices) { 673 const StreamDeviceInfoArray& devices) {
629 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 674 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
630 DeviceRequests::iterator request_it = requests_.find(label); 675 DeviceRequests::iterator request_it = requests_.find(label);
631 if (request_it != requests_.end()) { 676 if (request_it == requests_.end()) {
632 if (devices.empty()) { 677 return;
633 // No available devices or user didn't accept device usage. 678 }
634 request_it->second.requester->StreamGenerationFailed(request_it->first); 679
635 requests_.erase(request_it); 680 DeviceRequest& request = request_it->second;
636 return; 681
682 if (devices.empty()) {
683 // No available devices or user didn't accept device usage.
684 request.requester->StreamGenerationFailed(request_it->first);
685 requests_.erase(request_it);
686 return;
687 }
688
689 // Process all newly-accepted devices for this request.
690 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin();
691 device_it != devices.end(); ++device_it) {
692 StreamDeviceInfo device_info = *device_it; // make a copy
693
694 // Set in_use to false to be able to track if this device has been
695 // opened. in_use might be true if the device type can be used in more
696 // than one session.
697 DCHECK_EQ(request.state[device_it->stream_type],
698 DeviceRequest::STATE_PENDING_APPROVAL);
699 device_info.in_use = false;
700 device_info.session_id =
701 GetDeviceManager(device_info.stream_type)->Open(device_info);
702 request.state[device_it->stream_type] = DeviceRequest::STATE_OPENING;
703 request.devices.push_back(device_info);
704 }
705
706 // Check whether we've received all stream types requested.
707 bool found_audio = false, found_video = false;
708 for (StreamDeviceInfoArray::const_iterator i = request.devices.begin();
709 i != request.devices.end(); ++i) {
710 if (i->stream_type == request.options.audio_type) {
711 found_audio = true;
712 } else if (i->stream_type == request.options.video_type) {
713 found_video = true;
714 } else {
715 NOTREACHED();
637 } 716 }
638 717 }
639 // Loop through all device types for this request. 718 if (request.options.audio_type !=
640 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin(); 719 content::MEDIA_STREAM_DEVICE_TYPE_NO_SERVICE &&
641 device_it != devices.end(); ++device_it) { 720 !found_audio) {
642 StreamDeviceInfo device_info = *device_it; 721 request.state[request.options.audio_type] = DeviceRequest::STATE_ERROR;
643 722 }
644 // Set in_use to false to be able to track if this device has been 723 if (request.options.video_type !=
645 // opened. in_use might be true if the device type can be used in more 724 content::MEDIA_STREAM_DEVICE_TYPE_NO_SERVICE &&
646 // than one session. 725 !found_video) {
647 DCHECK_EQ(request_it->second.state[device_it->stream_type], 726 request.state[request.options.video_type] = DeviceRequest::STATE_ERROR;
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
742 void MediaStreamManager::UseAudioManager(media::AudioManager* audio_manager) {
743 LOG_IF(FATAL, (audio_manager_ != NULL) && (audio_manager_ != audio_manager))
744 << "Cannot override AudioManager after it has been set.";
745 audio_manager_ = audio_manager;
746 }
747
692 void MediaStreamManager::UseFakeDevice() { 748 void MediaStreamManager::UseFakeDevice() {
693 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 749 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
694 video_capture_manager()->UseFakeDevice(); 750 for (int i = content::MEDIA_STREAM_DEVICE_TYPE_NO_SERVICE + 1;
751 i < content::NUM_MEDIA_STREAM_DEVICE_TYPES; ++i) {
752 const MediaStreamType stream_type = static_cast<MediaStreamType>(i);
753 if (content::IsVideoMediaStreamDeviceType(stream_type)) {
754 GetVideoCaptureManager(stream_type)->UseFakeDevice();
755 }
756 }
695 device_settings_->UseFakeUI(); 757 device_settings_->UseFakeUI();
696 } 758 }
697 759
698 void MediaStreamManager::WillDestroyCurrentMessageLoop() { 760 void MediaStreamManager::WillDestroyCurrentMessageLoop() {
699 DCHECK_EQ(MessageLoop::current(), io_loop_); 761 DCHECK_EQ(MessageLoop::current(), io_loop_);
700 DCHECK(requests_.empty()); 762 DCHECK(requests_.empty());
701 if (device_thread_.get()) { 763 if (device_thread_.get()) {
702 StopMonitoring(); 764 StopMonitoring();
703 765
704 video_capture_manager_->Unregister(); 766 for (int i = content::MEDIA_STREAM_DEVICE_TYPE_NO_SERVICE + 1;
705 audio_input_device_manager_->Unregister(); 767 i < content::NUM_MEDIA_STREAM_DEVICE_TYPES; ++i) {
768 if (device_manager_[i].get()) {
769 device_manager_[i]->Unregister();
770 }
771 }
772
706 device_thread_.reset(); 773 device_thread_.reset();
707 } 774 }
708 775
709 audio_input_device_manager_ = NULL; 776 for (int i = content::MEDIA_STREAM_DEVICE_TYPE_NO_SERVICE + 1;
710 video_capture_manager_ = NULL; 777 i < content::NUM_MEDIA_STREAM_DEVICE_TYPES; ++i) {
778 device_manager_[i] = NULL;
779 }
711 io_loop_ = NULL; 780 io_loop_ = NULL;
712 device_settings_.reset(); 781 device_settings_.reset();
713 } 782 }
714 783
715 void MediaStreamManager::NotifyObserverDevicesOpened(DeviceRequest* request) { 784 void MediaStreamManager::NotifyObserverDevicesOpened(DeviceRequest* request) {
716 content::MediaObserver* media_observer = 785 content::MediaObserver* media_observer =
717 content::GetContentClient()->browser()->GetMediaObserver(); 786 content::GetContentClient()->browser()->GetMediaObserver();
718 content::MediaStreamDevices opened_devices; 787 content::MediaStreamDevices opened_devices;
719 DevicesFromRequest(request, &opened_devices); 788 DevicesFromRequest(request, &opened_devices);
720 DCHECK(!opened_devices.empty()); 789 DCHECK(!opened_devices.empty());
721 media_observer->OnCaptureDevicesOpened(request->render_process_id, 790 media_observer->OnCaptureDevicesOpened(request->render_process_id,
722 request->render_view_id, 791 request->render_view_id,
723 opened_devices); 792 opened_devices);
724 } 793 }
725 794
726 void MediaStreamManager::NotifyObserverDevicesClosed(DeviceRequest* request) { 795 void MediaStreamManager::NotifyObserverDevicesClosed(DeviceRequest* request) {
727 content::MediaObserver* media_observer = 796 content::MediaObserver* media_observer =
728 content::GetContentClient()->browser()->GetMediaObserver(); 797 content::GetContentClient()->browser()->GetMediaObserver();
729 content::MediaStreamDevices closed_devices; 798 content::MediaStreamDevices closed_devices;
730 DevicesFromRequest(request, &closed_devices); 799 DevicesFromRequest(request, &closed_devices);
731 if (closed_devices.empty()) 800 if (closed_devices.empty())
732 return; 801 return;
733 media_observer->OnCaptureDevicesClosed(request->render_process_id, 802 media_observer->OnCaptureDevicesClosed(request->render_process_id,
734 request->render_view_id, 803 request->render_view_id,
735 closed_devices); 804 closed_devices);
736 } 805 }
737 806
738 void MediaStreamManager::DevicesFromRequest( 807 void MediaStreamManager::DevicesFromRequest(
739 DeviceRequest* request, content::MediaStreamDevices* devices) { 808 DeviceRequest* request, content::MediaStreamDevices* devices) {
740 StreamDeviceInfoArray::const_iterator it = request->audio_devices.begin(); 809 for (StreamDeviceInfoArray::const_iterator it = request->devices.begin();
741 for (; it != request->audio_devices.end(); ++it) { 810 it != request->devices.end(); ++it) {
742 devices->push_back( 811 devices->push_back(content::MediaStreamDevice(
743 content::MediaStreamDevice( 812 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 } 813 }
756 } 814 }
757 815
758 bool MediaStreamManager::RequestDone(const DeviceRequest& request) const { 816 bool MediaStreamManager::RequestDone(const DeviceRequest& request) const {
759 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 817 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 818
768 for (StreamDeviceInfoArray::const_iterator it = 819 const bool requested_audio =
769 request.audio_devices.begin(); it != request.audio_devices.end(); 820 content::IsAudioMediaStreamDeviceType(request.options.audio_type);
770 ++it) { 821 const bool requested_video =
771 if (it->in_use == false) { 822 content::IsVideoMediaStreamDeviceType(request.options.video_type);
772 return false; 823
773 } 824 const bool audio_done =
774 } 825 !requested_audio ||
826 request.state[request.options.audio_type] == DeviceRequest::STATE_DONE ||
827 request.state[request.options.audio_type] == DeviceRequest::STATE_ERROR;
828 if (!audio_done) {
829 return false;
775 } 830 }
776 831
777 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE; 832 const bool video_done =
778 if (Requested(request.options, stream_type)) { 833 !requested_video ||
779 if (request.state[stream_type] != DeviceRequest::STATE_DONE && 834 request.state[request.options.video_type] == DeviceRequest::STATE_DONE ||
780 request.state[stream_type] != DeviceRequest::STATE_ERROR) { 835 request.state[request.options.video_type] == DeviceRequest::STATE_ERROR;
836 if (!video_done) {
837 return false;
838 }
839
840 for (StreamDeviceInfoArray::const_iterator it = request.devices.begin();
841 it != request.devices.end(); ++it) {
842 if ((content::IsAudioMediaStreamDeviceType(it->stream_type) &&
843 !requested_audio) ||
844 (content::IsVideoMediaStreamDeviceType(it->stream_type) &&
845 !requested_video)) {
846 continue;
847 }
848 if (it->in_use == false) {
781 return false; 849 return false;
782 } 850 }
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 } 851 }
792 852
793 return true; 853 return true;
794 } 854 }
795 855
796 // Called to get media capture device manager of specified type.
797 MediaStreamProvider* MediaStreamManager::GetDeviceManager( 856 MediaStreamProvider* MediaStreamManager::GetDeviceManager(
798 MediaStreamType stream_type) { 857 MediaStreamType stream_type) {
799 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) { 858 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
800 return video_capture_manager(); 859 EnsureDeviceManagerStarted(stream_type);
801 } else if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { 860 return device_manager_[stream_type];
802 return audio_input_device_manager(); 861 }
803 } 862
804 NOTREACHED(); 863 VideoCaptureManager* MediaStreamManager::GetVideoCaptureManager(
805 return NULL; 864 MediaStreamType stream_type) {
865 DCHECK(content::IsVideoMediaStreamDeviceType(stream_type));
866 return reinterpret_cast<VideoCaptureManager*>(GetDeviceManager(stream_type));
867 }
868
869 AudioInputDeviceManager* MediaStreamManager::GetAudioInputDeviceManager(
870 MediaStreamType stream_type) {
871 DCHECK(content::IsAudioMediaStreamDeviceType(stream_type));
872 return reinterpret_cast<AudioInputDeviceManager*>(
873 GetDeviceManager(stream_type));
806 } 874 }
807 875
808 void MediaStreamManager::OnDevicesChanged( 876 void MediaStreamManager::OnDevicesChanged(
809 base::SystemMonitor::DeviceType device_type) { 877 base::SystemMonitor::DeviceType device_type) {
810 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 878 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
879
880 // NOTE: This method is only called in response to user audio/video device
881 // changes (from the operating system).
882
811 MediaStreamType stream_type; 883 MediaStreamType stream_type;
812 EnumerationCache* cache; 884 EnumerationCache* cache;
813 if (device_type == base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE) { 885 if (device_type == base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE) {
814 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE; 886 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_USER_AUDIO_CAPTURE;
815 cache = &audio_enumeration_cache_; 887 cache = &user_audio_enumeration_cache_;
816 } else if (device_type == base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE) { 888 } else if (device_type == base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE) {
817 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE; 889 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_USER_VIDEO_CAPTURE;
818 cache = &video_enumeration_cache_; 890 cache = &user_video_enumeration_cache_;
819 } else { 891 } else {
820 return; // Uninteresting device change. 892 return; // Uninteresting device change.
821 } 893 }
822 894
823 if (!HasEnumerationRequest(stream_type)) { 895 if (!HasEnumerationRequest(stream_type)) {
824 // There is no request for that type, No need to enumerate devices. 896 // There is no request for that type, No need to enumerate devices.
825 // Therefore, invalidate the cache of that type. 897 // Therefore, invalidate the cache of that type.
826 ClearEnumerationCache(cache); 898 ClearEnumerationCache(cache);
827 return; 899 return;
828 } 900 }
(...skipping 23 matching lines...) Expand all
852 it != requests_.end(); ++it) { 924 it != requests_.end(); ++it) {
853 if (it->second.type == DeviceRequest::ENUMERATE_DEVICES && 925 if (it->second.type == DeviceRequest::ENUMERATE_DEVICES &&
854 Requested(it->second.options, stream_type)) { 926 Requested(it->second.options, stream_type)) {
855 return true; 927 return true;
856 } 928 }
857 } 929 }
858 return false; 930 return false;
859 } 931 }
860 932
861 } // namespace media_stream 933 } // namespace media_stream
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698