Don't preload rarely seen large images
[chromium-blink-merge.git] / components / html_viewer / frame_tree_manager.cc
blob98d8947e2f70fc5d6a8bdc965b98825f84dbd501
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/html_viewer/frame_tree_manager.h"
7 #include <algorithm>
9 #include "base/command_line.h"
10 #include "base/logging.h"
11 #include "components/html_viewer/blink_url_request_type_converters.h"
12 #include "components/html_viewer/frame.h"
13 #include "components/html_viewer/frame_tree_manager_delegate.h"
14 #include "components/html_viewer/global_state.h"
15 #include "components/view_manager/public/cpp/view_manager.h"
16 #include "mojo/application/public/cpp/application_connection.h"
17 #include "mojo/application/public/cpp/application_impl.h"
18 #include "third_party/WebKit/public/web/WebLocalFrame.h"
19 #include "third_party/WebKit/public/web/WebRemoteFrame.h"
20 #include "third_party/WebKit/public/web/WebTreeScopeType.h"
21 #include "third_party/WebKit/public/web/WebView.h"
22 #include "ui/gfx/geometry/dip_util.h"
23 #include "ui/gfx/geometry/size.h"
25 namespace html_viewer {
26 namespace {
28 mojo::Target WebNavigationPolicyToNavigationTarget(
29 blink::WebNavigationPolicy policy) {
30 switch (policy) {
31 case blink::WebNavigationPolicyCurrentTab:
32 return mojo::TARGET_SOURCE_NODE;
33 case blink::WebNavigationPolicyNewBackgroundTab:
34 case blink::WebNavigationPolicyNewForegroundTab:
35 case blink::WebNavigationPolicyNewWindow:
36 case blink::WebNavigationPolicyNewPopup:
37 return mojo::TARGET_NEW_NODE;
38 default:
39 return mojo::TARGET_DEFAULT;
43 bool CanNavigateLocally(blink::WebFrame* frame,
44 const blink::WebURLRequest& request) {
45 // If we have extraData() it means we already have the url response
46 // (presumably because we are being called via Navigate()). In that case we
47 // can go ahead and navigate locally.
48 if (request.extraData())
49 return true;
51 // Otherwise we don't know if we're the right app to handle this request. Ask
52 // host to do the navigation for us.
53 return false;
56 // Creates a Frame per FrameData element in |frame_data|.
57 Frame* BuildFrameTree(FrameTreeManager* frame_tree_manager,
58 const mojo::Array<mandoline::FrameDataPtr>& frame_data) {
59 std::vector<Frame*> parents;
60 Frame* root = nullptr;
61 Frame* last_frame = nullptr;
62 for (size_t i = 0; i < frame_data.size(); ++i) {
63 if (last_frame && frame_data[i]->parent_id == last_frame->id()) {
64 parents.push_back(last_frame);
65 } else if (!parents.empty()) {
66 while (parents.back()->id() != frame_data[i]->parent_id)
67 parents.pop_back();
69 Frame::CreateParams params(frame_tree_manager,
70 !parents.empty() ? parents.back() : nullptr,
71 frame_data[i]->frame_id);
72 Frame* frame = new Frame(params);
73 if (!last_frame)
74 root = frame;
75 else
76 DCHECK(frame->parent());
77 last_frame = frame;
79 return root;
82 } // namespace
84 FrameTreeManager::FrameTreeManager(GlobalState* global_state,
85 mojo::ApplicationImpl* app,
86 mojo::ApplicationConnection* app_connection,
87 uint32_t local_frame_id,
88 mandoline::FrameTreeServerPtr server)
89 : global_state_(global_state),
90 app_(app),
91 delegate_(nullptr),
92 local_frame_id_(local_frame_id),
93 server_(server.Pass()),
94 navigator_host_(app_connection->GetServiceProvider()),
95 root_(nullptr) {
98 FrameTreeManager::~FrameTreeManager() {
99 if (root_)
100 root_->Close(); // This should call back to OnFrameDestroyed().
101 DCHECK(!root_);
104 void FrameTreeManager::Init(mojo::View* local_view,
105 mojo::Array<mandoline::FrameDataPtr> frame_data) {
106 root_ = BuildFrameTree(this, frame_data);
107 CHECK(root_);
108 Frame* local_frame = root_->FindFrame(local_frame_id_);
109 CHECK(local_frame);
110 local_frame->SetView(local_view);
111 InitFrames(local_view, root_);
112 local_frame->UpdateFocus();
115 Frame* FrameTreeManager::GetLocalFrame() {
116 return root_->FindFrame(local_frame_id_);
119 blink::WebLocalFrame* FrameTreeManager::GetLocalWebFrame() {
120 return GetLocalFrame()->web_frame()->toWebLocalFrame();
123 blink::WebView* FrameTreeManager::GetWebView() {
124 return root_->web_view();
127 void FrameTreeManager::InitFrames(mojo::View* local_view, Frame* frame) {
128 frame->Init(local_view);
130 for (Frame* child_frame : frame->children())
131 InitFrames(local_view, child_frame);
134 blink::WebNavigationPolicy FrameTreeManager::DecidePolicyForNavigation(
135 Frame* frame,
136 const blink::WebFrameClient::NavigationPolicyInfo& info) {
137 if (info.frame == frame->web_frame() && frame == root_ && delegate_ &&
138 delegate_->ShouldNavigateLocallyInMainFrame()) {
139 return info.defaultPolicy;
142 if (CanNavigateLocally(info.frame, info.urlRequest))
143 return info.defaultPolicy;
145 // TODO(sky): this is wrong for subframes. In fact NavigatorHost should likely
146 // be merged with Frame.
147 if (navigator_host_.get()) {
148 mojo::URLRequestPtr url_request = mojo::URLRequest::From(info.urlRequest);
149 navigator_host_->RequestNavigate(
150 WebNavigationPolicyToNavigationTarget(info.defaultPolicy),
151 url_request.Pass());
154 return blink::WebNavigationPolicyIgnore;
157 void FrameTreeManager::OnFrameDidFinishLoad(Frame* frame) {
158 if (delegate_)
159 delegate_->OnFrameDidFinishLoad(frame);
162 void FrameTreeManager::OnFrameDidNavigateLocally(Frame* frame,
163 const std::string& url) {
164 if (navigator_host_.get() && frame == root_)
165 navigator_host_->DidNavigateLocally(url);
168 void FrameTreeManager::OnFrameDestroyed(Frame* frame) {
169 if (frame == root_) {
170 root_ = nullptr;
171 // Shortly after this HTMLDocumentOOPIF should get ViewManagerDestroyed()
172 // and delete us.
176 void FrameTreeManager::OnConnect(
177 mandoline::FrameTreeServerPtr server,
178 mojo::Array<mandoline::FrameDataPtr> frame_data) {
179 // OnConnection() is only sent once, and has been received (by
180 // DocumentResourceWaiter) by the time we get here.
181 NOTREACHED();
184 void FrameTreeManager::OnFrameAdded(mandoline::FrameDataPtr frame_data) {
185 NOTIMPLEMENTED();
188 void FrameTreeManager::OnFrameRemoved(uint32_t frame_id) {
189 NOTIMPLEMENTED();
192 } // namespace mojo