1 // Copyright 2017 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 #include "chrome/browser/media/webrtc/webrtc_event_log_manager.h"
6
7 #include <limits>
8
9 #include "base/bind.h"
10 #include "base/callback_helpers.h"
11 #include "base/memory/ptr_util.h"
12 #include "base/task/post_task.h"
13 #include "base/task/thread_pool.h"
14 #include "build/build_config.h"
15 #include "chrome/browser/browser_process.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/common/chrome_features.h"
18 #include "chrome/common/pref_names.h"
19 #include "components/prefs/pref_service.h"
20 #include "content/public/browser/browser_context.h"
21 #include "content/public/browser/browser_task_traits.h"
22 #include "content/public/browser/browser_thread.h"
23 #include "content/public/browser/network_service_instance.h"
24 #include "content/public/browser/render_process_host.h"
25
26 namespace webrtc_event_logging {
27
28 namespace {
29
30 using BrowserContext = content::BrowserContext;
31 using BrowserThread = content::BrowserThread;
32 using RenderProcessHost = content::RenderProcessHost;
33
34 using BrowserContextId = WebRtcEventLogManager::BrowserContextId;
35
36 class PeerConnectionTrackerProxyImpl
37 : public WebRtcEventLogManager::PeerConnectionTrackerProxy {
38 public:
39 ~PeerConnectionTrackerProxyImpl() override = default;
40
EnableWebRtcEventLogging(const WebRtcEventLogPeerConnectionKey & key,int output_period_ms)41 void EnableWebRtcEventLogging(const WebRtcEventLogPeerConnectionKey& key,
42 int output_period_ms) override {
43 content::GetUIThreadTaskRunner({})->PostTask(
44 FROM_HERE,
45 base::BindOnce(
46 &PeerConnectionTrackerProxyImpl::EnableWebRtcEventLoggingInternal,
47 key, output_period_ms));
48 }
49
DisableWebRtcEventLogging(const WebRtcEventLogPeerConnectionKey & key)50 void DisableWebRtcEventLogging(
51 const WebRtcEventLogPeerConnectionKey& key) override {
52 content::GetUIThreadTaskRunner({})->PostTask(
53 FROM_HERE,
54 base::BindOnce(
55 &PeerConnectionTrackerProxyImpl::DisableWebRtcEventLoggingInternal,
56 key));
57 }
58
59 private:
EnableWebRtcEventLoggingInternal(WebRtcEventLogPeerConnectionKey key,int output_period_ms)60 static void EnableWebRtcEventLoggingInternal(
61 WebRtcEventLogPeerConnectionKey key,
62 int output_period_ms) {
63 DCHECK_CURRENTLY_ON(BrowserThread::UI);
64 RenderProcessHost* host = RenderProcessHost::FromID(key.render_process_id);
65 if (!host) {
66 return; // The host has been asynchronously removed; not a problem.
67 }
68 host->EnableWebRtcEventLogOutput(key.lid, output_period_ms);
69 }
70
DisableWebRtcEventLoggingInternal(WebRtcEventLogPeerConnectionKey key)71 static void DisableWebRtcEventLoggingInternal(
72 WebRtcEventLogPeerConnectionKey key) {
73 DCHECK_CURRENTLY_ON(BrowserThread::UI);
74 RenderProcessHost* host = RenderProcessHost::FromID(key.render_process_id);
75 if (!host) {
76 return; // The host has been asynchronously removed; not a problem.
77 }
78 host->DisableWebRtcEventLogOutput(key.lid);
79 }
80 };
81
82 // Check whether remote-bound logging is generally allowed, although not
83 // necessarily for any given user profile.
84 // 1. Certain platforms (mobile) are blocked from remote-bound logging.
85 // 2. There is a Finch-controlled kill-switch for the feature.
IsRemoteLoggingFeatureEnabled()86 bool IsRemoteLoggingFeatureEnabled() {
87 #if defined(OS_ANDROID)
88 bool enabled = false;
89 #else
90 bool enabled = base::FeatureList::IsEnabled(features::kWebRtcRemoteEventLog);
91 #endif
92
93 VLOG(1) << "WebRTC remote-bound event logging "
94 << (enabled ? "enabled" : "disabled") << ".";
95
96 return enabled;
97 }
98
GetBrowserContext(int render_process_id)99 BrowserContext* GetBrowserContext(int render_process_id) {
100 DCHECK_CURRENTLY_ON(BrowserThread::UI);
101 RenderProcessHost* const host = RenderProcessHost::FromID(render_process_id);
102 return host ? host->GetBrowserContext() : nullptr;
103 }
104
105 // Post reply back if non-empty.
106 template <typename... Args>
MaybeReply(const base::Location & location,base::OnceCallback<void (Args...)> reply,Args...args)107 inline void MaybeReply(const base::Location& location,
108 base::OnceCallback<void(Args...)> reply,
109 Args... args) {
110 if (reply) {
111 base::PostTask(location, {BrowserThread::UI},
112 base::BindOnce(std::move(reply), args...));
113 }
114 }
115
116 } // namespace
117
118 WebRtcEventLogManager* WebRtcEventLogManager::g_webrtc_event_log_manager =
119 nullptr;
120
121 std::unique_ptr<WebRtcEventLogManager>
CreateSingletonInstance()122 WebRtcEventLogManager::CreateSingletonInstance() {
123 DCHECK_CURRENTLY_ON(BrowserThread::UI);
124 DCHECK(!g_webrtc_event_log_manager);
125 g_webrtc_event_log_manager = new WebRtcEventLogManager;
126 return base::WrapUnique<WebRtcEventLogManager>(g_webrtc_event_log_manager);
127 }
128
GetInstance()129 WebRtcEventLogManager* WebRtcEventLogManager::GetInstance() {
130 DCHECK_CURRENTLY_ON(BrowserThread::UI);
131 return g_webrtc_event_log_manager;
132 }
133
GetRemoteBoundWebRtcEventLogsDir(content::BrowserContext * browser_context)134 base::FilePath WebRtcEventLogManager::GetRemoteBoundWebRtcEventLogsDir(
135 content::BrowserContext* browser_context) {
136 DCHECK_CURRENTLY_ON(BrowserThread::UI);
137 DCHECK(browser_context);
138 // Incognito BrowserContext will return their parent profile's directory.
139 return webrtc_event_logging::GetRemoteBoundWebRtcEventLogsDir(
140 browser_context->GetPath());
141 }
142
WebRtcEventLogManager()143 WebRtcEventLogManager::WebRtcEventLogManager()
144 : task_runner_(base::ThreadPool::CreateUpdateableSequencedTaskRunner(
145 {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
146 base::ThreadPolicy::PREFER_BACKGROUND,
147 base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})),
148 num_user_blocking_tasks_(0),
149 remote_logging_feature_enabled_(IsRemoteLoggingFeatureEnabled()),
150 local_logs_observer_(nullptr),
151 remote_logs_observer_(nullptr),
152 local_logs_manager_(this),
153 remote_logs_manager_(this, task_runner_),
154 pc_tracker_proxy_(new PeerConnectionTrackerProxyImpl),
155 first_browser_context_initializations_done_(false) {
156 DCHECK_CURRENTLY_ON(BrowserThread::UI);
157 DCHECK(!g_webrtc_event_log_manager);
158 g_webrtc_event_log_manager = this;
159 }
160
~WebRtcEventLogManager()161 WebRtcEventLogManager::~WebRtcEventLogManager() {
162 DCHECK_CURRENTLY_ON(BrowserThread::UI);
163
164 for (RenderProcessHost* host : observed_render_process_hosts_) {
165 host->RemoveObserver(this);
166 }
167
168 DCHECK(g_webrtc_event_log_manager);
169 g_webrtc_event_log_manager = nullptr;
170 }
171
EnableForBrowserContext(BrowserContext * browser_context,base::OnceClosure reply)172 void WebRtcEventLogManager::EnableForBrowserContext(
173 BrowserContext* browser_context,
174 base::OnceClosure reply) {
175 DCHECK_CURRENTLY_ON(BrowserThread::UI);
176 DCHECK(browser_context);
177 CHECK(!browser_context->IsOffTheRecord());
178
179 if (!first_browser_context_initializations_done_) {
180 OnFirstBrowserContextLoaded();
181 first_browser_context_initializations_done_ = true;
182 }
183
184 StartListeningForPrefChangeForBrowserContext(browser_context);
185
186 if (!IsRemoteLoggingAllowedForBrowserContext(browser_context)) {
187 // If remote-bound logging was enabled during a previous Chrome session,
188 // it might have produced some pending log files, which we will now
189 // wish to remove.
190 // |this| is destroyed by ~BrowserProcessImpl(), so base::Unretained(this)
191 // will not be dereferenced after destruction.
192 task_runner_->PostTask(
193 FROM_HERE,
194 base::BindOnce(
195 &WebRtcEventLogManager::
196 RemovePendingRemoteBoundLogsForNotEnabledBrowserContext,
197 base::Unretained(this), GetBrowserContextId(browser_context),
198 browser_context->GetPath(), std::move(reply)));
199 return;
200 }
201
202 // |this| is destroyed by ~BrowserProcessImpl(), so base::Unretained(this)
203 // will not be dereferenced after destruction.
204 task_runner_->PostTask(
205 FROM_HERE,
206 base::BindOnce(
207 &WebRtcEventLogManager::EnableRemoteBoundLoggingForBrowserContext,
208 base::Unretained(this), GetBrowserContextId(browser_context),
209 browser_context->GetPath(), std::move(reply)));
210 }
211
DisableForBrowserContext(content::BrowserContext * browser_context,base::OnceClosure reply)212 void WebRtcEventLogManager::DisableForBrowserContext(
213 content::BrowserContext* browser_context,
214 base::OnceClosure reply) {
215 DCHECK_CURRENTLY_ON(BrowserThread::UI);
216 DCHECK(browser_context);
217
218 StopListeningForPrefChangeForBrowserContext(browser_context);
219
220 // |this| is destroyed by ~BrowserProcessImpl(), so base::Unretained(this)
221 // will not be dereferenced after destruction.
222 task_runner_->PostTask(
223 FROM_HERE,
224 base::BindOnce(
225 &WebRtcEventLogManager::DisableRemoteBoundLoggingForBrowserContext,
226 base::Unretained(this), GetBrowserContextId(browser_context),
227 std::move(reply)));
228 }
229
PeerConnectionAdded(int render_process_id,int lid,base::OnceCallback<void (bool)> reply)230 void WebRtcEventLogManager::PeerConnectionAdded(
231 int render_process_id,
232 int lid,
233 base::OnceCallback<void(bool)> reply) {
234 DCHECK_CURRENTLY_ON(BrowserThread::UI);
235
236 RenderProcessHost* rph = RenderProcessHost::FromID(render_process_id);
237 if (!rph) {
238 // RPH died before processing of this notification.
239 MaybeReply(FROM_HERE, std::move(reply), false);
240 return;
241 }
242
243 auto it = observed_render_process_hosts_.find(rph);
244 if (it == observed_render_process_hosts_.end()) {
245 // This is the first PeerConnection which we see that's associated
246 // with this RPH.
247 rph->AddObserver(this);
248 observed_render_process_hosts_.insert(rph);
249 }
250
251 const auto browser_context_id = GetBrowserContextId(rph->GetBrowserContext());
252 DCHECK_NE(browser_context_id, kNullBrowserContextId);
253
254 // |this| is destroyed by ~BrowserProcessImpl(), so base::Unretained(this)
255 // will not be dereferenced after destruction.
256 task_runner_->PostTask(
257 FROM_HERE,
258 base::BindOnce(
259 &WebRtcEventLogManager::PeerConnectionAddedInternal,
260 base::Unretained(this),
261 PeerConnectionKey(render_process_id, lid, browser_context_id),
262 std::move(reply)));
263 }
264
PeerConnectionRemoved(int render_process_id,int lid,base::OnceCallback<void (bool)> reply)265 void WebRtcEventLogManager::PeerConnectionRemoved(
266 int render_process_id,
267 int lid,
268 base::OnceCallback<void(bool)> reply) {
269 DCHECK_CURRENTLY_ON(BrowserThread::UI);
270
271 const auto browser_context_id = GetBrowserContextId(render_process_id);
272 if (browser_context_id == kNullBrowserContextId) {
273 // RPH died before processing of this notification. This is handled by
274 // RenderProcessExited() / RenderProcessHostDestroyed.
275 MaybeReply(FROM_HERE, std::move(reply), false);
276 return;
277 }
278
279 // |this| is destroyed by ~BrowserProcessImpl(), so base::Unretained(this)
280 // will not be dereferenced after destruction.
281 task_runner_->PostTask(
282 FROM_HERE,
283 base::BindOnce(
284 &WebRtcEventLogManager::PeerConnectionRemovedInternal,
285 base::Unretained(this),
286 PeerConnectionKey(render_process_id, lid, browser_context_id),
287 std::move(reply)));
288 }
289
PeerConnectionStopped(int render_process_id,int lid,base::OnceCallback<void (bool)> reply)290 void WebRtcEventLogManager::PeerConnectionStopped(
291 int render_process_id,
292 int lid,
293 base::OnceCallback<void(bool)> reply) {
294 DCHECK_CURRENTLY_ON(BrowserThread::UI);
295 return PeerConnectionRemoved(render_process_id, lid, std::move(reply));
296 }
297
PeerConnectionSessionIdSet(int render_process_id,int lid,const std::string & session_id,base::OnceCallback<void (bool)> reply)298 void WebRtcEventLogManager::PeerConnectionSessionIdSet(
299 int render_process_id,
300 int lid,
301 const std::string& session_id,
302 base::OnceCallback<void(bool)> reply) {
303 DCHECK_CURRENTLY_ON(BrowserThread::UI);
304
305 const auto browser_context_id = GetBrowserContextId(render_process_id);
306 if (browser_context_id == kNullBrowserContextId) {
307 // RPH died before processing of this notification. This is handled by
308 // RenderProcessExited() / RenderProcessHostDestroyed.
309 MaybeReply(FROM_HERE, std::move(reply), false);
310 return;
311 }
312
313 // |this| is destroyed by ~BrowserProcessImpl(), so base::Unretained(this)
314 // will not be dereferenced after destruction.
315 task_runner_->PostTask(
316 FROM_HERE,
317 base::BindOnce(
318 &WebRtcEventLogManager::PeerConnectionSessionIdSetInternal,
319 base::Unretained(this),
320 PeerConnectionKey(render_process_id, lid, browser_context_id),
321 session_id, std::move(reply)));
322 }
323
EnableLocalLogging(const base::FilePath & base_path,base::OnceCallback<void (bool)> reply)324 void WebRtcEventLogManager::EnableLocalLogging(
325 const base::FilePath& base_path,
326 base::OnceCallback<void(bool)> reply) {
327 DCHECK_CURRENTLY_ON(BrowserThread::UI);
328 EnableLocalLogging(base_path, kDefaultMaxLocalLogFileSizeBytes,
329 std::move(reply));
330 }
331
EnableLocalLogging(const base::FilePath & base_path,size_t max_file_size_bytes,base::OnceCallback<void (bool)> reply)332 void WebRtcEventLogManager::EnableLocalLogging(
333 const base::FilePath& base_path,
334 size_t max_file_size_bytes,
335 base::OnceCallback<void(bool)> reply) {
336 DCHECK_CURRENTLY_ON(BrowserThread::UI);
337 DCHECK(!base_path.empty());
338 // |this| is destroyed by ~BrowserProcessImpl(), so base::Unretained(this)
339 // will not be dereferenced after destruction.
340 task_runner_->PostTask(
341 FROM_HERE,
342 base::BindOnce(&WebRtcEventLogManager::EnableLocalLoggingInternal,
343 base::Unretained(this), base_path, max_file_size_bytes,
344 std::move(reply)));
345 }
346
DisableLocalLogging(base::OnceCallback<void (bool)> reply)347 void WebRtcEventLogManager::DisableLocalLogging(
348 base::OnceCallback<void(bool)> reply) {
349 DCHECK_CURRENTLY_ON(BrowserThread::UI);
350 // |this| is destroyed by ~BrowserProcessImpl(), so base::Unretained(this)
351 // will not be dereferenced after destruction.
352 task_runner_->PostTask(
353 FROM_HERE,
354 base::BindOnce(&WebRtcEventLogManager::DisableLocalLoggingInternal,
355 base::Unretained(this), std::move(reply)));
356 }
357
OnWebRtcEventLogWrite(int render_process_id,int lid,const std::string & message,base::OnceCallback<void (std::pair<bool,bool>)> reply)358 void WebRtcEventLogManager::OnWebRtcEventLogWrite(
359 int render_process_id,
360 int lid,
361 const std::string& message,
362 base::OnceCallback<void(std::pair<bool, bool>)> reply) {
363 DCHECK_CURRENTLY_ON(BrowserThread::UI);
364
365 const BrowserContext* browser_context = GetBrowserContext(render_process_id);
366 if (!browser_context) {
367 // RPH died before processing of this notification.
368 MaybeReply(FROM_HERE, std::move(reply), std::make_pair(false, false));
369 return;
370 }
371
372 const auto browser_context_id = GetBrowserContextId(browser_context);
373 DCHECK_NE(browser_context_id, kNullBrowserContextId);
374
375 // |this| is destroyed by ~BrowserProcessImpl(), so base::Unretained(this)
376 // will not be dereferenced after destruction.
377 task_runner_->PostTask(
378 FROM_HERE,
379 base::BindOnce(
380 &WebRtcEventLogManager::OnWebRtcEventLogWriteInternal,
381 base::Unretained(this),
382 PeerConnectionKey(render_process_id, lid, browser_context_id),
383 message, std::move(reply)));
384 }
385
StartRemoteLogging(int render_process_id,const std::string & session_id,size_t max_file_size_bytes,int output_period_ms,size_t web_app_id,base::OnceCallback<void (bool,const std::string &,const std::string &)> reply)386 void WebRtcEventLogManager::StartRemoteLogging(
387 int render_process_id,
388 const std::string& session_id,
389 size_t max_file_size_bytes,
390 int output_period_ms,
391 size_t web_app_id,
392 base::OnceCallback<void(bool, const std::string&, const std::string&)>
393 reply) {
394 DCHECK_CURRENTLY_ON(BrowserThread::UI);
395 DCHECK(reply);
396
397 BrowserContext* browser_context = GetBrowserContext(render_process_id);
398 const char* error = nullptr;
399
400 if (!browser_context) {
401 // RPH died before processing of this notification.
402 UmaRecordWebRtcEventLoggingApi(WebRtcEventLoggingApiUma::kDeadRph);
403 error = kStartRemoteLoggingFailureDeadRenderProcessHost;
404 } else if (!IsRemoteLoggingAllowedForBrowserContext(browser_context)) {
405 UmaRecordWebRtcEventLoggingApi(WebRtcEventLoggingApiUma::kFeatureDisabled);
406 error = kStartRemoteLoggingFailureFeatureDisabled;
407 } else if (browser_context->IsOffTheRecord()) {
408 // Feature disable in incognito. Since the feature can be disabled for
409 // non-incognito sessions, this should not expose incognito mode.
410 UmaRecordWebRtcEventLoggingApi(WebRtcEventLoggingApiUma::kIncognito);
411 error = kStartRemoteLoggingFailureFeatureDisabled;
412 }
413
414 if (error) {
415 content::GetUIThreadTaskRunner({})->PostTask(
416 FROM_HERE, base::BindOnce(std::move(reply), false, std::string(),
417 std::string(error)));
418 return;
419 }
420
421 const auto browser_context_id = GetBrowserContextId(browser_context);
422 DCHECK_NE(browser_context_id, kNullBrowserContextId);
423
424 // |this| is destroyed by ~BrowserProcessImpl(), so base::Unretained(this)
425 // will not be dereferenced after destruction.
426 task_runner_->PostTask(
427 FROM_HERE,
428 base::BindOnce(&WebRtcEventLogManager::StartRemoteLoggingInternal,
429 base::Unretained(this), render_process_id,
430 browser_context_id, session_id, browser_context->GetPath(),
431 max_file_size_bytes, output_period_ms, web_app_id,
432 std::move(reply)));
433 }
434
ClearCacheForBrowserContext(const BrowserContext * browser_context,const base::Time & delete_begin,const base::Time & delete_end,base::OnceClosure reply)435 void WebRtcEventLogManager::ClearCacheForBrowserContext(
436 const BrowserContext* browser_context,
437 const base::Time& delete_begin,
438 const base::Time& delete_end,
439 base::OnceClosure reply) {
440 DCHECK_CURRENTLY_ON(BrowserThread::UI);
441
442 const auto browser_context_id = GetBrowserContextId(browser_context);
443 DCHECK_NE(browser_context_id, kNullBrowserContextId);
444
445 DCHECK_LT(num_user_blocking_tasks_, std::numeric_limits<size_t>::max());
446 if (++num_user_blocking_tasks_ == 1) {
447 task_runner_->UpdatePriority(base::TaskPriority::USER_BLOCKING);
448 }
449
450 // |this| is destroyed by ~BrowserProcessImpl(), so base::Unretained(this)
451 // will not be dereferenced after destruction.
452 task_runner_->PostTaskAndReply(
453 FROM_HERE,
454 base::BindOnce(
455 &WebRtcEventLogManager::ClearCacheForBrowserContextInternal,
456 base::Unretained(this), browser_context_id, delete_begin, delete_end),
457 base::BindOnce(
458 &WebRtcEventLogManager::OnClearCacheForBrowserContextDoneInternal,
459 base::Unretained(this), std::move(reply)));
460 }
461
GetHistory(BrowserContextId browser_context_id,base::OnceCallback<void (const std::vector<UploadList::UploadInfo> &)> reply)462 void WebRtcEventLogManager::GetHistory(
463 BrowserContextId browser_context_id,
464 base::OnceCallback<void(const std::vector<UploadList::UploadInfo>&)>
465 reply) {
466 DCHECK_CURRENTLY_ON(BrowserThread::UI);
467 DCHECK(reply);
468
469 // |this| is destroyed by ~BrowserProcessImpl(), so base::Unretained(this)
470 // will not be dereferenced after destruction.
471 task_runner_->PostTask(
472 FROM_HERE, base::BindOnce(&WebRtcEventLogManager::GetHistoryInternal,
473 base::Unretained(this), browser_context_id,
474 std::move(reply)));
475 }
476
SetLocalLogsObserver(WebRtcLocalEventLogsObserver * observer,base::OnceClosure reply)477 void WebRtcEventLogManager::SetLocalLogsObserver(
478 WebRtcLocalEventLogsObserver* observer,
479 base::OnceClosure reply) {
480 DCHECK_CURRENTLY_ON(BrowserThread::UI);
481 // |this| is destroyed by ~BrowserProcessImpl(), so base::Unretained(this)
482 // will not be dereferenced after destruction.
483 task_runner_->PostTask(
484 FROM_HERE,
485 base::BindOnce(&WebRtcEventLogManager::SetLocalLogsObserverInternal,
486 base::Unretained(this), observer, std::move(reply)));
487 }
488
SetRemoteLogsObserver(WebRtcRemoteEventLogsObserver * observer,base::OnceClosure reply)489 void WebRtcEventLogManager::SetRemoteLogsObserver(
490 WebRtcRemoteEventLogsObserver* observer,
491 base::OnceClosure reply) {
492 DCHECK_CURRENTLY_ON(BrowserThread::UI);
493 // |this| is destroyed by ~BrowserProcessImpl(), so base::Unretained(this)
494 // will not be dereferenced after destruction.
495 task_runner_->PostTask(
496 FROM_HERE,
497 base::BindOnce(&WebRtcEventLogManager::SetRemoteLogsObserverInternal,
498 base::Unretained(this), observer, std::move(reply)));
499 }
500
IsRemoteLoggingAllowedForBrowserContext(BrowserContext * browser_context) const501 bool WebRtcEventLogManager::IsRemoteLoggingAllowedForBrowserContext(
502 BrowserContext* browser_context) const {
503 DCHECK_CURRENTLY_ON(BrowserThread::UI);
504 DCHECK(browser_context);
505
506 if (!remote_logging_feature_enabled_) {
507 return false;
508 }
509
510 const Profile* profile = Profile::FromBrowserContext(browser_context);
511 DCHECK(profile);
512
513 const PrefService::Preference* webrtc_event_log_collection_allowed_pref =
514 profile->GetPrefs()->FindPreference(
515 prefs::kWebRtcEventLogCollectionAllowed);
516 DCHECK(webrtc_event_log_collection_allowed_pref);
517
518 if (webrtc_event_log_collection_allowed_pref->IsDefaultValue()) {
519 // The pref has not been set. GetBoolean would only return the default
520 // value. However, there is no single default value,
521 // because it depends on whether the profile receives cloud-based
522 // enterprise policies.
523 return DoesProfileDefaultToLoggingEnabled(profile);
524 }
525
526 // There is a non-default value set, so this value is authoritative.
527 return profile->GetPrefs()->GetBoolean(
528 prefs::kWebRtcEventLogCollectionAllowed);
529 }
530
531 std::unique_ptr<LogFileWriter::Factory>
CreateRemoteLogFileWriterFactory()532 WebRtcEventLogManager::CreateRemoteLogFileWriterFactory() {
533 if (remote_log_file_writer_factory_for_testing_) {
534 return std::move(remote_log_file_writer_factory_for_testing_);
535 #if !defined(OS_ANDROID)
536 } else if (base::FeatureList::IsEnabled(
537 features::kWebRtcRemoteEventLogGzipped)) {
538 return std::make_unique<GzippedLogFileWriterFactory>(
539 std::make_unique<GzipLogCompressorFactory>(
540 std::make_unique<DefaultGzippedSizeEstimator::Factory>()));
541 #endif
542 } else {
543 return std::make_unique<BaseLogFileWriterFactory>();
544 }
545 }
546
RenderProcessExited(RenderProcessHost * host,const content::ChildProcessTerminationInfo & info)547 void WebRtcEventLogManager::RenderProcessExited(
548 RenderProcessHost* host,
549 const content::ChildProcessTerminationInfo& info) {
550 DCHECK_CURRENTLY_ON(BrowserThread::UI);
551 RenderProcessHostExitedDestroyed(host);
552 }
553
RenderProcessHostDestroyed(RenderProcessHost * host)554 void WebRtcEventLogManager::RenderProcessHostDestroyed(
555 RenderProcessHost* host) {
556 DCHECK_CURRENTLY_ON(BrowserThread::UI);
557 RenderProcessHostExitedDestroyed(host);
558 }
559
RenderProcessHostExitedDestroyed(RenderProcessHost * host)560 void WebRtcEventLogManager::RenderProcessHostExitedDestroyed(
561 RenderProcessHost* host) {
562 DCHECK_CURRENTLY_ON(BrowserThread::UI);
563 DCHECK(host);
564
565 auto it = observed_render_process_hosts_.find(host);
566 if (it == observed_render_process_hosts_.end()) {
567 return; // We've never seen PeerConnections associated with this RPH.
568 }
569 host->RemoveObserver(this);
570 observed_render_process_hosts_.erase(host);
571
572 // |this| is destroyed by ~BrowserProcessImpl(), so base::Unretained(this)
573 // will not be dereferenced after destruction.
574 task_runner_->PostTask(
575 FROM_HERE,
576 base::BindOnce(&WebRtcEventLogManager::RenderProcessExitedInternal,
577 base::Unretained(this), host->GetID()));
578 }
579
OnLocalLogStarted(PeerConnectionKey peer_connection,const base::FilePath & file_path)580 void WebRtcEventLogManager::OnLocalLogStarted(PeerConnectionKey peer_connection,
581 const base::FilePath& file_path) {
582 DCHECK(task_runner_->RunsTasksInCurrentSequence());
583
584 constexpr int kLogOutputPeriodMsForLocalLogging = 0; // No batching.
585 OnLoggingTargetStarted(LoggingTarget::kLocalLogging, peer_connection,
586 kLogOutputPeriodMsForLocalLogging);
587
588 if (local_logs_observer_) {
589 local_logs_observer_->OnLocalLogStarted(peer_connection, file_path);
590 }
591 }
592
OnLocalLogStopped(PeerConnectionKey peer_connection)593 void WebRtcEventLogManager::OnLocalLogStopped(
594 PeerConnectionKey peer_connection) {
595 DCHECK(task_runner_->RunsTasksInCurrentSequence());
596
597 OnLoggingTargetStopped(LoggingTarget::kLocalLogging, peer_connection);
598
599 if (local_logs_observer_) {
600 local_logs_observer_->OnLocalLogStopped(peer_connection);
601 }
602 }
603
OnRemoteLogStarted(PeerConnectionKey key,const base::FilePath & file_path,int output_period_ms)604 void WebRtcEventLogManager::OnRemoteLogStarted(PeerConnectionKey key,
605 const base::FilePath& file_path,
606 int output_period_ms) {
607 DCHECK(task_runner_->RunsTasksInCurrentSequence());
608 OnLoggingTargetStarted(LoggingTarget::kRemoteLogging, key, output_period_ms);
609 if (remote_logs_observer_) {
610 remote_logs_observer_->OnRemoteLogStarted(key, file_path, output_period_ms);
611 }
612 }
613
OnRemoteLogStopped(WebRtcEventLogPeerConnectionKey key)614 void WebRtcEventLogManager::OnRemoteLogStopped(
615 WebRtcEventLogPeerConnectionKey key) {
616 DCHECK(task_runner_->RunsTasksInCurrentSequence());
617 OnLoggingTargetStopped(LoggingTarget::kRemoteLogging, key);
618 if (remote_logs_observer_) {
619 remote_logs_observer_->OnRemoteLogStopped(key);
620 }
621 }
622
OnLoggingTargetStarted(LoggingTarget target,PeerConnectionKey key,int output_period_ms)623 void WebRtcEventLogManager::OnLoggingTargetStarted(LoggingTarget target,
624 PeerConnectionKey key,
625 int output_period_ms) {
626 DCHECK(task_runner_->RunsTasksInCurrentSequence());
627 auto it = peer_connections_with_event_logging_enabled_in_webrtc_.find(key);
628 if (it != peer_connections_with_event_logging_enabled_in_webrtc_.end()) {
629 DCHECK_EQ((it->second & target), 0u);
630 it->second |= target;
631 } else {
632 // This is the first client for WebRTC event logging - let WebRTC know
633 // that it should start informing us of events.
634 peer_connections_with_event_logging_enabled_in_webrtc_.emplace(key, target);
635 pc_tracker_proxy_->EnableWebRtcEventLogging(key, output_period_ms);
636 }
637 }
638
OnLoggingTargetStopped(LoggingTarget target,PeerConnectionKey key)639 void WebRtcEventLogManager::OnLoggingTargetStopped(LoggingTarget target,
640 PeerConnectionKey key) {
641 DCHECK(task_runner_->RunsTasksInCurrentSequence());
642
643 // Record that we're no longer performing this type of logging for this PC.
644 auto it = peer_connections_with_event_logging_enabled_in_webrtc_.find(key);
645 CHECK(it != peer_connections_with_event_logging_enabled_in_webrtc_.end());
646 DCHECK_NE(it->second, 0u);
647 it->second &= ~target;
648
649 // If we're not doing any other type of logging for this peer connection,
650 // it's time to stop receiving notifications for it from WebRTC.
651 if (it->second == 0u) {
652 peer_connections_with_event_logging_enabled_in_webrtc_.erase(it);
653 pc_tracker_proxy_->DisableWebRtcEventLogging(key);
654 }
655 }
656
StartListeningForPrefChangeForBrowserContext(BrowserContext * browser_context)657 void WebRtcEventLogManager::StartListeningForPrefChangeForBrowserContext(
658 BrowserContext* browser_context) {
659 DCHECK_CURRENTLY_ON(BrowserThread::UI);
660 DCHECK(first_browser_context_initializations_done_);
661 CHECK(!browser_context->IsOffTheRecord());
662
663 const auto browser_context_id = GetBrowserContextId(browser_context);
664 auto it = pref_change_registrars_.emplace(std::piecewise_construct,
665 std::make_tuple(browser_context_id),
666 std::make_tuple());
667 DCHECK(it.second) << "Already listening.";
668 PrefChangeRegistrar& registrar = it.first->second;
669
670 Profile* profile = Profile::FromBrowserContext(browser_context);
671 DCHECK(profile);
672 registrar.Init(profile->GetPrefs());
673
674 // * |this| is destroyed by ~BrowserProcessImpl(), so base::Unretained(this)
675 // will not be dereferenced after destruction.
676 // * base::Unretained(browser_context) is safe, because |browser_context|
677 // stays alive until Chrome shut-down, at which point we'll stop listening
678 // as part of its (BrowserContext's) tear-down process.
679 registrar.Add(prefs::kWebRtcEventLogCollectionAllowed,
680 base::BindRepeating(&WebRtcEventLogManager::OnPrefChange,
681 base::Unretained(this),
682 base::Unretained(browser_context)));
683 }
684
StopListeningForPrefChangeForBrowserContext(BrowserContext * browser_context)685 void WebRtcEventLogManager::StopListeningForPrefChangeForBrowserContext(
686 BrowserContext* browser_context) {
687 DCHECK_CURRENTLY_ON(BrowserThread::UI);
688
689 const auto browser_context_id = GetBrowserContextId(browser_context);
690
691 size_t erased_count = pref_change_registrars_.erase(browser_context_id);
692 DCHECK_EQ(erased_count, 1u);
693 }
694
OnPrefChange(BrowserContext * browser_context)695 void WebRtcEventLogManager::OnPrefChange(BrowserContext* browser_context) {
696 DCHECK_CURRENTLY_ON(BrowserThread::UI);
697 DCHECK(first_browser_context_initializations_done_);
698
699 const Profile* profile = Profile::FromBrowserContext(browser_context);
700 DCHECK(profile);
701
702 const bool enabled = IsRemoteLoggingAllowedForBrowserContext(browser_context);
703
704 if (!enabled) {
705 // Dynamic refresh of the policy to DISABLED; stop ongoing logs, remove
706 // pending log files and stop any active uploads.
707 ClearCacheForBrowserContext(browser_context, base::Time::Min(),
708 base::Time::Max(), base::DoNothing());
709 }
710
711 // |this| is destroyed by ~BrowserProcessImpl(), so base::Unretained(this)
712 // will not be dereferenced after destruction.
713 base::OnceClosure task;
714 if (enabled) {
715 task = base::BindOnce(
716 &WebRtcEventLogManager::EnableRemoteBoundLoggingForBrowserContext,
717 base::Unretained(this), GetBrowserContextId(browser_context),
718 browser_context->GetPath(), base::OnceClosure());
719 } else {
720 task = base::BindOnce(
721 &WebRtcEventLogManager::DisableRemoteBoundLoggingForBrowserContext,
722 base::Unretained(this), GetBrowserContextId(browser_context),
723 base::OnceClosure());
724 }
725
726 task_runner_->PostTask(FROM_HERE, std::move(task));
727 }
728
OnFirstBrowserContextLoaded()729 void WebRtcEventLogManager::OnFirstBrowserContextLoaded() {
730 DCHECK_CURRENTLY_ON(BrowserThread::UI);
731
732 network::NetworkConnectionTracker* network_connection_tracker =
733 content::GetNetworkConnectionTracker();
734 DCHECK(network_connection_tracker);
735
736 auto log_file_writer_factory = CreateRemoteLogFileWriterFactory();
737 DCHECK(log_file_writer_factory);
738
739 // |network_connection_tracker| is owned by BrowserProcessImpl, which owns
740 // the IOThread. The internal task runner on which |this| uses
741 // |network_connection_tracker|, stops before IOThread dies, so we can trust
742 // that |network_connection_tracker| will not be used after destruction.
743 task_runner_->PostTask(
744 FROM_HERE,
745 base::BindOnce(
746 &WebRtcEventLogManager::OnFirstBrowserContextLoadedInternal,
747 base::Unretained(this), base::Unretained(network_connection_tracker),
748 std::move(log_file_writer_factory)));
749 }
750
OnFirstBrowserContextLoadedInternal(network::NetworkConnectionTracker * network_connection_tracker,std::unique_ptr<LogFileWriter::Factory> log_file_writer_factory)751 void WebRtcEventLogManager::OnFirstBrowserContextLoadedInternal(
752 network::NetworkConnectionTracker* network_connection_tracker,
753 std::unique_ptr<LogFileWriter::Factory> log_file_writer_factory) {
754 DCHECK(task_runner_->RunsTasksInCurrentSequence());
755 DCHECK(network_connection_tracker);
756 DCHECK(log_file_writer_factory);
757 remote_logs_manager_.SetNetworkConnectionTracker(network_connection_tracker);
758 remote_logs_manager_.SetLogFileWriterFactory(
759 std::move(log_file_writer_factory));
760 }
761
EnableRemoteBoundLoggingForBrowserContext(BrowserContextId browser_context_id,const base::FilePath & browser_context_dir,base::OnceClosure reply)762 void WebRtcEventLogManager::EnableRemoteBoundLoggingForBrowserContext(
763 BrowserContextId browser_context_id,
764 const base::FilePath& browser_context_dir,
765 base::OnceClosure reply) {
766 DCHECK(task_runner_->RunsTasksInCurrentSequence());
767 DCHECK_NE(browser_context_id, kNullBrowserContextId);
768
769 remote_logs_manager_.EnableForBrowserContext(browser_context_id,
770 browser_context_dir);
771
772 MaybeReply(FROM_HERE, std::move(reply));
773 }
774
DisableRemoteBoundLoggingForBrowserContext(BrowserContextId browser_context_id,base::OnceClosure reply)775 void WebRtcEventLogManager::DisableRemoteBoundLoggingForBrowserContext(
776 BrowserContextId browser_context_id,
777 base::OnceClosure reply) {
778 DCHECK(task_runner_->RunsTasksInCurrentSequence());
779
780 // Note that the BrowserContext might never have been enabled in the
781 // remote-bound manager; that's not a problem.
782 remote_logs_manager_.DisableForBrowserContext(browser_context_id);
783
784 MaybeReply(FROM_HERE, std::move(reply));
785 }
786
787 void WebRtcEventLogManager::
RemovePendingRemoteBoundLogsForNotEnabledBrowserContext(BrowserContextId browser_context_id,const base::FilePath & browser_context_dir,base::OnceClosure reply)788 RemovePendingRemoteBoundLogsForNotEnabledBrowserContext(
789 BrowserContextId browser_context_id,
790 const base::FilePath& browser_context_dir,
791 base::OnceClosure reply) {
792 DCHECK(task_runner_->RunsTasksInCurrentSequence());
793
794 remote_logs_manager_.RemovePendingLogsForNotEnabledBrowserContext(
795 browser_context_id, browser_context_dir);
796
797 MaybeReply(FROM_HERE, std::move(reply));
798 }
799
PeerConnectionAddedInternal(PeerConnectionKey key,base::OnceCallback<void (bool)> reply)800 void WebRtcEventLogManager::PeerConnectionAddedInternal(
801 PeerConnectionKey key,
802 base::OnceCallback<void(bool)> reply) {
803 DCHECK(task_runner_->RunsTasksInCurrentSequence());
804
805 const bool local_result = local_logs_manager_.PeerConnectionAdded(key);
806 const bool remote_result = remote_logs_manager_.PeerConnectionAdded(key);
807 DCHECK_EQ(local_result, remote_result);
808
809 MaybeReply(FROM_HERE, std::move(reply), local_result);
810 }
811
PeerConnectionRemovedInternal(PeerConnectionKey key,base::OnceCallback<void (bool)> reply)812 void WebRtcEventLogManager::PeerConnectionRemovedInternal(
813 PeerConnectionKey key,
814 base::OnceCallback<void(bool)> reply) {
815 DCHECK(task_runner_->RunsTasksInCurrentSequence());
816
817 const bool local_result = local_logs_manager_.PeerConnectionRemoved(key);
818 const bool remote_result = remote_logs_manager_.PeerConnectionRemoved(key);
819 DCHECK_EQ(local_result, remote_result);
820
821 MaybeReply(FROM_HERE, std::move(reply), local_result);
822 }
823
PeerConnectionSessionIdSetInternal(PeerConnectionKey key,const std::string & session_id,base::OnceCallback<void (bool)> reply)824 void WebRtcEventLogManager::PeerConnectionSessionIdSetInternal(
825 PeerConnectionKey key,
826 const std::string& session_id,
827 base::OnceCallback<void(bool)> reply) {
828 DCHECK(task_runner_->RunsTasksInCurrentSequence());
829 const bool result =
830 remote_logs_manager_.PeerConnectionSessionIdSet(key, session_id);
831 MaybeReply(FROM_HERE, std::move(reply), result);
832 }
833
EnableLocalLoggingInternal(const base::FilePath & base_path,size_t max_file_size_bytes,base::OnceCallback<void (bool)> reply)834 void WebRtcEventLogManager::EnableLocalLoggingInternal(
835 const base::FilePath& base_path,
836 size_t max_file_size_bytes,
837 base::OnceCallback<void(bool)> reply) {
838 DCHECK(task_runner_->RunsTasksInCurrentSequence());
839
840 const bool result =
841 local_logs_manager_.EnableLogging(base_path, max_file_size_bytes);
842
843 MaybeReply(FROM_HERE, std::move(reply), result);
844 }
845
DisableLocalLoggingInternal(base::OnceCallback<void (bool)> reply)846 void WebRtcEventLogManager::DisableLocalLoggingInternal(
847 base::OnceCallback<void(bool)> reply) {
848 DCHECK(task_runner_->RunsTasksInCurrentSequence());
849
850 const bool result = local_logs_manager_.DisableLogging();
851
852 MaybeReply(FROM_HERE, std::move(reply), result);
853 }
854
OnWebRtcEventLogWriteInternal(PeerConnectionKey key,const std::string & message,base::OnceCallback<void (std::pair<bool,bool>)> reply)855 void WebRtcEventLogManager::OnWebRtcEventLogWriteInternal(
856 PeerConnectionKey key,
857 const std::string& message,
858 base::OnceCallback<void(std::pair<bool, bool>)> reply) {
859 DCHECK(task_runner_->RunsTasksInCurrentSequence());
860
861 const bool local_result = local_logs_manager_.EventLogWrite(key, message);
862 const bool remote_result = remote_logs_manager_.EventLogWrite(key, message);
863
864 MaybeReply(FROM_HERE, std::move(reply),
865 std::make_pair(local_result, remote_result));
866 }
867
StartRemoteLoggingInternal(int render_process_id,BrowserContextId browser_context_id,const std::string & session_id,const base::FilePath & browser_context_dir,size_t max_file_size_bytes,int output_period_ms,size_t web_app_id,base::OnceCallback<void (bool,const std::string &,const std::string &)> reply)868 void WebRtcEventLogManager::StartRemoteLoggingInternal(
869 int render_process_id,
870 BrowserContextId browser_context_id,
871 const std::string& session_id,
872 const base::FilePath& browser_context_dir,
873 size_t max_file_size_bytes,
874 int output_period_ms,
875 size_t web_app_id,
876 base::OnceCallback<void(bool, const std::string&, const std::string&)>
877 reply) {
878 DCHECK(task_runner_->RunsTasksInCurrentSequence());
879
880 std::string log_id;
881 std::string error_message;
882 const bool result = remote_logs_manager_.StartRemoteLogging(
883 render_process_id, browser_context_id, session_id, browser_context_dir,
884 max_file_size_bytes, output_period_ms, web_app_id, &log_id,
885 &error_message);
886
887 // |log_id| set only if successful; |error_message| set only if unsuccessful.
888 DCHECK_EQ(result, !log_id.empty());
889 DCHECK_EQ(!result, !error_message.empty());
890
891 content::GetUIThreadTaskRunner({})->PostTask(
892 FROM_HERE,
893 base::BindOnce(std::move(reply), result, log_id, error_message));
894 }
895
ClearCacheForBrowserContextInternal(BrowserContextId browser_context_id,const base::Time & delete_begin,const base::Time & delete_end)896 void WebRtcEventLogManager::ClearCacheForBrowserContextInternal(
897 BrowserContextId browser_context_id,
898 const base::Time& delete_begin,
899 const base::Time& delete_end) {
900 DCHECK(task_runner_->RunsTasksInCurrentSequence());
901 remote_logs_manager_.ClearCacheForBrowserContext(browser_context_id,
902 delete_begin, delete_end);
903 }
904
OnClearCacheForBrowserContextDoneInternal(base::OnceClosure reply)905 void WebRtcEventLogManager::OnClearCacheForBrowserContextDoneInternal(
906 base::OnceClosure reply) {
907 DCHECK_CURRENTLY_ON(BrowserThread::UI);
908 DCHECK_GT(num_user_blocking_tasks_, 0u);
909 if (--num_user_blocking_tasks_ == 0) {
910 task_runner_->UpdatePriority(base::TaskPriority::BEST_EFFORT);
911 }
912 std::move(reply).Run();
913 }
914
GetHistoryInternal(BrowserContextId browser_context_id,base::OnceCallback<void (const std::vector<UploadList::UploadInfo> &)> reply)915 void WebRtcEventLogManager::GetHistoryInternal(
916 BrowserContextId browser_context_id,
917 base::OnceCallback<void(const std::vector<UploadList::UploadInfo>&)>
918 reply) {
919 DCHECK(task_runner_->RunsTasksInCurrentSequence());
920 DCHECK(reply);
921 remote_logs_manager_.GetHistory(browser_context_id, std::move(reply));
922 }
923
RenderProcessExitedInternal(int render_process_id)924 void WebRtcEventLogManager::RenderProcessExitedInternal(int render_process_id) {
925 DCHECK(task_runner_->RunsTasksInCurrentSequence());
926 local_logs_manager_.RenderProcessHostExitedDestroyed(render_process_id);
927 remote_logs_manager_.RenderProcessHostExitedDestroyed(render_process_id);
928 }
929
SetLocalLogsObserverInternal(WebRtcLocalEventLogsObserver * observer,base::OnceClosure reply)930 void WebRtcEventLogManager::SetLocalLogsObserverInternal(
931 WebRtcLocalEventLogsObserver* observer,
932 base::OnceClosure reply) {
933 DCHECK(task_runner_->RunsTasksInCurrentSequence());
934
935 local_logs_observer_ = observer;
936
937 if (reply) {
938 content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE, std::move(reply));
939 }
940 }
941
SetRemoteLogsObserverInternal(WebRtcRemoteEventLogsObserver * observer,base::OnceClosure reply)942 void WebRtcEventLogManager::SetRemoteLogsObserverInternal(
943 WebRtcRemoteEventLogsObserver* observer,
944 base::OnceClosure reply) {
945 DCHECK(task_runner_->RunsTasksInCurrentSequence());
946
947 remote_logs_observer_ = observer;
948
949 if (reply) {
950 content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE, std::move(reply));
951 }
952 }
953
SetClockForTesting(base::Clock * clock,base::OnceClosure reply)954 void WebRtcEventLogManager::SetClockForTesting(base::Clock* clock,
955 base::OnceClosure reply) {
956 DCHECK_CURRENTLY_ON(BrowserThread::UI);
957 DCHECK(reply);
958
959 auto task = [](WebRtcEventLogManager* manager, base::Clock* clock,
960 base::OnceClosure reply) {
961 manager->local_logs_manager_.SetClockForTesting(clock);
962
963 content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE, std::move(reply));
964 };
965
966 // |this| is destroyed by ~BrowserProcessImpl(), so base::Unretained(this)
967 // will not be dereferenced after destruction.
968 task_runner_->PostTask(FROM_HERE, base::BindOnce(task, base::Unretained(this),
969 clock, std::move(reply)));
970 }
971
SetPeerConnectionTrackerProxyForTesting(std::unique_ptr<PeerConnectionTrackerProxy> pc_tracker_proxy,base::OnceClosure reply)972 void WebRtcEventLogManager::SetPeerConnectionTrackerProxyForTesting(
973 std::unique_ptr<PeerConnectionTrackerProxy> pc_tracker_proxy,
974 base::OnceClosure reply) {
975 DCHECK_CURRENTLY_ON(BrowserThread::UI);
976 DCHECK(reply);
977
978 auto task = [](WebRtcEventLogManager* manager,
979 std::unique_ptr<PeerConnectionTrackerProxy> pc_tracker_proxy,
980 base::OnceClosure reply) {
981 manager->pc_tracker_proxy_ = std::move(pc_tracker_proxy);
982
983 content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE, std::move(reply));
984 };
985
986 // |this| is destroyed by ~BrowserProcessImpl(), so base::Unretained(this)
987 // will not be dereferenced after destruction.
988 task_runner_->PostTask(
989 FROM_HERE, base::BindOnce(task, base::Unretained(this),
990 std::move(pc_tracker_proxy), std::move(reply)));
991 }
992
SetWebRtcEventLogUploaderFactoryForTesting(std::unique_ptr<WebRtcEventLogUploader::Factory> uploader_factory,base::OnceClosure reply)993 void WebRtcEventLogManager::SetWebRtcEventLogUploaderFactoryForTesting(
994 std::unique_ptr<WebRtcEventLogUploader::Factory> uploader_factory,
995 base::OnceClosure reply) {
996 DCHECK_CURRENTLY_ON(BrowserThread::UI);
997 DCHECK(reply);
998
999 auto task =
1000 [](WebRtcEventLogManager* manager,
1001 std::unique_ptr<WebRtcEventLogUploader::Factory> uploader_factory,
1002 base::OnceClosure reply) {
1003 auto& remote_logs_manager = manager->remote_logs_manager_;
1004 remote_logs_manager.SetWebRtcEventLogUploaderFactoryForTesting(
1005 std::move(uploader_factory));
1006
1007 content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
1008 std::move(reply));
1009 };
1010
1011 // |this| is destroyed by ~BrowserProcessImpl(), so base::Unretained(this)
1012 // will not be dereferenced after destruction.
1013 task_runner_->PostTask(
1014 FROM_HERE, base::BindOnce(task, base::Unretained(this),
1015 std::move(uploader_factory), std::move(reply)));
1016 }
1017
SetRemoteLogFileWriterFactoryForTesting(std::unique_ptr<LogFileWriter::Factory> factory)1018 void WebRtcEventLogManager::SetRemoteLogFileWriterFactoryForTesting(
1019 std::unique_ptr<LogFileWriter::Factory> factory) {
1020 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1021 DCHECK(!first_browser_context_initializations_done_) << "Too late.";
1022 DCHECK(!remote_log_file_writer_factory_for_testing_) << "Already called.";
1023 remote_log_file_writer_factory_for_testing_ = std::move(factory);
1024 }
1025
UploadConditionsHoldForTesting(base::OnceCallback<void (bool)> callback)1026 void WebRtcEventLogManager::UploadConditionsHoldForTesting(
1027 base::OnceCallback<void(bool)> callback) {
1028 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1029 // Unit tests block until |callback| is sent back, so the use
1030 // of base::Unretained(&remote_logs_manager_) is safe.
1031 task_runner_->PostTask(
1032 FROM_HERE,
1033 base::BindOnce(
1034 &WebRtcRemoteEventLogManager::UploadConditionsHoldForTesting,
1035 base::Unretained(&remote_logs_manager_), std::move(callback)));
1036 }
1037
1038 scoped_refptr<base::SequencedTaskRunner>
GetTaskRunnerForTesting()1039 WebRtcEventLogManager::GetTaskRunnerForTesting() {
1040 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1041 return task_runner_;
1042 }
1043
PostNullTaskForTesting(base::OnceClosure reply)1044 void WebRtcEventLogManager::PostNullTaskForTesting(base::OnceClosure reply) {
1045 task_runner_->PostTask(FROM_HERE, std::move(reply));
1046 }
1047
ShutDownForTesting(base::OnceClosure reply)1048 void WebRtcEventLogManager::ShutDownForTesting(base::OnceClosure reply) {
1049 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1050 // Unit tests block until |callback| is sent back, so the use
1051 // of base::Unretained(&remote_logs_manager_) is safe.
1052 task_runner_->PostTask(
1053 FROM_HERE,
1054 base::BindOnce(&WebRtcRemoteEventLogManager::ShutDownForTesting,
1055 base::Unretained(&remote_logs_manager_),
1056 std::move(reply)));
1057 }
1058
1059 } // namespace webrtc_event_logging
1060