OLD | NEW |
| (Empty) |
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 "components/html_viewer/frame_tree_manager.h" | |
6 | |
7 #include <algorithm> | |
8 | |
9 #include "base/command_line.h" | |
10 #include "base/logging.h" | |
11 #include "components/html_viewer/blink_basic_type_converters.h" | |
12 #include "components/html_viewer/blink_url_request_type_converters.h" | |
13 #include "components/html_viewer/frame.h" | |
14 #include "components/html_viewer/frame_tree_manager_delegate.h" | |
15 #include "components/html_viewer/global_state.h" | |
16 #include "components/view_manager/public/cpp/view_manager.h" | |
17 #include "mojo/application/public/cpp/application_connection.h" | |
18 #include "mojo/application/public/cpp/application_impl.h" | |
19 #include "third_party/WebKit/public/web/WebLocalFrame.h" | |
20 #include "third_party/WebKit/public/web/WebRemoteFrame.h" | |
21 #include "third_party/WebKit/public/web/WebTreeScopeType.h" | |
22 #include "third_party/WebKit/public/web/WebView.h" | |
23 #include "ui/gfx/geometry/dip_util.h" | |
24 #include "ui/gfx/geometry/size.h" | |
25 | |
26 namespace html_viewer { | |
27 namespace { | |
28 | |
29 mojo::Target WebNavigationPolicyToNavigationTarget( | |
30 blink::WebNavigationPolicy policy) { | |
31 switch (policy) { | |
32 case blink::WebNavigationPolicyCurrentTab: | |
33 return mojo::TARGET_SOURCE_NODE; | |
34 case blink::WebNavigationPolicyNewBackgroundTab: | |
35 case blink::WebNavigationPolicyNewForegroundTab: | |
36 case blink::WebNavigationPolicyNewWindow: | |
37 case blink::WebNavigationPolicyNewPopup: | |
38 return mojo::TARGET_NEW_NODE; | |
39 default: | |
40 return mojo::TARGET_DEFAULT; | |
41 } | |
42 } | |
43 | |
44 bool CanNavigateLocally(blink::WebFrame* frame, | |
45 const blink::WebURLRequest& request) { | |
46 // If we have extraData() it means we already have the url response | |
47 // (presumably because we are being called via Navigate()). In that case we | |
48 // can go ahead and navigate locally. | |
49 if (request.extraData()) | |
50 return true; | |
51 | |
52 // Otherwise we don't know if we're the right app to handle this request. Ask | |
53 // host to do the navigation for us. | |
54 return false; | |
55 } | |
56 | |
57 // Creates a Frame per FrameData element in |frame_data|. | |
58 Frame* BuildFrameTree(FrameTreeManager* frame_tree_manager, | |
59 const mojo::Array<mandoline::FrameDataPtr>& frame_data, | |
60 uint32_t local_frame_id, | |
61 mojo::View* local_view) { | |
62 std::vector<Frame*> parents; | |
63 Frame* root = nullptr; | |
64 Frame* last_frame = nullptr; | |
65 for (size_t i = 0; i < frame_data.size(); ++i) { | |
66 if (last_frame && frame_data[i]->parent_id == last_frame->id()) { | |
67 parents.push_back(last_frame); | |
68 } else if (!parents.empty()) { | |
69 while (parents.back()->id() != frame_data[i]->parent_id) | |
70 parents.pop_back(); | |
71 } | |
72 Frame::CreateParams params(frame_tree_manager, | |
73 !parents.empty() ? parents.back() : nullptr, | |
74 frame_data[i]->frame_id); | |
75 Frame* frame = new Frame(params); | |
76 if (!last_frame) | |
77 root = frame; | |
78 else | |
79 DCHECK(frame->parent()); | |
80 last_frame = frame; | |
81 | |
82 frame->Init(local_view, frame_data[i]->name.To<blink::WebString>(), | |
83 frame_data[i]->origin.To<blink::WebString>()); | |
84 } | |
85 return root; | |
86 } | |
87 | |
88 } // namespace | |
89 | |
90 FrameTreeManager::FrameTreeManager(GlobalState* global_state, | |
91 mojo::ApplicationImpl* app, | |
92 mojo::ApplicationConnection* app_connection, | |
93 uint32_t local_frame_id, | |
94 mandoline::FrameTreeServerPtr server) | |
95 : global_state_(global_state), | |
96 app_(app), | |
97 delegate_(nullptr), | |
98 local_frame_id_(local_frame_id), | |
99 server_(server.Pass()), | |
100 navigator_host_(app_connection->GetServiceProvider()), | |
101 root_(nullptr) { | |
102 } | |
103 | |
104 FrameTreeManager::~FrameTreeManager() { | |
105 if (root_) | |
106 root_->Close(); // This should call back to OnFrameDestroyed(). | |
107 DCHECK(!root_); | |
108 } | |
109 | |
110 void FrameTreeManager::Init(mojo::View* local_view, | |
111 mojo::Array<mandoline::FrameDataPtr> frame_data) { | |
112 root_ = BuildFrameTree(this, frame_data, local_frame_id_, local_view); | |
113 Frame* local_frame = root_->FindFrame(local_frame_id_); | |
114 CHECK(local_frame); | |
115 local_frame->UpdateFocus(); | |
116 } | |
117 | |
118 Frame* FrameTreeManager::GetLocalFrame() { | |
119 return root_->FindFrame(local_frame_id_); | |
120 } | |
121 | |
122 blink::WebLocalFrame* FrameTreeManager::GetLocalWebFrame() { | |
123 return GetLocalFrame()->web_frame()->toWebLocalFrame(); | |
124 } | |
125 | |
126 blink::WebView* FrameTreeManager::GetWebView() { | |
127 return root_->web_view(); | |
128 } | |
129 | |
130 blink::WebNavigationPolicy FrameTreeManager::DecidePolicyForNavigation( | |
131 Frame* frame, | |
132 const blink::WebFrameClient::NavigationPolicyInfo& info) { | |
133 if (info.frame == frame->web_frame() && frame == root_ && delegate_ && | |
134 delegate_->ShouldNavigateLocallyInMainFrame()) { | |
135 return info.defaultPolicy; | |
136 } | |
137 | |
138 if (CanNavigateLocally(info.frame, info.urlRequest)) | |
139 return info.defaultPolicy; | |
140 | |
141 // TODO(sky): this is wrong for subframes. In fact NavigatorHost should likely | |
142 // be merged with Frame. | |
143 if (navigator_host_.get()) { | |
144 mojo::URLRequestPtr url_request = mojo::URLRequest::From(info.urlRequest); | |
145 navigator_host_->RequestNavigate( | |
146 WebNavigationPolicyToNavigationTarget(info.defaultPolicy), | |
147 url_request.Pass()); | |
148 } | |
149 | |
150 return blink::WebNavigationPolicyIgnore; | |
151 } | |
152 | |
153 void FrameTreeManager::OnFrameDidFinishLoad(Frame* frame) { | |
154 if (delegate_) | |
155 delegate_->OnFrameDidFinishLoad(frame); | |
156 } | |
157 | |
158 void FrameTreeManager::OnFrameDidNavigateLocally(Frame* frame, | |
159 const std::string& url) { | |
160 if (navigator_host_.get() && frame == root_) | |
161 navigator_host_->DidNavigateLocally(url); | |
162 } | |
163 | |
164 void FrameTreeManager::OnFrameDestroyed(Frame* frame) { | |
165 if (frame == root_) { | |
166 root_ = nullptr; | |
167 // Shortly after this HTMLDocumentOOPIF should get ViewManagerDestroyed() | |
168 // and delete us. | |
169 } | |
170 } | |
171 | |
172 void FrameTreeManager::OnFrameDidChangeName(Frame* frame, | |
173 const blink::WebString& name) { | |
174 if (frame != GetLocalFrame()) | |
175 return; | |
176 | |
177 mojo::String mojo_name; | |
178 if (!name.isNull()) | |
179 mojo_name = name.utf8(); | |
180 server_->SetFrameName(mojo_name); | |
181 } | |
182 | |
183 void FrameTreeManager::OnConnect( | |
184 mandoline::FrameTreeServerPtr server, | |
185 mojo::Array<mandoline::FrameDataPtr> frame_data) { | |
186 // OnConnection() is only sent once, and has been received (by | |
187 // DocumentResourceWaiter) by the time we get here. | |
188 NOTREACHED(); | |
189 } | |
190 | |
191 void FrameTreeManager::LoadingStarted() { | |
192 server_->LoadingStarted(); | |
193 } | |
194 | |
195 void FrameTreeManager::LoadingStopped() { | |
196 server_->LoadingStopped(); | |
197 } | |
198 | |
199 void FrameTreeManager::ProgressChanged(double progress) { | |
200 server_->ProgressChanged(progress); | |
201 } | |
202 | |
203 void FrameTreeManager::OnFrameAdded(mandoline::FrameDataPtr frame_data) { | |
204 NOTIMPLEMENTED(); | |
205 } | |
206 | |
207 void FrameTreeManager::OnFrameRemoved(uint32_t frame_id) { | |
208 NOTIMPLEMENTED(); | |
209 } | |
210 | |
211 void FrameTreeManager::OnFrameNameChanged(uint32_t frame_id, | |
212 const mojo::String& name) { | |
213 Frame* frame = root_->FindFrame(frame_id); | |
214 if (frame) | |
215 frame->SetRemoteFrameName(name); | |
216 } | |
217 | |
218 } // namespace mojo | |
OLD | NEW |