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

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: Fix issues 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);
Henrik Grunell 2017/03/03 12:40:09 Not being particularly familiar with base::Value,
tommi (sloooow) - chröme 2017/03/03 14:15:14 Yes, it's a polymorphic design with an enum that p
Henrik Grunell 2017/03/06 11:49:24 Acknowledged.
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) {
Henrik Grunell 2017/03/03 12:40:09 Great that you cleaned up the awkward code in this
tommi (sloooow) - chröme 2017/03/03 14:15:14 :D
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 i;
Henrik Grunell 2017/03/03 12:40:09 Nit: perhaps a more descriptive variable name?
tommi (sloooow) - chröme 2017/03/03 14:15:14 Done... although I only changed it to 'index'. |i
156 int this_lid = 0; 162 base::DictionaryValue* dict = FindRecord(pid, lid, &i);
157 dict->GetInteger("pid", &this_pid); 163 if (dict) {
158 dict->GetInteger("lid", &this_lid);
159
160 if (this_pid != static_cast<int>(pid) || this_lid != lid)
161 continue;
162
163 MaybeClosePeerConnection(dict); 164 MaybeClosePeerConnection(dict);
164 peer_connection_data_.Remove(i, NULL); 165 peer_connection_data_.Remove(i, NULL);
166 }
165 167
166 if (observers_.might_have_observers()) { 168 if (observers_.might_have_observers()) {
167 std::unique_ptr<base::DictionaryValue> id(new base::DictionaryValue()); 169 std::unique_ptr<base::DictionaryValue> id(new base::DictionaryValue());
168 id->SetInteger("pid", static_cast<int>(pid)); 170 id->SetInteger("pid", static_cast<int>(pid));
169 id->SetInteger("lid", lid); 171 id->SetInteger("lid", lid);
170 SendUpdate("removePeerConnection", std::move(id)); 172 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 && type == "stop")
182 peer_connection_data_.GetDictionary(i, &record); 182 MaybeClosePeerConnection(record);
183 183
184 int this_pid = 0, this_lid = 0; 184 // Don't update entries if there aren't any observers.
185 record->GetInteger("pid", &this_pid); 185 if (!observers_.might_have_observers())
186 record->GetInteger("lid", &this_lid); 186 return;
187 187
188 if (this_pid != static_cast<int>(pid) || this_lid != lid) 188 std::unique_ptr<base::DictionaryValue> log_entry(new base::DictionaryValue());
189 continue;
190 189
191 if (type == "stop") { 190 double epoch_time = base::Time::Now().ToJsTime();
192 MaybeClosePeerConnection(record); 191 string time = base::DoubleToString(epoch_time);
193 } 192 log_entry->SetString("time", time);
193 log_entry->SetString("type", type);
194 log_entry->SetString("value", value);
194 195
196 std::unique_ptr<base::DictionaryValue> update(new base::DictionaryValue());
197 update->SetInteger("pid", static_cast<int>(pid));
198 update->SetInteger("lid", lid);
199 update->MergeDictionary(log_entry.get());
200
201 SendUpdate("updatePeerConnection", std::move(update));
Henrik Grunell 2017/03/03 12:40:09 In the previous code, this would not be done if no
tommi (sloooow) - chröme 2017/03/03 14:15:14 Not intentional. Changed the behavior back now.
202
203 if (record) {
195 // Append the update to the end of the log. 204 // Append the update to the end of the log.
196 base::ListValue* log = EnsureLogList(record); 205 EnsureLogList(record)->Append(std::move(log_entry));
197 if (!log)
198 return;
199
200 std::unique_ptr<base::DictionaryValue> log_entry(
201 new base::DictionaryValue());
202
203 double epoch_time = base::Time::Now().ToJsTime();
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
209 if (observers_.might_have_observers()) {
210 std::unique_ptr<base::DictionaryValue> update(
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 } 206 }
223 } 207 }
224 208
225 void WebRTCInternals::OnAddStats(base::ProcessId pid, int lid, 209 void WebRTCInternals::OnAddStats(base::ProcessId pid, int lid,
226 const base::ListValue& value) { 210 const base::ListValue& value) {
227 if (!observers_.might_have_observers()) 211 if (!observers_.might_have_observers())
228 return; 212 return;
229 213
230 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); 214 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
231 dict->SetInteger("pid", static_cast<int>(pid)); 215 dict->SetInteger("pid", static_cast<int>(pid));
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 } 251 }
268 252
269 void WebRTCInternals::AddObserver(WebRTCInternalsUIObserver* observer) { 253 void WebRTCInternals::AddObserver(WebRTCInternalsUIObserver* observer) {
270 DCHECK_CURRENTLY_ON(BrowserThread::UI); 254 DCHECK_CURRENTLY_ON(BrowserThread::UI);
271 observers_.AddObserver(observer); 255 observers_.AddObserver(observer);
272 } 256 }
273 257
274 void WebRTCInternals::RemoveObserver(WebRTCInternalsUIObserver* observer) { 258 void WebRTCInternals::RemoveObserver(WebRTCInternalsUIObserver* observer) {
275 DCHECK_CURRENTLY_ON(BrowserThread::UI); 259 DCHECK_CURRENTLY_ON(BrowserThread::UI);
276 observers_.RemoveObserver(observer); 260 observers_.RemoveObserver(observer);
261 if (observers_.might_have_observers())
262 return;
277 263
278 // Disables event log and audio debug recordings if enabled and the last 264 // Disables event log and audio debug recordings if enabled and the last
279 // webrtc-internals page is going away. 265 // webrtc-internals page is going away.
280 if (!observers_.might_have_observers()) { 266 DisableAudioDebugRecordings();
281 if (audio_debug_recordings_) 267 DisableEventLogRecordings();
282 DisableAudioDebugRecordings(); 268
283 DisableEventLogRecordings(); 269 // TODO(tommi): Consider removing all the peer_connection_data_.
284 } 270 for (auto& dictionary : peer_connection_data_)
271 FreeLogList(dictionary.get());
Henrik Grunell 2017/03/03 12:40:09 I don't know the design of WebRTC internals, so to
tommi (sloooow) - chröme 2017/03/03 14:15:14 We do loose data but the thinking is that when chr
Henrik Grunell 2017/03/06 11:49:24 OK, if that's the intention that's fine then.
285 } 272 }
286 273
287 void WebRTCInternals::UpdateObserver(WebRTCInternalsUIObserver* observer) { 274 void WebRTCInternals::UpdateObserver(WebRTCInternalsUIObserver* observer) {
288 DCHECK_CURRENTLY_ON(BrowserThread::UI); 275 DCHECK_CURRENTLY_ON(BrowserThread::UI);
289 if (peer_connection_data_.GetSize() > 0) 276 if (peer_connection_data_.GetSize() > 0)
290 observer->OnUpdate("updateAllPeerConnections", &peer_connection_data_); 277 observer->OnUpdate("updateAllPeerConnections", &peer_connection_data_);
291 278
292 for (const auto& request : get_user_media_requests_) { 279 for (const auto& request : get_user_media_requests_) {
293 observer->OnUpdate("addGetUserMedia", request.get()); 280 observer->OnUpdate("addGetUserMedia", request.get());
294 } 281 }
(...skipping 18 matching lines...) Expand all
313 FILE_PATH_LITERAL(""), 300 FILE_PATH_LITERAL(""),
314 web_contents->GetTopLevelNativeWindow(), 301 web_contents->GetTopLevelNativeWindow(),
315 NULL); 302 NULL);
316 #endif 303 #endif
317 #endif 304 #endif
318 } 305 }
319 306
320 void WebRTCInternals::DisableAudioDebugRecordings() { 307 void WebRTCInternals::DisableAudioDebugRecordings() {
321 DCHECK_CURRENTLY_ON(BrowserThread::UI); 308 DCHECK_CURRENTLY_ON(BrowserThread::UI);
322 #if BUILDFLAG(ENABLE_WEBRTC) 309 #if BUILDFLAG(ENABLE_WEBRTC)
310 if (!audio_debug_recordings_)
311 return;
312
323 audio_debug_recordings_ = false; 313 audio_debug_recordings_ = false;
324 314
325 // Tear down the dialog since the user has unchecked the audio debug 315 // Tear down the dialog since the user has unchecked the audio debug
326 // recordings box. 316 // recordings box.
327 select_file_dialog_ = nullptr; 317 select_file_dialog_ = nullptr;
328 318
329 for (RenderProcessHost::iterator i( 319 for (RenderProcessHost::iterator i(
330 content::RenderProcessHost::AllHostsIterator()); 320 content::RenderProcessHost::AllHostsIterator());
331 !i.IsAtEnd(); i.Advance()) { 321 !i.IsAtEnd(); i.Advance()) {
332 i.GetCurrentValue()->DisableAudioDebugRecordings(); 322 i.GetCurrentValue()->DisableAudioDebugRecordings();
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
570 void WebRTCInternals::ProcessPendingUpdates() { 560 void WebRTCInternals::ProcessPendingUpdates() {
571 DCHECK_CURRENTLY_ON(BrowserThread::UI); 561 DCHECK_CURRENTLY_ON(BrowserThread::UI);
572 while (!pending_updates_.empty()) { 562 while (!pending_updates_.empty()) {
573 const auto& update = pending_updates_.front(); 563 const auto& update = pending_updates_.front();
574 for (auto& observer : observers_) 564 for (auto& observer : observers_)
575 observer.OnUpdate(update.command(), update.value()); 565 observer.OnUpdate(update.command(), update.value());
576 pending_updates_.pop(); 566 pending_updates_.pop();
577 } 567 }
578 } 568 }
579 569
570 base::DictionaryValue* WebRTCInternals::FindRecord(
571 ProcessId pid,
572 int lid,
573 size_t* index /*= nullptr*/) {
574 DCHECK_CURRENTLY_ON(BrowserThread::UI);
575
576 base::DictionaryValue* record = nullptr;
577 for (size_t i = 0; i < peer_connection_data_.GetSize(); ++i) {
578 peer_connection_data_.GetDictionary(i, &record);
579
580 int this_pid = 0, this_lid = 0;
581 record->GetInteger("pid", &this_pid);
582 record->GetInteger("lid", &this_lid);
583
584 if (this_pid == static_cast<int>(pid) && this_lid == lid) {
585 if (index)
586 *index = i;
587 return record;
588 }
589 }
590 return nullptr;
591 }
580 } // namespace content 592 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698