OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "headless/lib/browser/headless_browser_impl.h" | 5 #include "headless/lib/browser/headless_browser_impl.h" |
6 | 6 |
7 #include "base/memory/ptr_util.h" | 7 #include "base/memory/ptr_util.h" |
8 #include "base/thread_task_runner_handle.h" | 8 #include "base/thread_task_runner_handle.h" |
9 #include "content/public/app/content_main.h" | 9 #include "content/public/app/content_main.h" |
10 #include "content/public/browser/browser_thread.h" | 10 #include "content/public/browser/browser_thread.h" |
11 #include "content/public/browser/web_contents.h" | 11 #include "content/public/browser/web_contents.h" |
12 #include "headless/lib/browser/headless_browser_context.h" | 12 #include "headless/lib/browser/headless_browser_context.h" |
13 #include "headless/lib/browser/headless_browser_main_parts.h" | 13 #include "headless/lib/browser/headless_browser_main_parts.h" |
14 #include "headless/lib/browser/headless_web_contents_impl.h" | 14 #include "headless/lib/browser/headless_web_contents_impl.h" |
| 15 #include "headless/lib/browser/headless_window_tree_client.h" |
15 #include "headless/lib/headless_content_main_delegate.h" | 16 #include "headless/lib/headless_content_main_delegate.h" |
16 #include "ui/aura/env.h" | 17 #include "ui/aura/env.h" |
17 #include "ui/aura/window_tree_host.h" | 18 #include "ui/aura/window_tree_host.h" |
18 #include "ui/gfx/geometry/size.h" | 19 #include "ui/gfx/geometry/size.h" |
19 | 20 |
20 namespace headless { | 21 namespace headless { |
21 | 22 |
22 HeadlessBrowserImpl::HeadlessBrowserImpl( | 23 HeadlessBrowserImpl::HeadlessBrowserImpl( |
23 const base::Callback<void(HeadlessBrowser*)>& on_start_callback, | 24 const base::Callback<void(HeadlessBrowser*)>& on_start_callback, |
24 const HeadlessBrowser::Options& options) | 25 const HeadlessBrowser::Options& options) |
25 : on_start_callback_(on_start_callback), | 26 : on_start_callback_(on_start_callback), |
26 options_(options), | 27 options_(options), |
27 browser_main_parts_(nullptr) { | 28 browser_main_parts_(nullptr) { |
28 DCHECK(!on_start_callback_.is_null()); | 29 DCHECK(!on_start_callback_.is_null()); |
29 } | 30 } |
30 | 31 |
31 HeadlessBrowserImpl::~HeadlessBrowserImpl() {} | 32 HeadlessBrowserImpl::~HeadlessBrowserImpl() {} |
32 | 33 |
33 std::unique_ptr<HeadlessWebContents> HeadlessBrowserImpl::CreateWebContents( | 34 HeadlessWebContents* HeadlessBrowserImpl::CreateWebContents( |
34 const GURL& initial_url, | 35 const GURL& initial_url, |
35 const gfx::Size& size) { | 36 const gfx::Size& size) { |
36 DCHECK(BrowserMainThread()->BelongsToCurrentThread()); | 37 DCHECK(BrowserMainThread()->BelongsToCurrentThread()); |
37 std::unique_ptr<HeadlessWebContentsImpl> web_contents = | 38 std::unique_ptr<HeadlessWebContentsImpl> headless_web_contents = |
38 base::WrapUnique(new HeadlessWebContentsImpl( | 39 HeadlessWebContentsImpl::Create(browser_context(), |
39 browser_context(), window_tree_host_->window(), size)); | 40 window_tree_host_->window(), size, this); |
40 // We require the user to pass in an initial URL to ensure that the renderer | 41 |
41 // gets initialized and eventually becomes ready to be inspected. See | 42 if (!headless_web_contents->OpenURL(initial_url)) |
42 // HeadlessWebContents::Observer::WebContentsReady. | |
43 if (!web_contents->OpenURL(initial_url)) | |
44 return nullptr; | 43 return nullptr; |
45 return std::move(web_contents); | 44 |
| 45 return RegisterWebContents(std::move(headless_web_contents)); |
46 } | 46 } |
47 | 47 |
48 scoped_refptr<base::SingleThreadTaskRunner> | 48 scoped_refptr<base::SingleThreadTaskRunner> |
49 HeadlessBrowserImpl::BrowserMainThread() const { | 49 HeadlessBrowserImpl::BrowserMainThread() const { |
50 return content::BrowserThread::GetMessageLoopProxyForThread( | 50 return content::BrowserThread::GetMessageLoopProxyForThread( |
51 content::BrowserThread::UI); | 51 content::BrowserThread::UI); |
52 } | 52 } |
53 | 53 |
54 void HeadlessBrowserImpl::Shutdown() { | 54 void HeadlessBrowserImpl::Shutdown() { |
55 DCHECK(BrowserMainThread()->BelongsToCurrentThread()); | 55 DCHECK(BrowserMainThread()->BelongsToCurrentThread()); |
56 BrowserMainThread()->PostTask(FROM_HERE, | 56 BrowserMainThread()->PostTask(FROM_HERE, |
57 base::MessageLoop::QuitWhenIdleClosure()); | 57 base::MessageLoop::QuitWhenIdleClosure()); |
58 } | 58 } |
59 | 59 |
| 60 std::vector<HeadlessWebContents*> HeadlessBrowserImpl::GetAllWebContents() { |
| 61 std::vector<HeadlessWebContents*> result; |
| 62 result.reserve(web_contents_.size()); |
| 63 |
| 64 for (const auto& web_contents_pair : web_contents_) { |
| 65 result.push_back(web_contents_pair.first); |
| 66 } |
| 67 |
| 68 return result; |
| 69 } |
| 70 |
60 HeadlessBrowserContext* HeadlessBrowserImpl::browser_context() const { | 71 HeadlessBrowserContext* HeadlessBrowserImpl::browser_context() const { |
61 DCHECK(BrowserMainThread()->BelongsToCurrentThread()); | 72 DCHECK(BrowserMainThread()->BelongsToCurrentThread()); |
62 DCHECK(browser_main_parts()); | 73 DCHECK(browser_main_parts()); |
63 return browser_main_parts()->browser_context(); | 74 return browser_main_parts()->browser_context(); |
64 } | 75 } |
65 | 76 |
66 HeadlessBrowserMainParts* HeadlessBrowserImpl::browser_main_parts() const { | 77 HeadlessBrowserMainParts* HeadlessBrowserImpl::browser_main_parts() const { |
67 DCHECK(BrowserMainThread()->BelongsToCurrentThread()); | 78 DCHECK(BrowserMainThread()->BelongsToCurrentThread()); |
68 return browser_main_parts_; | 79 return browser_main_parts_; |
69 } | 80 } |
70 | 81 |
71 void HeadlessBrowserImpl::set_browser_main_parts( | 82 void HeadlessBrowserImpl::set_browser_main_parts( |
72 HeadlessBrowserMainParts* browser_main_parts) { | 83 HeadlessBrowserMainParts* browser_main_parts) { |
73 DCHECK(!browser_main_parts_); | 84 DCHECK(!browser_main_parts_); |
74 browser_main_parts_ = browser_main_parts; | 85 browser_main_parts_ = browser_main_parts; |
75 } | 86 } |
76 | 87 |
77 void HeadlessBrowserImpl::RunOnStartCallback() { | 88 void HeadlessBrowserImpl::RunOnStartCallback() { |
78 DCHECK(aura::Env::GetInstance()); | 89 DCHECK(aura::Env::GetInstance()); |
79 window_tree_host_.reset(aura::WindowTreeHost::Create(gfx::Rect())); | 90 window_tree_host_.reset(aura::WindowTreeHost::Create(gfx::Rect())); |
80 window_tree_host_->InitHost(); | 91 window_tree_host_->InitHost(); |
81 | 92 |
| 93 window_tree_client_.reset( |
| 94 new HeadlessWindowTreeClient(window_tree_host_->window())); |
| 95 |
82 on_start_callback_.Run(this); | 96 on_start_callback_.Run(this); |
83 on_start_callback_ = base::Callback<void(HeadlessBrowser*)>(); | 97 on_start_callback_ = base::Callback<void(HeadlessBrowser*)>(); |
84 } | 98 } |
85 | 99 |
| 100 HeadlessWebContentsImpl* HeadlessBrowserImpl::RegisterWebContents( |
| 101 std::unique_ptr<HeadlessWebContentsImpl> web_contents) { |
| 102 HeadlessWebContentsImpl* unowned_web_contents = web_contents.get(); |
| 103 web_contents_[unowned_web_contents] = std::move(web_contents); |
| 104 return unowned_web_contents; |
| 105 } |
| 106 |
| 107 void HeadlessBrowserImpl::DestroyWebContents( |
| 108 HeadlessWebContentsImpl* web_contents) { |
| 109 auto it = web_contents_.find(web_contents); |
| 110 DCHECK(it != web_contents_.end()); |
| 111 web_contents_.erase(it); |
| 112 } |
| 113 |
86 void HeadlessBrowserImpl::SetOptionsForTesting( | 114 void HeadlessBrowserImpl::SetOptionsForTesting( |
87 const HeadlessBrowser::Options& options) { | 115 const HeadlessBrowser::Options& options) { |
88 options_ = options; | 116 options_ = options; |
89 browser_context()->SetOptionsForTesting(options); | 117 browser_context()->SetOptionsForTesting(options); |
90 } | 118 } |
91 | 119 |
92 int HeadlessBrowserMain( | 120 int HeadlessBrowserMain( |
93 const HeadlessBrowser::Options& options, | 121 const HeadlessBrowser::Options& options, |
94 const base::Callback<void(HeadlessBrowser*)>& on_browser_start_callback) { | 122 const base::Callback<void(HeadlessBrowser*)>& on_browser_start_callback) { |
95 std::unique_ptr<HeadlessBrowserImpl> browser( | 123 std::unique_ptr<HeadlessBrowserImpl> browser( |
96 new HeadlessBrowserImpl(on_browser_start_callback, options)); | 124 new HeadlessBrowserImpl(on_browser_start_callback, options)); |
97 | 125 |
98 // TODO(skyostil): Implement custom message pumps. | 126 // TODO(skyostil): Implement custom message pumps. |
99 DCHECK(!options.message_pump); | 127 DCHECK(!options.message_pump); |
100 | 128 |
101 headless::HeadlessContentMainDelegate delegate(std::move(browser)); | 129 headless::HeadlessContentMainDelegate delegate(std::move(browser)); |
102 content::ContentMainParams params(&delegate); | 130 content::ContentMainParams params(&delegate); |
103 params.argc = options.argc; | 131 params.argc = options.argc; |
104 params.argv = options.argv; | 132 params.argv = options.argv; |
105 return content::ContentMain(params); | 133 return content::ContentMain(params); |
106 } | 134 } |
107 | 135 |
108 } // namespace headless | 136 } // namespace headless |
OLD | NEW |