1 // Copyright 2015 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 "extensions/test/background_page_watcher.h"
6
7 #include "base/auto_reset.h"
8 #include "base/check_op.h"
9 #include "base/run_loop.h"
10 #include "base/scoped_observer.h"
11 #include "content/public/browser/render_frame_host.h"
12 #include "content/public/browser/render_process_host.h"
13 #include "content/public/browser/render_view_host.h"
14 #include "content/public/browser/web_contents.h"
15 #include "extensions/browser/extension_host.h"
16 #include "extensions/browser/process_manager.h"
17 #include "extensions/common/extension.h"
18
19 namespace extensions {
20
BackgroundPageWatcher(ProcessManager * process_manager,const Extension * extension)21 BackgroundPageWatcher::BackgroundPageWatcher(ProcessManager* process_manager,
22 const Extension* extension)
23 : process_manager_(process_manager),
24 extension_id_(extension->id()),
25 is_waiting_for_open_(false),
26 is_waiting_for_close_(false) {}
27
~BackgroundPageWatcher()28 BackgroundPageWatcher::~BackgroundPageWatcher() {}
29
WaitForOpen()30 void BackgroundPageWatcher::WaitForOpen() {
31 WaitForOpenState(true);
32 }
33
WaitForClose()34 void BackgroundPageWatcher::WaitForClose() {
35 WaitForOpenState(false);
36 }
37
WaitForOpenState(bool wait_for_open)38 void BackgroundPageWatcher::WaitForOpenState(bool wait_for_open) {
39 if (IsBackgroundPageOpen() == wait_for_open)
40 return;
41 ScopedObserver<ProcessManager, ProcessManagerObserver> observer(this);
42 observer.Add(process_manager_);
43 bool* flag = wait_for_open ? &is_waiting_for_open_ : &is_waiting_for_close_;
44 base::AutoReset<bool> set_flag(flag, true);
45 base::RunLoop run_loop;
46 base::AutoReset<base::OnceClosure> set_quit_run_loop(&quit_run_loop_,
47 run_loop.QuitClosure());
48 run_loop.Run();
49 DCHECK_EQ(wait_for_open, IsBackgroundPageOpen());
50 }
51
IsBackgroundPageOpen()52 bool BackgroundPageWatcher::IsBackgroundPageOpen() {
53 ExtensionHost* host =
54 process_manager_->GetBackgroundHostForExtension(extension_id_);
55 if (!host)
56 return false;
57 content::RenderProcessHost* rph =
58 host->host_contents()->GetMainFrame()->GetProcess();
59 return rph && rph->IsInitializedAndNotDead();
60 }
61
OnExtensionFrameRegistered(const std::string & extension_id,content::RenderFrameHost * rfh)62 void BackgroundPageWatcher::OnExtensionFrameRegistered(
63 const std::string& extension_id,
64 content::RenderFrameHost* rfh) {
65 if (is_waiting_for_open_ && extension_id == extension_id_ &&
66 IsBackgroundPageOpen())
67 std::move(quit_run_loop_).Run();
68 }
69
OnExtensionFrameUnregistered(const std::string & extension_id,content::RenderFrameHost * rfh)70 void BackgroundPageWatcher::OnExtensionFrameUnregistered(
71 const std::string& extension_id,
72 content::RenderFrameHost* rfh) {
73 if (is_waiting_for_close_ && extension_id == extension_id_ &&
74 !IsBackgroundPageOpen())
75 std::move(quit_run_loop_).Run();
76 }
77
78 } // namespace extensions
79