Index: components/html_viewer/html_frame_tree_manager.cc |
diff --git a/components/html_viewer/html_frame_tree_manager.cc b/components/html_viewer/html_frame_tree_manager.cc |
deleted file mode 100644 |
index 1323b5ff3dfbea226a8daf58762649dcf48fcff9..0000000000000000000000000000000000000000 |
--- a/components/html_viewer/html_frame_tree_manager.cc |
+++ /dev/null |
@@ -1,411 +0,0 @@ |
-// Copyright 2015 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "components/html_viewer/html_frame_tree_manager.h" |
- |
-#include <stddef.h> |
-#include <algorithm> |
-#include <utility> |
- |
-#include "base/command_line.h" |
-#include "base/logging.h" |
-#include "base/macros.h" |
-#include "components/html_viewer/blink_basic_type_converters.h" |
-#include "components/html_viewer/blink_url_request_type_converters.h" |
-#include "components/html_viewer/document_resource_waiter.h" |
-#include "components/html_viewer/global_state.h" |
-#include "components/html_viewer/html_factory.h" |
-#include "components/html_viewer/html_frame.h" |
-#include "components/html_viewer/html_frame_delegate.h" |
-#include "components/html_viewer/html_frame_tree_manager_observer.h" |
-#include "components/mus/public/cpp/window_tree_connection.h" |
-#include "components/web_view/web_view_switches.h" |
-#include "third_party/WebKit/public/web/WebLocalFrame.h" |
-#include "third_party/WebKit/public/web/WebRemoteFrame.h" |
-#include "third_party/WebKit/public/web/WebTreeScopeType.h" |
-#include "third_party/WebKit/public/web/WebView.h" |
-#include "ui/gfx/geometry/dip_util.h" |
-#include "ui/gfx/geometry/size.h" |
- |
-namespace html_viewer { |
-namespace { |
- |
-// Returns the index of the FrameData with the id of |frame_id| in |index|. On |
-// success returns true, otherwise false. |
-bool FindFrameDataIndex( |
- const mojo::Array<web_view::mojom::FrameDataPtr>& frame_data, |
- uint32_t frame_id, |
- size_t* index) { |
- for (size_t i = 0; i < frame_data.size(); ++i) { |
- if (frame_data[i]->frame_id == frame_id) { |
- *index = i; |
- return true; |
- } |
- } |
- return false; |
-} |
- |
-} // namespace |
- |
-// Object that calls OnHTMLFrameTreeManagerChangeIdAdvanced() from the |
-// destructor. |
-class HTMLFrameTreeManager::ChangeIdAdvancedNotifier { |
- public: |
- explicit ChangeIdAdvancedNotifier( |
- base::ObserverList<HTMLFrameTreeManagerObserver>* observers) |
- : observers_(observers) {} |
- ~ChangeIdAdvancedNotifier() { |
- FOR_EACH_OBSERVER(HTMLFrameTreeManagerObserver, *observers_, |
- OnHTMLFrameTreeManagerChangeIdAdvanced()); |
- } |
- |
- private: |
- base::ObserverList<HTMLFrameTreeManagerObserver>* observers_; |
- |
- DISALLOW_COPY_AND_ASSIGN(ChangeIdAdvancedNotifier); |
-}; |
- |
-// static |
-HTMLFrameTreeManager::TreeMap* HTMLFrameTreeManager::instances_ = nullptr; |
- |
-// static |
-HTMLFrame* HTMLFrameTreeManager::CreateFrameAndAttachToTree( |
- GlobalState* global_state, |
- mus::Window* window, |
- scoped_ptr<DocumentResourceWaiter> resource_waiter, |
- HTMLFrameDelegate* delegate) { |
- if (!instances_) |
- instances_ = new TreeMap; |
- |
- mojo::InterfaceRequest<web_view::mojom::FrameClient> frame_client_request; |
- web_view::mojom::FramePtr server_frame; |
- mojo::Array<web_view::mojom::FrameDataPtr> frame_data; |
- uint32_t change_id; |
- uint32_t window_id; |
- web_view::mojom::WindowConnectType window_connect_type; |
- web_view::mojom::FrameClient::OnConnectCallback on_connect_callback; |
- resource_waiter->Release(&frame_client_request, &server_frame, &frame_data, |
- &change_id, &window_id, &window_connect_type, |
- &on_connect_callback); |
- resource_waiter.reset(); |
- |
- on_connect_callback.Run(); |
- |
- HTMLFrameTreeManager* frame_tree = |
- FindFrameTreeWithRoot(frame_data[0]->frame_id); |
- |
- DCHECK(!frame_tree || change_id <= frame_tree->change_id_); |
- |
- DVLOG(2) << "HTMLFrameTreeManager::CreateFrameAndAttachToTree " |
- << " frame_tree=" << frame_tree << " use_existing=" |
- << (window_connect_type == |
- web_view::mojom::WindowConnectType::USE_EXISTING) |
- << " frame_id=" << window_id; |
- if (window_connect_type == web_view::mojom::WindowConnectType::USE_EXISTING && |
- !frame_tree) { |
- DVLOG(1) << "was told to use existing window but do not have frame tree"; |
- return nullptr; |
- } |
- |
- if (!frame_tree) { |
- frame_tree = new HTMLFrameTreeManager(global_state); |
- frame_tree->Init(delegate, window, frame_data, change_id); |
- (*instances_)[frame_data[0]->frame_id] = frame_tree; |
- } else if (window_connect_type == |
- web_view::mojom::WindowConnectType::USE_EXISTING) { |
- HTMLFrame* existing_frame = frame_tree->root_->FindFrame(window_id); |
- if (!existing_frame) { |
- DVLOG(1) << "was told to use existing window but could not find window"; |
- return nullptr; |
- } |
- if (!existing_frame->IsLocal()) { |
- DVLOG(1) << "was told to use existing window, but frame is remote"; |
- return nullptr; |
- } |
- existing_frame->SwapDelegate(delegate); |
- } else { |
- // We're going to share a frame tree. We should know about the frame. |
- CHECK(window->id() != frame_data[0]->frame_id); |
- HTMLFrame* existing_frame = frame_tree->root_->FindFrame(window->id()); |
- if (existing_frame) { |
- CHECK(!existing_frame->IsLocal()); |
- size_t frame_data_index = 0u; |
- CHECK(FindFrameDataIndex(frame_data, window->id(), &frame_data_index)); |
- const web_view::mojom::FrameDataPtr& data = frame_data[frame_data_index]; |
- existing_frame->SwapToLocal(delegate, window, data->client_properties); |
- } else { |
- // If we can't find the frame and the change_id of the incoming |
- // tree is before the change id we've processed, then we removed the |
- // frame and need do nothing. |
- if (change_id < frame_tree->change_id_) |
- return nullptr; |
- |
- // We removed the frame but it hasn't been acked yet. |
- if (frame_tree->pending_remove_ids_.count(window->id())) |
- return nullptr; |
- |
- // We don't know about the frame, but should. Something is wrong. |
- DVLOG(1) << "unable to locate frame to attach to"; |
- return nullptr; |
- } |
- } |
- |
- HTMLFrame* frame = frame_tree->root_->FindFrame(window_id); |
- DCHECK(frame); |
- frame->Bind(std::move(server_frame), std::move(frame_client_request)); |
- return frame; |
-} |
- |
-// static |
-HTMLFrameTreeManager* HTMLFrameTreeManager::FindFrameTreeWithRoot( |
- uint32_t root_frame_id) { |
- return (!base::CommandLine::ForCurrentProcess()->HasSwitch( |
- web_view::switches::kOOPIFAlwaysCreateNewFrameTree) && |
- instances_ && instances_->count(root_frame_id)) |
- ? (*instances_)[root_frame_id] |
- : nullptr; |
-} |
- |
-blink::WebView* HTMLFrameTreeManager::GetWebView() { |
- return root_->web_view(); |
-} |
- |
-void HTMLFrameTreeManager::AddObserver(HTMLFrameTreeManagerObserver* observer) { |
- observers_.AddObserver(observer); |
-} |
- |
-void HTMLFrameTreeManager::RemoveObserver( |
- HTMLFrameTreeManagerObserver* observer) { |
- observers_.RemoveObserver(observer); |
-} |
- |
-void HTMLFrameTreeManager::OnFrameDestroyed(HTMLFrame* frame) { |
- if (!in_process_on_frame_removed_) |
- pending_remove_ids_.insert(frame->id()); |
- |
- if (frame == root_) { |
- // If |root_| is removed before |local_frame_|, we don't have a way to |
- // select a new local frame when |local_frame_| is removed. On the other |
- // hand, it is impossible to remove |root_| after all local frames are gone, |
- // because by that time this object has already been deleted. |
- CHECK_EQ(root_, local_frame_); |
- root_ = nullptr; |
- } |
- |
- if (frame != local_frame_) |
- return; |
- |
- // |local_frame_| is being removed. We need to find out whether we have local |
- // frames that are not descendants of |local_frame_|, and if yes select a new |
- // |local_frame_|. |
- local_frame_ = FindNewLocalFrame(); |
- if (!local_frame_) |
- delete this; |
-} |
- |
-HTMLFrameTreeManager::HTMLFrameTreeManager(GlobalState* global_state) |
- : global_state_(global_state), |
- root_(nullptr), |
- local_frame_(nullptr), |
- change_id_(0u), |
- in_process_on_frame_removed_(false), |
- weak_factory_(this) {} |
- |
-HTMLFrameTreeManager::~HTMLFrameTreeManager() { |
- DCHECK(!local_frame_); |
- RemoveFromInstances(); |
- |
- FOR_EACH_OBSERVER(HTMLFrameTreeManagerObserver, observers_, |
- OnHTMLFrameTreeManagerDestroyed()); |
-} |
- |
-void HTMLFrameTreeManager::Init( |
- HTMLFrameDelegate* delegate, |
- mus::Window* local_window, |
- const mojo::Array<web_view::mojom::FrameDataPtr>& frame_data, |
- uint32_t change_id) { |
- change_id_ = change_id; |
- root_ = |
- BuildFrameTree(delegate, frame_data, local_window->id(), local_window); |
- local_frame_ = root_->FindFrame(local_window->id()); |
- CHECK(local_frame_); |
- local_frame_->UpdateFocus(); |
-} |
- |
-HTMLFrame* HTMLFrameTreeManager::BuildFrameTree( |
- HTMLFrameDelegate* delegate, |
- const mojo::Array<web_view::mojom::FrameDataPtr>& frame_data, |
- uint32_t local_frame_id, |
- mus::Window* local_window) { |
- std::vector<HTMLFrame*> parents; |
- HTMLFrame* root = nullptr; |
- HTMLFrame* last_frame = nullptr; |
- for (size_t i = 0; i < frame_data.size(); ++i) { |
- if (last_frame && frame_data[i]->parent_id == last_frame->id()) { |
- parents.push_back(last_frame); |
- } else if (!parents.empty()) { |
- while (parents.back()->id() != frame_data[i]->parent_id) |
- parents.pop_back(); |
- } |
- HTMLFrame::CreateParams params(this, |
- !parents.empty() ? parents.back() : nullptr, |
- frame_data[i]->frame_id, local_window, |
- frame_data[i]->client_properties, nullptr); |
- if (frame_data[i]->frame_id == local_frame_id) |
- params.delegate = delegate; |
- |
- HTMLFrame* frame = delegate->GetHTMLFactory()->CreateHTMLFrame(¶ms); |
- if (!last_frame) |
- root = frame; |
- else |
- DCHECK(frame->parent()); |
- last_frame = frame; |
- } |
- return root; |
-} |
- |
-void HTMLFrameTreeManager::RemoveFromInstances() { |
- for (auto pair : *instances_) { |
- if (pair.second == this) { |
- instances_->erase(pair.first); |
- return; |
- } |
- } |
-} |
- |
-bool HTMLFrameTreeManager::PrepareForStructureChange(HTMLFrame* source, |
- uint32_t change_id) { |
- // The change ids may differ if multiple HTMLDocuments are attached to the |
- // same tree (which means we have multiple FrameClient for the same tree). |
- if (change_id != (change_id_ + 1)) |
- return false; |
- |
- // We only process changes for the topmost local root. |
- if (source != local_frame_) |
- return false; |
- |
- // Update the id as the change is going to be applied (or we can assume it |
- // will be applied if we get here). |
- change_id_ = change_id; |
- return true; |
-} |
- |
-void HTMLFrameTreeManager::ProcessOnFrameAdded( |
- HTMLFrame* source, |
- uint32_t change_id, |
- web_view::mojom::FrameDataPtr frame_data) { |
- if (!PrepareForStructureChange(source, change_id)) |
- return; |
- |
- ChangeIdAdvancedNotifier notifier(&observers_); |
- |
- HTMLFrame* parent = root_->FindFrame(frame_data->parent_id); |
- if (!parent) { |
- DVLOG(1) << "Received invalid parent in OnFrameAdded " |
- << frame_data->parent_id; |
- return; |
- } |
- if (root_->FindFrame(frame_data->frame_id)) { |
- DVLOG(1) << "Child with id already exists in OnFrameAdded " |
- << frame_data->frame_id; |
- return; |
- } |
- |
- // Because notification is async it's entirely possible for us to create a |
- // new frame, and remove it before we get the add from the server. This check |
- // ensures we don't add back a frame we explicitly removed. |
- if (pending_remove_ids_.count(frame_data->frame_id)) |
- return; |
- |
- DVLOG(2) << "OnFrameAdded this=" << this |
- << " frame_id=" << frame_data->frame_id; |
- |
- HTMLFrame::CreateParams params(this, parent, frame_data->frame_id, nullptr, |
- frame_data->client_properties, nullptr); |
- // |parent| takes ownership of created HTMLFrame. |
- source->GetFirstAncestorWithDelegate() |
- ->delegate_->GetHTMLFactory() |
- ->CreateHTMLFrame(¶ms); |
-} |
- |
-void HTMLFrameTreeManager::ProcessOnFrameRemoved(HTMLFrame* source, |
- uint32_t change_id, |
- uint32_t frame_id) { |
- if (!PrepareForStructureChange(source, change_id)) |
- return; |
- |
- ChangeIdAdvancedNotifier notifier(&observers_); |
- |
- pending_remove_ids_.erase(frame_id); |
- |
- HTMLFrame* frame = root_->FindFrame(frame_id); |
- if (!frame) { |
- DVLOG(1) << "OnFrameRemoved with unknown frame " << frame_id; |
- return; |
- } |
- |
- // We shouldn't see requests to remove the root. |
- if (frame == root_) { |
- DVLOG(1) << "OnFrameRemoved supplied root; ignoring"; |
- return; |
- } |
- |
- // Requests to remove local frames are followed by the Window being destroyed. |
- // We handle destruction there. |
- if (frame->IsLocal()) |
- return; |
- |
- DVLOG(2) << "OnFrameRemoved this=" << this << " frame_id=" << frame_id; |
- |
- DCHECK(!in_process_on_frame_removed_); |
- in_process_on_frame_removed_ = true; |
- base::WeakPtr<HTMLFrameTreeManager> ref(weak_factory_.GetWeakPtr()); |
- frame->Close(); |
- if (!ref) |
- return; // We were deleted. |
- |
- in_process_on_frame_removed_ = false; |
-} |
- |
-void HTMLFrameTreeManager::ProcessOnFrameClientPropertyChanged( |
- HTMLFrame* source, |
- uint32_t frame_id, |
- const mojo::String& name, |
- mojo::Array<uint8_t> new_data) { |
- if (source != local_frame_) |
- return; |
- |
- HTMLFrame* frame = root_->FindFrame(frame_id); |
- if (frame) |
- frame->SetValueFromClientProperty(name, std::move(new_data)); |
-} |
- |
-HTMLFrame* HTMLFrameTreeManager::FindNewLocalFrame() { |
- HTMLFrame* new_local_frame = nullptr; |
- |
- if (root_) { |
- std::queue<HTMLFrame*> nodes; |
- nodes.push(root_); |
- |
- while (!nodes.empty()) { |
- HTMLFrame* node = nodes.front(); |
- nodes.pop(); |
- |
- if (node == local_frame_) |
- continue; |
- |
- if (node->IsLocal()) { |
- new_local_frame = node; |
- break; |
- } |
- |
- for (const auto& child : node->children()) |
- nodes.push(child); |
- } |
- } |
- |
- return new_local_frame; |
-} |
- |
-} // namespace mojo |