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.
5 #include "components/web_view/web_view_impl.h"
7 #include "base/command_line.h"
8 #include "components/devtools_service/public/cpp/switches.h"
9 #include "components/mus/public/cpp/scoped_view_ptr.h"
10 #include "components/mus/public/cpp/view.h"
11 #include "components/mus/public/cpp/view_tree_connection.h"
12 #include "components/web_view/client_initiated_frame_connection.h"
13 #include "components/web_view/frame.h"
14 #include "components/web_view/frame_connection.h"
15 #include "components/web_view/frame_devtools_agent.h"
16 #include "components/web_view/frame_tree.h"
17 #include "components/web_view/navigation_entry.h"
18 #include "components/web_view/pending_web_view_load.h"
19 #include "components/web_view/url_request_cloneable.h"
20 #include "mojo/application/public/cpp/application_impl.h"
21 #include "mojo/converters/geometry/geometry_type_converters.h"
27 bool EnableRemoteDebugging() {
28 return base::CommandLine::ForCurrentProcess()->HasSwitch(
29 devtools_service::kRemoteDebuggingPort
);
34 using web_view::mojom::ButtonState
;
36 ////////////////////////////////////////////////////////////////////////////////
37 // WebViewImpl, public:
39 WebViewImpl::WebViewImpl(mojo::ApplicationImpl
* app
,
40 mojom::WebViewClientPtr client
,
41 mojo::InterfaceRequest
<mojom::WebView
> request
)
43 client_(client
.Pass()),
44 binding_(this, request
.Pass()),
47 navigation_controller_(this) {
48 if (EnableRemoteDebugging())
49 devtools_agent_
.reset(new FrameDevToolsAgent(app_
, this));
53 WebViewImpl::~WebViewImpl() {
55 content_
->RemoveObserver(this);
57 root_
->RemoveObserver(this);
58 mus::ScopedViewPtr::DeleteViewOrViewManager(root_
);
62 void WebViewImpl::OnLoad() {
63 scoped_ptr
<PendingWebViewLoad
> pending_load(pending_load_
.Pass());
64 scoped_ptr
<FrameConnection
> frame_connection(
65 pending_load
->frame_connection());
66 mojo::ViewTreeClientPtr view_tree_client
=
67 frame_connection
->GetViewTreeClient();
69 Frame::ClientPropertyMap client_properties
;
70 if (devtools_agent_
) {
71 devtools_service::DevToolsAgentPtr forward_agent
;
72 frame_connection
->application_connection()->ConnectToService(
74 devtools_agent_
->AttachFrame(forward_agent
.Pass(), &client_properties
);
77 mojom::FrameClient
* frame_client
= frame_connection
->frame_client();
78 const uint32_t content_handler_id
= frame_connection
->GetContentHandlerID();
79 frame_tree_
.reset(new FrameTree(content_handler_id
, content_
,
80 view_tree_client
.Pass(), this, frame_client
,
81 frame_connection
.Pass(), client_properties
));
84 ////////////////////////////////////////////////////////////////////////////////
85 // WebViewImpl, WebView implementation:
87 void WebViewImpl::LoadRequest(mojo::URLRequestPtr request
) {
88 navigation_controller_
.LoadURL(request
.Pass());
91 void WebViewImpl::GetViewTreeClient(
92 mojo::InterfaceRequest
<mojo::ViewTreeClient
> view_tree_client
) {
93 mus::ViewTreeConnection::Create(this, view_tree_client
.Pass());
96 void WebViewImpl::GoBack() {
97 if (!navigation_controller_
.CanGoBack())
99 navigation_controller_
.GoBack();
102 void WebViewImpl::GoForward() {
103 if (!navigation_controller_
.CanGoForward())
105 navigation_controller_
.GoForward();
108 ////////////////////////////////////////////////////////////////////////////////
109 // WebViewImpl, mus::ViewTreeDelegate implementation:
111 void WebViewImpl::OnEmbed(mus::View
* root
) {
112 // We must have been granted embed root priviledges, otherwise we can't
113 // Embed() in any descendants.
114 DCHECK(root
->connection()->IsEmbedRoot());
115 root
->AddObserver(this);
117 content_
= root
->connection()->CreateView();
118 content_
->SetBounds(*mojo::Rect::From(gfx::Rect(0, 0, root
->bounds().width
,
119 root
->bounds().height
)));
120 root
->AddChild(content_
);
121 content_
->SetVisible(true);
122 content_
->AddObserver(this);
124 if (pending_load_
&& pending_load_
->is_content_handler_id_valid())
128 void WebViewImpl::OnConnectionLost(mus::ViewTreeConnection
* connection
) {
132 ////////////////////////////////////////////////////////////////////////////////
133 // WebViewImpl, mus::ViewObserver implementation:
135 void WebViewImpl::OnViewBoundsChanged(mus::View
* view
,
136 const mojo::Rect
& old_bounds
,
137 const mojo::Rect
& new_bounds
) {
138 if (view
!= content_
) {
140 rect
.width
= new_bounds
.width
;
141 rect
.height
= new_bounds
.height
;
142 content_
->SetBounds(rect
);
146 void WebViewImpl::OnViewDestroyed(mus::View
* view
) {
147 // |FrameTree| cannot outlive the content view.
148 if (view
== content_
) {
154 ////////////////////////////////////////////////////////////////////////////////
155 // WebViewImpl, FrameTreeDelegate implementation:
157 scoped_ptr
<FrameUserData
> WebViewImpl::CreateUserDataForNewFrame(
158 mojom::FrameClientPtr frame_client
) {
159 return make_scoped_ptr(
160 new ClientInitiatedFrameConnection(frame_client
.Pass()));
163 bool WebViewImpl::CanPostMessageEventToFrame(const Frame
* source
,
165 mojom::HTMLMessageEvent
* event
) {
169 void WebViewImpl::LoadingStateChanged(bool loading
, double progress
) {
170 client_
->LoadingStateChanged(loading
, progress
);
173 void WebViewImpl::TitleChanged(const mojo::String
& title
) {
174 client_
->TitleChanged(title
);
177 void WebViewImpl::NavigateTopLevel(Frame
* source
, mojo::URLRequestPtr request
) {
178 client_
->TopLevelNavigate(request
.Pass());
181 void WebViewImpl::CanNavigateFrame(Frame
* target
,
182 mojo::URLRequestPtr request
,
183 const CanNavigateFrameCallback
& callback
) {
184 FrameConnection::CreateConnectionForCanNavigateFrame(
185 app_
, target
, request
.Pass(), callback
);
188 void WebViewImpl::DidStartNavigation(Frame
* frame
) {}
190 void WebViewImpl::DidCommitProvisionalLoad(Frame
* frame
) {
191 navigation_controller_
.FrameDidCommitProvisionalLoad(frame
);
194 ////////////////////////////////////////////////////////////////////////////////
195 // WebViewImpl, FrameDevToolsAgentDelegate implementation:
197 void WebViewImpl::HandlePageNavigateRequest(const GURL
& url
) {
198 mojo::URLRequestPtr
request(mojo::URLRequest::New());
199 request
->url
= url
.spec();
200 client_
->TopLevelNavigate(request
.Pass());
203 ////////////////////////////////////////////////////////////////////////////////
204 // WebViewImpl, NavigationControllerDelegate implementation:
206 void WebViewImpl::OnNavigate(mojo::URLRequestPtr request
) {
207 pending_load_
.reset(new PendingWebViewLoad(this));
208 pending_load_
->Init(request
.Pass());
211 void WebViewImpl::OnDidNavigate() {
212 client_
->BackForwardChanged(navigation_controller_
.CanGoBack()
213 ? ButtonState::BUTTON_STATE_ENABLED
214 : ButtonState::BUTTON_STATE_DISABLED
,
215 navigation_controller_
.CanGoForward()
216 ? ButtonState::BUTTON_STATE_ENABLED
217 : ButtonState::BUTTON_STATE_DISABLED
);
220 } // namespace web_view