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