blob: 3abeb639a48ca6c679c2894b07891f7b6186ef07 [file] [log] [blame]
// Copyright 2016 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 "services/ui/view_manager/view_stub.h"
#include <utility>
#include "base/bind.h"
#include "base/logging.h"
#include "services/ui/view_manager/view_registry.h"
#include "services/ui/view_manager/view_state.h"
#include "services/ui/view_manager/view_tree_state.h"
namespace view_manager {
ViewStub::ViewStub(ViewRegistry* registry,
mojo::InterfaceHandle<mojo::ui::ViewOwner> owner)
: registry_(registry),
owner_(mojo::ui::ViewOwnerPtr::Create(std::move(owner))),
weak_factory_(this) {
DCHECK(registry_);
DCHECK(owner_);
owner_.set_connection_error_handler(
base::Bind(&ViewStub::OnViewResolved, base::Unretained(this), nullptr));
owner_->GetToken(
base::Bind(&ViewStub::OnViewResolved, base::Unretained(this)));
}
ViewStub::~ViewStub() {
// Ensure that everything was properly released before this object was
// destroyed. The |ViewRegistry| is responsible for maintaining the
// invariant that all |ViewState| objects are owned so by the time we
// get here, the view should have found a new owner or been unregistered.
DCHECK(is_unavailable());
}
ViewContainerState* ViewStub::container() const {
return parent_ ? static_cast<ViewContainerState*>(parent_) : tree_;
}
void ViewStub::AttachView(ViewState* state,
mojo::gfx::composition::ScenePtr stub_scene) {
DCHECK(state);
DCHECK(!state->view_stub());
DCHECK(stub_scene);
DCHECK(is_pending());
state_ = state;
state_->set_view_stub(this);
stub_scene_ = stub_scene.Pass();
}
void ViewStub::SetProperties(uint32_t scene_version,
mojo::ui::ViewPropertiesPtr properties) {
DCHECK(!is_unavailable());
scene_version_ = scene_version;
properties_ = properties.Pass();
}
void ViewStub::SetStubSceneToken(
mojo::gfx::composition::SceneTokenPtr stub_scene_token) {
DCHECK(stub_scene_token);
DCHECK(state_);
DCHECK(stub_scene_);
DCHECK(!stub_scene_token_);
stub_scene_token_ = stub_scene_token.Pass();
}
ViewState* ViewStub::ReleaseView() {
if (is_unavailable())
return nullptr;
ViewState* state = state_;
if (state) {
DCHECK(state->view_stub() == this);
state->set_view_stub(nullptr);
state_ = nullptr;
stub_scene_.reset();
stub_scene_token_.reset();
}
scene_version_ = mojo::gfx::composition::kSceneVersionNone;
properties_.reset();
unavailable_ = true;
return state;
}
void ViewStub::SetContainer(ViewContainerState* container, uint32_t key) {
DCHECK(container);
DCHECK(!tree_ && !parent_);
key_ = key;
parent_ = container->AsViewState();
if (parent_) {
if (parent_->view_stub())
SetTreeRecursively(parent_->view_stub()->tree());
} else {
ViewTreeState* tree = container->AsViewTreeState();
DCHECK(tree);
SetTreeRecursively(tree);
}
}
void ViewStub::Unlink() {
parent_ = nullptr;
key_ = 0;
SetTreeRecursively(nullptr);
}
void ViewStub::SetTreeRecursively(ViewTreeState* tree) {
if (tree_ == tree)
return;
tree_ = tree;
if (state_) {
for (const auto& pair : state_->children()) {
pair.second->SetTreeRecursively(tree);
}
}
}
void ViewStub::OnViewResolved(mojo::ui::ViewTokenPtr view_token) {
DCHECK(owner_);
owner_.reset();
registry_->OnViewResolved(this, view_token.Pass());
}
} // namespace view_manager