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