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

Side by Side Diff: content/browser/webrtc/webrtc_internals.cc

Issue 2727233002: Don't collect a log per peerconnection if webrtc-internals isn't open. (Closed)
Patch Set: Address comments, add tests Created 3 years, 9 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
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 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 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/webrtc/webrtc_internals.h" 5 #include "content/browser/webrtc/webrtc_internals.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <memory> 9 #include <memory>
10 #include <utility> 10 #include <utility>
(...skipping 17 matching lines...) Expand all
28 #define IntToStringType base::IntToString 28 #define IntToStringType base::IntToString
29 #endif 29 #endif
30 30
31 using base::ProcessId; 31 using base::ProcessId;
32 using std::string; 32 using std::string;
33 33
34 namespace content { 34 namespace content {
35 35
36 namespace { 36 namespace {
37 37
38 static base::LazyInstance<WebRTCInternals>::Leaky g_webrtc_internals = 38 base::LazyInstance<WebRTCInternals>::Leaky g_webrtc_internals =
39 LAZY_INSTANCE_INITIALIZER; 39 LAZY_INSTANCE_INITIALIZER;
40 40
41 // Makes sure that |dict| has a ListValue under path "log". 41 // Makes sure that |dict| has a ListValue under path "log".
42 static base::ListValue* EnsureLogList(base::DictionaryValue* dict) { 42 base::ListValue* EnsureLogList(base::DictionaryValue* dict) {
43 base::ListValue* log = NULL; 43 base::ListValue* log = NULL;
44 if (!dict->GetList("log", &log)) { 44 if (!dict->GetList("log", &log)) {
45 log = new base::ListValue(); 45 log = new base::ListValue();
46 if (log) 46 dict->Set("log", log);
47 dict->Set("log", log);
48 } 47 }
49 return log; 48 return log;
50 } 49 }
51 50
51 // Removes the log entry associated with a given record.
52 void FreeLogList(base::Value* value) {
53 DCHECK(value->IsType(base::Value::Type::DICTIONARY));
54 auto* dict = static_cast<base::DictionaryValue*>(value);
55 dict->Remove("log", nullptr);
56 }
57
52 } // namespace 58 } // namespace
53 59
54 WebRTCInternals::PendingUpdate::PendingUpdate( 60 WebRTCInternals::PendingUpdate::PendingUpdate(
55 const char* command, 61 const char* command,
56 std::unique_ptr<base::Value> value) 62 std::unique_ptr<base::Value> value)
57 : command_(command), value_(std::move(value)) {} 63 : command_(command), value_(std::move(value)) {}
58 64
59 WebRTCInternals::PendingUpdate::PendingUpdate(PendingUpdate&& other) 65 WebRTCInternals::PendingUpdate::PendingUpdate(PendingUpdate&& other)
60 : command_(other.command_), 66 : command_(other.command_),
61 value_(std::move(other.value_)) {} 67 value_(std::move(other.value_)) {}
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 } 122 }
117 123
118 void WebRTCInternals::OnAddPeerConnection(int render_process_id, 124 void WebRTCInternals::OnAddPeerConnection(int render_process_id,
119 ProcessId pid, 125 ProcessId pid,
120 int lid, 126 int lid,
121 const string& url, 127 const string& url,
122 const string& rtc_configuration, 128 const string& rtc_configuration,
123 const string& constraints) { 129 const string& constraints) {
124 DCHECK_CURRENTLY_ON(BrowserThread::UI); 130 DCHECK_CURRENTLY_ON(BrowserThread::UI);
125 131
132 // TODO(tommi): Consider changing this design so that webrtc-internals has
133 // minimal impact if chrome://webrtc-internals isn't open.
134
126 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); 135 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
127 dict->SetInteger("rid", render_process_id); 136 dict->SetInteger("rid", render_process_id);
128 dict->SetInteger("pid", static_cast<int>(pid)); 137 dict->SetInteger("pid", static_cast<int>(pid));
129 dict->SetInteger("lid", lid); 138 dict->SetInteger("lid", lid);
130 dict->SetString("rtcConfiguration", rtc_configuration); 139 dict->SetString("rtcConfiguration", rtc_configuration);
131 dict->SetString("constraints", constraints); 140 dict->SetString("constraints", constraints);
132 dict->SetString("url", url); 141 dict->SetString("url", url);
133 dict->SetBoolean("isOpen", true); 142 dict->SetBoolean("isOpen", true);
134 143
135 if (observers_.might_have_observers()) 144 if (observers_.might_have_observers())
136 SendUpdate("addPeerConnection", dict->CreateDeepCopy()); 145 SendUpdate("addPeerConnection", dict->CreateDeepCopy());
137 146
138 peer_connection_data_.Append(std::move(dict)); 147 peer_connection_data_.Append(std::move(dict));
139 ++num_open_connections_; 148 ++num_open_connections_;
140 CreateOrReleasePowerSaveBlocker(); 149 CreateOrReleasePowerSaveBlocker();
141 150
142 if (render_process_id_set_.insert(render_process_id).second) { 151 if (render_process_id_set_.insert(render_process_id).second) {
143 RenderProcessHost* host = RenderProcessHost::FromID(render_process_id); 152 RenderProcessHost* host = RenderProcessHost::FromID(render_process_id);
144 if (host) 153 if (host)
145 host->AddObserver(this); 154 host->AddObserver(this);
146 } 155 }
147 } 156 }
148 157
149 void WebRTCInternals::OnRemovePeerConnection(ProcessId pid, int lid) { 158 void WebRTCInternals::OnRemovePeerConnection(ProcessId pid, int lid) {
150 DCHECK_CURRENTLY_ON(BrowserThread::UI); 159 DCHECK_CURRENTLY_ON(BrowserThread::UI);
151 for (size_t i = 0; i < peer_connection_data_.GetSize(); ++i) {
152 base::DictionaryValue* dict = NULL;
153 peer_connection_data_.GetDictionary(i, &dict);
154 160
155 int this_pid = 0; 161 size_t index;
156 int this_lid = 0; 162 base::DictionaryValue* dict = FindRecord(pid, lid, &index);
157 dict->GetInteger("pid", &this_pid); 163 if (dict) {
158 dict->GetInteger("lid", &this_lid); 164 MaybeClosePeerConnection(dict);
165 peer_connection_data_.Remove(index, NULL);
166 }
159 167
160 if (this_pid != static_cast<int>(pid) || this_lid != lid) 168 if (observers_.might_have_observers()) {
161 continue; 169 std::unique_ptr<base::DictionaryValue> id(new base::DictionaryValue());
162 170 id->SetInteger("pid", static_cast<int>(pid));
163 MaybeClosePeerConnection(dict); 171 id->SetInteger("lid", lid);
164 peer_connection_data_.Remove(i, NULL); 172 SendUpdate("removePeerConnection", std::move(id));
165
166 if (observers_.might_have_observers()) {
167 std::unique_ptr<base::DictionaryValue> id(new base::DictionaryValue());
168 id->SetInteger("pid", static_cast<int>(pid));
169 id->SetInteger("lid", lid);
170 SendUpdate("removePeerConnection", std::move(id));
171 }
172 break;
173 } 173 }
174 } 174 }
175 175
176 void WebRTCInternals::OnUpdatePeerConnection( 176 void WebRTCInternals::OnUpdatePeerConnection(
177 ProcessId pid, int lid, const string& type, const string& value) { 177 ProcessId pid, int lid, const string& type, const string& value) {
178 DCHECK_CURRENTLY_ON(BrowserThread::UI); 178 DCHECK_CURRENTLY_ON(BrowserThread::UI);
179 179
180 for (size_t i = 0; i < peer_connection_data_.GetSize(); ++i) { 180 base::DictionaryValue* record = FindRecord(pid, lid);
181 base::DictionaryValue* record = NULL; 181 if (!record)
182 peer_connection_data_.GetDictionary(i, &record); 182 return;
183 183
184 int this_pid = 0, this_lid = 0; 184 if (type == "stop")
185 record->GetInteger("pid", &this_pid); 185 MaybeClosePeerConnection(record);
186 record->GetInteger("lid", &this_lid);
187 186
188 if (this_pid != static_cast<int>(pid) || this_lid != lid) 187 // Don't update entries if there aren't any observers.
189 continue; 188 if (!observers_.might_have_observers())
189 return;
190 190
191 if (type == "stop") { 191 std::unique_ptr<base::DictionaryValue> log_entry(new base::DictionaryValue());
192 MaybeClosePeerConnection(record);
193 }
194 192
195 // Append the update to the end of the log. 193 double epoch_time = base::Time::Now().ToJsTime();
196 base::ListValue* log = EnsureLogList(record); 194 string time = base::DoubleToString(epoch_time);
197 if (!log) 195 log_entry->SetString("time", time);
198 return; 196 log_entry->SetString("type", type);
197 log_entry->SetString("value", value);
199 198
200 std::unique_ptr<base::DictionaryValue> log_entry( 199 std::unique_ptr<base::DictionaryValue> update(new base::DictionaryValue());
201 new base::DictionaryValue()); 200 update->SetInteger("pid", static_cast<int>(pid));
201 update->SetInteger("lid", lid);
202 update->MergeDictionary(log_entry.get());
202 203
203 double epoch_time = base::Time::Now().ToJsTime(); 204 SendUpdate("updatePeerConnection", std::move(update));
204 string time = base::DoubleToString(epoch_time);
205 log_entry->SetString("time", time);
206 log_entry->SetString("type", type);
207 log_entry->SetString("value", value);
208 205
209 if (observers_.might_have_observers()) { 206 // Append the update to the end of the log.
210 std::unique_ptr<base::DictionaryValue> update( 207 EnsureLogList(record)->Append(std::move(log_entry));
211 new base::DictionaryValue());
212 update->SetInteger("pid", static_cast<int>(pid));
213 update->SetInteger("lid", lid);
214 update->MergeDictionary(log_entry.get());
215
216 SendUpdate("updatePeerConnection", std::move(update));
217 }
218
219 log->Append(std::move(log_entry));
220
221 return;
222 }
223 } 208 }
224 209
225 void WebRTCInternals::OnAddStats(base::ProcessId pid, int lid, 210 void WebRTCInternals::OnAddStats(base::ProcessId pid, int lid,
226 const base::ListValue& value) { 211 const base::ListValue& value) {
227 if (!observers_.might_have_observers()) 212 if (!observers_.might_have_observers())
228 return; 213 return;
229 214
230 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); 215 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
231 dict->SetInteger("pid", static_cast<int>(pid)); 216 dict->SetInteger("pid", static_cast<int>(pid));
232 dict->SetInteger("lid", lid); 217 dict->SetInteger("lid", lid);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 } 252 }
268 253
269 void WebRTCInternals::AddObserver(WebRTCInternalsUIObserver* observer) { 254 void WebRTCInternals::AddObserver(WebRTCInternalsUIObserver* observer) {
270 DCHECK_CURRENTLY_ON(BrowserThread::UI); 255 DCHECK_CURRENTLY_ON(BrowserThread::UI);
271 observers_.AddObserver(observer); 256 observers_.AddObserver(observer);
272 } 257 }
273 258
274 void WebRTCInternals::RemoveObserver(WebRTCInternalsUIObserver* observer) { 259 void WebRTCInternals::RemoveObserver(WebRTCInternalsUIObserver* observer) {
275 DCHECK_CURRENTLY_ON(BrowserThread::UI); 260 DCHECK_CURRENTLY_ON(BrowserThread::UI);
276 observers_.RemoveObserver(observer); 261 observers_.RemoveObserver(observer);
262 if (observers_.might_have_observers())
263 return;
277 264
278 // Disables event log and audio debug recordings if enabled and the last 265 // Disables event log and audio debug recordings if enabled and the last
279 // webrtc-internals page is going away. 266 // webrtc-internals page is going away.
280 if (!observers_.might_have_observers()) { 267 DisableAudioDebugRecordings();
281 if (audio_debug_recordings_) 268 DisableEventLogRecordings();
282 DisableAudioDebugRecordings(); 269
283 DisableEventLogRecordings(); 270 // TODO(tommi): Consider removing all the peer_connection_data_.
284 } 271 for (auto& dictionary : peer_connection_data_)
272 FreeLogList(dictionary.get());
285 } 273 }
286 274
287 void WebRTCInternals::UpdateObserver(WebRTCInternalsUIObserver* observer) { 275 void WebRTCInternals::UpdateObserver(WebRTCInternalsUIObserver* observer) {
288 DCHECK_CURRENTLY_ON(BrowserThread::UI); 276 DCHECK_CURRENTLY_ON(BrowserThread::UI);
289 if (peer_connection_data_.GetSize() > 0) 277 if (peer_connection_data_.GetSize() > 0)
290 observer->OnUpdate("updateAllPeerConnections", &peer_connection_data_); 278 observer->OnUpdate("updateAllPeerConnections", &peer_connection_data_);
291 279
292 for (const auto& request : get_user_media_requests_) { 280 for (const auto& request : get_user_media_requests_) {
293 observer->OnUpdate("addGetUserMedia", request.get()); 281 observer->OnUpdate("addGetUserMedia", request.get());
294 } 282 }
(...skipping 18 matching lines...) Expand all
313 FILE_PATH_LITERAL(""), 301 FILE_PATH_LITERAL(""),
314 web_contents->GetTopLevelNativeWindow(), 302 web_contents->GetTopLevelNativeWindow(),
315 NULL); 303 NULL);
316 #endif 304 #endif
317 #endif 305 #endif
318 } 306 }
319 307
320 void WebRTCInternals::DisableAudioDebugRecordings() { 308 void WebRTCInternals::DisableAudioDebugRecordings() {
321 DCHECK_CURRENTLY_ON(BrowserThread::UI); 309 DCHECK_CURRENTLY_ON(BrowserThread::UI);
322 #if BUILDFLAG(ENABLE_WEBRTC) 310 #if BUILDFLAG(ENABLE_WEBRTC)
311 if (!audio_debug_recordings_)
312 return;
313
323 audio_debug_recordings_ = false; 314 audio_debug_recordings_ = false;
324 315
325 // Tear down the dialog since the user has unchecked the audio debug 316 // Tear down the dialog since the user has unchecked the audio debug
326 // recordings box. 317 // recordings box.
327 select_file_dialog_ = nullptr; 318 select_file_dialog_ = nullptr;
328 319
329 for (RenderProcessHost::iterator i( 320 for (RenderProcessHost::iterator i(
330 content::RenderProcessHost::AllHostsIterator()); 321 content::RenderProcessHost::AllHostsIterator());
331 !i.IsAtEnd(); i.Advance()) { 322 !i.IsAtEnd(); i.Advance()) {
332 i.GetCurrentValue()->DisableAudioDebugRecordings(); 323 i.GetCurrentValue()->DisableAudioDebugRecordings();
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
570 void WebRTCInternals::ProcessPendingUpdates() { 561 void WebRTCInternals::ProcessPendingUpdates() {
571 DCHECK_CURRENTLY_ON(BrowserThread::UI); 562 DCHECK_CURRENTLY_ON(BrowserThread::UI);
572 while (!pending_updates_.empty()) { 563 while (!pending_updates_.empty()) {
573 const auto& update = pending_updates_.front(); 564 const auto& update = pending_updates_.front();
574 for (auto& observer : observers_) 565 for (auto& observer : observers_)
575 observer.OnUpdate(update.command(), update.value()); 566 observer.OnUpdate(update.command(), update.value());
576 pending_updates_.pop(); 567 pending_updates_.pop();
577 } 568 }
578 } 569 }
579 570
571 base::DictionaryValue* WebRTCInternals::FindRecord(
572 ProcessId pid,
573 int lid,
574 size_t* index /*= nullptr*/) {
575 DCHECK_CURRENTLY_ON(BrowserThread::UI);
576
577 base::DictionaryValue* record = nullptr;
578 for (size_t i = 0; i < peer_connection_data_.GetSize(); ++i) {
579 peer_connection_data_.GetDictionary(i, &record);
580
581 int this_pid = 0, this_lid = 0;
582 record->GetInteger("pid", &this_pid);
583 record->GetInteger("lid", &this_lid);
584
585 if (this_pid == static_cast<int>(pid) && this_lid == lid) {
586 if (index)
587 *index = i;
588 return record;
589 }
590 }
591 return nullptr;
592 }
580 } // namespace content 593 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/webrtc/webrtc_internals.h ('k') | content/browser/webrtc/webrtc_internals_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698