| 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 |