// Copyright 2017 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 "chrome/browser/vr/ui_scene_creator.h"

#include <memory>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/i18n/case_conversion.h"
#include "base/numerics/math_constants.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "cc/animation/animation_curve.h"
#include "cc/animation/animation_target.h"
#include "cc/animation/keyframe_effect.h"
#include "cc/animation/keyframed_animation_curve.h"
#include "chrome/browser/vr/content_input_delegate.h"
#include "chrome/browser/vr/databinding/binding.h"
#include "chrome/browser/vr/databinding/vector_binding.h"
#include "chrome/browser/vr/elements/button.h"
#include "chrome/browser/vr/elements/content_element.h"
#include "chrome/browser/vr/elements/controller.h"
#include "chrome/browser/vr/elements/disc_button.h"
#include "chrome/browser/vr/elements/draw_phase.h"
#include "chrome/browser/vr/elements/environment/background.h"
#include "chrome/browser/vr/elements/environment/grid.h"
#include "chrome/browser/vr/elements/environment/stars.h"
#include "chrome/browser/vr/elements/full_screen_rect.h"
#include "chrome/browser/vr/elements/indicator_spec.h"
#include "chrome/browser/vr/elements/invisible_hit_target.h"
#include "chrome/browser/vr/elements/keyboard.h"
#include "chrome/browser/vr/elements/laser.h"
#include "chrome/browser/vr/elements/linear_layout.h"
#include "chrome/browser/vr/elements/omnibox_formatting.h"
#include "chrome/browser/vr/elements/omnibox_text_field.h"
#include "chrome/browser/vr/elements/oval.h"
#include "chrome/browser/vr/elements/platform_ui_element.h"
#include "chrome/browser/vr/elements/rect.h"
#include "chrome/browser/vr/elements/repositioner.h"
#include "chrome/browser/vr/elements/resizer.h"
#include "chrome/browser/vr/elements/reticle.h"
#include "chrome/browser/vr/elements/scaled_depth_adjuster.h"
#include "chrome/browser/vr/elements/scrollable_element.h"
#include "chrome/browser/vr/elements/spinner.h"
#include "chrome/browser/vr/elements/text.h"
#include "chrome/browser/vr/elements/text_button.h"
#include "chrome/browser/vr/elements/text_input.h"
#include "chrome/browser/vr/elements/throbber.h"
#include "chrome/browser/vr/elements/transient_element.h"
#include "chrome/browser/vr/elements/ui_element.h"
#include "chrome/browser/vr/elements/ui_element_name.h"
#include "chrome/browser/vr/elements/ui_texture.h"
#include "chrome/browser/vr/elements/url_text.h"
#include "chrome/browser/vr/elements/vector_icon.h"
#include "chrome/browser/vr/elements/viewport_aware_root.h"
#include "chrome/browser/vr/keyboard_delegate.h"
#include "chrome/browser/vr/model/model.h"
#include "chrome/browser/vr/model/platform_toast.h"
#include "chrome/browser/vr/platform_ui_input_delegate.h"
#include "chrome/browser/vr/speech_recognizer.h"
#include "chrome/browser/vr/target_property.h"
#include "chrome/browser/vr/ui.h"
#include "chrome/browser/vr/ui_browser_interface.h"
#include "chrome/browser/vr/ui_scene.h"
#include "chrome/browser/vr/ui_scene_constants.h"
#include "chrome/grit/generated_resources.h"
#include "components/strings/grit/components_strings.h"
#include "components/url_formatter/elide_url.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/gfx/transform_util.h"

namespace vr {

namespace {

template <typename V, typename C, typename S>
void BindColor(Model* model,
               V* view,
               C color,
               const std::string& color_string,
               S setter,
               const std::string& setter_string) {
  view->AddBinding(std::make_unique<Binding<SkColor>>(
      base::BindRepeating([](Model* m, C c) { return (m->color_scheme()).*c; },
                          base::Unretained(model), color),
#ifndef NDEBUG
      color_string,
#endif
      base::BindRepeating(
          [](V* v, S s, const SkColor& value) { (v->*s)(value); },
          base::Unretained(view), setter)
#ifndef NDEBUG
          ,
      setter_string
#endif
      ));
}

#define VR_BIND_COLOR(m, v, c, s) BindColor(m, v, c, #c, s, #s)

template <typename V, typename C, typename S>
void BindButtonColors(Model* model,
                      V* view,
                      C colors,
                      const std::string& colors_string,
                      S setter,
                      const std::string& setter_string) {
  view->AddBinding(std::make_unique<Binding<ButtonColors>>(
      base::BindRepeating([](Model* m, C c) { return (m->color_scheme()).*c; },
                          base::Unretained(model), colors),
#ifndef NDEBUG
      colors_string,
#endif
      base::BindRepeating(
          [](V* v, S s, const ButtonColors& value) { (v->*s)(value); },
          base::Unretained(view), setter)
#ifndef NDEBUG
          ,
      setter_string
#endif
      ));
}

#define VR_BIND_BUTTON_COLORS(m, v, c, s) BindButtonColors(m, v, c, #c, s, #s)

#define VR_BIND_VISIBILITY(v, c) \
  v->AddBinding(                 \
      VR_BIND_FUNC(bool, Model, model_, c, UiElement, v.get(), SetVisible));

template <typename T, typename... Args>
std::unique_ptr<T> Create(UiElementName name, DrawPhase phase, Args&&... args) {
  auto element = std::make_unique<T>(std::forward<Args>(args)...);
  element->SetName(name);
  element->SetDrawPhase(phase);
  return element;
}

typedef VectorBinding<OmniboxSuggestion, Button> SuggestionSetBinding;
typedef typename SuggestionSetBinding::ElementBinding SuggestionBinding;

void OnSuggestionModelAdded(UiScene* scene,
                            UiBrowserInterface* browser,
                            Ui* ui,
                            Model* model,
                            AudioDelegate* audio_delegate,
                            SuggestionBinding* element_binding) {
  auto icon = std::make_unique<VectorIcon>(100);
  icon->SetDrawPhase(kPhaseForeground);
  icon->SetType(kTypeOmniboxSuggestionIcon);
  icon->SetSize(kSuggestionIconSizeDMM, kSuggestionIconSizeDMM);
  icon->AddBinding(VR_BIND_FUNC(SkColor, Model, model,
                                model->color_scheme().url_bar_button.foreground,
                                VectorIcon, icon.get(), SetColor));
  VectorIcon* p_icon = icon.get();

  auto icon_box = std::make_unique<UiElement>();
  icon_box->SetDrawPhase(kPhaseNone);
  icon_box->SetType(kTypeOmniboxSuggestionIconField);
  icon_box->set_hit_testable(true);
  icon_box->SetSize(kSuggestionIconFieldWidthDMM, kSuggestionHeightDMM);
  icon_box->AddChild(std::move(icon));

  auto content_text = std::make_unique<Text>(kSuggestionContentTextHeightDMM);
  content_text->SetDrawPhase(kPhaseForeground);
  content_text->SetType(kTypeOmniboxSuggestionContentText);
  content_text->SetLayoutMode(TextLayoutMode::kSingleLineFixedWidth);
  content_text->SetFieldWidth(kSuggestionTextFieldWidthDMM);
  content_text->SetAlignment(kTextAlignmentLeft);
  Text* p_content_text = content_text.get();

  auto description_text =
      std::make_unique<Text>(kSuggestionDescriptionTextHeightDMM);
  description_text->SetDrawPhase(kPhaseForeground);
  description_text->SetType(kTypeOmniboxSuggestionDescriptionText);
  description_text->SetLayoutMode(TextLayoutMode::kSingleLineFixedWidth);
  description_text->SetFieldWidth(kSuggestionTextFieldWidthDMM);
  description_text->SetAlignment(kTextAlignmentLeft);
  Text* p_description_text = description_text.get();

  auto text_layout = std::make_unique<LinearLayout>(LinearLayout::kDown);
  text_layout->SetType(kTypeOmniboxSuggestionTextLayout);
  text_layout->set_margin(kSuggestionLineGapDMM);
  text_layout->AddChild(std::move(content_text));
  text_layout->AddChild(std::move(description_text));

  auto right_margin = std::make_unique<UiElement>();
  right_margin->SetDrawPhase(kPhaseNone);
  right_margin->set_hit_testable(true);
  right_margin->SetSize(kSuggestionRightMarginDMM, kSuggestionHeightDMM);

  auto suggestion_layout = std::make_unique<LinearLayout>(LinearLayout::kRight);
  suggestion_layout->SetType(kTypeOmniboxSuggestionLayout);
  suggestion_layout->AddChild(std::move(icon_box));
  suggestion_layout->AddChild(std::move(text_layout));
  suggestion_layout->AddChild(std::move(right_margin));

  auto background = Create<Button>(
      kNone, kPhaseForeground,
      base::BindRepeating(
          [](UiBrowserInterface* b, Ui* ui, Model* m, SuggestionBinding* e) {
            b->Navigate(e->model()->destination,
                        NavigationMethod::kOmniboxSuggestionSelected);
            ui->OnUiRequestedNavigation();
          },
          base::Unretained(browser), base::Unretained(ui),
          base::Unretained(model), base::Unretained(element_binding)),
      audio_delegate);

  background->SetType(kTypeOmniboxSuggestionBackground);
  background->set_hit_testable(true);
  background->set_bubble_events(true);
  background->set_bounds_contain_children(true);
  background->set_hover_offset(0.0);
  VR_BIND_BUTTON_COLORS(model, background.get(), &ColorScheme::url_bar_button,
                        &Button::SetButtonColors);
  background->AddChild(std::move(suggestion_layout));

  element_binding->bindings().push_back(
      VR_BIND_FUNC(base::string16, SuggestionBinding, element_binding,
                   model->model()->contents, Text, p_content_text, SetText));
  element_binding->bindings().push_back(
      std::make_unique<Binding<TextFormatting>>(
          VR_BIND_LAMBDA(
              [](SuggestionBinding* suggestion, Model* model) {
                return ConvertClassification(
                    suggestion->model()->contents_classifications,
                    suggestion->model()->contents.size(),
                    model->color_scheme());
              },
              base::Unretained(element_binding), base::Unretained(model)),
          VR_BIND_LAMBDA(
              [](Text* v, const TextFormatting& formatting) {
                v->SetFormatting(formatting);
              },
              base::Unretained(p_content_text))));
  element_binding->bindings().push_back(
      std::make_unique<Binding<base::string16>>(
          VR_BIND_LAMBDA(
              [](SuggestionBinding* m) { return m->model()->description; },
              base::Unretained(element_binding)),
          VR_BIND_LAMBDA(
              [](Text* v, const base::string16& text) {
                v->SetVisible(!text.empty());
                v->SetText(text);
              },
              base::Unretained(p_description_text))));
  element_binding->bindings().push_back(
      std::make_unique<Binding<TextFormatting>>(
          VR_BIND_LAMBDA(
              [](SuggestionBinding* suggestion, Model* model) {
                return ConvertClassification(
                    suggestion->model()->description_classifications,
                    suggestion->model()->description.size(),
                    model->color_scheme());
              },
              base::Unretained(element_binding), base::Unretained(model)),
          VR_BIND_LAMBDA(
              [](Text* v, const TextFormatting& formatting) {
                v->SetFormatting(formatting);
              },
              base::Unretained(p_description_text))));
  element_binding->bindings().push_back(
      VR_BIND(const gfx::VectorIcon*, SuggestionBinding, element_binding,
              model->model()->icon, VectorIcon, p_icon, view->SetIcon(*value)));
  element_binding->set_view(background.get());
  scene->AddUiElement(kOmniboxSuggestions, std::move(background));
}

void OnSuggestionModelRemoved(UiScene* scene, SuggestionBinding* binding) {
  scene->RemoveUiElement(binding->view()->id());
}

std::unique_ptr<TransientElement> CreateTransientParent(UiElementName name,
                                                        int timeout_seconds,
                                                        bool animate_opacity) {
  auto element = std::make_unique<SimpleTransientElement>(
      base::TimeDelta::FromSeconds(timeout_seconds));
  element->SetName(name);
  element->SetVisible(false);
  if (animate_opacity)
    element->SetTransitionedProperties({OPACITY});
  return element;
}

std::unique_ptr<UiElement> CreateSpacer(float width, float height) {
  auto spacer = Create<UiElement>(kNone, kPhaseNone);
  spacer->SetType(kTypeSpacer);
  spacer->SetSize(width, height);
  return spacer;
}

std::unique_ptr<UiElement> CreatePrompt(Model* model) {
  auto primary_button = Create<TextButton>(kNone, kPhaseForeground,
                                           kPromptButtonTextSize, nullptr);
  primary_button->SetType(kTypePromptPrimaryButton);
  primary_button->set_corner_radius(kPromptButtonCornerRadius);
  VR_BIND_BUTTON_COLORS(model, primary_button.get(),
                        &ColorScheme::modal_prompt_primary_button_colors,
                        &Button::SetButtonColors);

  auto secondary_button = Create<TextButton>(kNone, kPhaseForeground,
                                             kPromptButtonTextSize, nullptr);
  secondary_button->SetType(kTypePromptSecondaryButton);
  secondary_button->set_corner_radius(kPromptButtonCornerRadius);
  VR_BIND_BUTTON_COLORS(model, secondary_button.get(),
                        &ColorScheme::modal_prompt_secondary_button_colors,
                        &Button::SetButtonColors);

  auto button_layout =
      Create<LinearLayout>(kNone, kPhaseNone, LinearLayout::kLeft);
  button_layout->AddChild(std::move(primary_button));
  button_layout->AddChild(std::move(secondary_button));
  button_layout->set_margin(kPromptButtonGap);
  button_layout->set_x_anchoring(RIGHT);

  auto icon = Create<VectorIcon>(kNone, kPhaseForeground, 100);
  icon->SetType(kTypePromptIcon);
  icon->SetSize(kPromptIconSize, kPromptIconSize);
  icon->set_y_anchoring(TOP);
  VR_BIND_COLOR(model, icon.get(), &ColorScheme::modal_prompt_icon_foreground,
                &VectorIcon::SetColor);

  auto text = Create<Text>(kNone, kPhaseForeground, kPromptFontSize);
  text->SetType(kTypePromptText);
  text->SetLayoutMode(kMultiLineFixedWidth);
  text->SetAlignment(kTextAlignmentLeft);
  text->SetFieldWidth(kPromptTextWidth);
  VR_BIND_COLOR(model, text.get(), &ColorScheme::modal_prompt_foreground,
                &Text::SetColor);

  // This spacer's padding ensures that the top line of text is aligned with the
  // icon even in the multi-line case.
  auto text_spacer = CreateSpacer(0, 0);
  text_spacer->set_bounds_contain_children(true);
  text_spacer->set_padding(0, (kPromptIconSize - kPromptFontSize) / 2, 0, 0);
  text_spacer->set_y_anchoring(TOP);
  text_spacer->AddChild(std::move(text));

  auto message_layout =
      Create<LinearLayout>(kNone, kPhaseNone, LinearLayout::kRight);
  message_layout->set_margin(kPromptIconTextGap);
  message_layout->AddChild(std::move(icon));
  message_layout->AddChild(std::move(text_spacer));

  auto prompt_layout =
      Create<LinearLayout>(kNone, kPhaseNone, LinearLayout::kDown);
  prompt_layout->set_margin(kPromptMessageButtonGap);
  prompt_layout->AddChild(std::move(message_layout));
  prompt_layout->AddChild(std::move(button_layout));

  auto background = Create<Rect>(kNone, kPhaseForeground);
  background->SetType(kTypePromptBackground);
  background->set_bounds_contain_children(true);
  background->set_hit_testable(true);
  background->set_padding(kPromptPadding, kPromptPadding);
  background->SetTranslate(0, 0, kPromptShadowOffsetDMM);
  background->set_corner_radius(kPromptCornerRadius);
  background->AddChild(std::move(prompt_layout));
  VR_BIND_COLOR(model, background.get(), &ColorScheme::modal_prompt_background,
                &Rect::SetColor);

  auto shadow = Create<Shadow>(kNone, kPhaseForeground);
  shadow->SetType(kTypePromptShadow);
  shadow->AddChild(std::move(background));

  // Place an invisible but hittable plane behind the exit prompt, to keep the
  // reticle roughly planar with the content if near content.
  auto backplane = Create<InvisibleHitTarget>(kNone, kPhaseForeground);
  backplane->SetType(kTypePromptBackplane);
  backplane->SetTranslate(0, kPromptVerticalOffsetDMM, 0);
  backplane->SetSize(kBackplaneSize, kBackplaneSize);
  backplane->SetTransitionedProperties({OPACITY});
  backplane->AddChild(std::move(shadow));

  auto scaler = Create<ScaledDepthAdjuster>(kNone, kPhaseNone, kPromptDistance);
  scaler->SetType(kTypeScaledDepthAdjuster);
  scaler->AddChild(std::move(backplane));
  scaler->set_contributes_to_parent_bounds(false);
  return scaler;
}

base::RepeatingCallback<void()> CreatePromptCallback(
    UiUnsupportedMode mode,
    ExitVrPromptChoice choice,
    Model* model,
    UiBrowserInterface* browser) {
  return base::BindRepeating(
      [](UiUnsupportedMode mode, ExitVrPromptChoice choice, Model* m,
         UiBrowserInterface* b) {
        b->OnExitVrPromptResult(choice, mode);
        m->active_modal_prompt_type = kModalPromptTypeNone;
        m->pop_mode(kModeModalPrompt);
      },
      mode, choice, base::Unretained(model), base::Unretained(browser));
}

typedef VectorBinding<ControllerModel, Controller> ControllerSetBinding;
typedef typename ControllerSetBinding::ElementBinding ControllerBinding;

std::unique_ptr<UiElement> CreateControllerLabel(
    UiElementName name,
    float z_offset,
    const base::string16& text,
    Model* model,
    ControllerBinding* element_binding) {
  auto layout = Create<LinearLayout>(name, kPhaseNone, LinearLayout::kLeft);
  layout->set_margin(kControllerLabelLayoutMargin);
  layout->SetTranslate(0, 0, z_offset);
  layout->set_contributes_to_parent_bounds(false);
  layout->AddBinding(VR_BIND_FUNC(
      LayoutAlignment, ControllerBinding, element_binding,
      model->model()->handedness == ControllerModel::kRightHanded ? LEFT
                                                                  : RIGHT,
      LinearLayout, layout.get(), set_x_centering));
  layout->AddBinding(
      VR_BIND_FUNC(LinearLayout::Direction, ControllerBinding, element_binding,
                   model->model()->handedness == ControllerModel::kRightHanded
                       ? LinearLayout::kRight
                       : LinearLayout::kLeft,
                   LinearLayout, layout.get(), set_direction));

  auto spacer = std::make_unique<UiElement>();
  spacer->SetType(kTypeSpacer);
  spacer->SetVisible(true);
  spacer->set_requires_layout(true);
  spacer->SetSize(kControllerLabelSpacerSize, kControllerLabelSpacerSize);

  auto callout = Create<Rect>(kNone, kPhaseForeground);
  callout->SetVisible(true);
  callout->SetColor(SK_ColorWHITE);
  callout->SetSize(kControllerLabelCalloutWidth, kControllerLabelCalloutHeight);
  callout->SetRotate(1, 0, 0, -base::kPiFloat / 2);

  auto label =
      Create<Text>(kNone, kPhaseForeground, kControllerLabelFontHeight);
  label->SetText(text);
  label->SetColor(model->color_scheme().controller_label_callout);
  label->SetVisible(true);
  label->SetAlignment(kTextAlignmentRight);
  label->SetLayoutMode(kSingleLine);
  label->SetRotate(1, 0, 0, -base::kPiFloat / 2);
  label->SetShadowsEnabled(true);
  label->SetScale(kControllerLabelScale, kControllerLabelScale,
                  kControllerLabelScale);

  layout->AddChild(std::move(spacer));
  layout->AddChild(std::move(callout));
  layout->AddChild(std::move(label));

  return layout;
}

std::unique_ptr<UiElement> CreateControllerElement(
    Model* model,
    ControllerBinding* element_binding) {
  auto controller = Create<Controller>(kController, kPhaseForeground);
  controller->AddBinding(VR_BIND_FUNC(gfx::Transform, ControllerBinding,
                                      element_binding,
                                      model->model()->transform, Controller,
                                      controller.get(), set_local_transform));
  controller->AddBinding(VR_BIND_FUNC(float, ControllerBinding, element_binding,
                                      model->model()->opacity, Controller,
                                      controller.get(), SetOpacity));

  auto touchpad_button =
      Create<Rect>(kControllerTouchpadButton, kPhaseForeground);
  touchpad_button->SetColor(model->color_scheme().controller_button);
  touchpad_button->SetSize(kControllerWidth, kControllerWidth);
  touchpad_button->SetRotate(1, 0, 0, -base::kPiFloat / 2);
  touchpad_button->SetTranslate(0.0f, 0.0f,
                                -(kControllerLength - kControllerWidth) / 2);
  touchpad_button->SetCornerRadii({kControllerWidth / 2, kControllerWidth / 2,
                                   kControllerWidth / 2, kControllerWidth / 2});
  touchpad_button->AddBinding(std::make_unique<Binding<SkColor>>(
      VR_BIND_LAMBDA(
          [](ControllerBinding* m, Model* model) {
            return m->model()->touchpad_button_state ==
                           ControllerModel::ButtonState::kDown
                       ? model->color_scheme().controller_button_down
                       : model->color_scheme().controller_button;
          },
          base::Unretained(element_binding), base::Unretained(model)),
      VR_BIND_LAMBDA(
          [](Rect* touchpad_button, const SkColor& value) {
            touchpad_button->SetColor(value);
          },
          base::Unretained(touchpad_button.get()))));

  controller->AddChild(std::move(touchpad_button));

  auto app_button =
      Create<VectorIcon>(kControllerAppButton, kPhaseForeground, 100);
  app_button->SetIcon(GetVrIcon(kVrDaydreamControllerAppButtonIcon));
  app_button->SetColor(model->color_scheme().controller_button);
  app_button->SetSize(kControllerSmallButtonSize, kControllerSmallButtonSize);
  app_button->SetRotate(1, 0, 0, -base::kPiFloat / 2);
  app_button->SetTranslate(0.0f, 0.0f, kControllerAppButtonZ);
  app_button->AddBinding(std::make_unique<Binding<SkColor>>(
      VR_BIND_LAMBDA(
          [](ControllerBinding* m, Model* model) {
            return m->model()->app_button_state ==
                           ControllerModel::ButtonState::kDown
                       ? model->color_scheme().controller_button_down
                       : model->color_scheme().controller_button;
          },
          base::Unretained(element_binding), base::Unretained(model)),
      VR_BIND_LAMBDA([](VectorIcon* app_button,
                        const SkColor& value) { app_button->SetColor(value); },
                     base::Unretained(app_button.get()))));

  controller->AddChild(std::move(app_button));

  auto home_button =
      Create<VectorIcon>(kControllerHomeButton, kPhaseForeground, 100);
  home_button->SetIcon(GetVrIcon(kVrDaydreamControllerHomeButtonIcon));
  home_button->SetColor(model->color_scheme().controller_button);
  home_button->SetSize(kControllerSmallButtonSize, kControllerSmallButtonSize);
  home_button->SetRotate(1, 0, 0, -base::kPiFloat / 2);
  home_button->SetTranslate(0.0f, 0.0f, kControllerHomeButtonZ);
  home_button->AddBinding(std::make_unique<Binding<SkColor>>(
      VR_BIND_LAMBDA(
          [](ControllerBinding* m, Model* model) {
            return m->model()->home_button_state ==
                           ControllerModel::ButtonState::kDown
                       ? model->color_scheme().controller_button_down
                       : model->color_scheme().controller_button;
          },
          base::Unretained(element_binding), base::Unretained(model)),
      VR_BIND_LAMBDA([](VectorIcon* home_button,
                        const SkColor& value) { home_button->SetColor(value); },
                     base::Unretained(home_button.get()))));

  controller->AddChild(std::move(home_button));

  auto battery_layout =
      Create<LinearLayout>(kNone, kPhaseNone, LinearLayout::kRight);
  battery_layout->set_margin(kControllerBatteryDotMargin);
  battery_layout->SetRotate(1, 0, 0, -base::kPiFloat / 2);
  battery_layout->SetTranslate(0.0f, 0.0f, kControllerBatteryDotZ);

  for (int i = 0; i < kControllerBatteryDotCount; ++i) {
    auto battery_dot =
        Create<Rect>(static_cast<UiElementName>(kControllerBatteryDot0 + i),
                     kPhaseForeground);
    battery_dot->SetSize(kControllerBatteryDotSize, kControllerBatteryDotSize);
    battery_dot->set_corner_radius(kControllerBatteryDotSize / 2);

    battery_dot->AddBinding(std::make_unique<Binding<SkColor>>(
        VR_BIND_LAMBDA(
            [](ControllerBinding* m, Model* model, int index) {
              return m->model()->battery_level > index
                         ? model->color_scheme().controller_battery_full
                         : model->color_scheme().controller_battery_empty;
            },
            base::Unretained(element_binding), base::Unretained(model), i),
        VR_BIND_LAMBDA(
            [](Rect* battery_dot, const SkColor& value) {
              battery_dot->SetColor(value);
            },
            base::Unretained(battery_dot.get()))));

    battery_layout->AddChild(std::move(battery_dot));
  }

  controller->AddChild(std::move(battery_layout));

  element_binding->set_view(controller.get());

  return controller;
}

void OnControllerModelAdded(UiScene* scene,
                            Model* model,
                            ControllerBinding* element_binding) {
  auto controller = CreateControllerElement(model, element_binding);

  auto callout_group = Create<UiElement>(kNone, kPhaseNone);
  callout_group->SetVisible(false);
  callout_group->SetTransitionedProperties({OPACITY});
  callout_group->SetTransitionDuration(
      base::TimeDelta::FromMilliseconds(kControllerLabelTransitionDurationMs));
  callout_group->AddBinding(
      VR_BIND_FUNC(bool, ControllerBinding, element_binding,
                   model->model()->resting_in_viewport, UiElement,
                   callout_group.get(), SetVisible));

  auto trackpad_button =
      CreateControllerLabel(kControllerTrackpadLabel, kControllerTrackpadOffset,
                            l10n_util::GetStringUTF16(IDS_VR_BUTTON_TRACKPAD),
                            model, element_binding);
  trackpad_button->AddBinding(
      VR_BIND_FUNC(bool, Model, model, !model->reposition_window_enabled(),
                   UiElement, trackpad_button.get(), SetVisible));
  callout_group->AddChild(std::move(trackpad_button));

  auto reposition_button = CreateControllerLabel(
      kControllerTrackpadRepositionLabel, kControllerTrackpadOffset,
      l10n_util::GetStringUTF16(IDS_VR_BUTTON_TRACKPAD_REPOSITION), model,
      element_binding);
  reposition_button->AddBinding(
      VR_BIND_FUNC(bool, Model, model, model->reposition_window_enabled(),
                   UiElement, reposition_button.get(), SetVisible));
  callout_group->AddChild(std::move(reposition_button));

  auto exit_button_label = CreateControllerLabel(
      kControllerExitButtonLabel, kControllerExitButtonOffset,
      l10n_util::GetStringUTF16(IDS_VR_BUTTON_EXIT), model, element_binding);
  exit_button_label->AddBinding(
      VR_BIND_FUNC(bool, Model, model, model->fullscreen_enabled(), UiElement,
                   exit_button_label.get(), SetVisible));
  callout_group->AddChild(std::move(exit_button_label));

  auto back_button_label = CreateControllerLabel(
      kControllerBackButtonLabel, kControllerBackButtonOffset,
      l10n_util::GetStringUTF16(IDS_VR_BUTTON_BACK), model, element_binding);
  back_button_label->AddBinding(VR_BIND_FUNC(
      bool, Model, model,
      model->omnibox_editing_enabled() || model->voice_search_active(),
      UiElement, back_button_label.get(), SetVisible));
  callout_group->AddChild(std::move(back_button_label));

  auto reposition_finish_button = CreateControllerLabel(
      kControllerRepositionFinishLabel, kControllerBackButtonOffset,
      l10n_util::GetStringUTF16(IDS_VR_BUTTON_APP_REPOSITION), model,
      element_binding);
  reposition_finish_button->AddBinding(
      VR_BIND_FUNC(bool, Model, model, model->reposition_window_enabled(),
                   UiElement, reposition_finish_button.get(), SetVisible));
  callout_group->AddChild(std::move(reposition_finish_button));

  controller->AddChild(std::move(callout_group));

  scene->AddUiElement(kControllerGroup, std::move(controller));
}

void OnControllerModelRemoved(UiScene* scene, ControllerBinding* binding) {
  scene->RemoveUiElement(binding->view()->id());
}

EventHandlers CreateRepositioningHandlers(Model* model, UiScene* scene) {
  EventHandlers handlers;
  handlers.button_down = base::BindRepeating(
      [](Model* model) { model->push_mode(kModeRepositionWindow); },
      base::Unretained(model));
  handlers.button_up = base::BindRepeating(
      [](Model* model, Repositioner* repositioner) {
        if (repositioner->HasMovedBeyondThreshold())
          model->pop_mode(kModeRepositionWindow);
      },
      base::Unretained(model),
      base::Unretained(static_cast<Repositioner*>(
          scene->GetUiElementByName(k2dBrowsingRepositioner))));
  return handlers;
}

void BindIndicatorText(Model* model, Text* text, const IndicatorSpec& spec) {
  text->AddBinding(std::make_unique<Binding<std::pair<bool, bool>>>(
      VR_BIND_LAMBDA(
          [](Model* model, bool CapturingStateModel::*signal) {
            return std::make_pair(model->active_capturing.*signal,
                                  model->background_capturing.*signal);
          },
          base::Unretained(model), spec.signal),
      VR_BIND_LAMBDA(
          [](Text* view, int resource, int background_resource,
             int potential_resource, const std::pair<bool, bool>& value) {
            if (value.first)
              view->SetText(l10n_util::GetStringUTF16(resource));
            else if (value.second)
              view->SetText(l10n_util::GetStringUTF16(background_resource));
            else
              view->SetText(l10n_util::GetStringUTF16(potential_resource));
          },
          base::Unretained(text), spec.resource_string,
          spec.background_resource_string, spec.potential_resource_string)));
}

std::unique_ptr<UiElement> CreateWebVrIndicator(Model* model,
                                                UiBrowserInterface* browser,
                                                IndicatorSpec spec) {
  auto container = Create<Rect>(spec.webvr_name, kPhaseOverlayForeground);
  VR_BIND_COLOR(model, container.get(),
                &ColorScheme::webvr_permission_background, &Rect::SetColor);
  container->set_corner_radius(kWebVrPermissionCornerRadius);
  container->set_bounds_contain_children(true);
  container->SetVisible(false);
  container->set_padding(
      kWebVrPermissionLeftPadding, kWebVrPermissionTopPadding,
      kWebVrPermissionRightPadding, kWebVrPermissionBottomPadding);

  auto layout = Create<LinearLayout>(kNone, kPhaseNone, LinearLayout::kRight);
  layout->set_margin(kWebVrPermissionMargin);

  auto icon_element = Create<VectorIcon>(kNone, kPhaseOverlayForeground, 128);
  VR_BIND_COLOR(model, icon_element.get(),
                &ColorScheme::webvr_permission_foreground,
                &VectorIcon::SetColor);
  icon_element->set_y_anchoring(TOP);
  icon_element->SetSize(kWebVrPermissionIconSize, kWebVrPermissionIconSize);
  if (spec.is_url) {
    icon_element->AddBinding(VR_BIND_FUNC(const gfx::VectorIcon*, Model, model,
                                          model->location_bar_state.vector_icon,
                                          VectorIcon, icon_element.get(),
                                          SetIcon));
  } else {
    icon_element->SetIcon(spec.icon);
  }

  std::unique_ptr<UiElement> description_element;
  if (spec.is_url) {
    auto url_text = Create<UrlText>(
        kNone, kPhaseOverlayForeground, kWebVrPermissionFontHeight,
        base::BindRepeating(&UiBrowserInterface::OnUnsupportedMode,
                            base::Unretained(browser),
                            UiUnsupportedMode::kUnhandledCodePoint)

            );
    url_text->SetFieldWidth(kWebVrPermissionTextWidth);
    url_text->AddBinding(VR_BIND_FUNC(GURL, Model, model,
                                      model->location_bar_state.gurl, UrlText,
                                      url_text.get(), SetUrl));
    VR_BIND_COLOR(model, url_text.get(),
                  &ColorScheme::webvr_permission_foreground,
                  &UrlText::SetEmphasizedColor);
    VR_BIND_COLOR(model, url_text.get(),
                  &ColorScheme::webvr_permission_foreground,
                  &UrlText::SetDeemphasizedColor);
    description_element = std::move(url_text);

  } else {
    auto text_element = Create<Text>(kNone, kPhaseOverlayForeground,
                                     kWebVrPermissionFontHeight);
    text_element->SetLayoutMode(kMultiLineFixedWidth);
    text_element->SetAlignment(kTextAlignmentLeft);
    text_element->SetColor(SK_ColorWHITE);
    text_element->SetFieldWidth(kWebVrPermissionTextWidth);
    if (spec.signal)
      BindIndicatorText(model, text_element.get(), spec);
    else
      text_element->SetText(l10n_util::GetStringUTF16(spec.resource_string));
    VR_BIND_COLOR(model, text_element.get(),
                  &ColorScheme::webvr_permission_foreground, &Text::SetColor);
    description_element = std::move(text_element);
  }

  layout->AddChild(std::move(icon_element));
  layout->AddChild(std::move(description_element));
  container->AddChild(std::move(layout));

  return container;
}

std::unique_ptr<UiElement> CreateHostedUi(
    Model* model,
    UiBrowserInterface* browser,
    UiElementName name,
    UiElementName element_name,
    float distance) {
  auto hosted_ui = Create<PlatformUiElement>(element_name, kPhaseForeground);
  hosted_ui->SetSize(kContentWidth * kHostedUiWidthRatio,
                     kContentHeight * kHostedUiHeightRatio);
  // The hosted UI doesn't steal focus so that clikcing on an autofill
  // suggestion doesn't hide the keyboard. We will probably need to change this
  // when we support the keyboard on native UI elements.
  hosted_ui->set_focusable(false);
  hosted_ui->set_requires_layout(false);
  hosted_ui->set_corner_radius(kContentCornerRadius);
  hosted_ui->SetTranslate(0, 0, kHostedUiShadowOffset);
  hosted_ui->AddBinding(VR_BIND_FUNC(PlatformUiInputDelegatePtr, Model, model,
                                     model->hosted_platform_ui.delegate,
                                     PlatformUiElement, hosted_ui.get(),
                                     SetDelegate));
  hosted_ui->AddBinding(VR_BIND_FUNC(
      unsigned int, Model, model, model->hosted_platform_ui.texture_id,
      PlatformUiElement, hosted_ui.get(), SetTextureId));
  hosted_ui->AddBinding(VR_BIND_FUNC(GlTextureLocation, Model, model,
                                     model->content_location, PlatformUiElement,
                                     hosted_ui.get(), SetTextureLocation));
  hosted_ui->AddBinding(std::make_unique<Binding<bool>>(
      VR_BIND_LAMBDA(
          [](Model* m) { return m->hosted_platform_ui.hosted_ui_enabled; },
          base::Unretained(model)),
      VR_BIND_LAMBDA(
          [](PlatformUiElement* dialog, const bool& enabled) {
            dialog->set_requires_layout(enabled);
            dialog->set_hit_testable(enabled);
          },
          base::Unretained(hosted_ui.get()))));
  hosted_ui->AddBinding(
      VR_BIND(bool, Model, model, model->hosted_platform_ui.floating, UiElement,
              hosted_ui.get(),
              view->SetTranslate(0, 0, value ? 0 : kHostedUiShadowOffset)));
  hosted_ui->AddBinding(std::make_unique<Binding<std::pair<bool, gfx::SizeF>>>(
      VR_BIND_LAMBDA(
          [](Model* m) {
            return std::pair<bool, gfx::SizeF>(
                m->hosted_platform_ui.floating,
                gfx::SizeF(m->hosted_platform_ui.rect.width(),
                           m->hosted_platform_ui.rect.height()));
          },
          base::Unretained(model)),
      VR_BIND_LAMBDA(
          [](PlatformUiElement* dialog,
             const std::pair<bool, gfx::SizeF>& value) {
            if (!value.first && value.second.width() > 0) {
              float ratio = static_cast<float>(value.second.height()) /
                            value.second.width();
              dialog->SetSize(kContentWidth * kHostedUiWidthRatio,
                              kContentWidth * kHostedUiWidthRatio * ratio);
            } else if (value.first) {
              dialog->SetSize(kContentWidth * value.second.width(),
                              kContentWidth * value.second.height());
            }
          },
          base::Unretained(hosted_ui.get()))));

  auto shadow = Create<Shadow>(kNone, kPhaseForeground);
  shadow->SetType(kTypePromptShadow);
  shadow->SetTranslate(0, 0, kHostedUiDepthOffset - kHostedUiShadowOffset);
  shadow->SetVisible(false);
  shadow->set_opacity_when_visible(1.0);
  shadow->set_contributes_to_parent_bounds(false);
  shadow->SetTransitionedProperties({OPACITY});
  shadow->AddChild(std::move(hosted_ui));
  shadow->AddBinding(std::make_unique<Binding<std::pair<bool, gfx::PointF>>>(
      VR_BIND_LAMBDA(
          [](Model* m) {
            return std::pair<bool, gfx::PointF>(
                m->hosted_platform_ui.floating,
                gfx::PointF(m->hosted_platform_ui.rect.x(),
                            m->hosted_platform_ui.rect.y()));
          },
          base::Unretained(model)),
      VR_BIND_LAMBDA(
          [](Shadow* shadow, const std::pair<bool, gfx::PointF>& value) {
            if (value.first /* floating */) {
              shadow->set_x_centering(LEFT);
              shadow->set_y_centering(TOP);
              shadow->SetTranslate((value.second.x() - 0.5) * kContentWidth,
                                   (0.5 - value.second.y()) * kContentHeight,
                                   kFloatingHostedUiDistance);
              shadow->set_intensity(0);
            } else {
              shadow->set_x_centering(NONE);
              shadow->set_y_centering(NONE);
              shadow->SetTranslate(
                  0, 0, kHostedUiDepthOffset - kHostedUiShadowOffset);
              shadow->set_intensity(1);
            }
          },
          base::Unretained(shadow.get()))));
  shadow->AddBinding(VR_BIND_FUNC(bool, Model, model,
                                  model->hosted_platform_ui.hosted_ui_enabled,
                                  Shadow, shadow.get(), SetVisible));

  auto backplane = Create<InvisibleHitTarget>(name, kPhaseForeground);
  backplane->SetType(kTypeHostedUiBackplane);
  backplane->SetSize(kSceneSize, kSceneSize);
  backplane->SetTranslate(0.0, kContentVerticalOffset, -kContentDistance);
  backplane->set_contributes_to_parent_bounds(false);
  EventHandlers event_handlers;
  event_handlers.button_up = base::BindRepeating(
      [](Model* model, UiBrowserInterface* browser) {
        if (model->hosted_platform_ui.hosted_ui_enabled) {
          browser->CloseHostedDialog();
        }
      },
      base::Unretained(model), base::Unretained(browser));
  backplane->set_event_handlers(event_handlers);
  backplane->AddChild(std::move(shadow));
  backplane->AddBinding(
      VR_BIND_FUNC(bool, Model, model,
                   model->hosted_platform_ui.hosted_ui_enabled &&
                       model->active_modal_prompt_type == kModalPromptTypeNone,
                   InvisibleHitTarget, backplane.get(), SetVisible));

  return backplane;
}

std::unique_ptr<Grid> CreateGrid(Model* model, UiElementName name) {
  auto grid = Create<Grid>(name, kPhaseBackground);
  grid->set_gridline_count(kFloorGridlineCount);
  grid->set_hit_testable(true);
  grid->set_focusable(false);
  return grid;
}

void ApplyFloorTransform(Rect* floor) {
  floor->SetSize(1.0f, 1.0f);
  floor->SetScale(kSceneSize, kSceneSize, kSceneSize);
  floor->SetTranslate(0.0, kFloorHeight, 0.0);
  floor->SetRotate(1, 0, 0, -base::kPiFloat / 2);
}

void SetVisibleInLayout(UiElement* e, bool v) {
  e->SetVisible(v);
  e->set_requires_layout(v);
}

std::unique_ptr<TransientElement> CreateTextToast(
    UiElementName transient_parent_name,
    UiElementName toast_name,
    Model* model,
    const base::string16& text) {
  auto parent =
      CreateTransientParent(transient_parent_name, kToastTimeoutSeconds, false);
  parent->set_bounds_contain_children(true);
  parent->SetScale(kContentDistance, kContentDistance, 1.0f);

  auto background_element = Create<Rect>(toast_name, kPhaseForeground);
  VR_BIND_COLOR(model, background_element.get(), &ColorScheme::toast_background,
                &Rect::SetColor);

  background_element->set_bounds_contain_children(true);
  background_element->set_padding(kToastXPaddingDMM, kToastYPaddingDMM,
                                  kToastXPaddingDMM, kToastYPaddingDMM);
  background_element->SetTransitionedProperties({OPACITY});
  background_element->SetType(kTypeToastBackground);
  background_element->set_corner_radius(kToastCornerRadiusDMM);

  auto text_element =
      Create<Text>(kNone, kPhaseForeground, kToastTextFontHeightDMM);
  text_element->SetLayoutMode(kSingleLine);
  text_element->SetColor(SK_ColorWHITE);
  text_element->set_owner_name_for_test(toast_name);
  text_element->SetType(kTypeToastText);
  text_element->SetText(text);

  VR_BIND_COLOR(model, text_element.get(), &ColorScheme::toast_foreground,
                &Text::SetColor);

  background_element->AddChild(std::move(text_element));
  parent->AddChild(std::move(background_element));
  return parent;
}

}  // namespace

UiSceneCreator::UiSceneCreator(UiBrowserInterface* browser,
                               UiScene* scene,
                               Ui* ui,
                               ContentInputDelegate* content_input_delegate,
                               KeyboardDelegate* keyboard_delegate,
                               TextInputDelegate* text_input_delegate,
                               AudioDelegate* audio_delegate,
                               Model* model)
    : browser_(browser),
      scene_(scene),
      ui_(ui),
      content_input_delegate_(content_input_delegate),
      keyboard_delegate_(keyboard_delegate),
      text_input_delegate_(text_input_delegate),
      audio_delegate_(audio_delegate),
      model_(model) {}

UiSceneCreator::~UiSceneCreator() {}

void UiSceneCreator::CreateScene() {
  Create2dBrowsingSubtreeRoots();
  CreateWebVrRoot();
  CreateBackground();
  CreateViewportAwareRoot();
  CreateContentQuad();
  Create2dBrowsingHostedUi();
  CreatePrompts();
  CreateSystemIndicators();
  CreateUrlBar();
  CreateOverflowMenu();
  CreateOmnibox();
  CreateCloseButton();
  CreateToasts();
  CreateVoiceSearchUiGroup();
  CreateContentRepositioningAffordance();
  CreateWebVrSubtree();
  CreateKeyboard();
  CreateControllers();
}

void UiSceneCreator::Create2dBrowsingHostedUi() {
  auto hosted_ui_root =
      CreateHostedUi(model_, browser_, k2dBrowsingHostedUi,
                     k2dBrowsingHostedUiContent, kContentDistance);
  scene_->AddUiElement(k2dBrowsingRepositioner, std::move(hosted_ui_root));
}

void UiSceneCreator::Create2dBrowsingSubtreeRoots() {
  auto element = Create<UiElement>(k2dBrowsingRoot, kPhaseNone);
  element->AddBinding(std::make_unique<Binding<bool>>(
      VR_BIND_LAMBDA(
          [](Model* m) {
            return m->browsing_enabled() && !m->waiting_for_background;
          },
          base::Unretained(model_)),
      VR_BIND_LAMBDA([](UiElement* e, const bool& v) { e->SetVisible(v); },
                     base::Unretained(element.get()))));
  element->AddBinding(VR_BIND(
      float, Model, model_, model->floor_height, UiElement, element.get(),
      view->SetTranslate(0, value ? value - kFloorHeight : 0.0, 0.0)));

  scene_->AddUiElement(kRoot, std::move(element));

  element = Create<UiElement>(k2dBrowsingBackground, kPhaseNone);
  scene_->AddUiElement(k2dBrowsingRoot, std::move(element));

  auto repositioner = Create<Repositioner>(k2dBrowsingRepositioner, kPhaseNone);
  repositioner->set_bounds_contain_children(true);
  repositioner->AddBinding(
      VR_BIND_FUNC(bool, Model, model_, model->reposition_window_enabled(),
                   Repositioner, repositioner.get(), SetEnabled));
  repositioner->AddBinding(
      VR_BIND_FUNC(gfx::Vector3dF, Model, model_,
                   model->primary_controller().laser_direction, Repositioner,
                   repositioner.get(), set_laser_direction));
  repositioner->AddBinding(VR_BIND(
      bool, Model, model_, model->primary_controller().recentered, Repositioner,
      repositioner.get(), if (value) { view->Reset(); }));
  scene_->AddUiElement(k2dBrowsingRoot, std::move(repositioner));

  auto hider = Create<UiElement>(k2dBrowsingVisibiltyHider, kPhaseNone);
  hider->SetTransitionedProperties({OPACITY});
  hider->SetTransitionDuration(base::TimeDelta::FromMilliseconds(
      kSpeechRecognitionOpacityAnimationDurationMs));
  VR_BIND_VISIBILITY(
      hider, model->default_browsing_enabled() || model->fullscreen_enabled());
  scene_->AddUiElement(k2dBrowsingRepositioner, std::move(hider));

  auto fader = Create<UiElement>(k2dBrowsingVisibiltyFader, kPhaseNone);
  fader->SetTransitionedProperties({OPACITY});
  fader->SetTransitionDuration(base::TimeDelta::FromMilliseconds(
      kSpeechRecognitionOpacityAnimationDurationMs));
  fader->AddBinding(std::make_unique<Binding<float>>(
      VR_BIND_LAMBDA(
          [](Model* model) {
            if (model->has_mode_in_stack(kModeModalPrompt) ||
                (model->hosted_platform_ui.hosted_ui_enabled &&
                 !model->hosted_platform_ui.floating)) {
              return kModalPromptFadeOpacity;
            }
            return 1.0f;
          },
          base::Unretained(model_)),
      VR_BIND_LAMBDA(
          [](UiElement* e, const float& value) { e->SetOpacity(value); },
          base::Unretained(fader.get()))));
  scene_->AddUiElement(k2dBrowsingVisibiltyHider, std::move(fader));

  element = Create<UiElement>(k2dBrowsingForeground, kPhaseNone);
  element->set_bounds_contain_children(true);
  element->SetTransitionedProperties({OPACITY});
  element->SetTransitionDuration(base::TimeDelta::FromMilliseconds(
      kSpeechRecognitionOpacityAnimationDurationMs));
  scene_->AddUiElement(k2dBrowsingVisibiltyFader, std::move(element));

  element = Create<UiElement>(k2dBrowsingContentGroup, kPhaseNone);
  element->SetTranslate(0, kContentVerticalOffset, -kContentDistance);
  element->SetTransitionedProperties({TRANSFORM});
  element->set_bounds_contain_children(true);
  element->AddBinding(
      VR_BIND(bool, Model, model_, model->fullscreen_enabled(), UiElement,
              element.get(),
              view->SetTranslate(
                  0, value ? kFullscreenVerticalOffset : kContentVerticalOffset,
                  value ? -kFullscreenDistance : -kContentDistance)));
  scene_->AddUiElement(k2dBrowsingForeground, std::move(element));
}

void UiSceneCreator::CreateWebVrRoot() {
  auto element = std::make_unique<UiElement>();
  element->SetName(kWebVrRoot);
  VR_BIND_VISIBILITY(element, model->web_vr_enabled());
  element->AddBinding(VR_BIND(
      float, Model, model_, model->floor_height, UiElement, element.get(),
      view->SetTranslate(0, value ? value - kFloorHeight : 0.0, 0.0)));
  scene_->AddUiElement(kRoot, std::move(element));
}

void UiSceneCreator::CreateSystemIndicators() {
  auto backplane =
      Create<InvisibleHitTarget>(kIndicatorBackplane, kPhaseForeground);
  backplane->set_bounds_contain_children(true);
  backplane->set_contributes_to_parent_bounds(false);
  backplane->set_y_anchoring(TOP);
  backplane->set_corner_radius(kIndicatorCornerRadiusDMM);
  backplane->SetTranslate(0, kIndicatorVerticalOffset,
                          kIndicatorDistanceOffset);
  backplane->SetScale(kIndicatorDepth, kIndicatorDepth, 1.0f);
  VR_BIND_VISIBILITY(backplane, !model->fullscreen_enabled());

  auto indicator_layout =
      Create<LinearLayout>(kIndicatorLayout, kPhaseNone, LinearLayout::kRight);
  indicator_layout->set_margin(kIndicatorMarginDMM);
  indicator_layout->set_contributes_to_parent_bounds(false);

  auto* content_frame = scene_->GetUiElementByName(kContentFrame);
  content_frame->AddBinding(std::make_unique<Binding<bool>>(
      VR_BIND_LAMBDA(
          [](UiElement* plane, UiElement* indicators) {
            if (static_cast<InvisibleHitTarget*>(plane)->hovered())
              return true;
            for (auto& child : indicators->children()) {
              if (static_cast<Button*>(child.get())->hovered())
                return true;
            }
            return false;
          },
          base::Unretained(scene_->GetUiElementByName(kContentFrameHitPlane)),
          base::Unretained(indicator_layout.get())),
      VR_BIND_LAMBDA(
          [](UiElement* e, const bool& value) {
            static_cast<Rect*>(e)->SetLocalOpacity(value ? 1.0f : 0.0f);
          },
          base::Unretained(content_frame))));

  auto specs = GetIndicatorSpecs();
  for (const auto& spec : specs) {
    auto element = std::make_unique<VectorIconButton>(
        base::RepeatingCallback<void()>(), spec.icon, audio_delegate_);
    element->SetName(spec.name);
    element->SetDrawPhase(kPhaseForeground);
    element->SetSize(kIndicatorHeightDMM, kIndicatorHeightDMM);
    element->SetIconScaleFactor(kIndicatorIconScaleFactor);
    element->set_hover_offset(0.0f);
    element->SetSounds(Sounds(), audio_delegate_);
    element->AddBinding(std::make_unique<Binding<bool>>(
        VR_BIND_LAMBDA(
            [](Model* model, bool CapturingStateModel::*signal) {
              return model->active_capturing.*signal ||
                     model->background_capturing.*signal;
            },
            base::Unretained(model_), spec.signal),
        VR_BIND_LAMBDA(
            [](UiElement* view, const bool& value) {
              view->SetVisible(value);
              view->set_requires_layout(value);
            },
            base::Unretained(element.get()))));
    element->AddBinding(std::make_unique<Binding<std::pair<bool, bool>>>(
        VR_BIND_LAMBDA(
            [](UiElement* parent, UiElement* child) {
              return std::make_pair(parent->FirstLaidOutChild() == child,
                                    parent->LastLaidOutChild() == child);
            },
            base::Unretained(indicator_layout.get()),
            base::Unretained(element.get())),
        VR_BIND_LAMBDA(
            [](UiElement* view, const std::pair<bool, bool>& value) {
              CornerRadii radii;
              radii.upper_left = value.first ? kIndicatorCornerRadiusDMM : 0.0f;
              radii.lower_left = radii.upper_left;
              radii.upper_right =
                  value.second ? kIndicatorCornerRadiusDMM : 0.0f;
              radii.lower_right = radii.upper_right;
              view->SetCornerRadii(radii);
            },
            base::Unretained(element.get()))));
    VR_BIND_BUTTON_COLORS(model_, element.get(), &ColorScheme::indicator,
                          &Button::SetButtonColors);

    auto tooltip = Create<Oval>(kNone, kPhaseForeground);
    VR_BIND_COLOR(model_, tooltip.get(),
                  &ColorScheme::webvr_permission_background, &Rect::SetColor);
    tooltip->set_bounds_contain_children(true);
    tooltip->set_contributes_to_parent_bounds(false);
    tooltip->set_padding(kIndicatorXPaddingDMM, kIndicatorYPaddingDMM,
                         kIndicatorXPaddingDMM, kIndicatorYPaddingDMM);
    tooltip->set_y_anchoring(BOTTOM);
    tooltip->set_y_centering(TOP);
    tooltip->SetVisible(false);
    tooltip->SetTranslate(0, kIndicatorOffsetDMM, 0);
    tooltip->set_owner_name_for_test(element->name());
    tooltip->SetTransitionedProperties({OPACITY});
    tooltip->SetType(kTypeTooltip);
    tooltip->AddBinding(VR_BIND_FUNC(bool, Button, element.get(),
                                     model->hovered(), UiElement, tooltip.get(),
                                     SetVisible));

    auto text_element =
        Create<Text>(kNone, kPhaseForeground, kWebVrPermissionFontHeight);
    text_element->SetLayoutMode(kSingleLine);
    text_element->SetColor(SK_ColorWHITE);
    text_element->set_owner_name_for_test(element->name());
    text_element->SetType(kTypeLabel);
    BindIndicatorText(model_, text_element.get(), spec);
    VR_BIND_COLOR(model_, text_element.get(),
                  &ColorScheme::webvr_permission_foreground, &Text::SetColor);

    tooltip->AddChild(std::move(text_element));
    element->AddChild(std::move(tooltip));
    indicator_layout->AddChild(std::move(element));
  }
  backplane->AddChild(std::move(indicator_layout));
  scene_->AddUiElement(k2dBrowsingContentGroup, std::move(backplane));
}

void UiSceneCreator::CreateContentQuad() {
  // Place an invisible but hittable plane behind the content quad, to keep the
  // reticle roughly planar with the content if near content.
  auto hit_plane = Create<InvisibleHitTarget>(kBackplane, kPhaseBackplanes);
  hit_plane->SetSize(kBackplaneSize, kSceneHeight);
  hit_plane->set_contributes_to_parent_bounds(false);

  scene_->AddUiElement(k2dBrowsingContentGroup, std::move(hit_plane));

  auto resizer = Create<Resizer>(kContentResizer, kPhaseNone);
  resizer->AddBinding(VR_BIND_FUNC(bool, Model, model_,
                                   model->reposition_window_enabled(), Resizer,
                                   resizer.get(), SetEnabled));
  resizer->AddBinding(
      VR_BIND_FUNC(gfx::PointF, Model, model_,
                   model->primary_controller().touchpad_touch_position, Resizer,
                   resizer.get(), set_touch_position));
  resizer->AddBinding(VR_BIND_FUNC(
      bool, Model, model_, model->primary_controller().touching_touchpad,
      Resizer, resizer.get(), SetTouchingTouchpad));

  auto main_content = std::make_unique<ContentElement>(
      content_input_delegate_,
      base::BindRepeating(&UiBrowserInterface::OnContentScreenBoundsChanged,
                          base::Unretained(browser_)));
  EventHandlers event_handlers;
  event_handlers.focus_change = base::BindRepeating(
      [](Model* model, ContentElement* e, ContentInputDelegate* delegate,
         bool focused) {
        if (!focused) {
          model->web_input_text_field_info = EditedText();
          delegate->ClearTextInputState();
        }
        e->UpdateInput(model->web_input_text_field_info);
      },
      model_, base::Unretained(main_content.get()),
      base::Unretained(content_input_delegate_));
  main_content->set_event_handlers(event_handlers);
  main_content->SetName(kContentQuad);
  main_content->set_hit_testable(true);
  main_content->SetDrawPhase(kPhaseForeground);
  main_content->SetSize(kContentWidth, kContentHeight);
  main_content->set_corner_radius(kContentCornerRadius);
  main_content->SetTransitionedProperties({BOUNDS});
  main_content->SetTextInputDelegate(text_input_delegate_);
  main_content->AddBinding(std::make_unique<Binding<bool>>(
      VR_BIND_LAMBDA([](Model* m) { return m->editing_web_input; },
                     base::Unretained(model_)),
      VR_BIND_LAMBDA(
          [](ContentElement* e, const bool& v) {
            if (v) {
              e->RequestFocus();
            } else {
              e->RequestUnfocus();
            }
          },
          base::Unretained(main_content.get()))));
  main_content->AddBinding(
      VR_BIND(bool, Model, model_, model->fullscreen_enabled(), UiElement,
              main_content.get(),
              view->SetSize(value ? kFullscreenWidth : kContentWidth,
                            value ? kFullscreenHeight : kContentHeight)));
  main_content->AddBinding(
      VR_BIND_FUNC(gfx::Transform, Model, model_, model->projection_matrix,
                   ContentElement, main_content.get(), SetProjectionMatrix));
  main_content->AddBinding(
      VR_BIND_FUNC(unsigned int, Model, model_, model->content_texture_id,
                   ContentElement, main_content.get(), SetTextureId));
  main_content->AddBinding(
      VR_BIND_FUNC(GlTextureLocation, Model, model_, model->content_location,
                   ContentElement, main_content.get(), SetTextureLocation));
  main_content->AddBinding(VR_BIND_FUNC(
      unsigned int, Model, model_, model->content_overlay_texture_id,
      ContentElement, main_content.get(), SetOverlayTextureId));
  main_content->AddBinding(VR_BIND_FUNC(
      GlTextureLocation, Model, model_, model->content_overlay_location,
      ContentElement, main_content.get(), SetOverlayTextureLocation));
  main_content->AddBinding(VR_BIND_FUNC(
      bool, Model, model_, !model->content_overlay_texture_non_empty,
      ContentElement, main_content.get(), SetOverlayTextureEmpty));
  main_content->AddBinding(std::make_unique<Binding<EditedText>>(
      VR_BIND_LAMBDA([](EditedText* info) { return *info; },
                     base::Unretained(&model_->web_input_text_field_info)),
      VR_BIND_LAMBDA([](ContentElement* e,
                        const EditedText& value) { e->UpdateInput(value); },
                     base::Unretained(main_content.get()))));

  auto indicator_bg = Create<Rect>(kLoadingIndicator, kPhaseForeground);
  indicator_bg->set_contributes_to_parent_bounds(false);
  indicator_bg->set_bounds_contain_children(true);
  indicator_bg->set_y_anchoring(BOTTOM);
  indicator_bg->set_y_centering(BOTTOM);
  indicator_bg->SetTranslate(0, kLoadingIndicatorYOffset, 0);
  indicator_bg->SetCornerRadii(
      {0, 0, kContentCornerRadius, kContentCornerRadius});
  indicator_bg->SetTransitionedProperties({OPACITY});
  VR_BIND_VISIBILITY(indicator_bg, model->loading);
  VR_BIND_COLOR(model_, indicator_bg.get(),
                &ColorScheme::loading_indicator_background, &Rect::SetColor);

  auto indicator_fg =
      Create<Rect>(kLoadingIndicatorForeground, kPhaseForeground);
  indicator_fg->SetCornerRadii(
      {0, 0, kContentCornerRadius, kContentCornerRadius});
  // Start at content width; size is later updated in a content callback.
  indicator_fg->SetSize(kContentWidth, kLoadingIndicatorHeight);
  VR_BIND_COLOR(model_, indicator_fg.get(),
                &ColorScheme::loading_indicator_foreground, &Rect::SetColor);
  indicator_fg->AddBinding(std::make_unique<Binding<float>>(
      VR_BIND_LAMBDA([](Model* m) { return m->load_progress; },
                     base::Unretained(model_)),
      VR_BIND_LAMBDA(
          [](Rect* r, const float& progress) {
            r->SetClipRect({0, 0, progress, 1});
          },
          base::Unretained(indicator_fg.get()))));

  // Have content explicitly resize the loading indicator as it changes, in lieu
  // of adding a UI framework capability.
  main_content->set_on_size_changed_callback(base::BindRepeating(
      [](Rect* rect, const gfx::SizeF& size) {
        rect->SetSize(size.width(), kLoadingIndicatorHeight);
      },
      base::Unretained(indicator_fg.get())));

  indicator_bg->AddChild(std::move(indicator_fg));
  main_content->AddChild(std::move(indicator_bg));

  auto frame = Create<Rect>(kContentFrame, kPhaseForeground);
  frame->set_hit_testable(true);
  frame->set_bounds_contain_children(true);
  frame->set_padding(kRepositionFrameEdgePadding, kRepositionFrameTopPadding,
                     kRepositionFrameEdgePadding, kRepositionFrameEdgePadding);
  frame->set_corner_radius(kContentCornerRadius);
  frame->set_bounds_contain_padding(false);
  frame->SetLocalOpacity(0.0f);
  frame->SetTransitionedProperties({LOCAL_OPACITY});
  frame->SetTransitionDuration(
      base::TimeDelta::FromMilliseconds(kRepositionFrameTransitionDurationMs));
  VR_BIND_COLOR(model_, frame.get(), &ColorScheme::content_reposition_frame,
                &Rect::SetColor);

  auto plane =
      Create<InvisibleHitTarget>(kContentFrameHitPlane, kPhaseForeground);
  plane->set_bounds_contain_children(true);
  plane->set_bounds_contain_padding(false);
  plane->set_corner_radius(kContentCornerRadius);
  plane->set_cursor_type(kCursorReposition);
  Sounds sounds;
  sounds.button_up = kSoundButtonClick;
  plane->SetSounds(sounds, audio_delegate_);
  plane->set_padding(0, kRepositionFrameHitPlaneTopPadding, 0, 0);
  plane->set_event_handlers(CreateRepositioningHandlers(model_, scene_));
  plane->AddBinding(VR_BIND_FUNC(bool, Model, model_,
                                 model->reposition_window_permitted(),
                                 UiElement, plane.get(), set_hit_testable));

  resizer->AddChild(std::move(main_content));
  plane->AddChild(std::move(resizer));
  frame->AddChild(std::move(plane));
  scene_->AddUiElement(k2dBrowsingContentGroup, std::move(frame));

  // Limit reticle distance to a sphere based on maximum content distance.
  scene_->set_background_distance(kFullscreenDistance *
                                  kBackgroundDistanceMultiplier);
}

void UiSceneCreator::CreateExternalPromptNotifcationOverlay() {
#if !defined(OS_ANDROID)
  auto phase = kPhaseForeground;
  auto icon = Create<VectorIcon>(kNone, phase, 100);
  icon->SetType(kTypePromptIcon);
  icon->SetSize(kPromptIconSize, kPromptIconSize);
  icon->set_y_anchoring(TOP);
  VR_BIND_COLOR(model_, icon.get(), &ColorScheme::modal_prompt_icon_foreground,
                &VectorIcon::SetColor);
  VectorIcon* vector_icon = icon.get();

  auto text1 = Create<Text>(kNone, phase, kPromptFontSize);
  text1->SetType(kTypePromptText);
  text1->SetLayoutMode(kMultiLineFixedWidth);
  text1->SetAlignment(kTextAlignmentLeft);
  text1->SetFieldWidth(kPromptTextWidth);
  VR_BIND_COLOR(model_, text1.get(), &ColorScheme::modal_prompt_foreground,
                &Text::SetColor);
  Text* line1_text = text1.get();

  auto text2 = Create<Text>(kNone, phase, kPromptFontSize);
  text2->SetType(kTypePromptText);
  text2->SetLayoutMode(kMultiLineFixedWidth);
  text2->SetAlignment(kTextAlignmentLeft);
  text2->SetFieldWidth(kPromptTextWidth);
  text2->SetText(l10n_util::GetStringUTF16(IDS_DESKTOP_PROMPT_DOFF_HEADSET));
  VR_BIND_COLOR(model_, text2.get(), &ColorScheme::modal_prompt_foreground,
                &Text::SetColor);

  // This spacer's padding ensures that the top line of text is aligned with the
  // icon even in the multi-line case.
  auto text_spacer1 = CreateSpacer(0, 0);
  text_spacer1->set_bounds_contain_children(true);
  text_spacer1->set_padding(0, (kPromptIconSize - kPromptFontSize) / 2, 0, 0);
  text_spacer1->AddChild(std::move(text1));

  // The second spacer gives space between the two strings.
  auto text_spacer2 = CreateSpacer(0, 0);
  text_spacer2->set_bounds_contain_children(true);
  text_spacer2->set_padding(0, kPromptFontSize * 2, 0, 0);
  text_spacer2->AddChild(std::move(text2));

  // Two lines of text:
  auto text_layout =
      Create<LinearLayout>(kNone, kPhaseNone, LinearLayout::kDown);
  text_layout->AddChild(std::move(text_spacer1));
  text_layout->AddChild(std::move(text_spacer2));

  // Contents of the message box.
  auto message_layout =
      Create<LinearLayout>(kNone, kPhaseNone, LinearLayout::kRight);
  message_layout->set_margin(kPromptIconTextGap);
  message_layout->AddChild(std::move(icon));
  message_layout->AddChild(std::move(text_layout));

  auto prompt_window = Create<Rect>(kNone, phase);
  prompt_window->SetType(kTypePromptBackground);
  prompt_window->set_bounds_contain_children(true);
  prompt_window->set_hit_testable(false);
  prompt_window->set_padding(kPromptPadding, kPromptPadding);
  prompt_window->SetTranslate(0, 0, kPromptShadowOffsetDMM);
  prompt_window->set_corner_radius(kPromptCornerRadius);
  prompt_window->AddChild(std::move(message_layout));
  VR_BIND_COLOR(model_, prompt_window.get(),
                &ColorScheme::modal_prompt_background, &Rect::SetColor);

  auto scaler = Create<ScaledDepthAdjuster>(kNone, kPhaseNone, kPromptDistance);
  scaler->SetName(kWebXrExternalPromptNotification);
  scaler->SetType(kTypeScaledDepthAdjuster);
  scaler->AddChild(std::move(prompt_window));
  scaler->set_contributes_to_parent_bounds(false);
  VR_BIND_VISIBILITY(scaler, model->web_vr_enabled() &&
                                 (model->web_vr.external_prompt_notification !=
                                  ExternalPromptNotificationType::kPromptNone));

  scaler->AddBinding(std::make_unique<
                     Binding<std::tuple<ExternalPromptNotificationType, GURL>>>(
      VR_BIND_LAMBDA(
          [](Model* m) {
            return std::tuple<ExternalPromptNotificationType, GURL>(
                m->web_vr.external_prompt_notification,
                m->location_bar_state.gurl);
          },
          base::Unretained(model_)),
      VR_BIND_LAMBDA(
          [](Text* text_element, VectorIcon* icon_element,
             const std::tuple<ExternalPromptNotificationType, GURL>&
                 prompt_data) {
            ExternalPromptNotificationType prompt = std::get<0>(prompt_data);
            if (prompt == ExternalPromptNotificationType::kPromptNone)
              return;

            int message_id = 0;
            const gfx::VectorIcon* icon = nullptr;
            switch (prompt) {
              case ExternalPromptNotificationType::kPromptGenericPermission:
                message_id = IDS_VR_DESKTOP_GENERIC_PERMISSION_PROMPT;
                icon = &GetVrIcon(kVrOpenInBrowserIcon);
                break;
              case ExternalPromptNotificationType::kPromptNone:
                NOTREACHED();
            }

            const GURL& gurl = std::get<1>(prompt_data);
            base::string16 url_text =
                url_formatter::FormatUrlForSecurityDisplay(
                    gurl.GetOrigin(),
                    url_formatter::SchemeDisplay::OMIT_CRYPTOGRAPHIC);

            text_element->SetText(
                l10n_util::GetStringFUTF16(message_id, url_text));
            icon_element->SetIcon(icon);
          },
          base::Unretained(line1_text), base::Unretained(vector_icon))));

  scene_->AddUiElement(kWebVrViewportAwareRoot, std::move(scaler));
#endif  // !defined(OS_ANDROID)
}

void UiSceneCreator::CreateWebVrSubtree() {
  CreateWebVrOverlayElements();
  CreateWebVrTimeoutScreen();
  CreateExternalPromptNotifcationOverlay();

  // This is needed to for accepting permissions in WebVR mode.
  auto hosted_ui_root =
      CreateHostedUi(model_, browser_, kWebVrHostedUi, kWebVrHostedUiContent,
                     kTimeoutScreenDisatance);
  scene_->AddUiElement(kWebVrViewportAwareRoot, std::move(hosted_ui_root));

  // Note, this cannot be a descendant of the viewport aware root, otherwise it
  // will fade out when the viewport aware elements reposition.
  auto bg = std::make_unique<FullScreenRect>();
  bg->SetName(kWebVrBackground);
  bg->SetDrawPhase(kPhaseBackground);
  bg->SetVisible(false);
  bg->SetColor(model_->color_scheme().web_vr_background);
  bg->SetTransitionedProperties({OPACITY});
  VR_BIND_VISIBILITY(bg, model->web_vr_enabled() &&
                             (!model->web_vr.IsImmersiveWebXrVisible() ||
                              model->web_vr.showing_hosted_ui ||
                              model->web_vr.external_prompt_notification !=
                                  ExternalPromptNotificationType::kPromptNone));
  auto grid = CreateGrid(model_, kNone);
  grid->set_owner_name_for_test(kWebVrFloor);
  VR_BIND_COLOR(model_, grid.get(), &ColorScheme::web_vr_floor_grid,
                &Grid::SetGridColor);
  auto grid_bg = Create<Rect>(kWebVrFloor, kPhaseBackground);
  ApplyFloorTransform(grid_bg.get());
  VR_BIND_COLOR(model_, grid_bg.get(), &ColorScheme::web_vr_floor_center,
                &Rect::SetCenterColor);
  VR_BIND_COLOR(model_, grid_bg.get(), &ColorScheme::web_vr_floor_edge,
                &Rect::SetEdgeColor);
  grid_bg->AddBinding(std::make_unique<Binding<bool>>(
      VR_BIND_LAMBDA(
          [](Model* model, UiElement* timeout_screen) {
            return model->web_vr_enabled() &&
                   (model->web_vr.showing_hosted_ui ||
                    timeout_screen->GetTargetOpacity() != 0.f);
          },
          base::Unretained(model_),
          base::Unretained(scene_->GetUiElementByName(kWebVrTimeoutRoot))),
      VR_BIND_LAMBDA(
          [](UiElement* e, const bool& value) { e->SetVisible(value); },
          base::Unretained(grid_bg.get()))));
  grid_bg->AddChild(std::move(grid));
  bg->AddChild(std::move(grid_bg));
  scene_->AddUiElement(kWebVrRoot, std::move(bg));
}

void UiSceneCreator::CreateWebVrTimeoutScreen() {
  auto scaler = std::make_unique<ScaledDepthAdjuster>(kTimeoutScreenDisatance);
  scaler->SetName(kWebVrTimeoutRoot);
  scaler->AddBinding(std::make_unique<Binding<bool>>(
      VR_BIND_LAMBDA(
          [](Model* model) {
            return (model->web_vr.state == kWebVrTimeoutImminent ||
                    model->web_vr.state == kWebVrTimedOut);
          },
          base::Unretained(model_)),
      VR_BIND_LAMBDA(
          [](UiElement* e, const bool& value) { e->SetVisible(value); },
          base::Unretained(scaler.get()))));

  auto spinner = std::make_unique<Spinner>(512);
  spinner->SetName(kWebVrTimeoutSpinner);
  spinner->SetDrawPhase(kPhaseForeground);
  spinner->SetTransitionedProperties({OPACITY});
  spinner->SetVisible(false);
  spinner->SetSize(kTimeoutSpinnerSizeDMM, kTimeoutSpinnerSizeDMM);
  spinner->SetTranslate(0, kTimeoutSpinnerVerticalOffsetDMM, 0);
  spinner->SetColor(model_->color_scheme().web_vr_timeout_spinner);
  spinner->set_hit_testable(true);
  VR_BIND_VISIBILITY(spinner, model->web_vr.state == kWebVrTimeoutImminent);

  auto timeout_message = Create<Rect>(kWebVrTimeoutMessage, kPhaseForeground);
  timeout_message->SetVisible(false);
  timeout_message->set_hit_testable(true);
  timeout_message->set_bounds_contain_children(true);
  timeout_message->set_corner_radius(kTimeoutMessageCornerRadiusDMM);
  timeout_message->SetTransitionedProperties({OPACITY, TRANSFORM});
  timeout_message->set_padding(kTimeoutMessageHorizontalPaddingDMM,
                               kTimeoutMessageVerticalPaddingDMM);
  VR_BIND_VISIBILITY(timeout_message, model->web_vr.state == kWebVrTimedOut);
  timeout_message->SetColor(
      model_->color_scheme().web_vr_timeout_message_background);

  auto timeout_layout = Create<LinearLayout>(kWebVrTimeoutMessageLayout,
                                             kPhaseNone, LinearLayout::kRight);
  timeout_layout->set_margin(kTimeoutMessageLayoutGapDMM);

  auto timeout_icon =
      Create<VectorIcon>(kWebVrTimeoutMessageIcon, kPhaseForeground, 512);
  timeout_icon->SetIcon(GetVrIcon(kVrSadTabIcon));
  timeout_icon->set_hit_testable(true);
  timeout_icon->SetSize(kTimeoutMessageIconWidthDMM,
                        kTimeoutMessageIconHeightDMM);

  auto timeout_text = Create<Text>(kWebVrTimeoutMessageText, kPhaseForeground,
                                   kTimeoutMessageTextFontHeightDMM);
  timeout_text->SetText(
      l10n_util::GetStringUTF16(IDS_VR_WEB_VR_TIMEOUT_MESSAGE));
  timeout_text->SetColor(
      model_->color_scheme().web_vr_timeout_message_foreground);
  timeout_text->SetAlignment(kTextAlignmentLeft);
  timeout_text->SetFieldWidth(kTimeoutMessageTextWidthDMM);
  timeout_text->set_hit_testable(true);

  auto button_scaler =
      std::make_unique<ScaledDepthAdjuster>(kTimeoutButtonDepthOffset);

  auto button =
      Create<DiscButton>(kWebVrTimeoutMessageButton, kPhaseForeground,
                         base::BindRepeating(&UiBrowserInterface::ExitPresent,
                                             base::Unretained(browser_)),
                         GetVrIcon(kVrCloseRoundedIcon), audio_delegate_);
  button->SetVisible(false);
  button->SetTranslate(0, -kTimeoutMessageTextWidthDMM, 0);
  button->SetRotate(1, 0, 0, kTimeoutButtonRotationRad);
  button->SetTransitionedProperties({OPACITY});
  button->SetSize(kWebVrTimeoutMessageButtonDiameterDMM,
                  kWebVrTimeoutMessageButtonDiameterDMM);
  VR_BIND_VISIBILITY(button, model->web_vr.state == kWebVrTimedOut);
  VR_BIND_BUTTON_COLORS(model_, button.get(), &ColorScheme::disc_button_colors,
                        &DiscButton::SetButtonColors);

  auto timeout_button_text =
      Create<Text>(kWebVrTimeoutMessageButtonText, kPhaseForeground,
                   kTimeoutMessageTextFontHeightDMM);

  // Disc-style button text is not uppercase. See https://crbug.com/787654.
  timeout_button_text->SetText(
      l10n_util::GetStringUTF16(IDS_VR_WEB_VR_EXIT_BUTTON_LABEL));
  timeout_button_text->SetColor(model_->color_scheme().web_vr_timeout_spinner);
  timeout_button_text->SetFieldWidth(kTimeoutButtonTextWidthDMM);
  timeout_button_text->set_contributes_to_parent_bounds(false);
  timeout_button_text->set_y_anchoring(BOTTOM);
  timeout_button_text->SetTranslate(0, -kTimeoutButtonTextVerticalOffsetDMM, 0);
  timeout_button_text->set_hit_testable(true);

  button->AddChild(std::move(timeout_button_text));
  timeout_layout->AddChild(std::move(timeout_icon));
  timeout_layout->AddChild(std::move(timeout_text));
  timeout_message->AddChild(std::move(timeout_layout));
  button_scaler->AddChild(std::move(button));
  timeout_message->AddChild(std::move(button_scaler));
  scaler->AddChild(std::move(timeout_message));
  scaler->AddChild(std::move(spinner));
  scene_->AddUiElement(kWebVrViewportAwareRoot, std::move(scaler));
}

void UiSceneCreator::CreateBackground() {
  // Textured background.
  auto background =
      Create<Background>(k2dBrowsingTexturedBackground, kPhaseBackground);
  background->SetVisible(true);
  VR_BIND_VISIBILITY(background, model->background_loaded);
  background->AddBinding(
      VR_BIND_FUNC(float, Model, model_, model->color_scheme().normal_factor,
                   Background, background.get(), SetNormalFactor));
  background->AddBinding(
      VR_BIND_FUNC(float, Model, model_, model->color_scheme().incognito_factor,
                   Background, background.get(), SetIncognitoFactor));
  background->AddBinding(VR_BIND_FUNC(
      float, Model, model_, model->color_scheme().fullscreen_factor, Background,
      background.get(), SetFullscreenFactor));
  scene_->AddUiElement(k2dBrowsingBackground, std::move(background));

  auto stars = Create<Stars>(kStars, kPhaseBackground);
  stars->SetRotate(1, 0, 0, base::kPiFloat * 0.5);
  scene_->AddUiElement(k2dBrowsingTexturedBackground, std::move(stars));

  auto grid = CreateGrid(model_, kNone);
  ApplyFloorTransform(grid.get());
  VR_BIND_COLOR(model_, grid.get(), &ColorScheme::floor_grid,
                &Grid::SetGridColor);
  grid->SetOpacity(kGridOpacity);
  scene_->AddUiElement(k2dBrowsingTexturedBackground, std::move(grid));

  // Fallback background.
  auto element = Create<UiElement>(k2dBrowsingDefaultBackground, kPhaseNone);
  VR_BIND_VISIBILITY(element, !model->background_loaded);
  scene_->AddUiElement(k2dBrowsingBackground, std::move(element));

  auto solid_background =
      Create<FullScreenRect>(kSolidBackground, kPhaseBackground);
  VR_BIND_COLOR(model_, solid_background.get(), &ColorScheme::world_background,
                &Rect::SetColor);
  VR_BIND_VISIBILITY(solid_background, model->browsing_enabled());
  scene_->AddUiElement(k2dBrowsingDefaultBackground,
                       std::move(solid_background));

  auto grid_fallback = CreateGrid(model_, kNone);
  grid_fallback->set_owner_name_for_test(kFloor);
  VR_BIND_COLOR(model_, grid_fallback.get(), &ColorScheme::floor_grid,
                &Grid::SetGridColor);
  auto floor = Create<Rect>(kFloor, kPhaseBackground);
  ApplyFloorTransform(floor.get());
  VR_BIND_COLOR(model_, floor.get(), &ColorScheme::floor,
                &Rect::SetCenterColor);
  VR_BIND_COLOR(model_, floor.get(), &ColorScheme::world_background,
                &Rect::SetEdgeColor);
  floor->AddChild(std::move(grid_fallback));
  scene_->AddUiElement(k2dBrowsingDefaultBackground, std::move(floor));

  // Ceiling.
  auto ceiling = Create<Rect>(kCeiling, kPhaseBackground);
  ceiling->set_hit_testable(true);
  ceiling->set_focusable(false);
  ceiling->SetSize(kSceneSize, kSceneSize);
  ceiling->SetTranslate(0.0, kSceneHeight / 2, 0.0);
  ceiling->SetRotate(1, 0, 0, base::kPiFloat / 2);
  VR_BIND_COLOR(model_, ceiling.get(), &ColorScheme::ceiling,
                &Rect::SetCenterColor);
  VR_BIND_COLOR(model_, ceiling.get(), &ColorScheme::world_background,
                &Rect::SetEdgeColor);
  scene_->AddUiElement(k2dBrowsingDefaultBackground, std::move(ceiling));
}

void UiSceneCreator::CreateViewportAwareRoot() {
  auto element = std::make_unique<ViewportAwareRoot>();
  element->SetName(kWebVrViewportAwareRoot);
  scene_->AddUiElement(kWebVrRoot, std::move(element));

  element = std::make_unique<ViewportAwareRoot>();
  element->SetName(k2dBrowsingViewportAwareRoot);
  element->set_contributes_to_parent_bounds(false);
  scene_->AddUiElement(k2dBrowsingRepositioner, std::move(element));
}

void UiSceneCreator::CreateVoiceSearchUiGroup() {
  auto speech_recognition_root = std::make_unique<UiElement>();
  speech_recognition_root->SetName(kSpeechRecognitionRoot);
  speech_recognition_root->SetVisible(false);
  speech_recognition_root->set_contributes_to_parent_bounds(false);
  speech_recognition_root->SetTranslate(0.f, 0.f, -kContentDistance);
  speech_recognition_root->SetTransitionedProperties({OPACITY});
  speech_recognition_root->SetTransitionDuration(
      base::TimeDelta::FromMilliseconds(
          kSpeechRecognitionOpacityAnimationDurationMs));
  VR_BIND_VISIBILITY(speech_recognition_root, model->voice_search_active());

  auto inner_circle = std::make_unique<Rect>();
  inner_circle->SetName(kSpeechRecognitionCircle);
  inner_circle->SetDrawPhase(kPhaseForeground);
  inner_circle->SetSize(kCloseButtonDiameter * 2, kCloseButtonDiameter * 2);
  inner_circle->set_corner_radius(kCloseButtonDiameter);
  VR_BIND_COLOR(model_, inner_circle.get(),
                &ColorScheme::speech_recognition_circle_background,
                &Rect::SetColor);

  auto microphone_icon = std::make_unique<VectorIcon>(512);
  microphone_icon->SetIcon(GetVrIcon(kVrMicIcon));
  microphone_icon->SetName(kSpeechRecognitionMicrophoneIcon);
  microphone_icon->SetDrawPhase(kPhaseForeground);
  microphone_icon->SetSize(kCloseButtonDiameter, kCloseButtonDiameter);

  auto speech_result_parent =
      Create<UiElement>(kSpeechRecognitionResult, kPhaseNone);
  speech_result_parent->SetTransitionedProperties({OPACITY});
  speech_result_parent->SetTransitionDuration(base::TimeDelta::FromMilliseconds(
      kSpeechRecognitionOpacityAnimationDurationMs));
  speech_result_parent->AddBinding(std::make_unique<Binding<bool>>(
      VR_BIND_LAMBDA(
          [](Model* m) { return !m->speech.recognition_result.empty(); },
          base::Unretained(model_)),
      VR_BIND_LAMBDA(
          [](UiElement* e, const bool& v) {
            if (v)
              e->SetVisibleImmediately(true);
            else
              e->SetVisible(false);
          },
          speech_result_parent.get())));
  auto speech_result =
      std::make_unique<Text>(kVoiceSearchRecognitionResultTextHeight);
  speech_result->SetName(kSpeechRecognitionResultText);
  speech_result->SetDrawPhase(kPhaseForeground);
  speech_result->SetTranslate(0.f, kSpeechRecognitionResultTextYOffset, 0.f);
  speech_result->SetFieldWidth(kVoiceSearchRecognitionResultTextWidth);
  speech_result->SetAlignment(kTextAlignmentCenter);
  VR_BIND_COLOR(model_, speech_result.get(), &ColorScheme::prompt_foreground,
                &Text::SetColor);
  speech_result->AddBinding(VR_BIND_FUNC(base::string16, Model, model_,
                                         model->speech.recognition_result, Text,
                                         speech_result.get(), SetText));
  speech_result_parent->AddChild(std::move(speech_result));

  auto hit_target = std::make_unique<InvisibleHitTarget>();
  hit_target->SetName(kSpeechRecognitionResultBackplane);
  hit_target->SetDrawPhase(kPhaseForeground);
  hit_target->SetSize(kBackplaneSize, kBackplaneSize);
  speech_result_parent->AddChild(std::move(hit_target));

  auto speech_recognition_listening = std::make_unique<UiElement>();
  speech_recognition_listening->SetName(kSpeechRecognitionListening);
  VR_BIND_VISIBILITY(speech_recognition_listening,
                     model->speech.recognition_result.empty());

  auto growing_circle = std::make_unique<Throbber>();
  growing_circle->SetName(kSpeechRecognitionListeningGrowingCircle);
  growing_circle->SetDrawPhase(kPhaseForeground);
  growing_circle->SetSize(kCloseButtonDiameter * 2, kCloseButtonDiameter * 2);
  growing_circle->set_corner_radius(kCloseButtonDiameter);
  VR_BIND_COLOR(model_, growing_circle.get(),
                &ColorScheme::speech_recognition_circle_background,
                &Rect::SetColor);
  growing_circle->AddBinding(
      VR_BIND(int, Model, model_, model->speech.speech_recognition_state,
              Throbber, growing_circle.get(),
              view->SetCircleGrowAnimationEnabled(
                  value == SPEECH_RECOGNITION_IN_SPEECH ||
                  value == SPEECH_RECOGNITION_RECOGNIZING ||
                  value == SPEECH_RECOGNITION_READY)));

  auto close_button = Create<DiscButton>(
      kSpeechRecognitionListeningCloseButton, kPhaseForeground,
      base::BindRepeating(&UiBrowserInterface::SetVoiceSearchActive,
                          base::Unretained(browser_), false),
      GetVrIcon(kVrCloseRoundedIcon), audio_delegate_);
  close_button->SetSize(kVoiceSearchCloseButtonDiameter,
                        kVoiceSearchCloseButtonDiameter);
  close_button->set_hover_offset(kButtonZOffsetHoverDMM * kContentDistance);
  close_button->SetTranslate(0, -kVoiceSearchCloseButtonYOffset, 0);
  close_button->SetRotate(
      1, 0, 0, atan(-kVoiceSearchCloseButtonYOffset / kContentDistance));
  VR_BIND_BUTTON_COLORS(model_, close_button.get(),
                        &ColorScheme::disc_button_colors,
                        &DiscButton::SetButtonColors);

  speech_recognition_listening->AddChild(std::move(growing_circle));
  speech_recognition_listening->AddChild(std::move(close_button));

  speech_recognition_root->AddChild(std::move(inner_circle));
  speech_recognition_root->AddChild(std::move(microphone_icon));
  speech_recognition_root->AddChild(std::move(speech_recognition_listening));
  speech_recognition_root->AddChild(std::move(speech_result_parent));

  scene_->AddUiElement(k2dBrowsingRepositioner,
                       std::move(speech_recognition_root));
}

void UiSceneCreator::CreateContentRepositioningAffordance() {
  auto content_toggle =
      Create<UiElement>(kContentRepositionVisibilityToggle, kPhaseNone);
  content_toggle->SetTransitionedProperties({OPACITY});
  content_toggle->set_bounds_contain_children(true);
  content_toggle->AddBinding(VR_BIND_FUNC(
      float, Model, model_,
      model->reposition_window_enabled() ? kRepositionContentOpacity : 1.0f,
      UiElement, content_toggle.get(), SetOpacity));
  scene_->AddParentUiElement(k2dBrowsingForeground,
                             std::move(content_toggle));

  auto hit_plane =
      Create<InvisibleHitTarget>(kContentRepositionHitPlane, kPhaseForeground);
  hit_plane->set_contributes_to_parent_bounds(false);
  hit_plane->SetSize(kSceneSize, kSceneSize);
  hit_plane->SetTranslate(0.0f, 0.0f, -kContentDistance);
  hit_plane->set_cursor_type(kCursorReposition);
  Sounds sounds;
  sounds.button_up = kSoundButtonClick;
  hit_plane->SetSounds(sounds, audio_delegate_);
  EventHandlers event_handlers;
  event_handlers.button_up = base::BindRepeating(
      [](Model* m) {
        DCHECK(m->reposition_window_enabled());
        m->pop_mode(kModeRepositionWindow);
      },
      base::Unretained(model_));
  hit_plane->set_event_handlers(event_handlers);
  VR_BIND_VISIBILITY(hit_plane, model->reposition_window_enabled());
  scene_->AddUiElement(k2dBrowsingRepositioner, std::move(hit_plane));
}

void UiSceneCreator::CreateControllers() {
  auto root = std::make_unique<UiElement>();
  root->SetName(kControllerRoot);
  VR_BIND_VISIBILITY(root, model->browsing_enabled() ||
                               model->web_vr.state == kWebVrTimedOut ||
                               model->hosted_platform_ui.hosted_ui_enabled);
  scene_->AddUiElement(kRoot, std::move(root));

  auto group = Create<UiElement>(kNone, kPhaseNone);
  group->SetName(kControllerGroup);

  // Set up the vector binding to manage controllers dynamically.
  ControllerSetBinding::ModelAddedCallback added_callback =
      base::BindRepeating(&OnControllerModelAdded, base::Unretained(scene_),
                          base::Unretained(model_));
  ControllerSetBinding::ModelRemovedCallback removed_callback =
      base::BindRepeating(&OnControllerModelRemoved, base::Unretained(scene_));

  group->AddBinding(std::make_unique<ControllerSetBinding>(
      &model_->controllers, added_callback, removed_callback));

  scene_->AddUiElement(kControllerRoot, std::move(group));

  auto reticle_laser_group = Create<UiElement>(kReticleLaserGroup, kPhaseNone);
  reticle_laser_group->SetTransitionedProperties({OPACITY});
  reticle_laser_group->SetTransitionDuration(
      base::TimeDelta::FromMilliseconds(kControllerLabelTransitionDurationMs));
  VR_BIND_VISIBILITY(reticle_laser_group, !model->reposition_window_enabled());

  auto laser = std::make_unique<Laser>(model_);
  laser->SetDrawPhase(kPhaseForeground);
  laser->AddBinding(VR_BIND_FUNC(float, Model, model_,
                                 model->primary_controller().opacity, Laser,
                                 laser.get(), SetOpacity));

  auto reticle = std::make_unique<Reticle>(scene_, model_);
  reticle->SetDrawPhase(kPhaseForeground);
  VR_BIND_VISIBILITY(reticle, model->reticle.target_point != gfx::Point3F());

  auto reposition_group = Create<UiElement>(kRepositionCursor, kPhaseNone);
  VR_BIND_VISIBILITY(reposition_group,
                     model->reticle.cursor_type == kCursorReposition);

  auto reposition_bg = Create<Rect>(kNone, kPhaseForeground);
  reposition_bg->set_owner_name_for_test(kRepositionCursor);
  reposition_bg->SetType(kTypeCursorBackground);
  reposition_bg->SetSize(kRepositionCursorBackgroundSize,
                         kRepositionCursorBackgroundSize);
  reposition_bg->SetDrawPhase(kPhaseForeground);
  VR_BIND_COLOR(model_, reposition_bg.get(),
                &ColorScheme::cursor_background_edge, &Rect::SetEdgeColor);
  VR_BIND_COLOR(model_, reposition_bg.get(),
                &ColorScheme::cursor_background_center, &Rect::SetCenterColor);

  auto reposition_icon = std::make_unique<VectorIcon>(128);
  reposition_icon->set_owner_name_for_test(kRepositionCursor);
  reposition_icon->SetType(kTypeCursorForeground);
  reposition_icon->SetIcon(GetVrIcon(kVrRepositionIcon));
  reposition_icon->SetDrawPhase(kPhaseForeground);
  reposition_icon->SetSize(kRepositionCursorSize, kRepositionCursorSize);
  VR_BIND_COLOR(model_, reposition_icon.get(), &ColorScheme::cursor_foreground,
                &VectorIcon::SetColor);

  reposition_group->AddChild(std::move(reposition_bg));
  reposition_group->AddChild(std::move(reposition_icon));

  reticle->AddChild(std::move(reposition_group));

  reticle_laser_group->AddChild(std::move(laser));
  reticle_laser_group->AddChild(std::move(reticle));

  scene_->AddUiElement(kControllerGroup, std::move(reticle_laser_group));
}

void UiSceneCreator::CreateKeyboard() {
  auto scaler = std::make_unique<ScaledDepthAdjuster>(kKeyboardDistance);
  scaler->SetName(kKeyboardDmmRoot);

  auto keyboard = std::make_unique<Keyboard>();
  keyboard->SetKeyboardDelegate(keyboard_delegate_);
  keyboard->SetDrawPhase(kPhaseForeground);
  keyboard->SetTranslate(0.0, kKeyboardVerticalOffsetDMM, 0.0);
  keyboard->AddBinding(std::make_unique<Binding<std::pair<bool, gfx::PointF>>>(
      VR_BIND_LAMBDA(
          [](Model* m) {
            return std::pair<bool, gfx::PointF>(
                m->primary_controller().touching_touchpad,
                m->primary_controller().touchpad_touch_position);
          },
          base::Unretained(model_)),
      VR_BIND_LAMBDA(
          [](Keyboard* keyboard, const std::pair<bool, gfx::PointF>& value) {
            keyboard->OnTouchStateUpdated(value.first, value.second);
          },
          base::Unretained(keyboard.get()))));
  keyboard->AddBinding(std::make_unique<Binding<bool>>(
      VR_BIND_LAMBDA([](Model* m) { return m->editing_web_input; },
                     base::Unretained(model_)),
      VR_BIND_LAMBDA(
          [](UiElement* e, const bool& enabled) {
            if (enabled) {
              e->SetTranslate(
                  0.0, kKeyboardVerticalOffsetDMM * kKeyboardWebInputOffset,
                  0.0);
            } else {
              e->SetTranslate(0.0, kKeyboardVerticalOffsetDMM, 0.0);
            }
          },
          base::Unretained(keyboard.get()))));
  VR_BIND_VISIBILITY(keyboard, (model->editing_input ||
                                (model->editing_web_input &&
                                 (model->get_mode() == kModeBrowsing ||
                                  model->get_mode() == kModeFullscreen))));
  scene_->AddPerFrameCallback(base::BindRepeating(
      [](Keyboard* keyboard) { keyboard->AdvanceKeyboardFrameIfNeeded(); },
      base::Unretained(keyboard.get())));
  scaler->AddChild(std::move(keyboard));
  scene_->AddUiElement(k2dBrowsingRepositioner, std::move(scaler));
}

void UiSceneCreator::CreateUrlBar() {
  auto positioner = Create<UiElement>(kUrlBarPositioner, kPhaseNone);
  positioner->set_y_anchoring(BOTTOM);
  positioner->SetTranslate(0, kUrlBarRelativeOffset, 0);
  positioner->set_contributes_to_parent_bounds(false);
  scene_->AddUiElement(k2dBrowsingForeground, std::move(positioner));

  auto scaler = std::make_unique<ScaledDepthAdjuster>(kUrlBarDistance);
  scaler->SetName(kUrlBarDmmRoot);
  scaler->set_contributes_to_parent_bounds(false);
  scene_->AddUiElement(kUrlBarPositioner, std::move(scaler));

  auto url_bar = Create<Rect>(kUrlBar, kPhaseForeground);
  url_bar->SetRotate(1, 0, 0, kUrlBarRotationRad);
  url_bar->set_bounds_contain_children(true);
  url_bar->set_corner_radius(kUrlBarHeightDMM / 2);
  url_bar->SetTransitionedProperties({FOREGROUND_COLOR, BACKGROUND_COLOR});
  VR_BIND_VISIBILITY(url_bar, !model->fullscreen_enabled());
  VR_BIND_COLOR(model_, url_bar.get(), &ColorScheme::url_bar_background,
                &Rect::SetColor);
  scene_->AddUiElement(kUrlBarDmmRoot, std::move(url_bar));

  auto layout =
      Create<LinearLayout>(kUrlBarLayout, kPhaseNone, LinearLayout::kRight);
  layout->set_bounds_contain_children(true);
  scene_->AddUiElement(kUrlBar, std::move(layout));

  auto back_button = Create<VectorIconButton>(
      kUrlBarBackButton, kPhaseForeground,
      base::BindRepeating(&UiBrowserInterface::NavigateBack,
                          base::Unretained(browser_)),
      GetVrIcon(kVrBackArrowIcon), audio_delegate_);
  back_button->SetSize(kUrlBarEndButtonWidthDMM, kUrlBarHeightDMM);
  back_button->SetCornerRadii(
      {kUrlBarHeightDMM / 2, 0, kUrlBarHeightDMM / 2, 0});
  back_button->set_hover_offset(0);
  back_button->SetIconScaleFactor(kUrlBarButtonIconSizeDMM / kUrlBarHeightDMM);
  back_button->SetIconTranslation(kUrlBarEndButtonIconOffsetDMM, 0);
  back_button->AddBinding(VR_BIND_FUNC(bool, Model, model_,
                                       model->can_navigate_back, Button,
                                       back_button.get(), SetEnabled));
  VR_BIND_BUTTON_COLORS(model_, back_button.get(), &ColorScheme::url_bar_button,
                        &Button::SetButtonColors);
  scene_->AddUiElement(kUrlBarLayout, std::move(back_button));

  auto separator = Create<Rect>(kUrlBarLeftSeparator, kPhaseForeground);
  separator->set_hit_testable(true);
  separator->SetSize(kUrlBarSeparatorWidthDMM, kUrlBarHeightDMM);
  VR_BIND_COLOR(model_, separator.get(), &ColorScheme::url_bar_separator,
                &Rect::SetColor);
  scene_->AddUiElement(kUrlBarLayout, std::move(separator));

  auto url_click_callback = base::BindRepeating(
      [](Model* model, UiBrowserInterface* browser) {
        if (model->needs_keyboard_update) {
          browser->OnUnsupportedMode(UiUnsupportedMode::kNeedsKeyboardUpdate);
        } else {
          model->push_mode(kModeEditingOmnibox);
        }
      },
      base::Unretained(model_), base::Unretained(browser_));

  auto origin_region = Create<Button>(kUrlBarOriginRegion, kPhaseForeground,
                                      url_click_callback, audio_delegate_);
  origin_region->set_hit_testable(true);
  origin_region->set_bounds_contain_children(true);
  origin_region->set_hover_offset(0);
  VR_BIND_BUTTON_COLORS(model_, origin_region.get(),
                        &ColorScheme::url_bar_button, &Button::SetButtonColors);
  scene_->AddUiElement(kUrlBarLayout, std::move(origin_region));

  // This layout contains the page info icon and URL.
  auto origin_layout = Create<LinearLayout>(kUrlBarOriginLayout, kPhaseNone,
                                            LinearLayout::kRight);
  VR_BIND_VISIBILITY(origin_layout,
                     model->location_bar_state.should_display_url);

  scene_->AddUiElement(kUrlBarOriginRegion, std::move(origin_layout));

  // This layout contains hint-text items, shown when there's no origin.
  auto hint_layout =
      Create<LinearLayout>(kUrlBarHintLayout, kPhaseNone, LinearLayout::kRight);
  VR_BIND_VISIBILITY(hint_layout,
                     !model->location_bar_state.should_display_url);
  scene_->AddUiElement(kUrlBarOriginRegion, std::move(hint_layout));

  auto security_button_region =
      Create<Rect>(kUrlBarSecurityButtonRegion, kPhaseNone);
  security_button_region->SetType(kTypeSpacer);
  security_button_region->SetSize(kUrlBarEndButtonWidthDMM, kUrlBarHeightDMM);
  scene_->AddUiElement(kUrlBarOriginLayout, std::move(security_button_region));

  auto security_button = Create<VectorIconButton>(
      kUrlBarSecurityButton, kPhaseForeground,
      base::BindRepeating(&UiBrowserInterface::ShowPageInfo,
                          base::Unretained(browser_)),
      GetVrIcon(kVrNoneIcon), audio_delegate_);
  security_button->SetIconScaleFactor(kUrlBarButtonIconScaleFactor);
  security_button->SetSize(kUrlBarButtonSizeDMM, kUrlBarButtonSizeDMM);
  security_button->set_corner_radius(kUrlBarItemCornerRadiusDMM);
  security_button->set_hover_offset(kUrlBarButtonHoverOffsetDMM);
  VR_BIND_BUTTON_COLORS(model_, security_button.get(),
                        &ColorScheme::url_bar_button, &Button::SetButtonColors);
  security_button->AddBinding(std::make_unique<Binding<const gfx::VectorIcon*>>(
      VR_BIND_LAMBDA([](Model* m) { return m->location_bar_state.vector_icon; },
                     base::Unretained(model_)),
      VR_BIND_LAMBDA(
          [](VectorIconButton* e, const gfx::VectorIcon* const& icon) {
            if (icon != nullptr) {
              e->SetIcon(*icon);
            }
          },
          security_button.get())));
  security_button->AddBinding(std::make_unique<Binding<ButtonColors>>(
      VR_BIND_LAMBDA(
          [](Model* m) {
            ButtonColors colors = m->color_scheme().url_bar_button;
            if (m->location_bar_state.security_level ==
                security_state::SecurityLevel::DANGEROUS) {
              colors.foreground = m->color_scheme().url_bar_dangerous_icon;
            }
            return colors;
          },
          base::Unretained(model_)),
      VR_BIND_LAMBDA(
          [](VectorIconButton* e, const ButtonColors& colors) {
            e->SetButtonColors(colors);
          },
          base::Unretained(security_button.get()))));
  scene_->AddUiElement(kUrlBarSecurityButtonRegion, std::move(security_button));

  auto url_text = Create<UrlText>(
      kUrlBarUrlText, kPhaseForeground, kUrlBarFontHeightDMM,
      base::BindRepeating(&UiBrowserInterface::OnUnsupportedMode,
                          base::Unretained(browser_),
                          UiUnsupportedMode::kUnhandledCodePoint));
  url_text->SetFieldWidth(kUrlBarUrlWidthDMM);
  url_text->AddBinding(VR_BIND_FUNC(GURL, Model, model_,
                                    model->location_bar_state.gurl, UrlText,
                                    url_text.get(), SetUrl));
  VR_BIND_COLOR(model_, url_text.get(), &ColorScheme::url_text_emphasized,
                &UrlText::SetEmphasizedColor);
  VR_BIND_COLOR(model_, url_text.get(), &ColorScheme::url_text_deemphasized,
                &UrlText::SetDeemphasizedColor);
  scene_->AddUiElement(kUrlBarOriginLayout, std::move(url_text));

  auto right_margin = Create<Rect>(kNone, kPhaseNone);
  right_margin->SetType(kTypeSpacer);
  right_margin->SetSize(kUrlBarOriginRightMarginDMM, 0);
  scene_->AddUiElement(kUrlBarOriginLayout, std::move(right_margin));

  auto hint_text_spacer = Create<Rect>(kNone, kPhaseNone);
  hint_text_spacer->SetType(kTypeSpacer);
  hint_text_spacer->SetSize(kUrlBarOriginContentOffsetDMM, kUrlBarHeightDMM);
  scene_->AddUiElement(kUrlBarHintLayout, std::move(hint_text_spacer));

  auto hint_text =
      Create<Text>(kUrlBarHintText, kPhaseForeground, kUrlBarFontHeightDMM);
  hint_text->SetFieldWidth(kUrlBarOriginRegionWidthDMM -
                           kUrlBarOriginContentOffsetDMM);
  hint_text->SetLayoutMode(TextLayoutMode::kSingleLineFixedWidth);
  hint_text->SetAlignment(kTextAlignmentLeft);
  hint_text->SetText(l10n_util::GetStringUTF16(IDS_SEARCH_OR_TYPE_WEB_ADDRESS));
  VR_BIND_COLOR(model_, hint_text.get(), &ColorScheme::url_bar_hint_text,
                &Text::SetColor);
  scene_->AddUiElement(kUrlBarHintLayout, std::move(hint_text));

  separator = Create<Rect>(kUrlBarRightSeparator, kPhaseForeground);
  separator->set_hit_testable(true);
  separator->SetSize(kUrlBarSeparatorWidthDMM, kUrlBarHeightDMM);
  VR_BIND_COLOR(model_, separator.get(), &ColorScheme::url_bar_separator,
                &Rect::SetColor);
  scene_->AddUiElement(kUrlBarLayout, std::move(separator));

  auto overflow_button = Create<VectorIconButton>(
      kUrlBarOverflowButton, kPhaseForeground,
      base::BindRepeating(
          [](Model* model) { model->overflow_menu_enabled = true; },
          base::Unretained(model_)),
      GetVrIcon(kVrMoreVertIcon), audio_delegate_);
  overflow_button->SetSize(kUrlBarEndButtonWidthDMM, kUrlBarHeightDMM);
  overflow_button->SetCornerRadii(
      {0, kUrlBarHeightDMM / 2, 0, kUrlBarHeightDMM / 2});
  overflow_button->set_hover_offset(0);
  overflow_button->SetIconScaleFactor(kUrlBarButtonIconSizeDMM /
                                      kUrlBarHeightDMM);
  overflow_button->SetIconTranslation(-kUrlBarEndButtonIconOffsetDMM, 0);
  VR_BIND_BUTTON_COLORS(model_, overflow_button.get(),
                        &ColorScheme::url_bar_button, &Button::SetButtonColors);
  scene_->AddUiElement(kUrlBarLayout, std::move(overflow_button));
}

void UiSceneCreator::CreateOverflowMenu() {
  auto overflow_backplane =
      Create<InvisibleHitTarget>(kOverflowMenuBackplane, kPhaseForeground);
  EventHandlers event_handlers;
  event_handlers.button_up = base::BindRepeating(
      [](Model* model) { model->overflow_menu_enabled = false; },
      base::Unretained(model_));
  overflow_backplane->set_event_handlers(event_handlers);
  overflow_backplane->SetSize(kBackplaneSize, kBackplaneSize);
  overflow_backplane->set_contributes_to_parent_bounds(false);
  overflow_backplane->set_y_anchoring(TOP);
  overflow_backplane->SetRotate(1, 0, 0, -kUrlBarRotationRad);
  VR_BIND_VISIBILITY(overflow_backplane, model->overflow_menu_enabled);

  auto overflow_menu = Create<Rect>(kOverflowMenu, kPhaseForeground);
  overflow_menu->set_hit_testable(true);
  overflow_menu->set_y_centering(BOTTOM);
  overflow_menu->set_bounds_contain_children(true);
  overflow_menu->set_contributes_to_parent_bounds(false);
  overflow_menu->SetTranslate(0, kOverflowMenuOffset, 0);
  overflow_menu->set_corner_radius(kUrlBarItemCornerRadiusDMM);
  VR_BIND_COLOR(model_, overflow_menu.get(), &ColorScheme::omnibox_background,
                &Rect::SetColor);

  auto overflow_outer_layout =
      Create<LinearLayout>(kNone, kPhaseNone, LinearLayout::kUp);

  auto button_region = Create<UiElement>(kNone, kPhaseNone);
  button_region->set_bounds_contain_children(true);
  button_region->set_y_anchoring(BOTTOM);
  button_region->set_y_centering(BOTTOM);
  button_region->set_contributes_to_parent_bounds(false);

  auto button_region_bg = Create<Rect>(kNone, kPhaseForeground);
  button_region_bg->SetSize(kOverflowMenuMinimumWidth,
                            kOverflowButtonRegionHeight);
  button_region_bg->SetCornerRadii(
      {0.0f, 0.0f, kUrlBarItemCornerRadiusDMM, kUrlBarItemCornerRadiusDMM});
  button_region_bg->SetOpacity(kOverflowButtonRegionOpacity);
  VR_BIND_COLOR(model_, button_region_bg.get(),
                &ColorScheme::omnibox_background, &Rect::SetColor);
  button_region->AddChild(std::move(button_region_bg));

  // The forward and refresh buttons are anchored to the bottom corners of the
  // reserved space. In the future, when we have more buttons, they may instead
  // be placed in a linear layout (locked to one side).
  std::vector<
      std::tuple<UiElementName, LayoutAlignment, const gfx::VectorIcon&>>
      menu_buttons = {
          {kOverflowMenuForwardButton, LEFT, GetVrIcon(kVrForwardArrowIcon)},
          {kOverflowMenuReloadButton, RIGHT, GetVrIcon(kVrReloadIcon)},
      };
  for (auto& item : menu_buttons) {
    auto button = Create<VectorIconButton>(std::get<0>(item), kPhaseForeground,
                                           base::DoNothing(), std::get<2>(item),
                                           audio_delegate_);
    button->SetType(kTypeOverflowMenuButton);
    button->SetDrawPhase(kPhaseForeground);
    button->SetSize(kUrlBarButtonSizeDMM, kUrlBarButtonSizeDMM);
    button->SetIconScaleFactor(kUrlBarButtonIconScaleFactor);
    button->set_hover_offset(kUrlBarButtonHoverOffsetDMM);
    button->set_corner_radius(kUrlBarItemCornerRadiusDMM);
    button->set_requires_layout(false);
    button->set_contributes_to_parent_bounds(false);
    button->set_x_anchoring(std::get<1>(item));
    button->set_x_centering(std::get<1>(item));
    button->set_y_anchoring(BOTTOM);
    button->set_y_centering(BOTTOM);
    button->SetTranslate(
        kOverflowButtonXPadding * (std::get<1>(item) == RIGHT ? -1 : 1),
        kOverflowMenuYPadding, 0);
    VR_BIND_BUTTON_COLORS(model_, button.get(), &ColorScheme::url_bar_button,
                          &Button::SetButtonColors);

    switch (std::get<0>(item)) {
      case kOverflowMenuForwardButton:
        button->set_click_handler(base::BindRepeating(
            [](Model* model, UiBrowserInterface* browser) {
              model->overflow_menu_enabled = false;
              browser->NavigateForward();
            },
            base::Unretained(model_), base::Unretained(browser_)));
        button->AddBinding(VR_BIND_FUNC(bool, Model, model_,
                                        model->can_navigate_forward, Button,
                                        button.get(), SetEnabled));
        break;
      case kOverflowMenuReloadButton:
        button->set_click_handler(base::BindRepeating(
            [](Model* model, UiBrowserInterface* browser) {
              model->overflow_menu_enabled = false;
              browser->ReloadTab();
            },
            base::Unretained(model_), base::Unretained(browser_)));
        break;
      default:
        break;
    }

    button_region->AddChild(std::move(button));
  }

  int new_incognito_tab_res_id = IDS_VR_MENU_NEW_PRIVATE_TAB;
  int close_incognito_tabs_res_id = IDS_VR_MENU_CLOSE_PRIVATE_TABS;
  if (!model_->use_new_incognito_strings) {
    new_incognito_tab_res_id = IDS_VR_MENU_NEW_INCOGNITO_TAB;
    close_incognito_tabs_res_id = IDS_VR_MENU_CLOSE_INCOGNITO_TABS;
  }

  struct MenuItem {
    UiElementName name;
    int string_id;
    base::RepeatingCallback<void(UiBrowserInterface*)> action;
    base::RepeatingCallback<bool(Model*)> visibility;
  };
  std::vector<MenuItem> menu_items = {
      {
          kOverflowMenuNewIncognitoTabItem, new_incognito_tab_res_id,
          base::BindRepeating(
              [](UiBrowserInterface* browser) { browser->OpenNewTab(true); }),
          base::BindRepeating([](Model* m) { return !m->incognito; }),
      },
      {kOverflowMenuCloseAllIncognitoTabsItem, close_incognito_tabs_res_id,
       base::BindRepeating([](UiBrowserInterface* browser) {
         browser->CloseAllIncognitoTabs();
       }),
       base::BindRepeating([](Model* m) { return m->incognito_tabs_open; })},
      {kOverflowMenuPreferencesItem, IDS_VR_MENU_PREFERENCES,
       base::BindRepeating(
           [](UiBrowserInterface* browser) { browser->OpenSettings(); }),
       base::BindRepeating([](Model* m) { return m->standalone_vr_device; })},
  };

  auto overflow_menu_scroll = Create<ScrollableElement>(
      kNone, kPhaseNone, ScrollableElement::kVertical);
  overflow_menu_scroll->set_max_span(kOverflowMenuMaxSpan);
  overflow_menu_scroll->SetScrollAnchoring(TOP);
  auto overflow_menu_layout = Create<LinearLayout>(
      kOverflowMenuLayout, kPhaseNone, LinearLayout::kDown);

  for (auto& item : menu_items) {
    auto layout = std::make_unique<LinearLayout>(LinearLayout::kRight);
    layout->SetType(kTypeOverflowMenuItem);
    layout->SetDrawPhase(kPhaseNone);

    auto text =
        Create<Text>(kNone, kPhaseForeground, kSuggestionContentTextHeightDMM);
    text->SetDrawPhase(kPhaseForeground);
    text->SetText(l10n_util::GetStringUTF16(item.string_id));
    text->SetLayoutMode(TextLayoutMode::kSingleLineFixedWidth);
    text->SetFieldWidth(kOverflowMenuMinimumWidth -
                        2 * kOverflowMenuItemXPadding);
    text->SetAlignment(kTextAlignmentLeft);
    VR_BIND_COLOR(model_, text.get(), &ColorScheme::menu_text, &Text::SetColor);
    layout->AddChild(std::move(text));

    auto spacer = Create<Rect>(kNone, kPhaseNone);
    spacer->SetType(kTypeSpacer);
    spacer->SetSize(0, kOverflowMenuItemHeight);
    layout->AddChild(std::move(spacer));

    auto background = Create<Button>(item.name, kPhaseForeground,
                                     base::DoNothing(), audio_delegate_);
    background->set_hit_testable(true);
    background->set_bounds_contain_children(true);
    background->set_hover_offset(0);
    background->set_padding(kOverflowMenuItemXPadding, 0);
    VR_BIND_BUTTON_COLORS(model_, background.get(),
                          &ColorScheme::url_bar_button,
                          &Button::SetButtonColors);
    background->AddChild(std::move(layout));
    base::RepeatingClosure callback =
        base::BindRepeating(item.action, base::Unretained(browser_));
    background->set_click_handler(base::BindRepeating(
        [](Model* model, const base::RepeatingClosure& callback) {
          model->overflow_menu_enabled = false;
          callback.Run();
        },
        base::Unretained(model_), callback));
    background->AddBinding(std::make_unique<Binding<bool>>(
        VR_BIND_LAMBDA(item.visibility, base::Unretained(model_)),
        VR_BIND_LAMBDA(
            [](UiElement* e, const bool& value) { e->SetVisible(value); },
            base::Unretained(background.get()))));

    overflow_menu_layout->AddChild(std::move(background));
  }

  // The item that reserves space in the menu layout for the buttons.
  auto button_spacer =
      CreateSpacer(kOverflowMenuMinimumWidth, kOverflowButtonRegionHeight);
  overflow_menu_layout->AddChild(std::move(button_spacer));

  overflow_menu_scroll->AddScrollingChild(std::move(overflow_menu_layout));
  overflow_outer_layout->AddChild(std::move(overflow_menu_scroll));

  auto top_cap = Create<Rect>(kNone, kPhaseNone);
  top_cap->SetType(kTypeSpacer);
  top_cap->SetSize(kOverflowMenuMinimumWidth, kOverflowMenuYPadding);
  overflow_outer_layout->AddChild(std::move(top_cap));
  overflow_menu->AddChild(std::move(overflow_outer_layout));

  overflow_menu->AddChild(std::move(button_region));

  overflow_backplane->AddChild(std::move(overflow_menu));
  scene_->AddUiElement(kUrlBarOverflowButton, std::move(overflow_backplane));
}

void UiSceneCreator::CreateOmnibox() {
  auto scaler =
      Create<ScaledDepthAdjuster>(kOmniboxDmmRoot, kPhaseNone, kUrlBarDistance);

  auto omnibox_root = Create<UiElement>(kOmniboxRoot, kPhaseNone);
  omnibox_root->SetVisible(false);
  omnibox_root->SetTransitionedProperties({OPACITY});
  omnibox_root->SetTransitionDuration(
      base::TimeDelta::FromMilliseconds(kOmniboxTransitionMs));
  VR_BIND_VISIBILITY(omnibox_root, model->get_mode() == kModeEditingOmnibox);

  auto omnibox_outer_layout =
      Create<LinearLayout>(kOmniboxOuterLayout, kPhaseNone, LinearLayout::kUp);

  auto omnibox_suggestion_divider = Create<Rect>(kNone, kPhaseForeground);
  omnibox_suggestion_divider->SetType(kTypeSpacer);
  omnibox_suggestion_divider->SetSize(kOmniboxWidthDMM, kSuggestionGapDMM);
  VR_BIND_COLOR(model_, omnibox_suggestion_divider.get(),
                &ColorScheme::url_bar_separator, &Rect::SetColor);

  auto omnibox_text_field = Create<OmniboxTextField>(
      kOmniboxTextField, kPhaseNone, kOmniboxTextHeightDMM,
      base::BindRepeating(
          [](Model* model, const EditedText& text_input_info) {
            model->omnibox_text_field_info = text_input_info;
          },
          base::Unretained(model_)),
      base::BindRepeating(
          [](UiBrowserInterface* browser, const AutocompleteRequest& request) {
            browser->StartAutocomplete(request);
          },
          base::Unretained(browser_)),
      base::BindRepeating(
          [](UiBrowserInterface* browser) { browser->StopAutocomplete(); },
          base::Unretained(browser_)));
  omnibox_text_field->SetTextInputDelegate(text_input_delegate_);
  omnibox_text_field->set_hit_testable(false);
  omnibox_text_field->SetHintText(
      l10n_util::GetStringUTF16(IDS_SEARCH_OR_TYPE_WEB_ADDRESS));
  // TODO(crbug.com/834308): Refactor this element to be resized by a
  // fixed-width layout, rather than adjusting based on other elements.
  omnibox_text_field->AddBinding(std::make_unique<Binding<bool>>(
      VR_BIND_LAMBDA(&Model::voice_search_available, base::Unretained(model_)),
      VR_BIND_LAMBDA(
          [](TextInput* e, const bool& mic_button_visible) {
            float width = kOmniboxWidthDMM - 2 * kOmniboxTextMarginDMM;
            if (mic_button_visible) {
              width -= kOmniboxTextFieldIconButtonSizeDMM +
                       kOmniboxTextFieldRightMargin;
            }
            e->SetSize(width, 0);
          },
          base::Unretained(omnibox_text_field.get()))));

  EventHandlers event_handlers;
  event_handlers.focus_change = base::BindRepeating(
      [](Model* model, TextInput* text_input, bool focused) {
        if (focused) {
          model->editing_input = true;
          text_input->UpdateInput(model->omnibox_text_field_info);
        } else {
          model->editing_input = false;
          model->pop_mode(kModeEditingOmnibox);
        }
      },
      base::Unretained(model_), base::Unretained(omnibox_text_field.get()));
  omnibox_text_field->set_event_handlers(event_handlers);

  omnibox_text_field->AddBinding(VR_BIND_FUNC(
      bool, Model, model_, model->has_mode_in_stack(kModeEditingOmnibox),
      OmniboxTextField, omnibox_text_field.get(), SetEnabled));
  omnibox_text_field->AddBinding(std::make_unique<Binding<EditedText>>(
      VR_BIND_LAMBDA(
          [](Model* model) { return model->omnibox_text_field_info; },
          base::Unretained(model_)),
      VR_BIND_LAMBDA([](OmniboxTextField* e,
                        const EditedText& value) { e->UpdateInput(value); },
                     base::Unretained(omnibox_text_field.get()))));
  omnibox_text_field->set_input_committed_callback(base::BindRepeating(
      [](Model* model, UiBrowserInterface* browser, Ui* ui,
         const EditedText& text) {
        if (!model->omnibox_suggestions.empty()) {
          browser->Navigate(model->omnibox_suggestions.front().destination,
                            NavigationMethod::kOmniboxUrlEntry);
          ui->OnUiRequestedNavigation();
        }
      },
      base::Unretained(model_), base::Unretained(browser_),
      base::Unretained(ui_)));
  omnibox_text_field->AddBinding(std::make_unique<Binding<Autocompletion>>(
      VR_BIND_LAMBDA(
          [](Model* m) {
            if (!m->omnibox_suggestions.empty()) {
              return m->omnibox_suggestions.front().autocompletion;
            } else {
              return Autocompletion();
            }
          },
          base::Unretained(model_)),
      VR_BIND_LAMBDA([](OmniboxTextField* e,
                        const Autocompletion& v) { e->SetAutocompletion(v); },
                     base::Unretained(omnibox_text_field.get()))));
  omnibox_text_field->AddBinding(std::make_unique<Binding<bool>>(
      VR_BIND_LAMBDA(
          [](Model* m) {
            return m->omnibox_editing_enabled() &&
                   m->active_modal_prompt_type == kModalPromptTypeNone;
          },
          base::Unretained(model_)),
      VR_BIND_LAMBDA(
          [](TextInput* e, Model* m, const bool& v) {
            if (v) {
              e->RequestFocus();
            } else {
              e->RequestUnfocus();
            }
          },
          base::Unretained(omnibox_text_field.get()),
          base::Unretained(model_))));
  omnibox_text_field->AddBinding(VR_BIND_FUNC(
      bool, Model, model_, model->supports_selection, OmniboxTextField,
      omnibox_text_field.get(), set_allow_inline_autocomplete));

  VR_BIND_COLOR(model_, omnibox_text_field.get(), &ColorScheme::url_bar_text,
                &TextInput::SetTextColor);
  VR_BIND_COLOR(model_, omnibox_text_field.get(),
                &ColorScheme::url_bar_hint_text, &TextInput::SetHintColor);
  omnibox_text_field->AddBinding(std::make_unique<Binding<TextSelectionColors>>(
      VR_BIND_LAMBDA(
          [](Model* m) { return m->color_scheme().omnibox_text_selection; },
          base::Unretained(model_)),
      VR_BIND_LAMBDA(
          [](TextInput* e, const TextSelectionColors& colors) {
            e->SetSelectionColors(colors);
          },
          base::Unretained(omnibox_text_field.get()))));

  auto mic_button = Create<VectorIconButton>(
      kOmniboxVoiceSearchButton, kPhaseForeground,
      base::BindRepeating(
          [](UiBrowserInterface* b, Ui* ui) { b->SetVoiceSearchActive(true); },
          base::Unretained(browser_), base::Unretained(ui_)),
      GetVrIcon(kVrMicIcon), audio_delegate_);
  mic_button->SetSize(kUrlBarButtonSizeDMM, kUrlBarButtonSizeDMM);
  mic_button->SetIconScaleFactor(kUrlBarButtonIconScaleFactor);
  mic_button->set_hover_offset(kUrlBarButtonHoverOffsetDMM);
  mic_button->set_corner_radius(kUrlBarItemCornerRadiusDMM);
  VR_BIND_VISIBILITY(mic_button, model->voice_search_available());
  VR_BIND_BUTTON_COLORS(model_, mic_button.get(), &ColorScheme::url_bar_button,
                        &Button::SetButtonColors);

  auto mic_button_spacer =
      CreateSpacer(kOmniboxMicIconRightMarginDMM, kOmniboxHeightDMM);
  VR_BIND_VISIBILITY(mic_button_spacer, model->voice_search_available());

  auto text_field_layout = Create<LinearLayout>(
      kOmniboxTextFieldLayout, kPhaseNone, LinearLayout::kRight);
  text_field_layout->AddChild(
      CreateSpacer(kOmniboxTextMarginDMM, kOmniboxHeightDMM));
  text_field_layout->AddChild(std::move(omnibox_text_field));
  text_field_layout->AddChild(
      CreateSpacer(kOmniboxTextMarginDMM, kOmniboxHeightDMM));
  text_field_layout->AddChild(std::move(mic_button));
  text_field_layout->AddChild(std::move(mic_button_spacer));

  // Set up the vector binding to manage suggestions dynamically.
  SuggestionSetBinding::ModelAddedCallback added_callback = base::BindRepeating(
      &OnSuggestionModelAdded, base::Unretained(scene_),
      base::Unretained(browser_), base::Unretained(ui_),
      base::Unretained(model_), base::Unretained(audio_delegate_));
  SuggestionSetBinding::ModelRemovedCallback removed_callback =
      base::BindRepeating(&OnSuggestionModelRemoved, base::Unretained(scene_));

  auto suggestions_layout =
      Create<LinearLayout>(kOmniboxSuggestions, kPhaseNone, LinearLayout::kUp);
  suggestions_layout->AddBinding(std::make_unique<SuggestionSetBinding>(
      &model_->omnibox_suggestions, added_callback, removed_callback));

  auto button_scaler = Create<ScaledDepthAdjuster>(
      kNone, kPhaseNone, kOmniboxCloseButtonDepthOffset);

  auto close_button = Create<DiscButton>(
      kOmniboxCloseButton, kPhaseForeground,
      base::BindRepeating(
          [](Model* model) { model->pop_mode(kModeEditingOmnibox); },
          base::Unretained(model_)),
      GetVrIcon(kVrBackArrowIcon), audio_delegate_);
  close_button->SetSize(kOmniboxCloseButtonDiameterDMM,
                        kOmniboxCloseButtonDiameterDMM);
  close_button->SetTranslate(0, kOmniboxCloseButtonVerticalOffsetDMM, 0);
  close_button->SetRotate(1, 0, 0, atan(kOmniboxCloseButtonVerticalOffsetDMM));
  close_button->set_hover_offset(kButtonZOffsetHoverDMM);
  VR_BIND_BUTTON_COLORS(model_, close_button.get(),
                        &ColorScheme::disc_button_colors,
                        &DiscButton::SetButtonColors);

  auto suggestions_outer_layout = Create<LinearLayout>(
      kOmniboxSuggestionsOuterLayout, kPhaseNone, LinearLayout::kUp);
  VR_BIND_VISIBILITY(suggestions_outer_layout,
                     !model->omnibox_suggestions.empty());
  suggestions_outer_layout->AddChild(std::move(omnibox_suggestion_divider));
  suggestions_outer_layout->AddChild(
      CreateSpacer(kOmniboxWidthDMM, kSuggestionVerticalPaddingDMM));
  suggestions_outer_layout->AddChild(std::move(suggestions_layout));
  suggestions_outer_layout->AddChild(
      CreateSpacer(kOmniboxWidthDMM, kSuggestionVerticalPaddingDMM));

  omnibox_outer_layout->AddChild(std::move(text_field_layout));
  omnibox_outer_layout->AddChild(std::move(suggestions_outer_layout));

  // Rounded-corner background of all omnibox and suggestion elements.
  auto omnibox_background = Create<Rect>(kOmniboxBackground, kPhaseForeground);
  omnibox_background->set_bounds_contain_children(true);
  omnibox_background->set_hit_testable(true);
  omnibox_background->set_y_centering(BOTTOM);
  omnibox_background->set_contributes_to_parent_bounds(false);
  omnibox_background->set_focusable(false);
  omnibox_background->set_corner_radius(kOmniboxCornerRadiusDMM);
  omnibox_background->SetTranslate(
      0, kOmniboxVerticalOffsetDMM - 0.5 * kOmniboxHeightDMM, 0);
  VR_BIND_COLOR(model_, omnibox_background.get(),
                &ColorScheme::omnibox_background, &Rect::SetColor);
  omnibox_background->AddChild(std::move(omnibox_outer_layout));

  button_scaler->AddChild(std::move(close_button));

  omnibox_root->AddChild(std::move(omnibox_background));
  omnibox_root->AddChild(std::move(button_scaler));

  scaler->AddChild(std::move(omnibox_root));

  UiElement* parent = scene_->GetUiElementByName(k2dBrowsingRepositioner);
  parent->AddChild(std::move(scaler));

  // This binding must run whether or not the omnibox is visible.
  parent->AddBinding(std::make_unique<Binding<std::pair<bool, base::string16>>>(
      VR_BIND_LAMBDA(
          [](Model* m) {
            bool editing_omnibox = m->has_mode_in_stack(kModeEditingOmnibox);
            base::string16 url_text =
                FormatUrlForVr(m->location_bar_state.gurl, nullptr);
            return std::make_pair(editing_omnibox, url_text);
          },
          base::Unretained(model_)),
      VR_BIND_LAMBDA(
          [](Model* m, const std::pair<bool, base::string16>& value) {
            if (value.first /* editing_omnibox */) {
              m->omnibox_text_field_info.current =
                  TextInputInfo(value.second, 0, value.second.size());
            } else {
              m->omnibox_text_field_info = EditedText();
            }
          },
          base::Unretained(model_))));
}

void UiSceneCreator::CreateCloseButton() {
  base::RepeatingCallback<void()> click_handler = base::BindRepeating(
      [](Model* model, UiBrowserInterface* browser) {
        if (model->fullscreen_enabled()) {
          browser->ExitFullscreen();
        }
      },
      base::Unretained(model_), base::Unretained(browser_));
  std::unique_ptr<DiscButton> element =
      Create<DiscButton>(kCloseButton, kPhaseForeground, click_handler,
                         GetVrIcon(kVrCloseRoundedIcon), audio_delegate_);
  element->set_contributes_to_parent_bounds(false);
  element->SetSize(kCloseButtonDiameter, kCloseButtonDiameter);
  element->set_hover_offset(kButtonZOffsetHoverDMM * kCloseButtonDistance);
  element->set_y_anchoring(BOTTOM);
  element->SetTranslate(0, kCloseButtonRelativeOffset, -kCloseButtonDistance);
  VR_BIND_BUTTON_COLORS(model_, element.get(), &ColorScheme::disc_button_colors,
                        &DiscButton::SetButtonColors);

  // Close button is a special control element that needs to be hidden when
  // in WebVR, but it needs to be visible when in cct or fullscreen.
  VR_BIND_VISIBILITY(element, model->fullscreen_enabled());
  element->AddBinding(
      VR_BIND(bool, Model, model_, model->fullscreen_enabled(), UiElement,
              element.get(),
              view->SetTranslate(0, kCloseButtonRelativeOffset,
                                 value ? -kCloseButtonFullscreenDistance
                                       : -kCloseButtonDistance)));
  element->AddBinding(VR_BIND(
      bool, Model, model_, model->fullscreen_enabled(), UiElement,
      element.get(),
      view->SetRotate(
          1, 0, 0,
          atan(value ? kCloseButtonFullscreenVerticalOffset /
                           kCloseButtonFullscreenDistance
                     : kCloseButtonVerticalOffset / kCloseButtonDistance))));
  element->AddBinding(VR_BIND(
      bool, Model, model_, model->fullscreen_enabled(), UiElement,
      element.get(),
      view->SetSize(
          value ? kCloseButtonFullscreenDiameter : kCloseButtonDiameter,
          value ? kCloseButtonFullscreenDiameter : kCloseButtonDiameter)));

  scene_->AddUiElement(k2dBrowsingForeground, std::move(element));
}

void UiSceneCreator::CreatePrompts() {
  auto prompt = CreatePrompt(model_);
  prompt->SetName(kExitPrompt);
  VR_BIND_VISIBILITY(prompt,
                     model->active_modal_prompt_type != kModalPromptTypeNone);
  prompt->AddBinding(std::make_unique<Binding<ModalPromptType>>(
      VR_BIND_LAMBDA([](Model* m) { return m->active_modal_prompt_type; },
                     base::Unretained(model_)),
      VR_BIND_LAMBDA(
          [](UiElement* e, Model* model, UiBrowserInterface* browser,
             const ModalPromptType& type) {
            if (type == kModalPromptTypeNone)
              return;

            int message_id = 0;
            const gfx::VectorIcon* icon = nullptr;
            int primary_button_text_id = 0;
            int secondary_button_text_id = 0;
            ExitVrPromptChoice primary_choice = CHOICE_EXIT;
            ExitVrPromptChoice secondary_choice = CHOICE_STAY;
            UiUnsupportedMode reason = GetReasonForPrompt(type);

            switch (type) {
              case kModalPromptTypeExitVRForVoiceSearchRecordAudioOsPermission:
                message_id = IDS_VR_SHELL_AUDIO_PERMISSION_PROMPT_DESCRIPTION;
                icon = &GetVrIcon(kVrMicIcon);
                primary_button_text_id =
                    IDS_VR_SHELL_AUDIO_PERMISSION_PROMPT_CONTINUE_BUTTON;
                secondary_button_text_id =
                    IDS_VR_SHELL_AUDIO_PERMISSION_PROMPT_ABORT_BUTTON;
                break;
              case kModalPromptTypeUpdateKeyboard:
                message_id = IDS_VR_UPDATE_KEYBOARD_PROMPT;
                icon = &GetVrIcon(kVrInfoOutlineIcon);
                primary_button_text_id =
                    IDS_VR_SHELL_AUDIO_PERMISSION_PROMPT_CONTINUE_BUTTON;
                secondary_button_text_id =
                    IDS_VR_SHELL_AUDIO_PERMISSION_PROMPT_ABORT_BUTTON;
                break;
              case kModalPromptTypeExitVRForSiteInfo:
                message_id = IDS_VR_SHELL_EXIT_PROMPT_DESCRIPTION_SITE_INFO;
                icon = &GetVrIcon(kVrInfoOutlineIcon);
                primary_button_text_id =
                    IDS_VR_SHELL_EXIT_PROMPT_EXIT_VR_BUTTON;
                secondary_button_text_id = IDS_VR_BUTTON_BACK;
                break;
              case kModalPromptTypeExitVRForCertificateInfo:
              case kModalPromptTypeExitVRForConnectionSecurityInfo:
              case kModalPromptTypeGenericUnsupportedFeature:
                message_id = IDS_VR_SHELL_EXIT_PROMPT_DESCRIPTION;
                icon = &GetVrIcon(kVrInfoOutlineIcon);
                primary_button_text_id =
                    IDS_VR_SHELL_EXIT_PROMPT_EXIT_VR_BUTTON;
                secondary_button_text_id = IDS_VR_BUTTON_BACK;
                break;
              case kNumModalPromptTypes:
              case kModalPromptTypeNone:
                NOTREACHED();
                break;
            }
            Text* text_element =
                static_cast<Text*>(e->GetDescendantByType(kTypePromptText));
            text_element->SetText(l10n_util::GetStringUTF16(message_id));
            VectorIcon* icon_element = static_cast<VectorIcon*>(
                e->GetDescendantByType(kTypePromptIcon));
            icon_element->SetIcon(icon);
            TextButton* primary_button = static_cast<TextButton*>(
                e->GetDescendantByType(kTypePromptPrimaryButton));
            // TODO(crbug.com/787654): Uppercasing should be conditional.
            primary_button->SetText(base::i18n::ToUpper(
                l10n_util::GetStringUTF16(primary_button_text_id)));
            primary_button->set_click_handler(
                CreatePromptCallback(reason, primary_choice, model, browser));
            TextButton* secondary_button = static_cast<TextButton*>(
                e->GetDescendantByType(kTypePromptSecondaryButton));
            // TODO(crbug.com/787654): Uppercasing should be conditional.
            secondary_button->SetText(base::i18n::ToUpper(
                l10n_util::GetStringUTF16(secondary_button_text_id)));
            secondary_button->set_click_handler(
                CreatePromptCallback(reason, secondary_choice, model, browser));
            InvisibleHitTarget* backplane = static_cast<InvisibleHitTarget*>(
                e->GetDescendantByType(kTypePromptBackplane));
            EventHandlers event_handlers;
            event_handlers.button_up =
                CreatePromptCallback(reason, CHOICE_NONE, model, browser);
            backplane->set_event_handlers(event_handlers);
          },
          base::Unretained(prompt.get()), base::Unretained(model_),
          base::Unretained(browser_))));
  scene_->AddUiElement(k2dBrowsingRepositioner, std::move(prompt));
}

void UiSceneCreator::CreateWebVrOverlayElements() {
  // Create transient WebVR elements.
  auto indicators = Create<LinearLayout>(kWebVrIndicatorLayout, kPhaseNone,
                                         LinearLayout::kDown);
  indicators->SetTranslate(0, 0, kWebVrPermissionDepth);
  indicators->set_margin(kWebVrPermissionOuterMargin);

  IndicatorSpec app_button_spec = {kNone,
                                   kWebVrExclusiveScreenToast,
                                   GetVrIcon(kVrRemoveCircleOutlineIcon),
                                   IDS_PRESS_APP_TO_EXIT,
                                   0,
                                   0,
                                   nullptr,
                                   false};
  indicators->AddChild(CreateWebVrIndicator(model_, browser_, app_button_spec));

  auto specs = GetIndicatorSpecs();
  for (const auto& spec : specs) {
    indicators->AddChild(CreateWebVrIndicator(model_, browser_, spec));
  }

  auto parent = CreateTransientParent(kWebVrIndicatorTransience,
                                      kToastTimeoutSeconds, true);
  parent->AddBinding(std::make_unique<Binding<std::tuple<bool, bool, bool>>>(
      VR_BIND_LAMBDA(
          [](Model* model) {
            return std::tuple<bool, bool, bool>(
                model->web_vr_enabled() &&
                    model->web_vr.IsImmersiveWebXrVisible() &&
                    model->web_vr.has_received_permissions,
                model->menu_button_long_pressed,
                model->web_vr.showing_hosted_ui);
          },
          base::Unretained(model_)),
      VR_BIND_LAMBDA(
          [](TransientElement* e, Model* model, UiScene* scene,
             const base::Optional<std::tuple<bool, bool, bool>>& last_value,
             const std::tuple<bool, bool, bool>& value) {
            const bool in_web_vr_presentation = std::get<0>(value);
            const bool in_long_press = std::get<1>(value);
            const bool showing_hosted_ui = std::get<2>(value);
            const bool was_in_long_press =
                last_value && std::get<1>(last_value.value());
            const bool was_showing_hosted_ui =
                last_value && std::get<2>(last_value.value());

            if (!in_web_vr_presentation) {
              e->SetVisibleImmediately(false);
              return;
            }

            // The reason we need the previous state is to disguish the
            // situation where the app button has been released after a long
            // press, and the situation when we want to initially show the
            // indicators.
            if (was_in_long_press && !in_long_press)
              return;

            // Similarly, we need to know when we've finished presenting hosted
            // ui because we should not show indicators then.
            if (was_showing_hosted_ui && !showing_hosted_ui)
              return;

            e->SetVisible(true);
            e->RefreshVisible();
            SetVisibleInLayout(
                scene->GetUiElementByName(kWebVrExclusiveScreenToast),
                !model->browsing_disabled && !in_long_press);

            auto specs = GetIndicatorSpecs();
            for (const auto& spec : specs) {
              SetVisibleInLayout(
                  scene->GetUiElementByName(spec.webvr_name),
                  model->active_capturing.*spec.signal ||
                      model->potential_capturing.*spec.signal ||
                      model->background_capturing.*spec.signal);
            }

            e->RemoveKeyframeModels(TRANSFORM);
            if (in_long_press) {
              // We do not do a translation animation for long press.
              e->SetTranslate(0, 0, 0);
              return;
            }

            e->SetTranslate(0, kWebVrPermissionOffsetStart, 0);

            // Build up a keyframe model for the initial transition.
            std::unique_ptr<cc::KeyframedTransformAnimationCurve> curve(
                cc::KeyframedTransformAnimationCurve::Create());

            cc::TransformOperations value_1;
            value_1.AppendTranslate(0, kWebVrPermissionOffsetStart, 0);
            curve->AddKeyframe(cc::TransformKeyframe::Create(
                base::TimeDelta(), value_1,
                cc::CubicBezierTimingFunction::CreatePreset(
                    cc::CubicBezierTimingFunction::EaseType::EASE)));

            cc::TransformOperations value_2;
            value_2.AppendTranslate(0, kWebVrPermissionOffsetOvershoot, 0);
            curve->AddKeyframe(cc::TransformKeyframe::Create(
                base::TimeDelta::FromMilliseconds(kWebVrPermissionOffsetMs),
                value_2,
                cc::CubicBezierTimingFunction::CreatePreset(
                    cc::CubicBezierTimingFunction::EaseType::EASE)));

            cc::TransformOperations value_3;
            value_3.AppendTranslate(0, kWebVrPermissionOffsetFinal, 0);
            curve->AddKeyframe(cc::TransformKeyframe::Create(
                base::TimeDelta::FromMilliseconds(
                    kWebVrPermissionAnimationDurationMs),
                value_3,
                cc::CubicBezierTimingFunction::CreatePreset(
                    cc::CubicBezierTimingFunction::EaseType::EASE)));

            e->AddKeyframeModel(cc::KeyframeModel::Create(
                std::move(curve), Animation::GetNextKeyframeModelId(),
                Animation::GetNextGroupId(), TRANSFORM));
          },
          base::Unretained(parent.get()), base::Unretained(model_),
          base::Unretained(scene_))));

  auto scaler = std::make_unique<ScaledDepthAdjuster>(kWebVrToastDistance);
  scaler->AddChild(std::move(indicators));
  parent->AddChild(std::move(scaler));

  scene_->AddUiElement(kWebVrViewportAwareRoot, std::move(parent));
}

void UiSceneCreator::CreateToasts() {
  auto platform_toast = CreateTextToast(
      kPlatformToastTransientParent, kPlatformToast, model_, base::string16());
  platform_toast->set_contributes_to_parent_bounds(false);
  platform_toast->set_y_anchoring(BOTTOM);
  platform_toast->set_y_centering(TOP);
  platform_toast->SetTranslate(0, kPlatformToastVerticalOffset,
                               kIndicatorDistanceOffset);
  platform_toast->AddBinding(std::make_unique<Binding<const PlatformToast*>>(
      VR_BIND_LAMBDA([](Model* m) { return m->platform_toast.get(); },
                     base::Unretained(model_)),
      VR_BIND_LAMBDA(
          [](TransientElement* t, const PlatformToast* const& value) {
            t->SetVisible(value);
            if (value) {
              t->RefreshVisible();
            }
          },
          base::Unretained(platform_toast.get()))));

  Text* text_element =
      static_cast<Text*>(platform_toast->GetDescendantByType(kTypeToastText));
  DCHECK(text_element);
  text_element->AddBinding(std::make_unique<Binding<const PlatformToast*>>(
      VR_BIND_LAMBDA([](Model* m) { return m->platform_toast.get(); },
                     base::Unretained(model_)),
      VR_BIND_LAMBDA(
          [](Text* t, const PlatformToast* const& value) {
            if (value) {
              t->SetText(value->text);
            }
          },
          base::Unretained(text_element))));

  scene_->AddUiElement(k2dBrowsingContentGroup, std::move(platform_toast));
}

}  // namespace vr
