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

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

Issue 140633004: Reland CL to implement browser-side logging to WebRtc log. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: These are the changes that should fix crbug.com/338848 Created 6 years, 10 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 #include <vector> 8 #include <vector>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/command_line.h" 11 #include "base/command_line.h"
12 #include "base/compiler_specific.h" 12 #include "base/compiler_specific.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/rand_util.h" 14 #include "base/rand_util.h"
15 #include "base/run_loop.h" 15 #include "base/run_loop.h"
16 #include "base/strings/stringprintf.h"
16 #include "base/threading/thread.h" 17 #include "base/threading/thread.h"
18 #include "content/browser/browser_main_loop.h"
17 #include "content/browser/renderer_host/media/audio_input_device_manager.h" 19 #include "content/browser/renderer_host/media/audio_input_device_manager.h"
18 #include "content/browser/renderer_host/media/device_request_message_filter.h" 20 #include "content/browser/renderer_host/media/device_request_message_filter.h"
19 #include "content/browser/renderer_host/media/media_stream_requester.h" 21 #include "content/browser/renderer_host/media/media_stream_requester.h"
20 #include "content/browser/renderer_host/media/media_stream_ui_proxy.h" 22 #include "content/browser/renderer_host/media/media_stream_ui_proxy.h"
21 #include "content/browser/renderer_host/media/video_capture_manager.h" 23 #include "content/browser/renderer_host/media/video_capture_manager.h"
22 #include "content/browser/renderer_host/media/web_contents_capture_util.h" 24 #include "content/browser/renderer_host/media/web_contents_capture_util.h"
25 #include "content/browser/renderer_host/render_process_host_impl.h"
23 #include "content/public/browser/browser_thread.h" 26 #include "content/public/browser/browser_thread.h"
24 #include "content/public/browser/content_browser_client.h" 27 #include "content/public/browser/content_browser_client.h"
25 #include "content/public/browser/media_device_id.h" 28 #include "content/public/browser/media_device_id.h"
26 #include "content/public/browser/media_observer.h" 29 #include "content/public/browser/media_observer.h"
27 #include "content/public/browser/media_request_state.h" 30 #include "content/public/browser/media_request_state.h"
31 #include "content/public/browser/render_process_host.h"
28 #include "content/public/common/content_switches.h" 32 #include "content/public/common/content_switches.h"
29 #include "content/public/common/media_stream_request.h" 33 #include "content/public/common/media_stream_request.h"
30 #include "media/audio/audio_manager_base.h" 34 #include "media/audio/audio_manager_base.h"
31 #include "media/audio/audio_parameters.h" 35 #include "media/audio/audio_parameters.h"
32 #include "media/base/channel_layout.h" 36 #include "media/base/channel_layout.h"
33 #include "url/gurl.h" 37 #include "url/gurl.h"
34 38
35 #if defined(OS_WIN) 39 #if defined(OS_WIN)
36 #include "base/win/scoped_com_initializer.h" 40 #include "base/win/scoped_com_initializer.h"
37 #endif 41 #endif
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 } else if (video_stream_source == kMediaStreamSourceDesktop) { 100 } else if (video_stream_source == kMediaStreamSourceDesktop) {
97 *video_type = content::MEDIA_DESKTOP_VIDEO_CAPTURE; 101 *video_type = content::MEDIA_DESKTOP_VIDEO_CAPTURE;
98 } 102 }
99 } else { 103 } else {
100 // This is normal video device capture. 104 // This is normal video device capture.
101 *video_type = content::MEDIA_DEVICE_VIDEO_CAPTURE; 105 *video_type = content::MEDIA_DEVICE_VIDEO_CAPTURE;
102 } 106 }
103 } 107 }
104 } 108 }
105 109
110 // Private helper method for SendMessageToNativeLog() that obtains the global
111 // MediaStreamManager instance on the UI thread before sending |message| to the
112 // webrtcLoggingPrivate API.
113 void DoAddLogMessage(const std::string& message) {
114 // Must be on the UI thread to access BrowserMainLoop.
115 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
116 // May be null in tests.
117 // TODO(vrk): Handle this more elegantly by having native log messages become
118 // no-ops until MediaStreamManager is aware that a renderer process has
119 // started logging. crbug.com/333894
120 if (content::BrowserMainLoop::GetInstance()) {
121 BrowserThread::PostTask(
122 BrowserThread::IO,
123 FROM_HERE,
124 base::Bind(&MediaStreamManager::AddLogMessageOnIOThread,
125 base::Unretained(content::BrowserMainLoop::GetInstance()
Henrik Grunell 2014/01/29 08:27:04 Why is base::Unretained safe when posting on the I
Henrik Grunell 2014/01/29 08:53:51 This is OK. See my comment below.
126 ->media_stream_manager()),
127 message));
128 }
129 }
130
131 // Private helper method to generate a string for the log message that lists the
132 // human readable names of |devices|.
133 std::string GetLogMessageString(MediaStreamType stream_type,
134 const StreamDeviceInfoArray& devices) {
135 std::string output_string =
136 base::StringPrintf("Getting devices for stream type %d:\n", stream_type);
137 if (devices.empty()) {
138 output_string += "No devices found.";
139 } else {
140 for (StreamDeviceInfoArray::const_iterator it = devices.begin();
141 it != devices.end(); ++it) {
142 output_string += " " + it->device.name + "\n";
143 }
144 }
145 return output_string;
146 }
147
106 } // namespace 148 } // namespace
107 149
108 150
109 // MediaStreamManager::DeviceRequest represents a request to either enumerate 151 // MediaStreamManager::DeviceRequest represents a request to either enumerate
110 // available devices or open one or more devices. 152 // available devices or open one or more devices.
111 // TODO(perkj): MediaStreamManager still needs refactoring. I propose we create 153 // TODO(perkj): MediaStreamManager still needs refactoring. I propose we create
112 // several subclasses of DeviceRequest and move some of the responsibility of 154 // several subclasses of DeviceRequest and move some of the responsibility of
113 // the MediaStreamManager to the subclasses to get rid of the way too many if 155 // the MediaStreamManager to the subclasses to get rid of the way too many if
114 // statements in MediaStreamManager. 156 // statements in MediaStreamManager.
115 class MediaStreamManager::DeviceRequest { 157 class MediaStreamManager::DeviceRequest {
(...skipping 891 matching lines...) Expand 10 before | Expand all | Expand 10 after
1007 FinalizeRequestFailed(label, request); 1049 FinalizeRequestFailed(label, request);
1008 return; 1050 return;
1009 } 1051 }
1010 1052
1011 if (!is_web_contents_capture && !is_screen_capture) { 1053 if (!is_web_contents_capture && !is_screen_capture) {
1012 if (EnumerationRequired(&audio_enumeration_cache_, audio_type) || 1054 if (EnumerationRequired(&audio_enumeration_cache_, audio_type) ||
1013 EnumerationRequired(&video_enumeration_cache_, video_type)) { 1055 EnumerationRequired(&video_enumeration_cache_, video_type)) {
1014 // Enumerate the devices if there is no valid device lists to be used. 1056 // Enumerate the devices if there is no valid device lists to be used.
1015 StartEnumeration(request); 1057 StartEnumeration(request);
1016 return; 1058 return;
1059 } else {
1060 // Cache is valid, so log the cached devices for MediaStream requests.
1061 if (request->request_type == MEDIA_GENERATE_STREAM) {
1062 std::string log_message("Using cached devices for request.\n");
1063 if (audio_type != MEDIA_NO_SERVICE) {
1064 log_message +=
1065 GetLogMessageString(audio_type, audio_enumeration_cache_.devices);
1066 }
1067 if (video_type != MEDIA_NO_SERVICE) {
1068 log_message +=
1069 GetLogMessageString(video_type, video_enumeration_cache_.devices);
1070 }
1071 SendMessageToNativeLog(log_message);
1072 }
1017 } 1073 }
1018 1074
1019 if (!SetupDeviceCaptureRequest(request)) { 1075 if (!SetupDeviceCaptureRequest(request)) {
1020 FinalizeRequestFailed(label, request); 1076 FinalizeRequestFailed(label, request);
1021 return; 1077 return;
1022 } 1078 }
1023 } 1079 }
1024 PostRequestToUI(label, request); 1080 PostRequestToUI(label, request);
1025 } 1081 }
1026 1082
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after
1396 1452
1397 void MediaStreamManager::Closed(MediaStreamType stream_type, 1453 void MediaStreamManager::Closed(MediaStreamType stream_type,
1398 int capture_session_id) { 1454 int capture_session_id) {
1399 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 1455 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1400 } 1456 }
1401 1457
1402 void MediaStreamManager::DevicesEnumerated( 1458 void MediaStreamManager::DevicesEnumerated(
1403 MediaStreamType stream_type, const StreamDeviceInfoArray& devices) { 1459 MediaStreamType stream_type, const StreamDeviceInfoArray& devices) {
1404 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 1460 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1405 DVLOG(1) << "DevicesEnumerated(" 1461 DVLOG(1) << "DevicesEnumerated("
1406 << ", {stream_type = " << stream_type << "})"; 1462 << "{stream_type = " << stream_type << "})" << std::endl;
1463
1464 std::string log_message = "New device enumeration result:\n" +
1465 GetLogMessageString(stream_type, devices);
1466 SendMessageToNativeLog(log_message);
1407 1467
1408 // Only cache the device list when the device list has been changed. 1468 // Only cache the device list when the device list has been changed.
1409 bool need_update_clients = false; 1469 bool need_update_clients = false;
1410 EnumerationCache* cache = 1470 EnumerationCache* cache =
1411 stream_type == MEDIA_DEVICE_AUDIO_CAPTURE ? 1471 stream_type == MEDIA_DEVICE_AUDIO_CAPTURE ?
1412 &audio_enumeration_cache_ : &video_enumeration_cache_; 1472 &audio_enumeration_cache_ : &video_enumeration_cache_;
1413 if (!cache->valid || 1473 if (!cache->valid ||
1414 devices.size() != cache->devices.size() || 1474 devices.size() != cache->devices.size() ||
1415 !std::equal(devices.begin(), devices.end(), cache->devices.begin(), 1475 !std::equal(devices.begin(), devices.end(), cache->devices.begin(),
1416 StreamDeviceInfo::IsEqual)) { 1476 StreamDeviceInfo::IsEqual)) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1469 else 1529 else
1470 PostRequestToUI(*it, request); 1530 PostRequestToUI(*it, request);
1471 break; 1531 break;
1472 } 1532 }
1473 } 1533 }
1474 label_list.clear(); 1534 label_list.clear();
1475 --active_enumeration_ref_count_[stream_type]; 1535 --active_enumeration_ref_count_[stream_type];
1476 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0); 1536 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0);
1477 } 1537 }
1478 1538
1539 // static
1540 void MediaStreamManager::SendMessageToNativeLog(const std::string& message) {
1541 BrowserThread::PostTask(
1542 BrowserThread::UI, FROM_HERE,
1543 base::Bind(DoAddLogMessage, message));
1544 }
1545
1546 void MediaStreamManager::AddLogMessageOnIOThread(const std::string& message) {
1547 // Get render process ids on the IO thread.
1548 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1549
1550 // Grab all unique process ids that request a MediaStream or have a
1551 // MediaStream running.
1552 std::set<int> requesting_process_ids;
tommi (sloooow) - chröme 2014/01/29 10:20:15 There's no need for a set<> (which is an ordered v
1553 for (DeviceRequests::const_iterator it = requests_.begin();
1554 it != requests_.end(); ++it) {
1555 DeviceRequest* request = it->second;
1556 if (request->request_type == MEDIA_GENERATE_STREAM)
1557 requesting_process_ids.insert(request->requesting_process_id);
1558 }
1559
1560 // MediaStreamManager is a singleton in BrowserMainLoop, which owns the UI
1561 // thread. MediaStreamManager has the same lifetime as the UI thread, so it is
1562 // safe to use base::Unretained.
vrk (LEFT CHROMIUM) 2014/01/29 03:06:40 Per (or others), can you double check that my logi
Henrik Grunell 2014/01/29 08:27:04 I should depend on if the UI thread is torn down b
Henrik Grunell 2014/01/29 08:53:51 OK, I read up on BrowserMainLoop. It owns UI and I
perkj_chrome 2014/01/29 09:02:25 Since it is deleted on UI - it has longer life tim
Henrik Grunell 2014/01/29 09:49:10 Right, I see that. I want to understand the tear-d
Henrik Grunell 2014/01/29 10:37:03 Sorry for spamming you :) To close this comment: B
1563 BrowserThread::PostTask(
1564 BrowserThread::UI,
1565 FROM_HERE,
1566 base::Bind(&MediaStreamManager::AddLogMessageOnUIThread,
1567 base::Unretained(this),
1568 requesting_process_ids,
1569 message));
1570 }
1571
1572 void MediaStreamManager::AddLogMessageOnUIThread(
1573 const std::set<int>& requesting_process_ids,
1574 const std::string& message) {
1575 #if defined(OS_ANDROID)
1576 // It appears android_aosp is being built with ENABLE_WEBRTC=0, since it does
1577 // not find RenderProcessHostImpl::WebRtcLogMessage. Logging is not enabled on
1578 // Android anyway, so make this function a no-op.
1579 // TODO(vrk): Figure out what's going on here and fix.
1580 return;
1581 #else
1582 // Must be on the UI thread to access RenderProcessHost from process ID.
1583 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1584
1585 for (std::set<int>::const_iterator it = requesting_process_ids.begin();
1586 it != requesting_process_ids.end(); ++it) {
1587 // Log the message to all renderers that are requesting a MediaStream or
1588 // have a MediaStream running.
1589 content::RenderProcessHostImpl* render_process_host_impl =
1590 static_cast<content::RenderProcessHostImpl*>(
1591 content::RenderProcessHost::FromID(*it));
1592 if (render_process_host_impl)
1593 render_process_host_impl->WebRtcLogMessage(message);
1594 }
1595 #endif
1596 }
1597
1479 void MediaStreamManager::HandleAccessRequestResponse( 1598 void MediaStreamManager::HandleAccessRequestResponse(
1480 const std::string& label, 1599 const std::string& label,
1481 const MediaStreamDevices& devices) { 1600 const MediaStreamDevices& devices) {
1482 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 1601 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1483 DVLOG(1) << "HandleAccessRequestResponse(" 1602 DVLOG(1) << "HandleAccessRequestResponse("
1484 << ", {label = " << label << "})"; 1603 << ", {label = " << label << "})";
1485 1604
1486 DeviceRequest* request = FindRequest(label); 1605 DeviceRequest* request = FindRequest(label);
1487 if (!request) { 1606 if (!request) {
1488 // The request has been canceled before the UI returned. 1607 // The request has been canceled before the UI returned.
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
1704 } 1823 }
1705 1824
1706 // Always do enumeration even though some enumeration is in progress, 1825 // Always do enumeration even though some enumeration is in progress,
1707 // because those enumeration commands could be sent before these devices 1826 // because those enumeration commands could be sent before these devices
1708 // change. 1827 // change.
1709 ++active_enumeration_ref_count_[stream_type]; 1828 ++active_enumeration_ref_count_[stream_type];
1710 GetDeviceManager(stream_type)->EnumerateDevices(stream_type); 1829 GetDeviceManager(stream_type)->EnumerateDevices(stream_type);
1711 } 1830 }
1712 1831
1713 } // namespace content 1832 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698