Chromium Code Reviews| Index: content/browser/renderer_host/media/media_stream_manager.cc |
| diff --git a/content/browser/renderer_host/media/media_stream_manager.cc b/content/browser/renderer_host/media/media_stream_manager.cc |
| index 6ed73ca48f62b6973c1cdf275b9c355ac32fce38..88a1aa129e31224fc05ce807b3f3ec455589ab22 100644 |
| --- a/content/browser/renderer_host/media/media_stream_manager.cc |
| +++ b/content/browser/renderer_host/media/media_stream_manager.cc |
| @@ -13,18 +13,22 @@ |
| #include "base/logging.h" |
| #include "base/rand_util.h" |
| #include "base/run_loop.h" |
| +#include "base/strings/stringprintf.h" |
| #include "base/threading/thread.h" |
| +#include "content/browser/browser_main_loop.h" |
| #include "content/browser/renderer_host/media/audio_input_device_manager.h" |
| #include "content/browser/renderer_host/media/device_request_message_filter.h" |
| #include "content/browser/renderer_host/media/media_stream_requester.h" |
| #include "content/browser/renderer_host/media/media_stream_ui_proxy.h" |
| #include "content/browser/renderer_host/media/video_capture_manager.h" |
| #include "content/browser/renderer_host/media/web_contents_capture_util.h" |
| +#include "content/browser/renderer_host/render_process_host_impl.h" |
| #include "content/public/browser/browser_thread.h" |
| #include "content/public/browser/content_browser_client.h" |
| #include "content/public/browser/media_device_id.h" |
| #include "content/public/browser/media_observer.h" |
| #include "content/public/browser/media_request_state.h" |
| +#include "content/public/browser/render_process_host.h" |
| #include "content/public/common/content_switches.h" |
| #include "content/public/common/media_stream_request.h" |
| #include "media/audio/audio_manager_base.h" |
| @@ -103,6 +107,44 @@ void ParseStreamType(const StreamOptions& options, |
| } |
| } |
| +// Private helper method for SendMessageToNativeLog() that obtains the global |
| +// MediaStreamManager instance on the UI thread before sending |message| to the |
| +// webrtcLoggingPrivate API. |
| +void DoAddLogMessage(const std::string& message) { |
| + // Must be on the UI thread to access BrowserMainLoop. |
| + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| + // May be null in tests. |
| + // TODO(vrk): Handle this more elegantly by having native log messages become |
| + // no-ops until MediaStreamManager is aware that a renderer process has |
| + // started logging. crbug.com/333894 |
| + if (content::BrowserMainLoop::GetInstance()) { |
| + BrowserThread::PostTask( |
| + BrowserThread::IO, |
| + FROM_HERE, |
| + base::Bind(&MediaStreamManager::AddLogMessageOnIOThread, |
| + 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.
|
| + ->media_stream_manager()), |
| + message)); |
| + } |
| +} |
| + |
| +// Private helper method to generate a string for the log message that lists the |
| +// human readable names of |devices|. |
| +std::string GetLogMessageString(MediaStreamType stream_type, |
| + const StreamDeviceInfoArray& devices) { |
| + std::string output_string = |
| + base::StringPrintf("Getting devices for stream type %d:\n", stream_type); |
| + if (devices.empty()) { |
| + output_string += "No devices found."; |
| + } else { |
| + for (StreamDeviceInfoArray::const_iterator it = devices.begin(); |
| + it != devices.end(); ++it) { |
| + output_string += " " + it->device.name + "\n"; |
| + } |
| + } |
| + return output_string; |
| +} |
| + |
| } // namespace |
| @@ -1014,6 +1056,20 @@ void MediaStreamManager::SetupRequest(const std::string& label) { |
| // Enumerate the devices if there is no valid device lists to be used. |
| StartEnumeration(request); |
| return; |
| + } else { |
| + // Cache is valid, so log the cached devices for MediaStream requests. |
| + if (request->request_type == MEDIA_GENERATE_STREAM) { |
| + std::string log_message("Using cached devices for request.\n"); |
| + if (audio_type != MEDIA_NO_SERVICE) { |
| + log_message += |
| + GetLogMessageString(audio_type, audio_enumeration_cache_.devices); |
| + } |
| + if (video_type != MEDIA_NO_SERVICE) { |
| + log_message += |
| + GetLogMessageString(video_type, video_enumeration_cache_.devices); |
| + } |
| + SendMessageToNativeLog(log_message); |
| + } |
| } |
| if (!SetupDeviceCaptureRequest(request)) { |
| @@ -1403,7 +1459,11 @@ void MediaStreamManager::DevicesEnumerated( |
| MediaStreamType stream_type, const StreamDeviceInfoArray& devices) { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| DVLOG(1) << "DevicesEnumerated(" |
| - << ", {stream_type = " << stream_type << "})"; |
| + << "{stream_type = " << stream_type << "})" << std::endl; |
| + |
| + std::string log_message = "New device enumeration result:\n" + |
| + GetLogMessageString(stream_type, devices); |
| + SendMessageToNativeLog(log_message); |
| // Only cache the device list when the device list has been changed. |
| bool need_update_clients = false; |
| @@ -1476,6 +1536,65 @@ void MediaStreamManager::DevicesEnumerated( |
| DCHECK_GE(active_enumeration_ref_count_[stream_type], 0); |
| } |
| +// static |
| +void MediaStreamManager::SendMessageToNativeLog(const std::string& message) { |
| + BrowserThread::PostTask( |
| + BrowserThread::UI, FROM_HERE, |
| + base::Bind(DoAddLogMessage, message)); |
| +} |
| + |
| +void MediaStreamManager::AddLogMessageOnIOThread(const std::string& message) { |
| + // Get render process ids on the IO thread. |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| + |
| + // Grab all unique process ids that request a MediaStream or have a |
| + // MediaStream running. |
| + 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
|
| + for (DeviceRequests::const_iterator it = requests_.begin(); |
| + it != requests_.end(); ++it) { |
| + DeviceRequest* request = it->second; |
| + if (request->request_type == MEDIA_GENERATE_STREAM) |
| + requesting_process_ids.insert(request->requesting_process_id); |
| + } |
| + |
| + // MediaStreamManager is a singleton in BrowserMainLoop, which owns the UI |
| + // thread. MediaStreamManager has the same lifetime as the UI thread, so it is |
| + // 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
|
| + BrowserThread::PostTask( |
| + BrowserThread::UI, |
| + FROM_HERE, |
| + base::Bind(&MediaStreamManager::AddLogMessageOnUIThread, |
| + base::Unretained(this), |
| + requesting_process_ids, |
| + message)); |
| +} |
| + |
| +void MediaStreamManager::AddLogMessageOnUIThread( |
| + const std::set<int>& requesting_process_ids, |
| + const std::string& message) { |
| +#if defined(OS_ANDROID) |
| + // It appears android_aosp is being built with ENABLE_WEBRTC=0, since it does |
| + // not find RenderProcessHostImpl::WebRtcLogMessage. Logging is not enabled on |
| + // Android anyway, so make this function a no-op. |
| + // TODO(vrk): Figure out what's going on here and fix. |
| + return; |
| +#else |
| + // Must be on the UI thread to access RenderProcessHost from process ID. |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + |
| + for (std::set<int>::const_iterator it = requesting_process_ids.begin(); |
| + it != requesting_process_ids.end(); ++it) { |
| + // Log the message to all renderers that are requesting a MediaStream or |
| + // have a MediaStream running. |
| + content::RenderProcessHostImpl* render_process_host_impl = |
| + static_cast<content::RenderProcessHostImpl*>( |
| + content::RenderProcessHost::FromID(*it)); |
| + if (render_process_host_impl) |
| + render_process_host_impl->WebRtcLogMessage(message); |
| + } |
| +#endif |
| +} |
| + |
| void MediaStreamManager::HandleAccessRequestResponse( |
| const std::string& label, |
| const MediaStreamDevices& devices) { |