// 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 "services/ui/view_manager/view_registry.h"

#include <algorithm>
#include <utility>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "mojo/services/ui/views/cpp/formatting.h"
#include "services/ui/view_manager/view_host_impl.h"
#include "services/ui/view_manager/view_tree_host_impl.h"

namespace view_manager {
namespace {
bool AreViewLayoutParamsValid(const mojo::ui::ViewLayoutParams* params) {
  return params && params->constraints && params->constraints->min_width >= 0 &&
         params->constraints->max_width >= params->constraints->min_width &&
         params->constraints->min_height >= 0 &&
         params->constraints->max_height >= params->constraints->min_height &&
         params->device_pixel_ratio > 0;
}

bool IsSizeInBounds(mojo::ui::BoxConstraints* constraints, mojo::Size* size) {
  return size && size->width >= constraints->min_width &&
         size->width <= constraints->max_width &&
         size->height >= constraints->min_height &&
         size->height <= constraints->max_height;
}
}  // namespace

ViewRegistry::ViewRegistry(mojo::gfx::composition::CompositorPtr compositor)
    : compositor_(compositor.Pass()) {}

ViewRegistry::~ViewRegistry() {}

void ViewRegistry::ConnectAssociates(
    mojo::ApplicationImpl* app_impl,
    const std::vector<std::string>& urls,
    const AssociateConnectionErrorCallback& connection_error_callback) {
  associate_table_.ConnectAssociates(app_impl, this, urls,
                                     connection_error_callback);
}

void ViewRegistry::RegisterView(
    mojo::ui::ViewPtr view,
    mojo::InterfaceRequest<mojo::ui::ViewHost> view_host_request,
    mojo::InterfaceRequest<mojo::ui::ViewOwner> view_owner_request,
    const mojo::String& label) {
  DCHECK(view);
  DCHECK(view_host_request.is_pending());
  DCHECK(view_owner_request.is_pending());

  auto view_token = mojo::ui::ViewToken::New();
  view_token->value = next_view_token_value_++;
  CHECK(view_token->value);
  CHECK(!FindView(view_token->value));

  // Create the state and bind host to it.
  std::string sanitized_label =
      label.get().substr(0, mojo::ui::kLabelMaxLength);
  ViewState* view_state =
      new ViewState(this, view.Pass(), view_token.Pass(),
                    view_host_request.Pass(), sanitized_label);
  view_state->BindOwner(view_owner_request.Pass());

  // Add to registry and return token.
  views_by_token_.insert({view_state->view_token()->value, view_state});
  DVLOG(1) << "RegisterView: view=" << view_state;
}

void ViewRegistry::OnViewDied(ViewState* view_state,
                              const std::string& reason) {
  DCHECK(IsViewStateRegisteredDebug(view_state));
  DVLOG(1) << "OnViewDied: view=" << view_state << ", reason=" << reason;

  UnregisterView(view_state);
}

void ViewRegistry::UnregisterView(ViewState* view_state) {
  DCHECK(IsViewStateRegisteredDebug(view_state));
  DVLOG(1) << "UnregisterView: view=" << view_state;

  // Remove from parent or roots.
  // This may send a view unavailable message to the view's parent or tree.
  HijackView(view_state);

  // Recursively unregister all children since they will become unowned
  // at this point taking care to unlink each one before its unregistration.
  for (auto& child : view_state->UnlinkAllChildren())
    UnregisterViewStub(std::move(child));

  // Remove from registry.
  views_by_token_.erase(view_state->view_token()->value);
  delete view_state;
}

void ViewRegistry::RegisterViewTree(
    mojo::ui::ViewTreePtr view_tree,
    mojo::InterfaceRequest<mojo::ui::ViewTreeHost> view_tree_host_request,
    const mojo::String& label) {
  DCHECK(view_tree);
  DCHECK(view_tree_host_request.is_pending());

  auto view_tree_token = mojo::ui::ViewTreeToken::New();
  view_tree_token->value = next_view_tree_token_value_++;
  CHECK(view_tree_token->value);
  CHECK(!FindViewTree(view_tree_token->value));

  // Create the state and bind host to it.
  std::string sanitized_label =
      label.get().substr(0, mojo::ui::kLabelMaxLength);
  ViewTreeState* tree_state =
      new ViewTreeState(this, view_tree.Pass(), view_tree_token.Pass(),
                        view_tree_host_request.Pass(), sanitized_label);

  // Add to registry.
  view_trees_by_token_.insert(
      {tree_state->view_tree_token()->value, tree_state});
  DVLOG(1) << "RegisterViewTree: tree=" << tree_state;
}

void ViewRegistry::OnViewTreeDied(ViewTreeState* tree_state,
                                  const std::string& reason) {
  DCHECK(IsViewTreeStateRegisteredDebug(tree_state));
  DVLOG(1) << "OnViewTreeDied: tree=" << tree_state << ", reason=" << reason;

  UnregisterViewTree(tree_state);
}

void ViewRegistry::UnregisterViewTree(ViewTreeState* tree_state) {
  DCHECK(IsViewTreeStateRegisteredDebug(tree_state));
  DVLOG(1) << "UnregisterViewTree: tree=" << tree_state;

  // Unlink the root if needed.
  if (tree_state->root())
    UnregisterViewStub(tree_state->UnlinkRoot());

  // Remove from registry.
  view_trees_by_token_.erase(tree_state->view_tree_token()->value);
  delete tree_state;
}

void ViewRegistry::CreateScene(
    ViewState* view_state,
    mojo::InterfaceRequest<mojo::gfx::composition::Scene> scene) {
  DCHECK(IsViewStateRegisteredDebug(view_state));
  DCHECK(scene.is_pending());
  DVLOG(1) << "CreateScene: view=" << view_state;

  compositor_->CreateScene(
      scene.Pass(), view_state->label(),
      base::Bind(&ViewRegistry::OnSceneCreated, base::Unretained(this),
                 view_state->GetWeakPtr()));
}

void ViewRegistry::OnSceneCreated(
    base::WeakPtr<ViewState> view_state_weak,
    mojo::gfx::composition::SceneTokenPtr scene_token) {
  DCHECK(scene_token);
  ViewState* view_state = view_state_weak.get();
  if (view_state) {
    DVLOG(1) << "OnSceneCreated: scene_token=" << scene_token;

    view_state->set_scene_token(scene_token.Pass());
    view_state->set_scene_changed_since_last_report(true);
    InvalidateLayout(view_state);
  }
}

void ViewRegistry::RequestLayout(ViewState* view_state) {
  DCHECK(IsViewStateRegisteredDebug(view_state));
  DVLOG(1) << "RequestLayout: view=" << view_state;

  InvalidateLayout(view_state);
}

void ViewRegistry::AddChild(ViewState* parent_state,
                            uint32_t child_key,
                            mojo::ui::ViewOwnerPtr child_view_owner) {
  DCHECK(IsViewStateRegisteredDebug(parent_state));
  DCHECK(child_view_owner);
  DVLOG(1) << "AddChild: parent=" << parent_state
           << ", child_key=" << child_key;

  // Ensure there are no other children with the same key.
  if (parent_state->children().find(child_key) !=
      parent_state->children().end()) {
    LOG(ERROR) << "View attempted to add a child with a duplicate key: "
               << "parent=" << parent_state << ", child_key=" << child_key;
    UnregisterView(parent_state);
    return;
  }

  // Add a stub, pending resolution of the view owner.
  parent_state->LinkChild(child_key, std::unique_ptr<ViewStub>(new ViewStub(
                                         this, child_view_owner.Pass())));

  // Schedule layout of the parent on behalf of its newly added child.
  // We don't need to schedule layout of the child until the parent provides
  // new layout parameters.
  InvalidateLayoutForChild(parent_state, child_key);
}

void ViewRegistry::RemoveChild(ViewState* parent_state,
                               uint32_t child_key,
                               mojo::InterfaceRequest<mojo::ui::ViewOwner>
                                   transferred_view_owner_request) {
  DCHECK(IsViewStateRegisteredDebug(parent_state));
  DVLOG(1) << "RemoveChild: parent=" << parent_state
           << ", child_key=" << child_key;

  // Ensure the child key exists in the parent.
  auto child_it = parent_state->children().find(child_key);
  if (child_it == parent_state->children().end()) {
    LOG(ERROR) << "View attempted to remove a child with an invalid key: "
               << "parent=" << parent_state << ", child_key=" << child_key;
    UnregisterView(parent_state);
    return;
  }

  // Unlink the child from its parent.
  TransferOrUnregisterViewStub(parent_state->UnlinkChild(child_key),
                               transferred_view_owner_request.Pass());

  // Schedule layout for the parent now that it has lost its child.
  // We don't need to schedule layout for the child itself since it will
  // retain its old layout parameters until it is reparented.
  InvalidateLayout(parent_state);
}

void ViewRegistry::LayoutChild(
    ViewState* parent_state,
    uint32_t child_key,
    mojo::ui::ViewLayoutParamsPtr child_layout_params,
    const ViewLayoutCallback& callback) {
  DCHECK(IsViewStateRegisteredDebug(parent_state));
  DCHECK(child_layout_params);
  DCHECK(child_layout_params->constraints);
  DVLOG(1) << "LayoutChild: parent=" << parent_state
           << ", child_key=" << child_key
           << ", child_layout_params=" << child_layout_params;

  // Check whether the layout parameters are well-formed.
  if (!AreViewLayoutParamsValid(child_layout_params.get())) {
    LOG(ERROR) << "View provided invalid child layout parameters: "
               << "parent=" << parent_state << ", child_key=" << child_key
               << ", child_layout_params=" << child_layout_params;
    UnregisterView(parent_state);
    callback.Run(nullptr);
    return;
  }

  // Check whether the child key exists in the parent.
  auto child_it = parent_state->children().find(child_key);
  if (child_it == parent_state->children().end()) {
    LOG(ERROR) << "View attempted to layout a child with an invalid key: "
               << "parent=" << parent_state << ", child_key=" << child_key
               << ", child_layout_params=" << child_layout_params;
    UnregisterView(parent_state);
    callback.Run(nullptr);
    return;
  }

  SetLayout(child_it->second.get(), child_layout_params.Pass(), callback);
}

void ViewRegistry::ConnectToViewService(
    ViewState* view_state,
    const mojo::String& service_name,
    mojo::ScopedMessagePipeHandle client_handle) {
  DCHECK(IsViewStateRegisteredDebug(view_state));

  associate_table_.ConnectToViewService(view_state->view_token()->Clone(),
                                        service_name, client_handle.Pass());
}

void ViewRegistry::RequestLayout(ViewTreeState* tree_state) {
  DCHECK(IsViewTreeStateRegisteredDebug(tree_state));
  DVLOG(1) << "RequestLayout: tree=" << tree_state;

  InvalidateLayoutForRoot(tree_state);
}

void ViewRegistry::SetRoot(ViewTreeState* tree_state,
                           uint32_t root_key,
                           mojo::ui::ViewOwnerPtr root_view_owner) {
  DCHECK(IsViewTreeStateRegisteredDebug(tree_state));
  DCHECK(root_view_owner);
  DVLOG(1) << "SetRoot: tree=" << tree_state << ", root_key=" << root_key;

  // Ensure there isn't already a root.
  if (tree_state->root()) {
    LOG(ERROR)
        << "View tree attempted to set the root while one is already set: tree="
        << tree_state << ", root_key=" << root_key;
    UnregisterViewTree(tree_state);
    return;
  }

  // Set the root to a stub, pending resolution of the view owner.
  tree_state->LinkRoot(root_key, std::unique_ptr<ViewStub>(new ViewStub(
                                     this, root_view_owner.Pass())));

  // Schedule layout of the tree on behalf of its newly added root.
  // We don't need to schedule layout of the root until the tree provides
  // new layout parameters.
  InvalidateLayoutForRoot(tree_state);
}

void ViewRegistry::ResetRoot(ViewTreeState* tree_state,
                             mojo::InterfaceRequest<mojo::ui::ViewOwner>
                                 transferred_view_owner_request) {
  DCHECK(IsViewTreeStateRegisteredDebug(tree_state));
  DVLOG(1) << "ResetRoot: tree=" << tree_state;

  // Ensure there is a root.
  if (!tree_state->root()) {
    LOG(ERROR)
        << "View tree attempted to reset the root but there is none: tree="
        << tree_state;
    UnregisterViewTree(tree_state);
    return;
  }

  // Unlink the root from its tree.
  TransferOrUnregisterViewStub(tree_state->UnlinkRoot(),
                               transferred_view_owner_request.Pass());

  // Note: We don't need to schedule layout for the root since it will retain
  // its old layout parameters.  And there's no need to tell the tree
  // either since it won't have any work to do.  So we're done.
}

void ViewRegistry::LayoutRoot(ViewTreeState* tree_state,
                              mojo::ui::ViewLayoutParamsPtr root_layout_params,
                              const ViewLayoutCallback& callback) {
  DCHECK(IsViewTreeStateRegisteredDebug(tree_state));
  DCHECK(root_layout_params);
  DCHECK(root_layout_params->constraints);
  DVLOG(1) << "LayoutRoot: tree=" << tree_state
           << ", root_layout_params=" << root_layout_params;

  // Check whether the layout parameters are well-formed.
  if (!AreViewLayoutParamsValid(root_layout_params.get())) {
    LOG(ERROR) << "View tree provided invalid root layout parameters: "
               << "tree=" << tree_state
               << ", root_layout_params=" << root_layout_params;
    UnregisterViewTree(tree_state);
    callback.Run(nullptr);
    return;
  }

  // Check whether the client called LayoutRoot without first having actually
  // set a root.
  if (!tree_state->root()) {
    LOG(ERROR) << "View tree attempted to layout the root without having "
                  "set one first: tree="
               << tree_state << ", root_layout_params=" << root_layout_params;
    UnregisterViewTree(tree_state);
    callback.Run(nullptr);
    return;
  }

  SetLayout(tree_state->root(), root_layout_params.Pass(), callback);
}

void ViewRegistry::ConnectToViewTreeService(
    ViewTreeState* tree_state,
    const mojo::String& service_name,
    mojo::ScopedMessagePipeHandle client_handle) {
  DCHECK(IsViewTreeStateRegisteredDebug(tree_state));

  associate_table_.ConnectToViewTreeService(
      tree_state->view_tree_token()->Clone(), service_name,
      client_handle.Pass());
}

ViewState* ViewRegistry::FindView(uint32_t view_token_value) {
  auto it = views_by_token_.find(view_token_value);
  return it != views_by_token_.end() ? it->second : nullptr;
}

ViewTreeState* ViewRegistry::FindViewTree(uint32_t view_tree_token_value) {
  auto it = view_trees_by_token_.find(view_tree_token_value);
  return it != view_trees_by_token_.end() ? it->second : nullptr;
}

void ViewRegistry::HijackView(ViewState* view_state) {
  DCHECK(IsViewStateRegisteredDebug(view_state));

  ViewStub* view_stub = view_state->view_stub();
  if (view_stub)
    ReleaseViewStubAndNotify(view_stub);
}

void ViewRegistry::OnViewResolved(ViewStub* view_stub,
                                  mojo::ui::ViewTokenPtr view_token) {
  DCHECK(view_stub);

  ViewState* view_state = view_token ? FindView(view_token->value) : nullptr;
  if (view_state)
    AttachViewStubAndNotify(view_stub, view_state);
  else
    ReleaseViewStubAndNotify(view_stub);
}

void ViewRegistry::AttachViewStubAndNotify(ViewStub* view_stub,
                                           ViewState* view_state) {
  DCHECK(view_stub);

  view_state->ReleaseOwner();  // don't need the ViewOwner pipe anymore
  view_stub->AttachView(view_state);

  if (view_stub->pending_layout_request()) {
    view_state->pending_layout_requests().push_back(
        std::move(view_stub->pending_layout_request()));
    IssueNextViewLayoutRequest(view_state);
  }
}

void ViewRegistry::ReleaseViewStubAndNotify(ViewStub* view_stub) {
  DCHECK(view_stub);

  view_stub->ReleaseView();

  if (view_stub->parent())
    SendChildUnavailable(view_stub->parent(), view_stub->key());
  else if (view_stub->tree())
    SendRootUnavailable(view_stub->tree(), view_stub->key());

  // Note: We don't need to schedule layout for the previous owner.
  // We can simply wait for it to remove its unavailable child or root in
  // response to the notification at which point layout will occur.
  // We don't need to schedule layout for the child either since it will
  // retain its old layout parameters.
}

void ViewRegistry::TransferOrUnregisterViewStub(
    std::unique_ptr<ViewStub> view_stub,
    mojo::InterfaceRequest<mojo::ui::ViewOwner>
        transferred_view_owner_request) {
  DCHECK(view_stub);

  if (transferred_view_owner_request.is_pending()) {
    if (view_stub->state())
      view_stub->state()->BindOwner(transferred_view_owner_request.Pass());
    else if (view_stub->is_pending())
      CHECK(false);  // TODO(jeffbrown): Handle transfer of pending view
  } else {
    UnregisterViewStub(std::move(view_stub));
  }
}

void ViewRegistry::UnregisterViewStub(std::unique_ptr<ViewStub> view_stub) {
  DCHECK(view_stub);

  if (view_stub->state())
    UnregisterView(view_stub->state());
}

void ViewRegistry::SetLayout(ViewStub* view_stub,
                             mojo::ui::ViewLayoutParamsPtr layout_params,
                             const ViewLayoutCallback& callback) {
  DCHECK(view_stub);
  DCHECK(AreViewLayoutParamsValid(layout_params.get()));

  // Immediately discard layout requests on unavailable views.
  if (view_stub->is_unavailable()) {
    callback.Run(nullptr);
    return;
  }

  // For pending views, only remember the most recent distinct layout request.
  if (view_stub->is_pending()) {
    if (!view_stub->pending_layout_request() ||
        !view_stub->pending_layout_request()->layout_params()->Equals(
            *layout_params)) {
      view_stub->pending_layout_request().reset(
          new ViewLayoutRequest(layout_params.Pass()));
    }
    view_stub->pending_layout_request()->AddCallback(callback);
    return;
  }

  // For actual views, maintain a queue of pending layout requests.
  ViewState* view_state = view_stub->state();
  DCHECK(view_state);
  DCHECK(!view_stub->pending_layout_request());

  // Check whether the currently cached layout parameters are the same
  // and we already have a result and we have no pending layout requests.
  if (view_state->pending_layout_requests().empty() &&
      view_state->layout_params() &&
      view_state->layout_params()->Equals(*layout_params)) {
    mojo::ui::ViewLayoutInfoPtr info = view_state->CreateLayoutInfo();
    if (info) {
      DVLOG(2) << "Layout cache hit";
      view_state->set_scene_changed_since_last_report(false);
      callback.Run(info.Pass());
      return;
    }
  }

  // Check whether the layout parameters are different from the most
  // recent pending layout request if we have one.
  if (view_state->pending_layout_requests().empty() ||
      !view_state->pending_layout_requests().back()->layout_params()->Equals(
          *layout_params)) {
    // Enqueue a new request for these parameters.
    EnqueueLayoutRequest(view_state, layout_params.Pass());
  }

  // Enlist ourselves into the callbacks for the pending request.
  view_state->pending_layout_requests().back()->AddCallback(callback);
  IssueNextViewLayoutRequest(view_state);
}

void ViewRegistry::EnqueueLayoutRequest(
    ViewState* view_state,
    mojo::ui::ViewLayoutParamsPtr layout_params) {
  DCHECK(view_state);
  DCHECK(AreViewLayoutParamsValid(layout_params.get()));

  // Drop the previous layout request if it hasn't been issued yet.
  // This may cause callbacks to be invoked will null information.
  if (!view_state->pending_layout_requests().empty() &&
      !view_state->pending_layout_requests().back()->issued())
    view_state->pending_layout_requests().pop_back();

  // Enqueue the new request.
  view_state->pending_layout_requests().emplace_back(
      std::unique_ptr<ViewLayoutRequest>(
          new ViewLayoutRequest(layout_params.Pass())));
}

void ViewRegistry::InvalidateLayout(ViewState* view_state) {
  DCHECK(IsViewStateRegisteredDebug(view_state));

  // We can consider the layout request to have been satisfied if
  // there is already a pending layout request in the queue that has not
  // yet been issued (this is coalescing).  Otherwise we must manufacture
  // a new one based on the current layout parameters.
  if (view_state->layout_params() &&
      (view_state->pending_layout_requests().empty() ||
       view_state->pending_layout_requests().back()->issued())) {
    EnqueueLayoutRequest(view_state, view_state->layout_params()->Clone());
    IssueNextViewLayoutRequest(view_state);
  }
}

void ViewRegistry::InvalidateLayoutForChild(ViewState* parent_state,
                                            uint32_t child_key) {
  DCHECK(IsViewStateRegisteredDebug(parent_state));
  DCHECK(parent_state->children().find(child_key) !=
         parent_state->children().end());

  parent_state->children_needing_layout().insert(child_key);
  InvalidateLayout(parent_state);
}

void ViewRegistry::InvalidateLayoutForRoot(ViewTreeState* tree_state) {
  DCHECK(IsViewTreeStateRegisteredDebug(tree_state));

  if (!tree_state->layout_request_pending()) {
    tree_state->set_layout_request_pending(true);
    IssueNextViewTreeLayoutRequest(tree_state);
  }
}

void ViewRegistry::IssueNextViewLayoutRequest(ViewState* view_state) {
  DCHECK(IsViewStateRegisteredDebug(view_state));

  if (view_state->pending_layout_requests().empty())
    return;

  ViewLayoutRequest* request =
      view_state->pending_layout_requests().front().get();
  if (request->issued())
    return;

  // TODO: Detect ANRs
  DVLOG(1) << "IssueNextViewLayoutRequest: view_state=" << view_state;
  view_state->view()->OnLayout(
      request->layout_params()->Clone(),
      mojo::Array<uint32_t>::From(view_state->children_needing_layout()),
      base::Bind(&ViewRegistry::OnViewLayoutResult, base::Unretained(this),
                 view_state->GetWeakPtr()));
  view_state->children_needing_layout().clear();
  request->set_issued(true);
}

void ViewRegistry::IssueNextViewTreeLayoutRequest(ViewTreeState* tree_state) {
  DCHECK(IsViewTreeStateRegisteredDebug(tree_state));

  if (!tree_state->layout_request_pending() ||
      tree_state->layout_request_issued())
    return;

  // TODO: Detect ANRs
  DVLOG(1) << "SendViewTreeLayoutRequest";
  tree_state->view_tree()->OnLayout(
      base::Bind(&ViewRegistry::OnViewTreeLayoutResult, base::Unretained(this),
                 tree_state->GetWeakPtr()));
  tree_state->set_layout_request_pending(false);
  tree_state->set_layout_request_issued(true);
}

void ViewRegistry::OnViewLayoutResult(base::WeakPtr<ViewState> view_state_weak,
                                      mojo::ui::ViewLayoutResultPtr result) {
  DCHECK(result);

  ViewState* view_state = view_state_weak.get();
  if (!view_state)
    return;

  DCHECK(!view_state->pending_layout_requests().empty());
  DCHECK(view_state->pending_layout_requests().front()->issued());

  std::unique_ptr<ViewLayoutRequest> request(
      std::move(view_state->pending_layout_requests().front()));
  view_state->pending_layout_requests().erase(
      view_state->pending_layout_requests().begin());

  DVLOG(1) << "OnViewLayoutResult: view=" << view_state
           << ", params=" << *request->layout_params() << ", result=" << result;

  // Validate the layout info.
  if (!IsSizeInBounds(request->layout_params()->constraints.get(),
                      result->size.get())) {
    LOG(ERROR) << "View returned invalid size in its layout info: "
               << "view=" << view_state
               << ", params=" << *request->layout_params()
               << ", result=" << result;
    UnregisterView(view_state);
    return;
  }

  // Assume the parent or root will not see the new layout information if
  // there are no callbacks so we need to inform it when things change.
  const bool size_changed =
      !view_state->layout_result() ||
      !view_state->layout_result()->size->Equals(*result->size);
  const bool recurse =
      !request->has_callbacks() &&
      (size_changed || view_state->scene_changed_since_last_report());

  view_state->set_layout_params(request->TakeLayoutParams().Pass());
  view_state->set_layout_result(result.Pass());

  mojo::ui::ViewLayoutInfoPtr info = view_state->CreateLayoutInfo();
  if (info) {
    view_state->set_scene_changed_since_last_report(false);
    request->DispatchLayoutInfo(info.Pass());
  }

  if (recurse && view_state->view_stub()) {
    if (view_state->view_stub()->parent()) {
      InvalidateLayoutForChild(view_state->view_stub()->parent(),
                               view_state->view_stub()->key());
    } else if (view_state->view_stub()->tree()) {
      InvalidateLayoutForRoot(view_state->view_stub()->tree());
    }
  }

  IssueNextViewLayoutRequest(view_state);
}

void ViewRegistry::OnViewTreeLayoutResult(
    base::WeakPtr<ViewTreeState> tree_state_weak) {
  ViewTreeState* tree_state = tree_state_weak.get();
  if (tree_state) {
    DCHECK(tree_state->layout_request_issued());

    DVLOG(1) << "OnViewTreeLayoutResult";

    tree_state->set_layout_request_issued(false);
    IssueNextViewTreeLayoutRequest(tree_state);
  }
}

void ViewRegistry::SendChildUnavailable(ViewState* parent_state,
                                        uint32_t child_key) {
  DCHECK(IsViewStateRegisteredDebug(parent_state));

  // TODO: Detect ANRs
  DVLOG(1) << "SendChildUnavailable: parent_state=" << parent_state
           << ", child_key=" << child_key;
  parent_state->view()->OnChildUnavailable(child_key,
                                           base::Bind(&base::DoNothing));
}

void ViewRegistry::SendRootUnavailable(ViewTreeState* tree_state,
                                       uint32_t root_key) {
  DCHECK(IsViewTreeStateRegisteredDebug(tree_state));

  // TODO: Detect ANRs
  DVLOG(1) << "SendRootUnavailable: tree_state=" << tree_state
           << ", root_key=" << root_key;
  tree_state->view_tree()->OnRootUnavailable(root_key,
                                             base::Bind(&base::DoNothing));
}

}  // namespace view_manager
