1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/bind.h"
6 #include "base/bind_helpers.h"
7 #include "base/command_line.h"
8 #include "base/run_loop.h"
9 #include "base/synchronization/waitable_event.h"
10 #include "base/task/post_task.h"
11 #include "base/test/metrics/histogram_tester.h"
12 #include "base/test/scoped_feature_list.h"
13 #include "base/test/simple_test_tick_clock.h"
14 #include "base/test/test_timeouts.h"
15 #include "build/build_config.h"
16 #include "content/browser/frame_host/render_frame_host_impl.h"
17 #include "content/browser/renderer_host/render_process_host_impl.h"
18 #include "content/public/browser/browser_task_traits.h"
19 #include "content/public/browser/browser_thread.h"
20 #include "content/public/browser/child_process_launcher_utils.h"
21 #include "content/public/browser/render_frame_host.h"
22 #include "content/public/browser/render_process_host.h"
23 #include "content/public/browser/render_process_host_observer.h"
24 #include "content/public/browser/web_contents.h"
25 #include "content/public/browser/web_contents_observer.h"
26 #include "content/public/common/content_client.h"
27 #include "content/public/common/content_features.h"
28 #include "content/public/common/content_switches.h"
29 #include "content/public/common/url_constants.h"
30 #include "content/public/test/browser_test_utils.h"
31 #include "content/public/test/content_browser_test.h"
32 #include "content/public/test/content_browser_test_utils.h"
33 #include "content/public/test/no_renderer_crashes_assertion.h"
34 #include "content/public/test/test_service.mojom.h"
35 #include "content/public/test/test_utils.h"
36 #include "content/shell/browser/shell.h"
37 #include "content/shell/browser/shell_browser_context.h"
38 #include "content/shell/browser/shell_browser_main_parts.h"
39 #include "content/shell/browser/shell_content_browser_client.h"
40 #include "content/test/test_content_browser_client.h"
41 #include "media/base/bind_to_current_loop.h"
42 #include "media/base/media_switches.h"
43 #include "media/base/test_data_util.h"
44 #include "media/mojo/buildflags.h"
45 #include "mojo/public/cpp/bindings/remote.h"
46 #include "net/dns/mock_host_resolver.h"
47 #include "net/test/embedded_test_server/embedded_test_server.h"
48 #include "net/test/embedded_test_server/http_request.h"
49 #include "net/test/embedded_test_server/http_response.h"
50 
51 #if defined(OS_WIN)
52 #include "base/win/windows_version.h"
53 #endif
54 
55 namespace content {
56 
57 namespace {
58 
59 // Similar to net::test_server::DelayedHttpResponse, but the delay is resolved
60 // through Resolver.
61 class DelayedHttpResponseWithResolver final
62     : public net::test_server::BasicHttpResponse {
63  public:
64   struct ResponseWithCallbacks final {
65     net::test_server::SendBytesCallback send_callback;
66     net::test_server::SendCompleteCallback done_callback;
67     std::string response_string;
68   };
69 
70   class Resolver final : public base::RefCountedThreadSafe<Resolver> {
71    public:
Resolve()72     void Resolve() {
73       base::AutoLock auto_lock(lock_);
74       DCHECK(!resolved_);
75       resolved_ = true;
76 
77       if (!task_runner_) {
78         return;
79       }
80 
81       task_runner_->PostTask(
82           FROM_HERE,
83           base::BindOnce(&Resolver::ResolveInServerTaskRunner, this));
84     }
85 
Add(ResponseWithCallbacks response)86     void Add(ResponseWithCallbacks response) {
87       base::AutoLock auto_lock(lock_);
88 
89       if (resolved_) {
90         response.send_callback.Run(response.response_string,
91                                    std::move(response.done_callback));
92         return;
93       }
94 
95       scoped_refptr<base::SingleThreadTaskRunner> task_runner =
96           base::ThreadTaskRunnerHandle::Get();
97       if (task_runner_) {
98         DCHECK_EQ(task_runner_, task_runner);
99       } else {
100         task_runner_ = std::move(task_runner);
101       }
102 
103       responses_with_callbacks_.push_back(std::move(response));
104     }
105 
106    private:
ResolveInServerTaskRunner()107     void ResolveInServerTaskRunner() {
108       auto responses_with_callbacks = std::move(responses_with_callbacks_);
109       for (auto& response_with_callbacks : responses_with_callbacks) {
110         response_with_callbacks.send_callback.Run(
111             response_with_callbacks.response_string,
112             std::move(response_with_callbacks.done_callback));
113       }
114     }
115 
116     friend class base::RefCountedThreadSafe<Resolver>;
117     ~Resolver() = default;
118 
119     base::Lock lock_;
120 
121     std::vector<ResponseWithCallbacks> responses_with_callbacks_;
122     bool resolved_ GUARDED_BY(lock_) = false;
123     scoped_refptr<base::SingleThreadTaskRunner> task_runner_ GUARDED_BY(lock_);
124   };
125 
DelayedHttpResponseWithResolver(scoped_refptr<Resolver> resolver)126   explicit DelayedHttpResponseWithResolver(scoped_refptr<Resolver> resolver)
127       : resolver_(std::move(resolver)) {}
128 
129   DelayedHttpResponseWithResolver(const DelayedHttpResponseWithResolver&) =
130       delete;
131   DelayedHttpResponseWithResolver& operator=(
132       const DelayedHttpResponseWithResolver&) = delete;
133 
SendResponse(const net::test_server::SendBytesCallback & send,net::test_server::SendCompleteCallback done)134   void SendResponse(const net::test_server::SendBytesCallback& send,
135                     net::test_server::SendCompleteCallback done) override {
136     resolver_->Add({send, std::move(done), ToResponseString()});
137   }
138 
139  private:
140   const scoped_refptr<Resolver> resolver_;
141 };
142 
HandleBeacon(const net::test_server::HttpRequest & request)143 std::unique_ptr<net::test_server::HttpResponse> HandleBeacon(
144     const net::test_server::HttpRequest& request) {
145   if (request.relative_url != "/beacon")
146     return nullptr;
147   return std::make_unique<net::test_server::BasicHttpResponse>();
148 }
149 
HandleHungBeacon(const base::RepeatingClosure & on_called,const net::test_server::HttpRequest & request)150 std::unique_ptr<net::test_server::HttpResponse> HandleHungBeacon(
151     const base::RepeatingClosure& on_called,
152     const net::test_server::HttpRequest& request) {
153   if (request.relative_url != "/beacon")
154     return nullptr;
155   if (on_called) {
156     on_called.Run();
157   }
158   return std::make_unique<net::test_server::HungResponse>();
159 }
160 
HandleHungBeaconWithResolver(scoped_refptr<DelayedHttpResponseWithResolver::Resolver> resolver,const net::test_server::HttpRequest & request)161 std::unique_ptr<net::test_server::HttpResponse> HandleHungBeaconWithResolver(
162     scoped_refptr<DelayedHttpResponseWithResolver::Resolver> resolver,
163     const net::test_server::HttpRequest& request) {
164   if (request.relative_url != "/beacon")
165     return nullptr;
166   return std::make_unique<DelayedHttpResponseWithResolver>(std::move(resolver));
167 }
168 
169 }  // namespace
170 
171 class RenderProcessHostTest : public ContentBrowserTest,
172                               public RenderProcessHostObserver {
173  public:
RenderProcessHostTest()174   RenderProcessHostTest()
175       : process_exits_(0), host_destructions_(0), use_frame_priority_(false) {}
176 
SetUp()177   void SetUp() override {
178     if (use_frame_priority_) {
179       feature_list_.InitAndEnableFeature(
180           features::kUseFramePriorityInRenderProcessHost);
181     } else {
182       feature_list_.InitAndDisableFeature(
183           features::kUseFramePriorityInRenderProcessHost);
184     }
185     ContentBrowserTest::SetUp();
186   }
187 
SetUpCommandLine(base::CommandLine * command_line)188   void SetUpCommandLine(base::CommandLine* command_line) override {
189 #if defined(OS_LINUX)
190     // Due to problems with PulseAudio failing to start, use a fake audio
191     // stream. https://crbug.com/1047655#c70
192     command_line->AppendSwitch(switches::kDisableAudioOutput);
193 #endif
194     command_line->AppendSwitchASCII(
195         switches::kAutoplayPolicy,
196         switches::autoplay::kNoUserGestureRequiredPolicy);
197   }
198 
SetUpOnMainThread()199   void SetUpOnMainThread() override {
200     // Support multiple sites on the test server.
201     host_resolver()->AddRule("*", "127.0.0.1");
202   }
203 
SetVisibleClients(RenderProcessHost * process,int32_t visible_clients)204   void SetVisibleClients(RenderProcessHost* process, int32_t visible_clients) {
205     RenderProcessHostImpl* impl = static_cast<RenderProcessHostImpl*>(process);
206     impl->visible_clients_ = visible_clients;
207   }
208  protected:
set_process_exit_callback(base::OnceClosure callback)209   void set_process_exit_callback(base::OnceClosure callback) {
210     process_exit_callback_ = std::move(callback);
211   }
212 
213   // RenderProcessHostObserver:
RenderProcessExited(RenderProcessHost * host,const ChildProcessTerminationInfo & info)214   void RenderProcessExited(RenderProcessHost* host,
215                            const ChildProcessTerminationInfo& info) override {
216     ++process_exits_;
217     if (process_exit_callback_)
218       std::move(process_exit_callback_).Run();
219   }
RenderProcessHostDestroyed(RenderProcessHost * host)220   void RenderProcessHostDestroyed(RenderProcessHost* host) override {
221     ++host_destructions_;
222   }
WaitUntilProcessExits(int target)223   void WaitUntilProcessExits(int target) {
224     while (process_exits_ < target)
225       base::RunLoop().RunUntilIdle();
226   }
227 
228   int process_exits_;
229   int host_destructions_;
230   base::OnceClosure process_exit_callback_;
231   bool use_frame_priority_;
232   base::test::ScopedFeatureList feature_list_;
233 };
234 
235 // A mock ContentBrowserClient that only considers a spare renderer to be a
236 // suitable host.
237 class SpareRendererContentBrowserClient : public TestContentBrowserClient {
238  public:
IsSuitableHost(RenderProcessHost * process_host,const GURL & site_url)239   bool IsSuitableHost(RenderProcessHost* process_host,
240                       const GURL& site_url) override {
241     if (RenderProcessHostImpl::GetSpareRenderProcessHostForTesting()) {
242       return process_host ==
243              RenderProcessHostImpl::GetSpareRenderProcessHostForTesting();
244     }
245     return true;
246   }
247 };
248 
249 // A mock ContentBrowserClient that only considers a non-spare renderer to be a
250 // suitable host, but otherwise tries to reuse processes.
251 class NonSpareRendererContentBrowserClient : public TestContentBrowserClient {
252  public:
253   NonSpareRendererContentBrowserClient() = default;
254 
IsSuitableHost(RenderProcessHost * process_host,const GURL & site_url)255   bool IsSuitableHost(RenderProcessHost* process_host,
256                       const GURL& site_url) override {
257     return RenderProcessHostImpl::GetSpareRenderProcessHostForTesting() !=
258            process_host;
259   }
260 
ShouldTryToUseExistingProcessHost(BrowserContext * context,const GURL & url)261   bool ShouldTryToUseExistingProcessHost(BrowserContext* context,
262                                          const GURL& url) override {
263     return true;
264   }
265 
ShouldUseSpareRenderProcessHost(BrowserContext * browser_context,const GURL & site_url)266   bool ShouldUseSpareRenderProcessHost(BrowserContext* browser_context,
267                                        const GURL& site_url) override {
268     return false;
269   }
270 
271  private:
272   DISALLOW_COPY_AND_ASSIGN(NonSpareRendererContentBrowserClient);
273 };
274 
IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,GuestsAreNotSuitableHosts)275 IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,
276                        GuestsAreNotSuitableHosts) {
277   // Set max renderers to 1 to force running out of processes.
278   RenderProcessHost::SetMaxRendererProcessCount(1);
279 
280   ASSERT_TRUE(embedded_test_server()->Start());
281 
282   GURL test_url = embedded_test_server()->GetURL("/simple_page.html");
283   EXPECT_TRUE(NavigateToURL(shell(), test_url));
284   RenderProcessHost* rph =
285       shell()->web_contents()->GetMainFrame()->GetProcess();
286   // Make it believe it's a guest.
287   reinterpret_cast<RenderProcessHostImpl*>(rph)->
288       set_is_for_guests_only_for_testing(true);
289   EXPECT_EQ(1, RenderProcessHost::GetCurrentRenderProcessCountForTesting());
290 
291   // Navigate to a different page.
292   GURL::Replacements replace_host;
293   replace_host.SetHostStr("localhost");
294   GURL another_url = embedded_test_server()->GetURL("/simple_page.html");
295   another_url = another_url.ReplaceComponents(replace_host);
296   EXPECT_TRUE(NavigateToURL(CreateBrowser(), another_url));
297 
298   // Expect that we got another process (the guest renderer was not reused).
299   EXPECT_EQ(2, RenderProcessHost::GetCurrentRenderProcessCountForTesting());
300 }
301 
IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,SpareRenderProcessHostTaken)302 IN_PROC_BROWSER_TEST_F(RenderProcessHostTest, SpareRenderProcessHostTaken) {
303   ASSERT_TRUE(embedded_test_server()->Start());
304 
305   RenderProcessHost::WarmupSpareRenderProcessHost(
306       ShellContentBrowserClient::Get()->browser_context());
307   RenderProcessHost* spare_renderer =
308       RenderProcessHostImpl::GetSpareRenderProcessHostForTesting();
309   EXPECT_NE(nullptr, spare_renderer);
310 
311   GURL test_url = embedded_test_server()->GetURL("/simple_page.html");
312   Shell* window = CreateBrowser();
313   EXPECT_TRUE(NavigateToURL(window, test_url));
314 
315   EXPECT_EQ(spare_renderer,
316             window->web_contents()->GetMainFrame()->GetProcess());
317 
318   // The old spare render process host should no longer be available.
319   EXPECT_NE(spare_renderer,
320             RenderProcessHostImpl::GetSpareRenderProcessHostForTesting());
321 
322   // Check if a fresh spare is available (depending on the operating mode).
323   if (RenderProcessHostImpl::IsSpareProcessKeptAtAllTimes()) {
324     EXPECT_NE(nullptr,
325               RenderProcessHostImpl::GetSpareRenderProcessHostForTesting());
326   } else {
327     EXPECT_EQ(nullptr,
328               RenderProcessHostImpl::GetSpareRenderProcessHostForTesting());
329   }
330 }
331 
IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,SpareRenderProcessHostNotTaken)332 IN_PROC_BROWSER_TEST_F(RenderProcessHostTest, SpareRenderProcessHostNotTaken) {
333   ASSERT_TRUE(embedded_test_server()->Start());
334 
335   RenderProcessHost::WarmupSpareRenderProcessHost(
336       ShellContentBrowserClient::Get()->off_the_record_browser_context());
337   RenderProcessHost* spare_renderer =
338       RenderProcessHostImpl::GetSpareRenderProcessHostForTesting();
339   GURL test_url = embedded_test_server()->GetURL("/simple_page.html");
340   Shell* window = CreateBrowser();
341   EXPECT_TRUE(NavigateToURL(window, test_url));
342 
343   // There should have been another process created for the navigation.
344   EXPECT_NE(spare_renderer,
345             window->web_contents()->GetMainFrame()->GetProcess());
346 
347   // Check if a fresh spare is available (depending on the operating mode).
348   // Note this behavior is identical to what would have happened if the
349   // RenderProcessHost were taken.
350   if (RenderProcessHostImpl::IsSpareProcessKeptAtAllTimes()) {
351     EXPECT_NE(nullptr,
352               RenderProcessHostImpl::GetSpareRenderProcessHostForTesting());
353   } else {
354     EXPECT_EQ(nullptr,
355               RenderProcessHostImpl::GetSpareRenderProcessHostForTesting());
356   }
357 }
358 
IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,SpareRenderProcessHostKilled)359 IN_PROC_BROWSER_TEST_F(RenderProcessHostTest, SpareRenderProcessHostKilled) {
360   RenderProcessHost::WarmupSpareRenderProcessHost(
361       ShellContentBrowserClient::Get()->browser_context());
362 
363   RenderProcessHost* spare_renderer =
364       RenderProcessHostImpl::GetSpareRenderProcessHostForTesting();
365   mojo::Remote<mojom::TestService> service;
366   ASSERT_NE(nullptr, spare_renderer);
367   spare_renderer->BindReceiver(service.BindNewPipeAndPassReceiver());
368 
369   base::RunLoop run_loop;
370   set_process_exit_callback(run_loop.QuitClosure());
371   spare_renderer->AddObserver(this);  // For process_exit_callback.
372 
373   // Should reply with a bad message and cause process death.
374   {
375     ScopedAllowRendererCrashes scoped_allow_renderer_crashes(spare_renderer);
376     service->DoSomething(base::DoNothing());
377     run_loop.Run();
378   }
379 
380   // The spare RenderProcessHost should disappear when its process dies.
381   EXPECT_EQ(nullptr,
382             RenderProcessHostImpl::GetSpareRenderProcessHostForTesting());
383 }
384 
385 // Test that the spare renderer works correctly when the limit on the maximum
386 // number of processes is small.
IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,SpareRendererSurpressedMaxProcesses)387 IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,
388                        SpareRendererSurpressedMaxProcesses) {
389   ASSERT_TRUE(embedded_test_server()->Start());
390 
391   SpareRendererContentBrowserClient browser_client;
392   ContentBrowserClient* old_client =
393       SetBrowserClientForTesting(&browser_client);
394 
395   RenderProcessHost::SetMaxRendererProcessCount(1);
396 
397   // A process is created with shell startup, so with a maximum of one renderer
398   // process the spare RPH should not be created.
399   RenderProcessHost::WarmupSpareRenderProcessHost(
400       ShellContentBrowserClient::Get()->browser_context());
401   EXPECT_EQ(nullptr,
402             RenderProcessHostImpl::GetSpareRenderProcessHostForTesting());
403 
404   // A spare RPH should be created with a max of 2 renderer processes.
405   RenderProcessHost::SetMaxRendererProcessCount(2);
406   RenderProcessHost::WarmupSpareRenderProcessHost(
407       ShellContentBrowserClient::Get()->browser_context());
408   RenderProcessHost* spare_renderer =
409       RenderProcessHostImpl::GetSpareRenderProcessHostForTesting();
410   EXPECT_NE(nullptr, spare_renderer);
411 
412   // Thanks to the injected SpareRendererContentBrowserClient and the limit on
413   // processes, the spare RPH will always be used via GetExistingProcessHost()
414   // rather than picked up via MaybeTakeSpareRenderProcessHost().
415   GURL test_url = embedded_test_server()->GetURL("/simple_page.html");
416   Shell* new_window = CreateBrowser();
417   EXPECT_TRUE(NavigateToURL(new_window, test_url));
418   // Outside of RenderProcessHostImpl::IsSpareProcessKeptAtAllTimes mode, the
419   // spare RPH should have been dropped during CreateBrowser() and given to the
420   // new window.  OTOH, even in the IsSpareProcessKeptAtAllTimes mode, the spare
421   // shouldn't be created because of the low process limit.
422   EXPECT_EQ(nullptr,
423             RenderProcessHostImpl::GetSpareRenderProcessHostForTesting());
424   EXPECT_EQ(spare_renderer,
425             new_window->web_contents()->GetMainFrame()->GetProcess());
426 
427   // Revert to the default process limit and original ContentBrowserClient.
428   RenderProcessHost::SetMaxRendererProcessCount(0);
429   SetBrowserClientForTesting(old_client);
430 }
431 
432 // Check that the spare renderer is dropped if an existing process is reused.
IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,SpareRendererOnProcessReuse)433 IN_PROC_BROWSER_TEST_F(RenderProcessHostTest, SpareRendererOnProcessReuse) {
434   ASSERT_TRUE(embedded_test_server()->Start());
435 
436   NonSpareRendererContentBrowserClient browser_client;
437   ContentBrowserClient* old_client =
438       SetBrowserClientForTesting(&browser_client);
439 
440   RenderProcessHost::WarmupSpareRenderProcessHost(
441       ShellContentBrowserClient::Get()->browser_context());
442   RenderProcessHost* spare_renderer =
443       RenderProcessHostImpl::GetSpareRenderProcessHostForTesting();
444   EXPECT_NE(nullptr, spare_renderer);
445 
446   // This should reuse the existing process.
447   Shell* new_browser = CreateBrowser();
448   EXPECT_EQ(shell()->web_contents()->GetMainFrame()->GetProcess(),
449             new_browser->web_contents()->GetMainFrame()->GetProcess());
450   EXPECT_NE(spare_renderer,
451             new_browser->web_contents()->GetMainFrame()->GetProcess());
452   if (RenderProcessHostImpl::IsSpareProcessKeptAtAllTimes()) {
453     EXPECT_NE(nullptr,
454               RenderProcessHostImpl::GetSpareRenderProcessHostForTesting());
455   } else {
456     EXPECT_EQ(nullptr,
457               RenderProcessHostImpl::GetSpareRenderProcessHostForTesting());
458   }
459 
460   // The launcher thread reads state from browser_client, need to wait for it to
461   // be done before resetting the browser client. crbug.com/742533.
462   base::WaitableEvent launcher_thread_done(
463       base::WaitableEvent::ResetPolicy::MANUAL,
464       base::WaitableEvent::InitialState::NOT_SIGNALED);
465   GetProcessLauncherTaskRunner()->PostTask(
466       FROM_HERE,
467       base::BindOnce([](base::WaitableEvent* done) { done->Signal(); },
468                      base::Unretained(&launcher_thread_done)));
469   ASSERT_TRUE(launcher_thread_done.TimedWait(TestTimeouts::action_timeout()));
470 
471   SetBrowserClientForTesting(old_client);
472 }
473 
474 // Verifies that the spare renderer maintained by SpareRenderProcessHostManager
475 // is correctly destroyed during browser shutdown.  This test is an analogue
476 // to the //chrome-layer FastShutdown.SpareRenderProcessHost test.
IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,SpareRenderProcessHostDuringShutdown)477 IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,
478                        SpareRenderProcessHostDuringShutdown) {
479   content::RenderProcessHost::WarmupSpareRenderProcessHost(
480       shell()->web_contents()->GetBrowserContext());
481 
482   // The verification is that there are no DCHECKs anywhere during test tear
483   // down.
484 }
485 
486 // Verifies that the spare renderer maintained by SpareRenderProcessHostManager
487 // is correctly destroyed when closing the last content shell.
IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,SpareRendererDuringClosing)488 IN_PROC_BROWSER_TEST_F(RenderProcessHostTest, SpareRendererDuringClosing) {
489   content::RenderProcessHost::WarmupSpareRenderProcessHost(
490       shell()->web_contents()->GetBrowserContext());
491   shell()->web_contents()->Close();
492 
493   // The verification is that there are no DCHECKs or UaF anywhere during test
494   // tear down.
495 }
496 
497 // Class that simulates the fact that some //content embedders (e.g. by
498 // overriding ChromeContentBrowserClient::GetStoragePartitionConfigForSite) can
499 // cause BrowserContext::GetDefaultStoragePartition(browser_context) to differ
500 // from BrowserContext::GetStoragePartition(browser_context, site_instance) even
501 // if |site_instance| is not for guests.
502 class CustomStoragePartitionForSomeSites : public TestContentBrowserClient {
503  public:
CustomStoragePartitionForSomeSites(const GURL & site_to_isolate)504   explicit CustomStoragePartitionForSomeSites(const GURL& site_to_isolate)
505       : site_to_isolate_(site_to_isolate) {}
506 
GetStoragePartitionConfigForSite(BrowserContext * browser_context,const GURL & site,bool can_be_default,std::string * partition_domain,std::string * partition_name,bool * in_memory)507   void GetStoragePartitionConfigForSite(BrowserContext* browser_context,
508                                         const GURL& site,
509                                         bool can_be_default,
510                                         std::string* partition_domain,
511                                         std::string* partition_name,
512                                         bool* in_memory) override {
513     // Default to the browser-wide storage partition and override based on
514     // |site| below.
515     partition_domain->clear();
516     partition_name->clear();
517     *in_memory = false;
518 
519     // Override for |site_to_isolate_|.
520     if (site == site_to_isolate_) {
521       *partition_domain = "blah_isolated_storage";
522       *partition_name = "blah_isolated_storage";
523       *in_memory = false;
524     }
525   }
526 
GetStoragePartitionIdForSite(BrowserContext * browser_context,const GURL & site)527   std::string GetStoragePartitionIdForSite(BrowserContext* browser_context,
528                                            const GURL& site) override {
529     if (site == site_to_isolate_)
530       return "custom";
531     return "";
532   }
533 
IsValidStoragePartitionId(BrowserContext * browser_context,const std::string & partition_id)534   bool IsValidStoragePartitionId(BrowserContext* browser_context,
535                                  const std::string& partition_id) override {
536     return partition_id == "" || partition_id == "custom";
537   }
538 
539  private:
540   GURL site_to_isolate_;
541 
542   DISALLOW_COPY_AND_ASSIGN(CustomStoragePartitionForSomeSites);
543 };
544 
545 // This test verifies that SpareRenderProcessHostManager correctly accounts
546 // for StoragePartition differences when handing out the spare process.
IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,SpareProcessVsCustomStoragePartition)547 IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,
548                        SpareProcessVsCustomStoragePartition) {
549   ASSERT_TRUE(embedded_test_server()->Start());
550 
551   // Provide custom storage partition for test sites.
552   GURL test_url = embedded_test_server()->GetURL("/simple_page.html");
553   BrowserContext* browser_context =
554       ShellContentBrowserClient::Get()->browser_context();
555   scoped_refptr<SiteInstance> test_site_instance =
556       SiteInstance::Create(browser_context)->GetRelatedSiteInstance(test_url);
557   GURL test_site = test_site_instance->GetSiteURL();
558   CustomStoragePartitionForSomeSites modified_client(test_site);
559   ContentBrowserClient* old_client =
560       SetBrowserClientForTesting(&modified_client);
561   StoragePartition* default_storage =
562       BrowserContext::GetDefaultStoragePartition(browser_context);
563   StoragePartition* custom_storage =
564       BrowserContext::GetStoragePartitionForSite(browser_context, test_site);
565   EXPECT_NE(default_storage, custom_storage);
566 
567   // Open a test window - it should be associated with the default storage
568   // partition.
569   Shell* window = CreateBrowser();
570   RenderProcessHost* old_process =
571       window->web_contents()->GetMainFrame()->GetProcess();
572   EXPECT_EQ(default_storage, old_process->GetStoragePartition());
573 
574   // Warm up the spare process - it should be associated with the default
575   // storage partition.
576   RenderProcessHost::WarmupSpareRenderProcessHost(browser_context);
577   RenderProcessHost* spare_renderer =
578       RenderProcessHostImpl::GetSpareRenderProcessHostForTesting();
579   ASSERT_TRUE(spare_renderer);
580   EXPECT_EQ(default_storage, spare_renderer->GetStoragePartition());
581 
582   // Navigate to a URL that requires a custom storage partition.
583   EXPECT_TRUE(NavigateToURL(window, test_url));
584   RenderProcessHost* new_process =
585       window->web_contents()->GetMainFrame()->GetProcess();
586   // Requirement to use a custom storage partition should force a process swap.
587   EXPECT_NE(new_process, old_process);
588   // The new process should be associated with the custom storage partition.
589   EXPECT_EQ(custom_storage, new_process->GetStoragePartition());
590   // And consequently, the spare shouldn't have been used.
591   EXPECT_NE(spare_renderer, new_process);
592 
593   // Restore the original ContentBrowserClient.
594   SetBrowserClientForTesting(old_client);
595 }
596 
597 class RenderProcessHostObserverCounter : public RenderProcessHostObserver {
598  public:
RenderProcessHostObserverCounter(RenderProcessHost * host)599   explicit RenderProcessHostObserverCounter(RenderProcessHost* host) {
600     host->AddObserver(this);
601     observing_ = true;
602     observed_host_ = host;
603   }
604 
~RenderProcessHostObserverCounter()605   ~RenderProcessHostObserverCounter() override {
606     if (observing_)
607       observed_host_->RemoveObserver(this);
608   }
609 
RenderProcessExited(RenderProcessHost * host,const ChildProcessTerminationInfo & info)610   void RenderProcessExited(RenderProcessHost* host,
611                            const ChildProcessTerminationInfo& info) override {
612     DCHECK(observing_);
613     DCHECK_EQ(host, observed_host_);
614     exited_count_++;
615   }
616 
RenderProcessHostDestroyed(RenderProcessHost * host)617   void RenderProcessHostDestroyed(RenderProcessHost* host) override {
618     DCHECK(observing_);
619     DCHECK_EQ(host, observed_host_);
620     destroyed_count_++;
621 
622     host->RemoveObserver(this);
623     observing_ = false;
624     observed_host_ = nullptr;
625   }
626 
exited_count() const627   int exited_count() const { return exited_count_; }
destroyed_count() const628   int destroyed_count() const { return destroyed_count_; }
629 
630  private:
631   int exited_count_ = 0;
632   int destroyed_count_ = 0;
633   bool observing_ = false;
634   RenderProcessHost* observed_host_ = nullptr;
635 
636   DISALLOW_COPY_AND_ASSIGN(RenderProcessHostObserverCounter);
637 };
638 
639 // Check that the spare renderer is properly destroyed via
640 // DisableKeepAliveRefCount.
IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,SpareVsDisableKeepAliveRefCount)641 IN_PROC_BROWSER_TEST_F(RenderProcessHostTest, SpareVsDisableKeepAliveRefCount) {
642   RenderProcessHost::WarmupSpareRenderProcessHost(
643       ShellContentBrowserClient::Get()->browser_context());
644   base::RunLoop().RunUntilIdle();
645 
646   RenderProcessHost* spare_renderer =
647       RenderProcessHostImpl::GetSpareRenderProcessHostForTesting();
648   RenderProcessHostObserverCounter counter(spare_renderer);
649 
650   RenderProcessHostWatcher process_watcher(
651       spare_renderer, RenderProcessHostWatcher::WATCH_FOR_HOST_DESTRUCTION);
652 
653   spare_renderer->DisableKeepAliveRefCount();
654 
655   process_watcher.Wait();
656   EXPECT_TRUE(process_watcher.did_exit_normally());
657 
658   // An important part of test verification is that UaF doesn't happen in the
659   // next revolution of the message pump - without extra care in the
660   // SpareRenderProcessHostManager RenderProcessHost::Cleanup could be called
661   // twice leading to a crash caused by double-free flavour of UaF in
662   // base::DeleteHelper<...>::DoDelete.
663   base::RunLoop().RunUntilIdle();
664 
665   DCHECK_EQ(1, counter.exited_count());
666   DCHECK_EQ(1, counter.destroyed_count());
667 }
668 
669 // Check that the spare renderer is properly destroyed via
670 // DisableKeepAliveRefCount.
IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,SpareVsFastShutdown)671 IN_PROC_BROWSER_TEST_F(RenderProcessHostTest, SpareVsFastShutdown) {
672   RenderProcessHost::WarmupSpareRenderProcessHost(
673       ShellContentBrowserClient::Get()->browser_context());
674   base::RunLoop().RunUntilIdle();
675 
676   RenderProcessHost* spare_renderer =
677       RenderProcessHostImpl::GetSpareRenderProcessHostForTesting();
678   RenderProcessHostObserverCounter counter(spare_renderer);
679 
680   RenderProcessHostWatcher process_watcher(
681       spare_renderer, RenderProcessHostWatcher::WATCH_FOR_HOST_DESTRUCTION);
682 
683   spare_renderer->FastShutdownIfPossible();
684 
685   process_watcher.Wait();
686   EXPECT_FALSE(process_watcher.did_exit_normally());
687 
688   // An important part of test verification is that UaF doesn't happen in the
689   // next revolution of the message pump - without extra care in the
690   // SpareRenderProcessHostManager RenderProcessHost::Cleanup could be called
691   // twice leading to a crash caused by double-free flavour of UaF in
692   // base::DeleteHelper<...>::DoDelete.
693   base::RunLoop().RunUntilIdle();
694 
695   DCHECK_EQ(1, counter.exited_count());
696   DCHECK_EQ(1, counter.destroyed_count());
697 }
698 
699 class ShellCloser : public RenderProcessHostObserver {
700  public:
ShellCloser(Shell * shell,std::string * logging_string)701   ShellCloser(Shell* shell, std::string* logging_string)
702       : shell_(shell), logging_string_(logging_string) {}
703 
704  protected:
705   // RenderProcessHostObserver:
RenderProcessExited(RenderProcessHost * host,const ChildProcessTerminationInfo & info)706   void RenderProcessExited(RenderProcessHost* host,
707                            const ChildProcessTerminationInfo& info) override {
708     logging_string_->append("ShellCloser::RenderProcessExited ");
709     shell_->Close();
710   }
711 
RenderProcessHostDestroyed(RenderProcessHost * host)712   void RenderProcessHostDestroyed(RenderProcessHost* host) override {
713     logging_string_->append("ShellCloser::RenderProcessHostDestroyed ");
714   }
715 
716   Shell* shell_;
717   std::string* logging_string_;
718 };
719 
720 class ObserverLogger : public RenderProcessHostObserver {
721  public:
ObserverLogger(std::string * logging_string)722   explicit ObserverLogger(std::string* logging_string)
723       : logging_string_(logging_string), host_destroyed_(false) {}
724 
host_destroyed()725   bool host_destroyed() { return host_destroyed_; }
726 
727  protected:
728   // RenderProcessHostObserver:
RenderProcessExited(RenderProcessHost * host,const ChildProcessTerminationInfo & info)729   void RenderProcessExited(RenderProcessHost* host,
730                            const ChildProcessTerminationInfo& info) override {
731     logging_string_->append("ObserverLogger::RenderProcessExited ");
732   }
733 
RenderProcessHostDestroyed(RenderProcessHost * host)734   void RenderProcessHostDestroyed(RenderProcessHost* host) override {
735     logging_string_->append("ObserverLogger::RenderProcessHostDestroyed ");
736     host_destroyed_ = true;
737   }
738 
739   std::string* logging_string_;
740   bool host_destroyed_;
741 };
742 
743 // Flaky on Android. http://crbug.com/759514.
744 #if defined(OS_ANDROID)
745 #define MAYBE_AllProcessExitedCallsBeforeAnyHostDestroyedCalls \
746   DISABLED_AllProcessExitedCallsBeforeAnyHostDestroyedCalls
747 #else
748 #define MAYBE_AllProcessExitedCallsBeforeAnyHostDestroyedCalls \
749   AllProcessExitedCallsBeforeAnyHostDestroyedCalls
750 #endif
IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,MAYBE_AllProcessExitedCallsBeforeAnyHostDestroyedCalls)751 IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,
752                        MAYBE_AllProcessExitedCallsBeforeAnyHostDestroyedCalls) {
753   ASSERT_TRUE(embedded_test_server()->Start());
754 
755   GURL test_url = embedded_test_server()->GetURL("/simple_page.html");
756   EXPECT_TRUE(NavigateToURL(shell(), test_url));
757 
758   std::string logging_string;
759   ShellCloser shell_closer(shell(), &logging_string);
760   ObserverLogger observer_logger(&logging_string);
761   RenderProcessHost* rph =
762       shell()->web_contents()->GetMainFrame()->GetProcess();
763 
764   // Ensure that the ShellCloser observer is first, so that it will have first
765   // dibs on the ProcessExited callback.
766   rph->AddObserver(&shell_closer);
767   rph->AddObserver(&observer_logger);
768 
769   // This will crash the render process, and start all the callbacks.
770   // We can't use NavigateToURL here since it accesses the shell() after
771   // navigating, which the shell_closer deletes.
772   ScopedAllowRendererCrashes scoped_allow_renderer_crashes(shell());
773   NavigateToURLBlockUntilNavigationsComplete(
774       shell(), GURL(kChromeUICrashURL), 1);
775 
776   // The key here is that all the RenderProcessExited callbacks precede all the
777   // RenderProcessHostDestroyed callbacks.
778   EXPECT_EQ("ShellCloser::RenderProcessExited "
779             "ObserverLogger::RenderProcessExited "
780             "ShellCloser::RenderProcessHostDestroyed "
781             "ObserverLogger::RenderProcessHostDestroyed ", logging_string);
782 
783   // If the test fails, and somehow the RPH is still alive somehow, at least
784   // deregister the observers so that the test fails and doesn't also crash.
785   if (!observer_logger.host_destroyed()) {
786     rph->RemoveObserver(&shell_closer);
787     rph->RemoveObserver(&observer_logger);
788   }
789 }
790 
IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,KillProcessOnBadMojoMessage)791 IN_PROC_BROWSER_TEST_F(RenderProcessHostTest, KillProcessOnBadMojoMessage) {
792   ASSERT_TRUE(embedded_test_server()->Start());
793 
794   GURL test_url = embedded_test_server()->GetURL("/simple_page.html");
795   EXPECT_TRUE(NavigateToURL(shell(), test_url));
796   RenderProcessHost* rph =
797       shell()->web_contents()->GetMainFrame()->GetProcess();
798 
799   host_destructions_ = 0;
800   process_exits_ = 0;
801   rph->AddObserver(this);
802 
803   mojo::Remote<mojom::TestService> service;
804   rph->BindReceiver(service.BindNewPipeAndPassReceiver());
805 
806   base::RunLoop run_loop;
807   set_process_exit_callback(run_loop.QuitClosure());
808 
809   // Should reply with a bad message and cause process death.
810   {
811     ScopedAllowRendererCrashes scoped_allow_renderer_crashes(rph);
812     service->DoSomething(base::DoNothing());
813     run_loop.Run();
814   }
815 
816   EXPECT_EQ(1, process_exits_);
817   EXPECT_EQ(0, host_destructions_);
818   if (!host_destructions_)
819     rph->RemoveObserver(this);
820 }
821 
822 class AudioStartObserver : public WebContentsObserver {
823  public:
AudioStartObserver(WebContents * web_contents,base::OnceClosure audible_closure)824   AudioStartObserver(WebContents* web_contents,
825                      base::OnceClosure audible_closure)
826       : WebContentsObserver(web_contents),
827         audible_closure_(std::move(audible_closure)) {}
~AudioStartObserver()828   ~AudioStartObserver() override {}
829 
830   // WebContentsObserver:
OnAudioStateChanged(bool audible)831   void OnAudioStateChanged(bool audible) override {
832     if (audible && audible_closure_)
833       std::move(audible_closure_).Run();
834   }
835 
836  private:
837   base::OnceClosure audible_closure_;
838 };
839 
840 // Tests that audio stream counts (used for process priority calculations) are
841 // properly set and cleared during media playback and renderer terminations.
842 //
843 // Note: This test can't run when the Mojo Renderer is used since it does not
844 // create audio streams through the normal audio pathways; at present this is
845 // only used by Chromecast.
846 //
847 // crbug.com/864476: flaky on Android for unclear reasons.
848 #if BUILDFLAG(ENABLE_MOJO_RENDERER) || defined(OS_ANDROID)
849 #define KillProcessZerosAudioStreams DISABLED_KillProcessZerosAudioStreams
850 #endif
IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,KillProcessZerosAudioStreams)851 IN_PROC_BROWSER_TEST_F(RenderProcessHostTest, KillProcessZerosAudioStreams) {
852   // TODO(maxmorin): This test only uses an output stream. There should be a
853   // similar test for input streams.
854   embedded_test_server()->ServeFilesFromSourceDirectory(
855       media::GetTestDataPath());
856   ASSERT_TRUE(embedded_test_server()->Start());
857   ASSERT_TRUE(NavigateToURL(
858       shell(), embedded_test_server()->GetURL("/webaudio_oscillator.html")));
859   RenderProcessHostImpl* rph = static_cast<RenderProcessHostImpl*>(
860       shell()->web_contents()->GetMainFrame()->GetProcess());
861 
862   {
863     // Start audio and wait for it to become audible.
864     base::RunLoop run_loop;
865     AudioStartObserver observer(shell()->web_contents(),
866                                 run_loop.QuitClosure());
867 
868     std::string result;
869     EXPECT_TRUE(
870         ExecuteScriptAndExtractString(shell(), "StartOscillator();", &result))
871         << "Failed to execute javascript.";
872     run_loop.Run();
873 
874     // No point in running the rest of the test if this is wrong.
875     ASSERT_EQ(1, rph->get_media_stream_count_for_testing());
876   }
877 
878   host_destructions_ = 0;
879   process_exits_ = 0;
880   rph->AddObserver(this);
881 
882   mojo::Remote<mojom::TestService> service;
883   rph->BindReceiver(service.BindNewPipeAndPassReceiver());
884 
885   {
886     // Force a bad message event to occur which will terminate the renderer.
887     // Note: We post task the QuitClosure since RenderProcessExited() is called
888     // before destroying BrowserMessageFilters; and the next portion of the test
889     // must run after these notifications have been delivered.
890     ScopedAllowRendererCrashes scoped_allow_renderer_crashes(rph);
891     base::RunLoop run_loop;
892     set_process_exit_callback(media::BindToCurrentLoop(run_loop.QuitClosure()));
893     service->DoSomething(base::DoNothing());
894     run_loop.Run();
895   }
896 
897   {
898     // Cycle UI and IO loop once to ensure OnChannelClosing() has been delivered
899     // to audio stream owners and they get a chance to notify of stream closure.
900     base::RunLoop run_loop;
901     base::PostTask(FROM_HERE, {BrowserThread::IO},
902                    media::BindToCurrentLoop(run_loop.QuitClosure()));
903     run_loop.Run();
904   }
905 
906   // Verify shutdown went as expected.
907   EXPECT_EQ(0, rph->get_media_stream_count_for_testing());
908   EXPECT_EQ(1, process_exits_);
909   EXPECT_EQ(0, host_destructions_);
910   if (!host_destructions_)
911     rph->RemoveObserver(this);
912 }
913 
914 // Test class instance to run specific setup steps for capture streams.
915 class CaptureStreamRenderProcessHostTest : public RenderProcessHostTest {
916  public:
SetUp()917   void SetUp() override {
918     // Pixel output is needed when digging pixel values out of video tags for
919     // verification in VideoCaptureStream tests.
920     EnablePixelOutput();
921     RenderProcessHostTest::SetUp();
922   }
923 
SetUpCommandLine(base::CommandLine * command_line)924   void SetUpCommandLine(base::CommandLine* command_line) override {
925     // These flags are necessary to emulate camera input for getUserMedia()
926     // tests.
927     command_line->AppendSwitch(switches::kUseFakeUIForMediaStream);
928     RenderProcessHostTest::SetUpCommandLine(command_line);
929   }
930 };
931 
932 // These tests contain WebRTC calls and cannot be run when it isn't enabled.
933 #if !BUILDFLAG(ENABLE_WEBRTC)
934 #define GetUserMediaIncrementsVideoCaptureStreams \
935   DISABLED_GetUserMediaIncrementsVideoCaptureStreams
936 #define StopResetsVideoCaptureStreams DISABLED_StopResetsVideoCaptureStreams
937 #define KillProcessZerosVideoCaptureStreams \
938   DISABLED_KillProcessZerosVideoCaptureStreams
939 #define GetUserMediaAudioOnlyIncrementsMediaStreams \
940   DISABLED_GetUserMediaAudioOnlyIncrementsMediaStreams
941 #define KillProcessZerosAudioCaptureStreams \
942   DISABLED_KillProcessZerosAudioCaptureStreams
943 #endif  // BUILDFLAG(ENABLE_WEBRTC)
944 
945 // Tests that video capture stream count increments when getUserMedia() is
946 // called.
IN_PROC_BROWSER_TEST_F(CaptureStreamRenderProcessHostTest,GetUserMediaIncrementsVideoCaptureStreams)947 IN_PROC_BROWSER_TEST_F(CaptureStreamRenderProcessHostTest,
948                        GetUserMediaIncrementsVideoCaptureStreams) {
949   ASSERT_TRUE(embedded_test_server()->Start());
950   EXPECT_TRUE(NavigateToURL(
951       shell(), embedded_test_server()->GetURL("/media/getusermedia.html")));
952   RenderProcessHostImpl* rph = static_cast<RenderProcessHostImpl*>(
953       shell()->web_contents()->GetMainFrame()->GetProcess());
954   std::string result;
955   EXPECT_TRUE(ExecuteScriptAndExtractString(
956       shell(), "getUserMediaAndExpectSuccess({video: true});", &result))
957       << "Failed to execute javascript.";
958   EXPECT_EQ(1, rph->get_media_stream_count_for_testing());
959 }
960 
961 // Tests that video capture stream count resets when getUserMedia() is called
962 // and stopped.
IN_PROC_BROWSER_TEST_F(CaptureStreamRenderProcessHostTest,StopResetsVideoCaptureStreams)963 IN_PROC_BROWSER_TEST_F(CaptureStreamRenderProcessHostTest,
964                        StopResetsVideoCaptureStreams) {
965   ASSERT_TRUE(embedded_test_server()->Start());
966   EXPECT_TRUE(NavigateToURL(
967       shell(), embedded_test_server()->GetURL("/media/getusermedia.html")));
968   RenderProcessHostImpl* rph = static_cast<RenderProcessHostImpl*>(
969       shell()->web_contents()->GetMainFrame()->GetProcess());
970   std::string result;
971   EXPECT_TRUE(ExecuteScriptAndExtractString(
972       shell(), "getUserMediaAndStop({video: true});", &result))
973       << "Failed to execute javascript.";
974   EXPECT_EQ(0, rph->get_media_stream_count_for_testing());
975 }
976 
977 // Tests that video capture stream counts (used for process priority
978 // calculations) are properly set and cleared during media playback and renderer
979 // terminations.
IN_PROC_BROWSER_TEST_F(CaptureStreamRenderProcessHostTest,KillProcessZerosVideoCaptureStreams)980 IN_PROC_BROWSER_TEST_F(CaptureStreamRenderProcessHostTest,
981                        KillProcessZerosVideoCaptureStreams) {
982   ASSERT_TRUE(embedded_test_server()->Start());
983   EXPECT_TRUE(NavigateToURL(
984       shell(), embedded_test_server()->GetURL("/media/getusermedia.html")));
985   RenderProcessHostImpl* rph = static_cast<RenderProcessHostImpl*>(
986       shell()->web_contents()->GetMainFrame()->GetProcess());
987   std::string result;
988   EXPECT_TRUE(ExecuteScriptAndExtractString(
989       shell(), "getUserMediaAndExpectSuccess({video: true});", &result))
990       << "Failed to execute javascript.";
991   EXPECT_EQ(1, rph->get_media_stream_count_for_testing());
992 
993   host_destructions_ = 0;
994   process_exits_ = 0;
995   rph->AddObserver(this);
996 
997   mojo::Remote<mojom::TestService> service;
998   rph->BindReceiver(service.BindNewPipeAndPassReceiver());
999 
1000   {
1001     // Force a bad message event to occur which will terminate the renderer.
1002     ScopedAllowRendererCrashes scoped_allow_renderer_crashes(rph);
1003     base::RunLoop run_loop;
1004     set_process_exit_callback(media::BindToCurrentLoop(run_loop.QuitClosure()));
1005     service->DoSomething(base::DoNothing());
1006     run_loop.Run();
1007   }
1008 
1009   {
1010     // Cycle UI and IO loop once to ensure OnChannelClosing() has been delivered
1011     // to audio stream owners and they get a chance to notify of stream closure.
1012     base::RunLoop run_loop;
1013     base::PostTask(FROM_HERE, {BrowserThread::IO},
1014                    media::BindToCurrentLoop(run_loop.QuitClosure()));
1015     run_loop.Run();
1016   }
1017 
1018   EXPECT_EQ(0, rph->get_media_stream_count_for_testing());
1019   EXPECT_EQ(1, process_exits_);
1020   EXPECT_EQ(0, host_destructions_);
1021   if (!host_destructions_)
1022     rph->RemoveObserver(this);
1023 }
1024 
1025 // Tests that media stream count increments when getUserMedia() is
1026 // called with audio only.
IN_PROC_BROWSER_TEST_F(CaptureStreamRenderProcessHostTest,GetUserMediaAudioOnlyIncrementsMediaStreams)1027 IN_PROC_BROWSER_TEST_F(CaptureStreamRenderProcessHostTest,
1028                        GetUserMediaAudioOnlyIncrementsMediaStreams) {
1029   ASSERT_TRUE(embedded_test_server()->Start());
1030   EXPECT_TRUE(NavigateToURL(
1031       shell(), embedded_test_server()->GetURL("/media/getusermedia.html")));
1032   RenderProcessHostImpl* rph = static_cast<RenderProcessHostImpl*>(
1033       shell()->web_contents()->GetMainFrame()->GetProcess());
1034   std::string result;
1035   EXPECT_TRUE(ExecuteScriptAndExtractString(
1036       shell(), "getUserMediaAndExpectSuccess({video: false, audio: true});",
1037       &result))
1038       << "Failed to execute javascript.";
1039   EXPECT_EQ(1, rph->get_media_stream_count_for_testing());
1040 }
1041 
1042 // Tests that media stream counts (used for process priority
1043 // calculations) are properly set and cleared during media playback and renderer
1044 // terminations for audio only streams.
IN_PROC_BROWSER_TEST_F(CaptureStreamRenderProcessHostTest,KillProcessZerosAudioCaptureStreams)1045 IN_PROC_BROWSER_TEST_F(CaptureStreamRenderProcessHostTest,
1046                        KillProcessZerosAudioCaptureStreams) {
1047   ASSERT_TRUE(embedded_test_server()->Start());
1048   EXPECT_TRUE(NavigateToURL(
1049       shell(), embedded_test_server()->GetURL("/media/getusermedia.html")));
1050   RenderProcessHostImpl* rph = static_cast<RenderProcessHostImpl*>(
1051       shell()->web_contents()->GetMainFrame()->GetProcess());
1052   std::string result;
1053   EXPECT_TRUE(ExecuteScriptAndExtractString(
1054       shell(), "getUserMediaAndExpectSuccess({video: false, audio: true});",
1055       &result))
1056       << "Failed to execute javascript.";
1057   EXPECT_EQ(1, rph->get_media_stream_count_for_testing());
1058 
1059   host_destructions_ = 0;
1060   process_exits_ = 0;
1061   rph->AddObserver(this);
1062 
1063   mojo::Remote<mojom::TestService> service;
1064   rph->BindReceiver(service.BindNewPipeAndPassReceiver());
1065 
1066   {
1067     // Force a bad message event to occur which will terminate the renderer.
1068     ScopedAllowRendererCrashes scoped_allow_renderer_crashes(rph);
1069     base::RunLoop run_loop;
1070     set_process_exit_callback(media::BindToCurrentLoop(run_loop.QuitClosure()));
1071     service->DoSomething(base::DoNothing());
1072     run_loop.Run();
1073   }
1074 
1075   {
1076     // Cycle UI and IO loop once to ensure OnChannelClosing() has been delivered
1077     // to audio stream owners and they get a chance to notify of stream closure.
1078     base::RunLoop run_loop;
1079     base::PostTask(FROM_HERE, {BrowserThread::IO},
1080                    media::BindToCurrentLoop(run_loop.QuitClosure()));
1081     run_loop.Run();
1082   }
1083 
1084   EXPECT_EQ(0, rph->get_media_stream_count_for_testing());
1085   EXPECT_EQ(1, process_exits_);
1086   EXPECT_EQ(0, host_destructions_);
1087   if (!host_destructions_)
1088     rph->RemoveObserver(this);
1089 }
1090 
IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,KeepAliveRendererProcess)1091 IN_PROC_BROWSER_TEST_F(RenderProcessHostTest, KeepAliveRendererProcess) {
1092   embedded_test_server()->RegisterRequestHandler(
1093       base::BindRepeating(HandleBeacon));
1094   ASSERT_TRUE(embedded_test_server()->Start());
1095 
1096   if (AreDefaultSiteInstancesEnabled()) {
1097     // Isolate "foo.com" so we are guaranteed that navigations to this site
1098     // will be in a different process.
1099     IsolateOriginsForTesting(embedded_test_server(), shell()->web_contents(),
1100                              {"foo.com"});
1101   }
1102 
1103   EXPECT_TRUE(NavigateToURL(
1104       shell(), embedded_test_server()->GetURL("/send-beacon.html")));
1105 
1106   RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>(
1107       shell()->web_contents()->GetMainFrame());
1108   RenderProcessHostImpl* rph =
1109       static_cast<RenderProcessHostImpl*>(rfh->GetProcess());
1110 
1111   host_destructions_ = 0;
1112   process_exits_ = 0;
1113   rph->AddObserver(this);
1114   rfh->SetKeepAliveTimeoutForTesting(base::TimeDelta::FromSeconds(30));
1115 
1116   // Navigate to a site that will be in a different process.
1117   base::TimeTicks start = base::TimeTicks::Now();
1118   EXPECT_TRUE(NavigateToURL(
1119       shell(), embedded_test_server()->GetURL("foo.com", "/title1.html")));
1120 
1121   WaitUntilProcessExits(1);
1122 
1123   EXPECT_LT(base::TimeTicks::Now() - start, base::TimeDelta::FromSeconds(30));
1124   if (!host_destructions_)
1125     rph->RemoveObserver(this);
1126 }
1127 
IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,KeepAliveRendererProcessWithServiceWorker)1128 IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,
1129                        KeepAliveRendererProcessWithServiceWorker) {
1130   base::RunLoop run_loop;
1131   embedded_test_server()->RegisterRequestHandler(
1132       base::BindRepeating(HandleHungBeacon, run_loop.QuitClosure()));
1133   ASSERT_TRUE(embedded_test_server()->Start());
1134 
1135   EXPECT_TRUE(NavigateToURL(
1136       shell(),
1137       embedded_test_server()->GetURL("/workers/service_worker_setup.html")));
1138   EXPECT_EQ("ok", EvalJs(shell(), "setup();"));
1139 
1140   RenderProcessHostImpl* rph = static_cast<RenderProcessHostImpl*>(
1141       shell()->web_contents()->GetMainFrame()->GetProcess());
1142   // 1 for the service worker.
1143   EXPECT_EQ(rph->keep_alive_ref_count(), 1u);
1144 
1145   // We use /workers/send-beacon.html, not send-beacon.html, due to the
1146   // service worker scope rule.
1147   EXPECT_TRUE(NavigateToURL(
1148       shell(), embedded_test_server()->GetURL("/workers/send-beacon.html")));
1149 
1150   run_loop.Run();
1151   // We are still using the same process.
1152   ASSERT_EQ(shell()->web_contents()->GetMainFrame()->GetProcess(), rph);
1153   // 1 for the service worker, 1 for the keepalive fetch.
1154   EXPECT_EQ(rph->keep_alive_ref_count(), 2u);
1155 }
1156 
1157 // Test is flaky on Android builders: https://crbug.com/875179
1158 #if defined(OS_ANDROID)
1159 #define MAYBE_KeepAliveRendererProcess_Hung \
1160   DISABLED_KeepAliveRendererProcess_Hung
1161 #else
1162 #define MAYBE_KeepAliveRendererProcess_Hung KeepAliveRendererProcess_Hung
1163 #endif
IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,MAYBE_KeepAliveRendererProcess_Hung)1164 IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,
1165                        MAYBE_KeepAliveRendererProcess_Hung) {
1166   embedded_test_server()->RegisterRequestHandler(
1167       base::BindRepeating(HandleHungBeacon, base::RepeatingClosure()));
1168   ASSERT_TRUE(embedded_test_server()->Start());
1169 
1170   EXPECT_TRUE(NavigateToURL(
1171       shell(), embedded_test_server()->GetURL("/send-beacon.html")));
1172 
1173   RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>(
1174       shell()->web_contents()->GetMainFrame());
1175   RenderProcessHostImpl* rph =
1176       static_cast<RenderProcessHostImpl*>(rfh->GetProcess());
1177 
1178   host_destructions_ = 0;
1179   process_exits_ = 0;
1180   rph->AddObserver(this);
1181   rfh->SetKeepAliveTimeoutForTesting(base::TimeDelta::FromSeconds(1));
1182 
1183   base::TimeTicks start = base::TimeTicks::Now();
1184   EXPECT_TRUE(NavigateToURL(shell(), GURL("data:text/html,<p>hello</p>")));
1185 
1186   WaitUntilProcessExits(1);
1187 
1188   EXPECT_GE(base::TimeTicks::Now() - start, base::TimeDelta::FromSeconds(1));
1189   if (!host_destructions_)
1190     rph->RemoveObserver(this);
1191 }
1192 
1193 // Test is flaky on Android builders: https://crbug.com/875179
1194 #if defined(OS_ANDROID)
1195 #define MAYBE_FetchKeepAliveRendererProcess_Hung \
1196   DISABLED_FetchKeepAliveRendererProcess_Hung
1197 #else
1198 #define MAYBE_FetchKeepAliveRendererProcess_Hung \
1199   FetchKeepAliveRendererProcess_Hung
1200 #endif
IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,MAYBE_FetchKeepAliveRendererProcess_Hung)1201 IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,
1202                        MAYBE_FetchKeepAliveRendererProcess_Hung) {
1203   embedded_test_server()->RegisterRequestHandler(
1204       base::BindRepeating(HandleHungBeacon, base::RepeatingClosure()));
1205   ASSERT_TRUE(embedded_test_server()->Start());
1206 
1207   EXPECT_TRUE(NavigateToURL(
1208       shell(), embedded_test_server()->GetURL("/fetch-keepalive.html")));
1209 
1210   RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>(
1211       shell()->web_contents()->GetMainFrame());
1212   RenderProcessHostImpl* rph =
1213       static_cast<RenderProcessHostImpl*>(rfh->GetProcess());
1214 
1215   host_destructions_ = 0;
1216   process_exits_ = 0;
1217   rph->AddObserver(this);
1218   rfh->SetKeepAliveTimeoutForTesting(base::TimeDelta::FromSeconds(1));
1219 
1220   base::TimeTicks start = base::TimeTicks::Now();
1221   EXPECT_TRUE(NavigateToURL(shell(), GURL("data:text/html,<p>hello</p>")));
1222 
1223   WaitUntilProcessExits(1);
1224 
1225   EXPECT_GE(base::TimeTicks::Now() - start, base::TimeDelta::FromSeconds(1));
1226   if (!host_destructions_)
1227     rph->RemoveObserver(this);
1228 }
1229 
IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,ManyKeepaliveRequests)1230 IN_PROC_BROWSER_TEST_F(RenderProcessHostTest, ManyKeepaliveRequests) {
1231   auto resolver =
1232       base::MakeRefCounted<DelayedHttpResponseWithResolver::Resolver>();
1233   embedded_test_server()->RegisterRequestHandler(
1234       base::BindRepeating(HandleHungBeaconWithResolver, resolver));
1235   const base::string16 title = base::ASCIIToUTF16("Resolved");
1236   const base::string16 waiting = base::ASCIIToUTF16("Waiting");
1237 
1238   ASSERT_TRUE(embedded_test_server()->Start());
1239   EXPECT_TRUE(NavigateToURL(
1240       shell(),
1241       embedded_test_server()->GetURL("/fetch-keepalive.html?requests=256")));
1242 
1243   {
1244     // Wait for the page to make all the keepalive requests.
1245     TitleWatcher watcher(shell()->web_contents(), waiting);
1246     EXPECT_EQ(waiting, watcher.WaitAndGetTitle());
1247   }
1248 
1249   resolver->Resolve();
1250 
1251   {
1252     TitleWatcher watcher(shell()->web_contents(), title);
1253     EXPECT_EQ(title, watcher.WaitAndGetTitle());
1254   }
1255 }
1256 
IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,TooManyKeepaliveRequests)1257 IN_PROC_BROWSER_TEST_F(RenderProcessHostTest, TooManyKeepaliveRequests) {
1258   embedded_test_server()->RegisterRequestHandler(
1259       base::BindRepeating(HandleHungBeacon, base::RepeatingClosure()));
1260   ASSERT_TRUE(embedded_test_server()->Start());
1261   const base::string16 title = base::ASCIIToUTF16("Rejected");
1262 
1263   TitleWatcher watcher(shell()->web_contents(), title);
1264 
1265   EXPECT_TRUE(NavigateToURL(
1266       shell(),
1267       embedded_test_server()->GetURL("/fetch-keepalive.html?requests=257")));
1268 
1269   EXPECT_EQ(title, watcher.WaitAndGetTitle());
1270 }
1271 
IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,LowPriorityFramesDisabled)1272 IN_PROC_BROWSER_TEST_F(RenderProcessHostTest, LowPriorityFramesDisabled) {
1273   // RenderProcessHostImpl::UpdateProcessPriority has an early check of
1274   // run_renderer_in_process and exits for RenderProcessHosts without a child
1275   // process launcher.  In order to skip initializing that here and the layer of
1276   // indirection, we explicitly run in-process, which we must also disable once
1277   // the test has finished to prevent crashing on exit.
1278   RenderProcessHost::SetRunRendererInProcess(true);
1279   RenderProcessHostImpl* process = static_cast<RenderProcessHostImpl*>(
1280       RenderProcessHostImpl::CreateRenderProcessHost(
1281           ShellContentBrowserClient::Get()->browser_context(), nullptr,
1282           nullptr));
1283   // It starts off as normal priority.
1284   EXPECT_FALSE(process->IsProcessBackgrounded());
1285   // With the feature off it stays low priority when adding low priority frames.
1286   process->UpdateFrameWithPriority(base::nullopt,
1287                                    RenderProcessHostImpl::FramePriority::kLow);
1288   process->UpdateFrameWithPriority(base::nullopt,
1289                                    RenderProcessHostImpl::FramePriority::kLow);
1290   EXPECT_FALSE(process->IsProcessBackgrounded());
1291   RenderProcessHost::SetRunRendererInProcess(false);
1292 }
1293 
IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,PriorityOverride)1294 IN_PROC_BROWSER_TEST_F(RenderProcessHostTest, PriorityOverride) {
1295   // RenderProcessHostImpl::UpdateProcessPriority has an early check of
1296   // run_renderer_in_process and exits for RenderProcessHosts without a child
1297   // process launcher.  In order to skip initializing that here and the layer of
1298   // indirection, we explicitly run in-process, which we must also disable once
1299   // the test has finished to prevent crashing on exit.
1300   RenderProcessHost::SetRunRendererInProcess(true);
1301   RenderProcessHostImpl* process = static_cast<RenderProcessHostImpl*>(
1302       RenderProcessHostImpl::CreateRenderProcessHost(
1303           ShellContentBrowserClient::Get()->browser_context(), nullptr,
1304           nullptr));
1305 
1306   // It starts off as normal priority with no override.
1307   EXPECT_FALSE(process->HasPriorityOverride());
1308   EXPECT_FALSE(process->IsProcessBackgrounded());
1309 
1310   process->SetPriorityOverride(false /* foreground */);
1311   EXPECT_TRUE(process->HasPriorityOverride());
1312   EXPECT_TRUE(process->IsProcessBackgrounded());
1313 
1314   process->SetPriorityOverride(true /* foreground */);
1315   EXPECT_TRUE(process->HasPriorityOverride());
1316   EXPECT_FALSE(process->IsProcessBackgrounded());
1317 
1318   process->SetPriorityOverride(false /* foreground */);
1319   EXPECT_TRUE(process->HasPriorityOverride());
1320   EXPECT_TRUE(process->IsProcessBackgrounded());
1321 
1322   // Add a pending view, and expect the process to *stay* backgrounded.
1323   process->AddPendingView();
1324   EXPECT_TRUE(process->HasPriorityOverride());
1325   EXPECT_TRUE(process->IsProcessBackgrounded());
1326 
1327   // Clear the override. The pending view should cause the process to go back to
1328   // being foregrounded.
1329   process->ClearPriorityOverride();
1330   EXPECT_FALSE(process->HasPriorityOverride());
1331   EXPECT_FALSE(process->IsProcessBackgrounded());
1332 
1333   // Clear the pending view so the test doesn't explode.
1334   process->RemovePendingView();
1335   EXPECT_FALSE(process->HasPriorityOverride());
1336   EXPECT_TRUE(process->IsProcessBackgrounded());
1337 
1338   RenderProcessHost::SetRunRendererInProcess(false);
1339 }
1340 
1341 // This test verifies properties of RenderProcessHostImpl *before* Init method
1342 // is called.
IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,ConstructedButNotInitializedYet)1343 IN_PROC_BROWSER_TEST_F(RenderProcessHostTest, ConstructedButNotInitializedYet) {
1344   RenderProcessHost* process = RenderProcessHostImpl::CreateRenderProcessHost(
1345       ShellContentBrowserClient::Get()->browser_context(), nullptr, nullptr);
1346 
1347   // Just verifying that the arguments of CreateRenderProcessHost got processed
1348   // correctly.
1349   EXPECT_EQ(ShellContentBrowserClient::Get()->browser_context(),
1350             process->GetBrowserContext());
1351   EXPECT_FALSE(process->IsForGuestsOnly());
1352 
1353   // There should be no OS process before Init() method is called.
1354   EXPECT_FALSE(process->IsInitializedAndNotDead());
1355   EXPECT_FALSE(process->IsReady());
1356   EXPECT_FALSE(process->GetProcess().IsValid());
1357   EXPECT_EQ(base::kNullProcessHandle, process->GetProcess().Handle());
1358 
1359   // TODO(lukasza): https://crbug.com/813045: RenderProcessHost shouldn't have
1360   // an associated IPC channel (and shouldn't accumulate IPC messages) unless
1361   // the Init() method was called and the RPH either has connection to an actual
1362   // OS process or is currently attempting to spawn the OS process.  After this
1363   // bug is fixed the 1st test assertion below should be reversed (unsure about
1364   // the 2nd one).
1365   EXPECT_TRUE(process->GetChannel());
1366   EXPECT_TRUE(process->GetRendererInterface());
1367 
1368   // Cleanup the resources acquired by the test.
1369   process->Cleanup();
1370 }
1371 
1372 // This test verifies that a fast shutdown is possible for a starting process.
IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,FastShutdownForStartingProcess)1373 IN_PROC_BROWSER_TEST_F(RenderProcessHostTest, FastShutdownForStartingProcess) {
1374   RenderProcessHost* process = RenderProcessHostImpl::CreateRenderProcessHost(
1375       ShellContentBrowserClient::Get()->browser_context(), nullptr, nullptr);
1376   process->Init();
1377   EXPECT_TRUE(process->FastShutdownIfPossible());
1378   process->Cleanup();
1379 }
1380 
1381 class RenderProcessHostFramePriorityTest : public RenderProcessHostTest {
1382  public:
1383   // Initialize the clock and set the fixture to use frame priority feature.
RenderProcessHostFramePriorityTest()1384   RenderProcessHostFramePriorityTest() {
1385     clock_ = std::make_unique<base::SimpleTestTickClock>();
1386     use_frame_priority_ = true;
1387   }
1388 
1389   // Check the histograms at TearDown.
TearDown()1390   void TearDown() override {
1391     RenderProcessHostTest::TearDown();
1392     // TODO(crbug/1045958): Check the histograms directly in the tests.
1393     CheckHistograms();
1394   }
1395 
1396   // Set the expected frame priorities seen and set TearDown check variable.
SetFramePrioritiesExpected(bool low,bool normal)1397   void SetFramePrioritiesExpected(bool low, bool normal) {
1398     low_priority_frames_expected_ = low;
1399     normal_priority_frames_expected_ = normal;
1400     check_frame_priorities_ = true;
1401   }
1402 
1403   // Set the times expected at low priority and overall.
SetPriorityTimesExpected(base::TimeDelta low_time,base::TimeDelta total_time)1404   void SetPriorityTimesExpected(base::TimeDelta low_time,
1405                                 base::TimeDelta total_time) {
1406     low_priority_time_expected_ = low_time;
1407     total_time_expected_ = total_time;
1408   }
1409 
1410   // Advance the internal clock for the RenderProcessHost.
AdvanceClock(base::TimeDelta time)1411   void AdvanceClock(base::TimeDelta time) { clock_->Advance(time); }
1412 
1413   // Create the process with the test clock, initialize, and return it.
CreateAndInitializeProcess()1414   RenderProcessHostImpl* CreateAndInitializeProcess() {
1415     // RenderProcessHostImpl::UpdateProcessPriority has an early check of
1416     // run_renderer_in_process and exits for RenderProcessHosts without a child
1417     // process launcher.  In order to skip initializing that here and the layer
1418     // of indirection, we explicitly run in-process, which we must also disable
1419     // once the test has finished to prevent crashing on exit.
1420     RenderProcessHostImpl::SetRunRendererInProcess(true);
1421     // Initialize the clock's value to the current time.
1422     clock_->SetNowTicks(base::TimeTicks::Now());
1423     // Create the process itself.
1424     process_ = static_cast<RenderProcessHostImpl*>(
1425         RenderProcessHostImpl::CreateRenderProcessHost(
1426             ShellContentBrowserClient::Get()->browser_context(), nullptr,
1427             nullptr));
1428     // For these tests, assume something is always visible.
1429     SetVisibleClients(process_, 1);
1430     // Any advancement before Init is ignored.
1431     AdvanceClock(base::TimeDelta::FromSeconds(10));
1432     // Don't start an actual process, just initialize times.
1433     process_->SetClockForTesting(clock_.get());
1434     // When no frames are attached, it's not low priority.
1435     EXPECT_FALSE(process_->IsProcessBackgrounded());
1436     // Return it so it can be used by tests.
1437     return process_;
1438   }
1439 
1440   // Shut down the created process.
ShutDownAndCleanUpProcess()1441   void ShutDownAndCleanUpProcess() {
1442     RenderProcessHostImpl::SetRunRendererInProcess(false);
1443   }
1444 
1445  private:
1446   // Check the histograms related to frame priority and backgrounding.
CheckHistograms()1447   void CheckHistograms() {
1448     if (total_time_expected_ != base::TimeDelta()) {
1449       histogram_tester_.ExpectUniqueSample(
1450           "BrowserRenderProcessHost.TotalTime",
1451           total_time_expected_.InMilliseconds(), 1);
1452       histogram_tester_.ExpectUniqueSample(
1453           "BrowserRenderProcessHost.BackgroundTime",
1454           low_priority_time_expected_.InMilliseconds(), 1);
1455     }
1456 
1457     if (!check_frame_priorities_)
1458       return;
1459 
1460     if (low_priority_frames_expected_ && normal_priority_frames_expected_) {
1461       histogram_tester_.ExpectBucketCount(
1462           "BrowserRenderProcessHost.FramePrioritiesSeen",
1463           RenderProcessHostImpl::FramePrioritiesSeen::kMixedPrioritiesSeen, 1);
1464     } else if (low_priority_frames_expected_) {
1465       histogram_tester_.ExpectBucketCount(
1466           "BrowserRenderProcessHost.FramePrioritiesSeen",
1467           RenderProcessHostImpl::FramePrioritiesSeen::kOnlyLowPrioritiesSeen,
1468           1);
1469     } else if (normal_priority_frames_expected_) {
1470       histogram_tester_.ExpectBucketCount(
1471           "BrowserRenderProcessHost.FramePrioritiesSeen",
1472           RenderProcessHostImpl::FramePrioritiesSeen::kOnlyNormalPrioritiesSeen,
1473           1);
1474     } else {
1475       // Two are expected here because tests using this create their own
1476       // process, meaning the default process is never used/has no frames
1477       // attached.
1478       histogram_tester_.ExpectBucketCount(
1479           "BrowserRenderProcessHost.FramePrioritiesSeen",
1480           RenderProcessHostImpl::FramePrioritiesSeen::kNoFramesSeen, 2);
1481     }
1482   }
1483 
1484   // The process that is created to add frames with various priorities.
1485   RenderProcessHostImpl* process_;
1486   // The histogram tester, to check backgrounding and priority histograms.
1487   base::HistogramTester histogram_tester_;
1488   // Whether frames with low priority have been attached to the process.
1489   bool low_priority_frames_expected_ = false;
1490   // Whether frames with normal priority have been attached to the process.
1491   bool normal_priority_frames_expected_ = false;
1492   // Whether we should check the frame priority histograms.
1493   bool check_frame_priorities_ = false;
1494   // The expected time a process hosts only low priority frames.
1495   base::TimeDelta low_priority_time_expected_;
1496   // The expected time a process hosts frames overall.
1497   base::TimeDelta total_time_expected_;
1498   // The clock that is used by the RenderProcessHost.
1499   std::unique_ptr<base::SimpleTestTickClock> clock_;
1500 };
1501 
IN_PROC_BROWSER_TEST_F(RenderProcessHostFramePriorityTest,NoFramesSeenPriorityTest)1502 IN_PROC_BROWSER_TEST_F(RenderProcessHostFramePriorityTest,
1503                        NoFramesSeenPriorityTest) {
1504   RenderProcessHostImpl* process = CreateAndInitializeProcess();
1505   DCHECK(process);
1506   ShutDownAndCleanUpProcess();
1507   SetFramePrioritiesExpected(false, false);
1508 }
1509 
IN_PROC_BROWSER_TEST_F(RenderProcessHostFramePriorityTest,LowPriorityFramesEnabled)1510 IN_PROC_BROWSER_TEST_F(RenderProcessHostFramePriorityTest,
1511                        LowPriorityFramesEnabled) {
1512   // When the process is first created with no frames, it's not low priority.
1513   RenderProcessHostImpl* process = CreateAndInitializeProcess();
1514   EXPECT_FALSE(process->IsProcessBackgrounded());
1515   AdvanceClock(base::TimeDelta::FromSeconds(1));
1516   // When all frames added are low priority, it's low priority.
1517   process->UpdateFrameWithPriority(base::nullopt,
1518                                    RenderProcessHostImpl::FramePriority::kLow);
1519   process->UpdateFrameWithPriority(base::nullopt,
1520                                    RenderProcessHostImpl::FramePriority::kLow);
1521   EXPECT_TRUE(process->IsProcessBackgrounded());
1522   AdvanceClock(base::TimeDelta::FromSeconds(2));
1523   // When all the low priority frames are removed, it's not low priority.
1524   process->UpdateFrameWithPriority(RenderProcessHostImpl::FramePriority::kLow,
1525                                    base::nullopt);
1526   process->UpdateFrameWithPriority(RenderProcessHostImpl::FramePriority::kLow,
1527                                    base::nullopt);
1528   EXPECT_FALSE(process->IsProcessBackgrounded());
1529   AdvanceClock(base::TimeDelta::FromSeconds(1));
1530   // When a low priority frame is added back in, it's low priority.
1531   process->UpdateFrameWithPriority(base::nullopt,
1532                                    RenderProcessHostImpl::FramePriority::kLow);
1533   EXPECT_TRUE(process->IsProcessBackgrounded());
1534   AdvanceClock(base::TimeDelta::FromSeconds(1));
1535   // As soon as a non-low priority frame is added, it's not low priority.
1536   process->UpdateFrameWithPriority(
1537       base::nullopt, RenderProcessHostImpl::FramePriority::kNormal);
1538   EXPECT_FALSE(process->IsProcessBackgrounded());
1539   AdvanceClock(base::TimeDelta::FromSeconds(1));
1540   // It remains not low priority even if we add more low priority frames.
1541   process->UpdateFrameWithPriority(base::nullopt,
1542                                    RenderProcessHostImpl::FramePriority::kLow);
1543   EXPECT_FALSE(process->IsProcessBackgrounded());
1544   AdvanceClock(base::TimeDelta::FromSeconds(1));
1545   // As soon as the non-low priority frame is removed, it becomes low priority.
1546   process->UpdateFrameWithPriority(
1547       RenderProcessHostImpl::FramePriority::kNormal, base::nullopt);
1548   EXPECT_TRUE(process->IsProcessBackgrounded());
1549   AdvanceClock(base::TimeDelta::FromSeconds(1));
1550   // Add a non-low priority frame, but then transition it to low, the process
1551   // should go from unbackgrounded to backgrounded.
1552   process->UpdateFrameWithPriority(
1553       base::nullopt, RenderProcessHostImpl::FramePriority::kNormal);
1554   EXPECT_FALSE(process->IsProcessBackgrounded());
1555   AdvanceClock(base::TimeDelta::FromSeconds(1));
1556   process->UpdateFrameWithPriority(
1557       RenderProcessHostImpl::FramePriority::kNormal,
1558       RenderProcessHostImpl::FramePriority::kLow);
1559   EXPECT_TRUE(process->IsProcessBackgrounded());
1560   AdvanceClock(base::TimeDelta::FromSeconds(2));
1561   // Transition the frame back to normal priority, it becomes normal priority.
1562   process->UpdateFrameWithPriority(
1563       RenderProcessHostImpl::FramePriority::kLow,
1564       RenderProcessHostImpl::FramePriority::kNormal);
1565   EXPECT_FALSE(process->IsProcessBackgrounded());
1566   AdvanceClock(base::TimeDelta::FromSeconds(1));
1567 
1568   // This process has had low and normal priority frames attached to it.
1569   ShutDownAndCleanUpProcess();
1570   SetFramePrioritiesExpected(true, true);
1571   SetPriorityTimesExpected(base::TimeDelta::FromSeconds(6),
1572                            base::TimeDelta::FromSeconds(12));
1573 }
1574 
IN_PROC_BROWSER_TEST_F(RenderProcessHostFramePriorityTest,LowPriorityFramesEnabledOnlyLowPriority)1575 IN_PROC_BROWSER_TEST_F(RenderProcessHostFramePriorityTest,
1576                        LowPriorityFramesEnabledOnlyLowPriority) {
1577   RenderProcessHostImpl* process = CreateAndInitializeProcess();
1578   AdvanceClock(base::TimeDelta::FromSeconds(1));
1579   // When all frames added are low priority, it's low priority.
1580   process->UpdateFrameWithPriority(base::nullopt,
1581                                    RenderProcessHostImpl::FramePriority::kLow);
1582   process->UpdateFrameWithPriority(base::nullopt,
1583                                    RenderProcessHostImpl::FramePriority::kLow);
1584   EXPECT_TRUE(process->IsProcessBackgrounded());
1585   AdvanceClock(base::TimeDelta::FromSeconds(2));
1586 
1587   // This process has had only low priority frames attached to it.
1588   ShutDownAndCleanUpProcess();
1589   SetFramePrioritiesExpected(true, false);
1590   SetPriorityTimesExpected(base::TimeDelta::FromSeconds(2),
1591                            base::TimeDelta::FromSeconds(3));
1592 }
1593 
IN_PROC_BROWSER_TEST_F(RenderProcessHostFramePriorityTest,LowPriorityFramesEnabledOnlyNormalPriority)1594 IN_PROC_BROWSER_TEST_F(RenderProcessHostFramePriorityTest,
1595                        LowPriorityFramesEnabledOnlyNormalPriority) {
1596   RenderProcessHostImpl* process = CreateAndInitializeProcess();
1597   AdvanceClock(base::TimeDelta::FromSeconds(1));
1598   // When all frames added are normal priority, it's not low priority.
1599   process->UpdateFrameWithPriority(
1600       base::nullopt, RenderProcessHostImpl::FramePriority::kNormal);
1601   process->UpdateFrameWithPriority(
1602       base::nullopt, RenderProcessHostImpl::FramePriority::kNormal);
1603   EXPECT_FALSE(process->IsProcessBackgrounded());
1604   AdvanceClock(base::TimeDelta::FromSeconds(2));
1605 
1606   // This process has had only normal priority frames attached to it.
1607   ShutDownAndCleanUpProcess();
1608   SetFramePrioritiesExpected(false, true);
1609   SetPriorityTimesExpected(base::TimeDelta(), base::TimeDelta::FromSeconds(3));
1610 }
1611 
1612 }  // namespace content
1613