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

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

Issue 10168008: Show camera and microphone status indicators. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: updated the media_stream_dispatcher_unittest Created 8 years, 7 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 "content/browser/renderer_host/media/audio_input_device_manager.h" 13 #include "content/browser/renderer_host/media/audio_input_device_manager.h"
14 #include "content/browser/renderer_host/media/media_stream_device_settings.h" 14 #include "content/browser/renderer_host/media/media_stream_device_settings.h"
15 #include "content/browser/renderer_host/media/media_stream_requester.h" 15 #include "content/browser/renderer_host/media/media_stream_requester.h"
16 #include "content/browser/renderer_host/media/video_capture_manager.h" 16 #include "content/browser/renderer_host/media/video_capture_manager.h"
17 #include "content/browser/resource_context_impl.h" 17 #include "content/browser/resource_context_impl.h"
18 #include "content/common/media/media_stream_options.h" 18 #include "content/common/media/media_stream_options.h"
19 #include "content/public/browser/browser_thread.h" 19 #include "content/public/browser/browser_thread.h"
20 #include "content/public/browser/content_browser_client.h"
21 #include "content/public/browser/media_observer.h"
20 #include "media/audio/audio_manager.h" 22 #include "media/audio/audio_manager.h"
21 23
22 using content::BrowserThread; 24 using content::BrowserThread;
23 25
24 static const char* kMediaStreamManagerKeyName = "content_media_stream_manager"; 26 static const char* kMediaStreamManagerKeyName = "content_media_stream_manager";
25 27
26 namespace media_stream { 28 namespace media_stream {
27 29
28 // Creates a random label used to identify requests. 30 // Creates a random label used to identify requests.
29 static std::string RandomLabel() { 31 static std::string RandomLabel() {
(...skipping 17 matching lines...) Expand all
47 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE && 49 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE &&
48 options.video) { 50 options.video) {
49 return true; 51 return true;
50 } else if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE && 52 } else if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE &&
51 options.audio) { 53 options.audio) {
52 return true; 54 return true;
53 } 55 }
54 return false; 56 return false;
55 } 57 }
56 58
59 // TODO(xians): Merge DeviceRequest with MediaStreamRequest.
57 struct MediaStreamManager::DeviceRequest { 60 struct MediaStreamManager::DeviceRequest {
58 enum RequestState { 61 enum RequestState {
59 kNotRequested = 0, 62 kNotRequested = 0,
60 kRequested, 63 kRequested,
61 kPendingApproval, 64 kPendingApproval,
62 kOpening, 65 kOpening,
63 kDone, 66 kDone,
64 kError 67 kError
65 }; 68 };
66 69
67 enum RequestType { 70 enum RequestType {
68 kGenerateStream = 0, 71 kGenerateStream = 0,
69 kEnumerateDevices, 72 kEnumerateDevices,
70 kOpenDevice 73 kOpenDevice
71 }; 74 };
72 75
73 DeviceRequest() 76 DeviceRequest()
74 : requester(NULL), 77 : requester(NULL),
75 state(content::NUM_MEDIA_STREAM_DEVICE_TYPES, kNotRequested), 78 state(content::NUM_MEDIA_STREAM_DEVICE_TYPES, kNotRequested),
76 type(kGenerateStream) { 79 type(kGenerateStream),
80 render_process_id(-1),
81 render_view_id(-1) {
77 options.audio = false; 82 options.audio = false;
78 options.video = false; 83 options.video = false;
79 } 84 }
80 85
81 DeviceRequest(MediaStreamRequester* requester, 86 DeviceRequest(MediaStreamRequester* requester,
82 const StreamOptions& request_options) 87 const StreamOptions& request_options,
88 int render_process_id,
89 int render_view_id,
90 const std::string& request_security_origin)
83 : requester(requester), 91 : requester(requester),
84 options(request_options), 92 options(request_options),
85 state(content::NUM_MEDIA_STREAM_DEVICE_TYPES, kNotRequested), 93 state(content::NUM_MEDIA_STREAM_DEVICE_TYPES, kNotRequested),
86 type(kGenerateStream) { 94 type(kGenerateStream),
95 render_process_id(render_process_id),
96 render_view_id(render_view_id),
97 security_origin(request_security_origin) {
87 DCHECK(requester); 98 DCHECK(requester);
88 } 99 }
89 100
90 ~DeviceRequest() {} 101 ~DeviceRequest() {}
91 102
92 MediaStreamRequester* requester; 103 MediaStreamRequester* requester;
93 StreamOptions options; 104 StreamOptions options;
94 std::vector<RequestState> state; 105 std::vector<RequestState> state;
95 RequestType type; 106 RequestType type;
107 int render_process_id;
108 int render_view_id;
109 std::string security_origin;
96 std::string requested_device_id; 110 std::string requested_device_id;
97 StreamDeviceInfoArray audio_devices; 111 StreamDeviceInfoArray audio_devices;
98 StreamDeviceInfoArray video_devices; 112 StreamDeviceInfoArray video_devices;
99 }; 113 };
100 114
101 // static 115 // static
102 MediaStreamManager* MediaStreamManager::GetForResourceContext( 116 MediaStreamManager* MediaStreamManager::GetForResourceContext(
103 content::ResourceContext* resource_context, 117 content::ResourceContext* resource_context,
104 media::AudioManager* audio_manager) { 118 media::AudioManager* audio_manager) {
105 MediaStreamManager* rv = static_cast<MediaStreamManager*>( 119 MediaStreamManager* rv = static_cast<MediaStreamManager*>(
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 161
148 void MediaStreamManager::GenerateStream(MediaStreamRequester* requester, 162 void MediaStreamManager::GenerateStream(MediaStreamRequester* requester,
149 int render_process_id, 163 int render_process_id,
150 int render_view_id, 164 int render_view_id,
151 const StreamOptions& options, 165 const StreamOptions& options,
152 const std::string& security_origin, 166 const std::string& security_origin,
153 std::string* label) { 167 std::string* label) {
154 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 168 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
155 169
156 // Create a new request based on options. 170 // Create a new request based on options.
157 DeviceRequest new_request = DeviceRequest(requester, options); 171 DeviceRequest new_request(requester, options,
158 StartEnumeration(&new_request, render_process_id, render_view_id, 172 render_process_id,
159 security_origin, label); 173 render_view_id,
174 security_origin);
175 StartEnumeration(&new_request, label);
160 } 176 }
161 177
162 void MediaStreamManager::CancelRequests(MediaStreamRequester* requester) { 178 void MediaStreamManager::CancelRequests(MediaStreamRequester* requester) {
163 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 179 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
164 DeviceRequests::iterator it = requests_.begin(); 180 DeviceRequests::iterator it = requests_.begin();
165 while (it != requests_.end()) { 181 while (it != requests_.end()) {
166 if (it->second.requester == requester && !RequestDone(it->second)) { 182 if (it->second.requester == requester && !RequestDone(it->second)) {
167 // The request isn't complete, but there might be some devices already 183 // The request isn't complete, but there might be some devices already
168 // opened -> close them. 184 // opened -> close them.
169 DeviceRequest* request = &(it->second); 185 DeviceRequest* request = &(it->second);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 for (StreamDeviceInfoArray::iterator audio_it = 218 for (StreamDeviceInfoArray::iterator audio_it =
203 it->second.audio_devices.begin(); 219 it->second.audio_devices.begin();
204 audio_it != it->second.audio_devices.end(); ++audio_it) { 220 audio_it != it->second.audio_devices.end(); ++audio_it) {
205 audio_input_device_manager()->Close(audio_it->session_id); 221 audio_input_device_manager()->Close(audio_it->session_id);
206 } 222 }
207 for (StreamDeviceInfoArray::iterator video_it = 223 for (StreamDeviceInfoArray::iterator video_it =
208 it->second.video_devices.begin(); 224 it->second.video_devices.begin();
209 video_it != it->second.video_devices.end(); ++video_it) { 225 video_it != it->second.video_devices.end(); ++video_it) {
210 video_capture_manager()->Close(video_it->session_id); 226 video_capture_manager()->Close(video_it->session_id);
211 } 227 }
228 if (it->second.type == DeviceRequest::kGenerateStream) {
229 NotifyObserverDevicesClosed(&(it->second));
230 }
212 requests_.erase(it); 231 requests_.erase(it);
213 return; 232 return;
214 } 233 }
215 } 234 }
216 235
217 void MediaStreamManager::EnumerateDevices( 236 void MediaStreamManager::EnumerateDevices(
218 MediaStreamRequester* requester, 237 MediaStreamRequester* requester,
219 int render_process_id, 238 int render_process_id,
220 int render_view_id, 239 int render_view_id,
221 MediaStreamType type, 240 MediaStreamType type,
222 const std::string& security_origin, 241 const std::string& security_origin,
223 std::string* label) { 242 std::string* label) {
224 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 243 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
225 244
226 // Create a new request. 245 // Create a new request.
227 StreamOptions options; 246 StreamOptions options;
228 if (type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) 247 if (type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE)
229 options.audio = true; 248 options.audio = true;
230 else 249 else
231 options.video = true; 250 options.video = true;
232 251
233 DeviceRequest new_request = DeviceRequest(requester, options); 252 DeviceRequest new_request(requester, options,
253 render_process_id,
254 render_view_id,
255 security_origin);
234 new_request.type = DeviceRequest::kEnumerateDevices; 256 new_request.type = DeviceRequest::kEnumerateDevices;
235 257
236 StartEnumeration(&new_request, render_process_id, render_view_id, 258 StartEnumeration(&new_request, label);
237 security_origin, label);
238 } 259 }
239 260
240 void MediaStreamManager::OpenDevice( 261 void MediaStreamManager::OpenDevice(
241 MediaStreamRequester* requester, 262 MediaStreamRequester* requester,
242 int render_process_id, 263 int render_process_id,
243 int render_view_id, 264 int render_view_id,
244 const std::string& device_id, 265 const std::string& device_id,
245 MediaStreamType type, 266 MediaStreamType type,
246 const std::string& security_origin, 267 const std::string& security_origin,
247 std::string* label) { 268 std::string* label) {
248 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 269 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
249 270
250 // Create a new request. 271 // Create a new request.
251 StreamOptions options; 272 StreamOptions options;
252 if (type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) 273 if (type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE)
253 options.audio = true; 274 options.audio = true;
254 else 275 else
255 options.video = true; 276 options.video = true;
256 277
257 DeviceRequest new_request = DeviceRequest(requester, options); 278 DeviceRequest new_request(requester, options,
279 render_process_id,
280 render_view_id,
281 security_origin);
258 new_request.type = DeviceRequest::kOpenDevice; 282 new_request.type = DeviceRequest::kOpenDevice;
259 new_request.requested_device_id = device_id; 283 new_request.requested_device_id = device_id;
260 284
261 StartEnumeration(&new_request, render_process_id, render_view_id, 285 StartEnumeration(&new_request, label);
262 security_origin, label);
263 } 286 }
264 287
265 void MediaStreamManager::StartEnumeration( 288 void MediaStreamManager::StartEnumeration(
266 DeviceRequest* new_request, 289 DeviceRequest* new_request,
267 int render_process_id,
268 int render_view_id,
269 const std::string& security_origin,
270 std::string* label) { 290 std::string* label) {
271 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 291 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
272 292
273 MediaStreamType stream_type = content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE; 293 MediaStreamType stream_type = content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE;
274 if (Requested(new_request->options, stream_type)) { 294 if (Requested(new_request->options, stream_type)) {
275 new_request->state[stream_type] = DeviceRequest::kRequested; 295 new_request->state[stream_type] = DeviceRequest::kRequested;
276 if (!enumeration_in_progress_[stream_type]) { 296 if (!enumeration_in_progress_[stream_type]) {
277 enumeration_in_progress_[stream_type] = true; 297 enumeration_in_progress_[stream_type] = true;
278 GetDeviceManager(stream_type)->EnumerateDevices(); 298 GetDeviceManager(stream_type)->EnumerateDevices();
279 } 299 }
(...skipping 16 matching lines...) Expand all
296 requests_.insert(std::make_pair(request_label, *new_request)); 316 requests_.insert(std::make_pair(request_label, *new_request));
297 317
298 // Get user confirmation to use capture devices. 318 // Get user confirmation to use capture devices.
299 // Need to make an asynchronous call to make sure the |requester| gets the 319 // Need to make an asynchronous call to make sure the |requester| gets the
300 // |label| before it would receive any event. 320 // |label| before it would receive any event.
301 if (new_request->type == DeviceRequest::kGenerateStream) { 321 if (new_request->type == DeviceRequest::kGenerateStream) {
302 BrowserThread::PostTask(BrowserThread::IO, 322 BrowserThread::PostTask(BrowserThread::IO,
303 FROM_HERE, 323 FROM_HERE,
304 base::Bind(&MediaStreamDeviceSettings::RequestCaptureDeviceUsage, 324 base::Bind(&MediaStreamDeviceSettings::RequestCaptureDeviceUsage,
305 base::Unretained(device_settings_.get()), 325 base::Unretained(device_settings_.get()),
306 request_label, render_process_id, 326 request_label, new_request->render_process_id,
307 render_view_id, new_request->options, 327 new_request->render_view_id, new_request->options,
308 security_origin)); 328 new_request->security_origin));
309 } 329 }
310 330
311 (*label) = request_label; 331 (*label) = request_label;
312 } 332 }
313 333
314 void MediaStreamManager::Opened(MediaStreamType stream_type, 334 void MediaStreamManager::Opened(MediaStreamType stream_type,
315 int capture_session_id) { 335 int capture_session_id) {
316 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 336 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
317 337
318 // Find the request containing this device and mark it as used. 338 // Find the request containing this device and mark it as used.
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 return; 383 return;
364 } 384 }
365 385
366 switch (request->type) { 386 switch (request->type) {
367 case DeviceRequest::kOpenDevice: 387 case DeviceRequest::kOpenDevice:
368 request->requester->DeviceOpened(label, (*devices)[0]); 388 request->requester->DeviceOpened(label, (*devices)[0]);
369 break; 389 break;
370 case DeviceRequest::kGenerateStream: 390 case DeviceRequest::kGenerateStream:
371 request->requester->StreamGenerated(label, request->audio_devices, 391 request->requester->StreamGenerated(label, request->audio_devices,
372 request->video_devices); 392 request->video_devices);
393 NotifyObserverDevicesOpened(request);
373 break; 394 break;
374 default: 395 default:
375 NOTREACHED(); 396 NOTREACHED();
376 } 397 }
377 } 398 }
378 399
379 void MediaStreamManager::Closed(MediaStreamType stream_type, 400 void MediaStreamManager::Closed(MediaStreamType stream_type,
380 int capture_session_id) { 401 int capture_session_id) {
381 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 402 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
382 } 403 }
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
549 return; 570 return;
550 } 571 }
551 } 572 }
552 573
553 void MediaStreamManager::UseFakeDevice() { 574 void MediaStreamManager::UseFakeDevice() {
554 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 575 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
555 video_capture_manager()->UseFakeDevice(); 576 video_capture_manager()->UseFakeDevice();
556 device_settings_->UseFakeUI(); 577 device_settings_->UseFakeUI();
557 } 578 }
558 579
580 void MediaStreamManager::NotifyObserverDevicesOpened(DeviceRequest* request) {
581 content::MediaObserver* media_observer =
582 content::GetContentClient()->browser()->GetMediaObserver();
583 content::MediaStreamDevices opened_devices;
584 DevicesFromRequest(request, &opened_devices);
585 DCHECK(!opened_devices.empty());
586 media_observer->OnCaptureDevicesOpened(request->render_process_id,
587 request->render_view_id,
588 opened_devices);
589 }
590
591 void MediaStreamManager::NotifyObserverDevicesClosed(DeviceRequest* request) {
592 content::MediaObserver* media_observer =
593 content::GetContentClient()->browser()->GetMediaObserver();
594 content::MediaStreamDevices closed_devices;
595 DevicesFromRequest(request, &closed_devices);
596 if (closed_devices.empty())
597 return;
598 media_observer->OnCaptureDevicesClosed(request->render_process_id,
599 request->render_view_id,
600 closed_devices);
601 }
602
603 void MediaStreamManager::DevicesFromRequest(
604 DeviceRequest* request, content::MediaStreamDevices* devices) {
605 StreamDeviceInfoArray::const_iterator it = request->audio_devices.begin();
606 for (; it != request->audio_devices.end(); ++it) {
607 devices->push_back(
608 content::MediaStreamDevice(
609 content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE,
610 it->device_id,
611 it->name));
612 }
613 for (it = request->video_devices.begin(); it != request->video_devices.end();
614 ++it) {
615 devices->push_back(
616 content::MediaStreamDevice(
617 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE,
618 it->device_id,
619 it->name));
620 }
621 }
622
559 bool MediaStreamManager::RequestDone(const DeviceRequest& request) const { 623 bool MediaStreamManager::RequestDone(const DeviceRequest& request) const {
560 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 624 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
561 // Check if all devices are opened. 625 // Check if all devices are opened.
562 if (Requested(request.options, 626 if (Requested(request.options,
563 content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE)) { 627 content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE)) {
564 for (StreamDeviceInfoArray::const_iterator it = 628 for (StreamDeviceInfoArray::const_iterator it =
565 request.audio_devices.begin(); it != request.audio_devices.end(); 629 request.audio_devices.begin(); it != request.audio_devices.end();
566 ++it) { 630 ++it) {
567 if (it->in_use == false) { 631 if (it->in_use == false) {
568 return false; 632 return false;
(...skipping 19 matching lines...) Expand all
588 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) { 652 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) {
589 return video_capture_manager(); 653 return video_capture_manager();
590 } else if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { 654 } else if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) {
591 return audio_input_device_manager(); 655 return audio_input_device_manager();
592 } 656 }
593 NOTREACHED(); 657 NOTREACHED();
594 return NULL; 658 return NULL;
595 } 659 }
596 660
597 } // namespace media_stream 661 } // namespace media_stream
OLDNEW
« no previous file with comments | « content/browser/renderer_host/media/media_stream_manager.h ('k') | content/browser/renderer_host/media/mock_media_observer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698