1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CONTENT_BROWSER_WEBRTC_WEBRTC_INTERNALS_H_ 6 #define CONTENT_BROWSER_WEBRTC_WEBRTC_INTERNALS_H_ 7 8 #include <memory> 9 #include <string> 10 #include <unordered_set> 11 12 #include "base/containers/queue.h" 13 #include "base/gtest_prod_util.h" 14 #include "base/memory/weak_ptr.h" 15 #include "base/observer_list.h" 16 #include "base/process/process.h" 17 #include "base/threading/thread_checker.h" 18 #include "base/values.h" 19 #include "content/common/content_export.h" 20 #include "content/public/browser/render_process_host_observer.h" 21 #include "media/media_buildflags.h" 22 #include "mojo/public/cpp/bindings/remote.h" 23 #include "services/device/public/mojom/wake_lock.mojom.h" 24 #include "ui/shell_dialogs/select_file_dialog.h" 25 26 namespace media { 27 class AudioDebugRecordingSession; 28 } 29 30 namespace content { 31 32 class WebContents; 33 class WebRtcInternalsConnectionsObserver; 34 class WebRTCInternalsUIObserver; 35 36 // This is a singleton class running in the browser UI thread. 37 // It collects peer connection infomation from the renderers, 38 // forwards the data to WebRTCInternalsUIObserver and 39 // sends data collecting commands to the renderers. 40 class CONTENT_EXPORT WebRTCInternals : public RenderProcessHostObserver, 41 public ui::SelectFileDialog::Listener { 42 public: 43 // * CreateSingletonInstance() ensures that no previous instantiation of the 44 // class was performed, then instantiates the class and returns the object. 45 // * GetInstance() returns the object previously constructed using 46 // CreateSingletonInstance(). It may return null in tests. 47 // * Creation is separated from access because WebRTCInternals may only be 48 // created from a context that allows blocking. If GetInstance were allowed 49 // to instantiate, as with a lazily constructed singleton, it would be 50 // difficult to guarantee that its construction is always first attempted 51 // from a context that allows it. 52 static WebRTCInternals* CreateSingletonInstance(); 53 static WebRTCInternals* GetInstance(); 54 55 ~WebRTCInternals() override; 56 57 // This method is called when a PeerConnection is created. 58 // |render_process_id| is the id of the render process (not OS pid), which is 59 // needed because we might not be able to get the OS process id when the 60 // render process terminates and we want to clean up. 61 // |pid| is the renderer process id, |lid| is the renderer local id used to 62 // identify a PeerConnection, |url| is the url of the tab owning the 63 // PeerConnection, |rtc_configuration| is the serialized RTCConfiguration, 64 // |constraints| is the media constraints used to initialize the 65 // PeerConnection. 66 void OnAddPeerConnection(int render_process_id, 67 base::ProcessId pid, 68 int lid, 69 const std::string& url, 70 const std::string& rtc_configuration, 71 const std::string& constraints); 72 73 // This method is called when PeerConnection is destroyed. 74 // |pid| is the renderer process id, |lid| is the renderer local id. 75 void OnRemovePeerConnection(base::ProcessId pid, int lid); 76 77 // This method is called when a PeerConnection is updated. 78 // |pid| is the renderer process id, |lid| is the renderer local id, 79 // |type| is the update type, |value| is the detail of the update. 80 void OnUpdatePeerConnection(base::ProcessId pid, 81 int lid, 82 const std::string& type, 83 const std::string& value); 84 85 // These methods are called when results from 86 // PeerConnectionInterface::GetStats (legacy or standard API) are available. 87 // |pid| is the renderer process id, |lid| is the renderer local id, |value| 88 // is the list of stats reports. 89 void OnAddStandardStats(base::ProcessId pid, int lid, base::Value value); 90 void OnAddLegacyStats(base::ProcessId pid, int lid, base::Value value); 91 92 // This method is called when getUserMedia is called. |render_process_id| is 93 // the id of the render process (not OS pid), which is needed because we might 94 // not be able to get the OS process id when the render process terminates and 95 // we want to clean up. |pid| is the renderer OS process id, |origin| is the 96 // security origin of the getUserMedia call, |audio| is true if audio stream 97 // is requested, |video| is true if the video stream is requested, 98 // |audio_constraints| is the constraints for the audio, |video_constraints| 99 // is the constraints for the video. 100 void OnGetUserMedia(int render_process_id, 101 base::ProcessId pid, 102 const std::string& origin, 103 bool audio, 104 bool video, 105 const std::string& audio_constraints, 106 const std::string& video_constraints); 107 108 // Methods for adding or removing WebRTCInternalsUIObserver. 109 void AddObserver(WebRTCInternalsUIObserver* observer); 110 void RemoveObserver(WebRTCInternalsUIObserver* observer); 111 112 // Methods for adding or removing WebRtcInternalsConnectionsObserver. 113 // |observer| is notified when there is a change in the count of active WebRTC 114 // connections. 115 void AddConnectionsObserver(WebRtcInternalsConnectionsObserver* observer); 116 void RemoveConnectionsObserver(WebRtcInternalsConnectionsObserver* observer); 117 118 // Sends all update data to |observer|. 119 void UpdateObserver(WebRTCInternalsUIObserver* observer); 120 121 // Enables or disables diagnostic audio recordings for debugging purposes. 122 void EnableAudioDebugRecordings(content::WebContents* web_contents); 123 void DisableAudioDebugRecordings(); 124 125 bool IsAudioDebugRecordingsEnabled() const; 126 const base::FilePath& GetAudioDebugRecordingsFilePath() const; 127 128 // Enables or disables diagnostic event log. 129 void EnableLocalEventLogRecordings(content::WebContents* web_contents); 130 void DisableLocalEventLogRecordings(); 131 132 bool IsEventLogRecordingsEnabled() const; 133 bool CanToggleEventLogRecordings() const; 134 num_connected_connections()135 int num_connected_connections() const { return num_connected_connections_; } 136 137 protected: 138 // Constructor/Destructor are protected to allow tests to derive from the 139 // class and do per-instance testing without having to use the global 140 // instance. 141 // The default ctor sets |aggregate_updates_ms| to 500ms. 142 WebRTCInternals(); 143 WebRTCInternals(int aggregate_updates_ms, bool should_block_power_saving); 144 145 mojo::Remote<device::mojom::WakeLock> wake_lock_; 146 147 private: 148 FRIEND_TEST_ALL_PREFIXES(WebRtcAudioDebugRecordingsBrowserTest, 149 CallWithAudioDebugRecordings); 150 FRIEND_TEST_ALL_PREFIXES(WebRtcAudioDebugRecordingsBrowserTest, 151 CallWithAudioDebugRecordingsEnabledThenDisabled); 152 FRIEND_TEST_ALL_PREFIXES(WebRtcAudioDebugRecordingsBrowserTest, 153 TwoCallsWithAudioDebugRecordings); 154 FRIEND_TEST_ALL_PREFIXES(WebRtcInternalsTest, 155 AudioDebugRecordingsFileSelectionCanceled); 156 157 static WebRTCInternals* g_webrtc_internals; 158 159 void SendUpdate(const char* command, 160 std::unique_ptr<base::Value> value); 161 162 // RenderProcessHostObserver implementation. 163 void RenderProcessExited(RenderProcessHost* host, 164 const ChildProcessTerminationInfo& info) override; 165 166 // ui::SelectFileDialog::Listener implementation. 167 void FileSelected(const base::FilePath& path, 168 int index, 169 void* unused_params) override; 170 void FileSelectionCanceled(void* params) override; 171 172 // Called when a renderer exits (including crashes). 173 void OnRendererExit(int render_process_id); 174 175 #if BUILDFLAG(ENABLE_WEBRTC) 176 // Enables diagnostic audio recordings on all render process hosts using 177 // |audio_debug_recordings_file_path_|. 178 void EnableAudioDebugRecordingsOnAllRenderProcessHosts(); 179 #endif 180 181 // Updates the number of open PeerConnections. Called when a PeerConnection 182 // is stopped or removed. 183 void MaybeClosePeerConnection(base::DictionaryValue* record); 184 185 void MaybeMarkPeerConnectionAsConnected(base::DictionaryValue* record); 186 void MaybeMarkPeerConnectionAsNotConnected(base::DictionaryValue* record); 187 188 // Called whenever a PeerConnection is created or stopped in order to 189 // request/cancel a wake lock on suspending the current application for power 190 // saving. 191 void UpdateWakeLock(); 192 193 device::mojom::WakeLock* GetWakeLock(); 194 195 // Called on a timer to deliver updates to javascript. 196 // We throttle and bulk together updates to avoid DOS like scenarios where 197 // a page uses a lot of peerconnection instances with many event 198 // notifications. 199 void ProcessPendingUpdates(); 200 201 base::DictionaryValue* FindRecord(base::ProcessId pid, 202 int lid, 203 size_t* index = nullptr); 204 205 base::ObserverList<WebRTCInternalsUIObserver>::Unchecked observers_; 206 207 base::ObserverList<WebRtcInternalsConnectionsObserver> connections_observers_; 208 209 // |peer_connection_data_| is a list containing all the PeerConnection 210 // updates. 211 // Each item of the list represents the data for one PeerConnection, which 212 // contains these fields: 213 // "rid" -- the renderer id. 214 // "pid" -- OS process id of the renderer that creates the PeerConnection. 215 // "lid" -- local Id assigned to the PeerConnection. 216 // "url" -- url of the web page that created the PeerConnection. 217 // "servers" and "constraints" -- server configuration and media constraints 218 // used to initialize the PeerConnection respectively. 219 // "log" -- a ListValue contains all the updates for the PeerConnection. Each 220 // list item is a DictionaryValue containing "time", which is the number of 221 // milliseconds since epoch as a string, and "type" and "value", both of which 222 // are strings representing the event. 223 base::ListValue peer_connection_data_; 224 225 // A list of getUserMedia requests. Each item is a DictionaryValue that 226 // contains these fields: 227 // "rid" -- the renderer id. 228 // "pid" -- proceddId of the renderer. 229 // "origin" -- the security origin of the request. 230 // "audio" -- the serialized audio constraints if audio is requested. 231 // "video" -- the serialized video constraints if video is requested. 232 base::ListValue get_user_media_requests_; 233 234 // For managing select file dialog. 235 scoped_refptr<ui::SelectFileDialog> select_file_dialog_; 236 enum class SelectionType { 237 kRtcEventLogs, 238 kAudioDebugRecordings 239 } selection_type_; 240 241 // Diagnostic audio recording state. 242 base::FilePath audio_debug_recordings_file_path_; 243 std::unique_ptr<media::AudioDebugRecordingSession> 244 audio_debug_recording_session_; 245 246 // If non-empty, WebRTC (local) event logging should be enabled using this 247 // path, and may not be turned off, except by restarting the browser. 248 const base::FilePath command_line_derived_logging_path_; 249 250 // Diagnostic event log recording state. These are meaningful only when 251 // |command_line_derived_logging_path_| is empty. 252 bool event_log_recordings_; 253 base::FilePath event_log_recordings_file_path_; 254 255 // While |num_connected_connections_| is greater than zero, request a wake 256 // lock service. This prevents the application from being suspended while 257 // remoting. 258 int num_connected_connections_; 259 const bool should_block_power_saving_; 260 261 // Set of render process hosts that |this| is registered as an observer on. 262 std::unordered_set<int> render_process_id_set_; 263 264 // Used to bulk up updates that we send to javascript. 265 // The class owns the value/dictionary and command name of an update. 266 // For each update, a PendingUpdate is stored in the |pending_updates_| queue 267 // and deleted as soon as the update has been delivered. 268 // The class is moveble and not copyable to avoid copying while still allowing 269 // us to use an stl container without needing scoped_ptr or similar. 270 // The class is single threaded, so all operations must occur on the same 271 // thread. 272 class PendingUpdate { 273 public: 274 PendingUpdate(const char* command, 275 std::unique_ptr<base::Value> value); 276 PendingUpdate(PendingUpdate&& other); 277 ~PendingUpdate(); 278 279 const char* command() const; 280 const base::Value* value() const; 281 282 private: 283 base::ThreadChecker thread_checker_; 284 const char* command_; 285 std::unique_ptr<base::Value> value_; 286 DISALLOW_COPY_AND_ASSIGN(PendingUpdate); 287 }; 288 289 base::queue<PendingUpdate> pending_updates_; 290 const int aggregate_updates_ms_; 291 292 // Weak factory for this object that we use for bulking up updates. 293 base::WeakPtrFactory<WebRTCInternals> weak_factory_{this}; 294 }; 295 296 } // namespace content 297 298 #endif // CONTENT_BROWSER_WEBRTC_WEBRTC_INTERNALS_H_ 299