blob: 6fca6a684f5430476701693a6b9fac331058d6ac [file] [log] [blame]
// Copyright 2016 The Fuchsia 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 "garnet/bin/ui/view_manager/view_stub.h"
#include <utility>
#include "garnet/bin/ui/view_manager/view_registry.h"
#include "garnet/bin/ui/view_manager/view_state.h"
#include "garnet/bin/ui/view_manager/view_tree_state.h"
#include "lib/fxl/logging.h"
namespace view_manager {
class PendingViewTransferState {
public:
PendingViewTransferState(std::unique_ptr<ViewStub> view_stub,
zx::eventpair transferred_view_token)
: view_stub_(std::move(view_stub)),
transferred_view_token_(std::move(transferred_view_token)) {}
~PendingViewTransferState() {}
// A reference to keep the |ViewStub| alive until |OnViewResolved| is called.
std::unique_ptr<ViewStub> view_stub_;
// The token paired with the ViewHolder we want to transfer ownership to.
zx::eventpair transferred_view_token_;
};
ViewStub::ViewStub(ViewRegistry* registry, zx::eventpair host_import_token)
: registry_(registry),
host_import_token_(std::move(host_import_token)),
weak_factory_(this) {
FXL_DCHECK(registry_);
FXL_DCHECK(host_import_token_);
}
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.
FXL_DCHECK(is_unavailable());
}
ViewContainerState* ViewStub::container() const {
return parent_ ? static_cast<ViewContainerState*>(parent_) : tree_;
}
void ViewStub::AttachView(ViewState* state) {
FXL_DCHECK(state);
FXL_DCHECK(!state->view_stub());
FXL_DCHECK(is_pending());
state_ = state;
state_->set_view_stub(this);
}
ViewState* ViewStub::ReleaseView() {
if (unavailable_)
return nullptr;
ViewState* state = state_;
if (state) {
FXL_DCHECK(state->view_stub() == this);
state->set_view_stub(nullptr);
state_ = nullptr;
}
properties_.reset();
unavailable_ = true;
return state;
}
void ViewStub::SetContainer(ViewContainerState* container, uint32_t key) {
FXL_DCHECK(container);
FXL_DCHECK(!tree_ && !parent_);
key_ = key;
parent_ = container->AsViewState();
}
void ViewStub::TransferViewWhenResolved(std::unique_ptr<ViewStub> view_stub,
zx::eventpair transferred_view_token) {
FXL_DCHECK(!container()); // Make sure we've been removed from the view tree
FXL_DCHECK(!pending_view_transfer_);
// When |OnViewResolved| gets called, we'll just transfer ownership
// of the view instead of calling |ViewRegistry.OnViewResolved|.
// Save the necessary state in |pending_view_transfer_|
pending_view_transfer_.reset(new PendingViewTransferState(
std::move(view_stub), std::move(transferred_view_token)));
}
void ViewStub::ReleaseHost() {
host_import_token_.reset();
host_node_.reset();
}
void ViewStub::ImportHostNode(scenic::Session* session) {
// Should be dead code.
FXL_CHECK(false);
}
} // namespace view_manager