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/view_manager/public/cpp/scoped_view_ptr.h"
10 #include "components/view_manager/public/cpp/view.h"
11 #include "components/view_manager/public/cpp/view_tree_connection.h"
12 #include "components/web_view/frame.h"
13 #include "components/web_view/frame_connection.h"
14 #include "components/web_view/frame_devtools_agent.h"
15 #include "components/web_view/frame_tree.h"
16 #include "components/web_view/pending_web_view_load.h"
17 #include "mojo/application/public/cpp/application_impl.h"
18 #include "mojo/converters/geometry/geometry_type_converters.h"
24 bool EnableRemoteDebugging() {
25 return base::CommandLine::ForCurrentProcess()->HasSwitch(
26 devtools_service::kRemoteDebuggingPort
);
31 ////////////////////////////////////////////////////////////////////////////////
32 // WebViewImpl, public:
34 WebViewImpl::WebViewImpl(mojo::ApplicationImpl
* app
,
35 mojom::WebViewClientPtr client
,
36 mojo::InterfaceRequest
<mojom::WebView
> request
)
38 client_(client
.Pass()),
39 binding_(this, request
.Pass()),
42 if (EnableRemoteDebugging())
43 devtools_agent_
.reset(new FrameDevToolsAgent(app_
, this));
46 WebViewImpl::~WebViewImpl() {
48 content_
->RemoveObserver(this);
50 root_
->RemoveObserver(this);
51 mojo::ScopedViewPtr::DeleteViewOrViewManager(root_
);
55 void WebViewImpl::OnLoad() {
56 scoped_ptr
<PendingWebViewLoad
> pending_load(pending_load_
.Pass());
57 scoped_ptr
<FrameConnection
> frame_connection(
58 pending_load
->frame_connection());
59 mojo::ViewTreeClientPtr view_tree_client
=
60 frame_connection
->GetViewTreeClient();
62 Frame::ClientPropertyMap client_properties
;
63 if (devtools_agent_
) {
64 devtools_service::DevToolsAgentPtr forward_agent
;
65 frame_connection
->application_connection()->ConnectToService(
67 devtools_agent_
->AttachFrame(forward_agent
.Pass(), &client_properties
);
70 FrameTreeClient
* frame_tree_client
= frame_connection
->frame_tree_client();
71 const uint32_t content_handler_id
= frame_connection
->GetContentHandlerID();
72 frame_tree_
.reset(new FrameTree(content_handler_id
, content_
, this,
73 frame_tree_client
, frame_connection
.Pass(),
75 content_
->Embed(view_tree_client
.Pass());
78 ////////////////////////////////////////////////////////////////////////////////
79 // WebViewImpl, WebView implementation:
81 void WebViewImpl::LoadRequest(mojo::URLRequestPtr request
) {
82 pending_load_
.reset(new PendingWebViewLoad(this));
83 pending_load_
->Init(request
.Pass());
86 void WebViewImpl::GetViewTreeClient(
87 mojo::InterfaceRequest
<mojo::ViewTreeClient
> view_tree_client
) {
88 mojo::ViewTreeConnection::Create(this, view_tree_client
.Pass());
91 ////////////////////////////////////////////////////////////////////////////////
92 // WebViewImpl, mojo::ViewTreeDelegate implementation:
94 void WebViewImpl::OnEmbed(mojo::View
* root
) {
95 // We must have been granted embed root priviledges, otherwise we can't
96 // Embed() in any descendants.
97 DCHECK(root
->connection()->IsEmbedRoot());
98 root
->AddObserver(this);
100 content_
= root
->connection()->CreateView();
101 content_
->SetBounds(*mojo::Rect::From(gfx::Rect(0, 0, root
->bounds().width
,
102 root
->bounds().height
)));
103 root
->AddChild(content_
);
104 content_
->SetVisible(true);
105 content_
->AddObserver(this);
107 if (pending_load_
&& pending_load_
->is_content_handler_id_valid())
111 void WebViewImpl::OnConnectionLost(mojo::ViewTreeConnection
* connection
) {
115 ////////////////////////////////////////////////////////////////////////////////
116 // WebViewImpl, mojo::ViewObserver implementation:
118 void WebViewImpl::OnViewBoundsChanged(mojo::View
* view
,
119 const mojo::Rect
& old_bounds
,
120 const mojo::Rect
& new_bounds
) {
121 if (view
!= content_
) {
123 rect
.width
= new_bounds
.width
;
124 rect
.height
= new_bounds
.height
;
125 content_
->SetBounds(rect
);
129 void WebViewImpl::OnViewDestroyed(mojo::View
* view
) {
130 // |FrameTree| cannot outlive the content view.
131 if (view
== content_
) {
137 ////////////////////////////////////////////////////////////////////////////////
138 // WebViewImpl, FrameTreeDelegate implementation:
140 bool WebViewImpl::CanPostMessageEventToFrame(const Frame
* source
,
142 HTMLMessageEvent
* event
) {
146 void WebViewImpl::LoadingStateChanged(bool loading
) {
147 client_
->LoadingStateChanged(loading
);
150 void WebViewImpl::ProgressChanged(double progress
) {
151 client_
->ProgressChanged(progress
);
154 void WebViewImpl::TitleChanged(const mojo::String
& title
) {
155 client_
->TitleChanged(title
);
158 void WebViewImpl::NavigateTopLevel(Frame
* source
, mojo::URLRequestPtr request
) {
159 client_
->TopLevelNavigate(request
.Pass());
162 void WebViewImpl::CanNavigateFrame(Frame
* target
,
163 mojo::URLRequestPtr request
,
164 const CanNavigateFrameCallback
& callback
) {
165 FrameConnection::CreateConnectionForCanNavigateFrame(
166 app_
, target
, request
.Pass(), callback
);
169 void WebViewImpl::DidStartNavigation(Frame
* frame
) {}
171 ////////////////////////////////////////////////////////////////////////////////
172 // WebViewImpl, FrameDevToolsAgentDelegate implementation:
174 void WebViewImpl::HandlePageNavigateRequest(const GURL
& url
) {
175 mojo::URLRequestPtr
request(mojo::URLRequest::New());
176 request
->url
= url
.spec();
177 client_
->TopLevelNavigate(request
.Pass());
180 } // namespace web_view