// Copyright 2018 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 "ash/magnifier/docked_magnifier_controller.h"

#include <algorithm>

#include "ash/accessibility/accessibility_controller.h"
#include "ash/host/ash_window_tree_host.h"
#include "ash/magnifier/magnifier_utils.h"
#include "ash/public/cpp/ash_pref_names.h"
#include "ash/public/cpp/shell_window_ids.h"
#include "ash/root_window_controller.h"
#include "ash/session/session_controller.h"
#include "ash/shell.h"
#include "ash/wm/overview/overview_controller.h"
#include "ash/wm/splitview/split_view_controller.h"
#include "ash/wm/work_area_insets.h"
#include "base/bind.h"
#include "base/numerics/ranges.h"
#include "components/prefs/pref_change_registrar.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "ui/aura/client/drag_drop_client.h"
#include "ui/aura/env.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/ime/ime_bridge.h"
#include "ui/base/ime/input_method.h"
#include "ui/base/ime/text_input_client.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/reflector.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/display/screen.h"
#include "ui/views/widget/widget.h"
#include "ui/wm/core/coordinate_conversion.h"

namespace ash {

namespace {

constexpr float kDefaultMagnifierScale = 4.0f;
constexpr float kMinMagnifierScale = 1.0f;
constexpr float kMaxMagnifierScale = 20.0f;

// The factor by which the offset of scroll events are scaled.
constexpr float kScrollScaleFactor = 0.0125f;

constexpr char kDockedMagnifierViewportWindowName[] =
    "DockedMagnifierViewportWindow";

// Returns true if High Contrast mode is enabled.
bool IsHighContrastEnabled() {
  return Shell::Get()->accessibility_controller()->high_contrast_enabled();
}

// Returns the current cursor location in screen coordinates.
inline gfx::Point GetCursorScreenPoint() {
  return display::Screen::GetScreen()->GetCursorScreenPoint();
}

// Updates the workarea of the display associated with |window| such that the
// given magnifier viewport |height| is allocated at the top of the screen.
void SetViewportHeightInWorkArea(aura::Window* window, int height) {
  DCHECK(window);
  WorkAreaInsets::ForWindow(window->GetRootWindow())
      ->SetDockedMagnifierHeight(height);
}

// Gets the bounds of the Docked Magnifier viewport widget when placed in the
// display whose root window is |root|. The bounds returned correspond to the
// top quarter portion of the screen.
gfx::Rect GetViewportWidgetBoundsInRoot(aura::Window* root) {
  DCHECK(root);
  DCHECK(root->IsRootWindow());

  auto root_bounds = root->GetBoundsInRootWindow();
  root_bounds.set_height(root_bounds.height() /
                         DockedMagnifierController::kScreenHeightDivisor);
  return root_bounds;
}

// Returns the separator layer bounds from the given |viewport_bounds|. The
// separator layer is to be placed right below the viewport.
inline gfx::Rect SeparatorBoundsFromViewportBounds(
    const gfx::Rect& viewport_bounds) {
  return gfx::Rect(viewport_bounds.x(), viewport_bounds.bottom(),
                   viewport_bounds.width(),
                   DockedMagnifierController::kSeparatorHeight);
}

// Returns the angle by which the magnifier layer should be rotated such that
// the effect of the current screen rotation is undone, and the magnifier
// layer shows its contents in the correct rotation.
double GetMagnifierLayerRotationAngle(
    display::Display::Rotation current_display_active_rotation) {
  switch (current_display_active_rotation) {
    case display::Display::ROTATE_0:
      return 0.0;

    case display::Display::ROTATE_90:
      return -90.0;

    case display::Display::ROTATE_180:
      return -180.0;

    case display::Display::ROTATE_270:
      return -270.0;
  }

  NOTREACHED();
  return 0.0;
}

// Returns the child container in |root| that should be used as the parent of
// viewport widget and the separator layer.
aura::Window* GetViewportParentContainerForRoot(aura::Window* root) {
  return root->GetChildById(kShellWindowId_DockedMagnifierContainer);
}

}  // namespace

DockedMagnifierController::DockedMagnifierController() : binding_(this) {
  Shell::Get()->session_controller()->AddObserver(this);
  if (ui::IMEBridge::Get())
    ui::IMEBridge::Get()->AddObserver(this);
}

DockedMagnifierController::~DockedMagnifierController() {
  if (input_method_)
    input_method_->RemoveObserver(this);
  input_method_ = nullptr;
  if (ui::IMEBridge::Get())
    ui::IMEBridge::Get()->RemoveObserver(this);

  Shell* shell = Shell::Get();
  shell->session_controller()->RemoveObserver(this);

  if (GetEnabled()) {
    shell->window_tree_host_manager()->RemoveObserver(this);
    shell->RemovePreTargetHandler(this);
  }
}

// static
void DockedMagnifierController::RegisterProfilePrefs(
    PrefRegistrySimple* registry,
    bool for_test) {
  if (for_test) {
    // In tests there is no remote pref service. Make ash own the prefs.
    registry->RegisterBooleanPref(prefs::kDockedMagnifierEnabled, false,
                                  PrefRegistry::PUBLIC);
  } else {
    // TODO(warx): move ownership to ash.
    registry->RegisterForeignPref(prefs::kDockedMagnifierEnabled);
  }
  registry->RegisterDoublePref(prefs::kDockedMagnifierScale,
                               kDefaultMagnifierScale, PrefRegistry::PUBLIC);
}

void DockedMagnifierController::BindRequest(
    mojom::DockedMagnifierControllerRequest request) {
  binding_.Bind(std::move(request));
}

bool DockedMagnifierController::GetEnabled() const {
  return active_user_pref_service_ &&
         active_user_pref_service_->GetBoolean(prefs::kDockedMagnifierEnabled);
}

float DockedMagnifierController::GetScale() const {
  if (active_user_pref_service_)
    return active_user_pref_service_->GetDouble(prefs::kDockedMagnifierScale);

  return kDefaultMagnifierScale;
}

void DockedMagnifierController::SetEnabled(bool enabled) {
  if (active_user_pref_service_) {
    active_user_pref_service_->SetBoolean(prefs::kDockedMagnifierEnabled,
                                          enabled);
  }
}

void DockedMagnifierController::SetScale(float scale) {
  if (active_user_pref_service_) {
    active_user_pref_service_->SetDouble(
        prefs::kDockedMagnifierScale,
        base::ClampToRange(scale, kMinMagnifierScale, kMaxMagnifierScale));
  }
}

void DockedMagnifierController::StepToNextScaleValue(int delta_index) {
  SetScale(magnifier_utils::GetNextMagnifierScaleValue(
      delta_index, GetScale(), kMinMagnifierScale, kMaxMagnifierScale));
}

void DockedMagnifierController::CenterOnPoint(
    const gfx::Point& point_in_screen) {
  if (!GetEnabled())
    return;

  auto* screen = display::Screen::GetScreen();
  auto* window = screen->GetWindowAtScreenPoint(point_in_screen);
  if (!window) {
    // In tests and sometimes initially on signin screen, |point_in_screen|
    // maybe invalid and doesn't belong to any existing root window. However, we
    // are here because the Docked Magnifier is enabled. We need to create the
    // viewport widget somewhere, so we'll use the primary root window until we
    // get a valid cursor event.
    window = Shell::GetPrimaryRootWindow();
  }

  auto* root_window = window->GetRootWindow();
  DCHECK(root_window);
  SwitchCurrentSourceRootWindowIfNeeded(root_window,
                                        true /* update_old_root_workarea */);

  auto* host = root_window->GetHost();
  DCHECK(host);

  MaybeCachePointOfInterestMinimumHeight(host);

  gfx::Point point_of_interest(point_in_screen);
  ::wm::ConvertPointFromScreen(root_window, &point_of_interest);

  // The point of interest in pixels.
  gfx::PointF point_in_pixels(point_of_interest);

  // Before transforming to pixels, make sure its y-coordinate doesn't go below
  // the minimum height. Do it here for this PointF since the
  // |minimum_point_of_interest_height_| is a float, in order to avoid rounding
  // in the transform to be able to reliably verify it in tests.
  if (point_in_pixels.y() < minimum_point_of_interest_height_)
    point_in_pixels.set_y(minimum_point_of_interest_height_);

  // The pixel space is the magnified space.
  host->GetRootTransform().TransformPoint(&point_in_pixels);
  const float scale = GetScale();
  point_in_pixels.Scale(scale);

  // Transform steps: (Note that the transform is applied in the opposite order)
  // 1- Scale the layer by |scale|.
  // 2- Translate the point of interest back to the origin so that we can rotate
  //    around the Z-axis.
  // 3- Rotate around the Z-axis to undo the effect of screen rotation (if any).
  // 4- Translate the point of interest to the center point of the viewport
  //    widget.
  gfx::Transform transform;

  // 4- Translate to the center of the viewport widget.
  const gfx::Point viewport_center_point =
      GetViewportWidgetBoundsInRoot(current_source_root_window_).CenterPoint();
  transform.Translate(viewport_center_point.x(), viewport_center_point.y());

  // 3- Rotate around Z-axis. Account for a possibly rotated screen.
  const int64_t display_id =
      screen->GetDisplayNearestPoint(point_in_screen).id();
  DCHECK_NE(display_id, display::kInvalidDisplayId);
  const auto& display_info =
      Shell::Get()->display_manager()->GetDisplayInfo(display_id);
  transform.RotateAboutZAxis(
      GetMagnifierLayerRotationAngle(display_info.GetActiveRotation()));

  // 2- Translate back to origin.
  transform.Translate(-point_in_pixels.x(), -point_in_pixels.y());

  // 1- Scale.
  transform.Scale(scale, scale);

  // When updating the transform, we don't want any animation, otherwise the
  // movement of the mouse won't be very smooth. We want the magnifier layer to
  // update immediately with the movement of the mouse (or the change in the
  // point of interest due to input caret bounds changes ... etc.).
  ui::ScopedLayerAnimationSettings settings(
      viewport_magnifier_layer_->GetAnimator());
  settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(0));
  settings.SetTweenType(gfx::Tween::ZERO);
  settings.SetPreemptionStrategy(ui::LayerAnimator::IMMEDIATELY_SET_NEW_TARGET);
  viewport_magnifier_layer_->SetTransform(transform);
}

void DockedMagnifierController::OnActiveUserPrefServiceChanged(
    PrefService* pref_service) {
  active_user_pref_service_ = pref_service;
  InitFromUserPrefs();
}

void DockedMagnifierController::OnSigninScreenPrefServiceInitialized(
    PrefService* prefs) {
  OnActiveUserPrefServiceChanged(prefs);
}

void DockedMagnifierController::OnMouseEvent(ui::MouseEvent* event) {
  DCHECK(GetEnabled());
  CenterOnPoint(GetCursorScreenPoint());
}

void DockedMagnifierController::OnScrollEvent(ui::ScrollEvent* event) {
  DCHECK(GetEnabled());
  if (!event->IsAltDown() || !event->IsControlDown())
    return;

  if (event->type() == ui::ET_SCROLL_FLING_START ||
      event->type() == ui::ET_SCROLL_FLING_CANCEL) {
    event->StopPropagation();
    return;
  }

  if (event->type() == ui::ET_SCROLL) {
    // Notes: - Clamping of the new scale value happens inside SetScale().
    //        - Refreshing the viewport happens in the handler of the scale pref
    //          changes.
    SetScale(magnifier_utils::GetScaleFromScroll(
        event->y_offset() * kScrollScaleFactor, GetScale(), kMaxMagnifierScale,
        kMinMagnifierScale));
    event->StopPropagation();
  }
}

void DockedMagnifierController::OnTouchEvent(ui::TouchEvent* event) {
  DCHECK(GetEnabled());

  aura::Window* target = static_cast<aura::Window*>(event->target());
  aura::Window* event_root = target->GetRootWindow();
  gfx::Point event_screen_point = event->root_location();
  ::wm::ConvertPointToScreen(event_root, &event_screen_point);
  CenterOnPoint(event_screen_point);
}

void DockedMagnifierController::OnInputContextHandlerChanged() {
  if (!GetEnabled())
    return;

  auto* new_input_method =
      magnifier_utils::GetInputMethod(current_source_root_window_);
  if (new_input_method == input_method_)
    return;

  if (input_method_)
    input_method_->RemoveObserver(this);
  input_method_ = new_input_method;
  if (input_method_)
    input_method_->AddObserver(this);
}

void DockedMagnifierController::OnInputMethodDestroyed(
    const ui::InputMethod* input_method) {
  DCHECK_EQ(input_method, input_method_);
  input_method_->RemoveObserver(this);
  input_method_ = nullptr;
}

void DockedMagnifierController::OnCaretBoundsChanged(
    const ui::TextInputClient* client) {
  if (!GetEnabled()) {
    // There is a small window between the time the "enabled" pref is updated to
    // false, and the time we're notified with this change, upon which we remove
    // the magnifier's viewport widget and stop observing the input method.
    // During this short interval, if focus is in an editable element, the input
    // method can notify us here. In this case, we should just return.
    return;
  }

  aura::client::DragDropClient* drag_drop_client =
      aura::client::GetDragDropClient(current_source_root_window_);
  if (drag_drop_client && drag_drop_client->IsDragDropInProgress()) {
    // Ignore caret bounds change events when they result from changes in window
    // bounds due to dragging. This is to leave the viewport centered around the
    // cursor.
    return;
  }

  const gfx::Rect caret_screen_bounds = client->GetCaretBounds();
  // In many cases, espcially text input events coming from webpages, the caret
  // screen width is 0. Hence we can't check IsEmpty() since it returns true if
  // either of the width or height is 0. We want to abort if only both are 0s.
  if (!caret_screen_bounds.width() && !caret_screen_bounds.height())
    return;

  CenterOnPoint(caret_screen_bounds.CenterPoint());
}

void DockedMagnifierController::OnWidgetDestroying(views::Widget* widget) {
  DCHECK_EQ(widget, viewport_widget_);

  SwitchCurrentSourceRootWindowIfNeeded(nullptr,
                                        false /* update_old_root_workarea */);
}

void DockedMagnifierController::OnDisplayConfigurationChanged() {
  DCHECK(GetEnabled());

  // The viewport might have been on a display that just got removed, and hence
  // the viewport widget and its associated layers are already destroyed. In
  // that case we also cleared the |current_source_root_window_|.
  if (current_source_root_window_) {
    // Resolution may have changed. Update all bounds.
    const auto viewport_bounds =
        GetViewportWidgetBoundsInRoot(current_source_root_window_);
    viewport_widget_->SetBounds(viewport_bounds);
    viewport_background_layer_->SetBounds(viewport_bounds);
    viewport_magnifier_layer_->SetBounds(viewport_bounds);
    separator_layer_->SetBounds(
        SeparatorBoundsFromViewportBounds(viewport_bounds));
    SetViewportHeightInWorkArea(current_source_root_window_,
                                GetTotalMagnifierHeight());

    // Resolution changes, screen rotation, etc. can reset the host to confine
    // the mouse cursor inside the root window. We want to make sure the cursor
    // is confined properly outside the viewport.
    ConfineMouseCursorOutsideViewport();
  }

  // A change in display configuration, such as resolution, rotation, ... etc.
  // invalidates the currently cached minimum height of the point of interest.
  is_minimum_point_of_interest_height_valid_ = false;

  // Update the viewport magnifier layer transform.
  CenterOnPoint(GetCursorScreenPoint());
}

bool DockedMagnifierController::GetFullscreenMagnifierEnabled() const {
  return active_user_pref_service_ &&
         active_user_pref_service_->GetBoolean(
             prefs::kAccessibilityScreenMagnifierEnabled);
}

void DockedMagnifierController::SetFullscreenMagnifierEnabled(bool enabled) {
  if (active_user_pref_service_) {
    active_user_pref_service_->SetBoolean(
        prefs::kAccessibilityScreenMagnifierEnabled, enabled);
  }
}

int DockedMagnifierController::GetTotalMagnifierHeight() const {
  if (separator_layer_)
    return separator_layer_->bounds().bottom();

  return 0;
}

const views::Widget* DockedMagnifierController::GetViewportWidgetForTesting()
    const {
  return viewport_widget_;
}

const ui::Layer*
DockedMagnifierController::GetViewportMagnifierLayerForTesting() const {
  return viewport_magnifier_layer_.get();
}

float DockedMagnifierController::GetMinimumPointOfInterestHeightForTesting()
    const {
  return minimum_point_of_interest_height_;
}

void DockedMagnifierController::SwitchCurrentSourceRootWindowIfNeeded(
    aura::Window* new_root_window,
    bool update_old_root_workarea) {
  if (current_source_root_window_ == new_root_window)
    return;

  aura::Window* old_root_window = current_source_root_window_;
  current_source_root_window_ = new_root_window;

  // Current window changes means the minimum height of the point of interest is
  // no longer valid.
  is_minimum_point_of_interest_height_valid_ = false;

  if (old_root_window) {
    if (separator_layer_) {
      GetViewportParentContainerForRoot(old_root_window)
          ->layer()
          ->Remove(separator_layer_.get());
    }
    if (update_old_root_workarea)
      SetViewportHeightInWorkArea(old_root_window, 0);

    if (input_method_)
      input_method_->RemoveObserver(this);
    input_method_ = nullptr;

    // Reset mouse cursor confinement to default.
    RootWindowController::ForWindow(old_root_window)
        ->ash_host()
        ->ConfineCursorToRootWindow();
  }

  // A change in the current root window means we must clear the existing
  // reflector and the viewport widget and its layers. New viewport and
  // reflector may be recreated later if |new_root_window| is not |nullptr|.
  if (reflector_) {
    Shell::Get()->aura_env()->context_factory_private()->RemoveReflector(
        reflector_.get());
    reflector_.reset();
  }

  separator_layer_ = nullptr;

  if (viewport_widget_) {
    viewport_widget_->RemoveObserver(this);
    viewport_widget_->Close();
    viewport_widget_ = nullptr;
  }

  viewport_background_layer_ = nullptr;
  viewport_magnifier_layer_ = nullptr;

  if (!current_source_root_window_) {
    // No need to create a new magnifier viewport.
    return;
  }

  CreateMagnifierViewport();

  input_method_ = magnifier_utils::GetInputMethod(current_source_root_window_);
  if (input_method_)
    input_method_->AddObserver(this);

  DCHECK(Shell::Get()->aura_env()->context_factory_private());
  DCHECK(viewport_widget_);
  reflector_ =
      Shell::Get()->aura_env()->context_factory_private()->CreateReflector(
          current_source_root_window_->layer()->GetCompositor(),
          viewport_magnifier_layer_.get());
}

void DockedMagnifierController::InitFromUserPrefs() {
  DCHECK(active_user_pref_service_);

  pref_change_registrar_ = std::make_unique<PrefChangeRegistrar>();
  pref_change_registrar_->Init(active_user_pref_service_);
  pref_change_registrar_->Add(
      prefs::kDockedMagnifierEnabled,
      base::BindRepeating(&DockedMagnifierController::OnEnabledPrefChanged,
                          base::Unretained(this)));
  pref_change_registrar_->Add(
      prefs::kDockedMagnifierScale,
      base::BindRepeating(&DockedMagnifierController::OnScalePrefChanged,
                          base::Unretained(this)));
  pref_change_registrar_->Add(
      prefs::kAccessibilityScreenMagnifierEnabled,
      base::BindRepeating(
          &DockedMagnifierController::OnFullscreenMagnifierEnabledPrefChanged,
          base::Unretained(this)));
  pref_change_registrar_->Add(
      prefs::kAccessibilityHighContrastEnabled,
      base::BindRepeating(
          &DockedMagnifierController::OnHighContrastEnabledPrefChanged,
          base::Unretained(this)));

  OnEnabledPrefChanged();
}

void DockedMagnifierController::OnEnabledPrefChanged() {
  // When switching from the signin screen to a newly created profile while the
  // Docked Magnifier is enabled, the prefs will be copied from the signin
  // profile to the user profile, and the Docked Magnifier will remain enabled.
  // We don't want to redo the below operations if the status doesn't change,
  // for example readding the same observer to the WindowTreeHostManager will
  // cause a crash on DCHECK on debug builds.
  const bool current_enabled = !!current_source_root_window_;
  const bool new_enabled = GetEnabled();
  if (current_enabled == new_enabled)
    return;

  // Toggling the status of the docked magnifier, changes the display's work
  // area. However, display's work area changes are not allowed while overview
  // mode is active (See https://crbug.com/834400). For this reason, we exit
  // overview mode, before we actually update the state of docked magnifier
  // below. https://crbug.com/894256.
  Shell* shell = Shell::Get();
  auto* overview_controller = shell->overview_controller();
  if (overview_controller->IsSelecting()) {
    auto* split_view_controller = shell->split_view_controller();
    if (split_view_controller->IsSplitViewModeActive()) {
      // In this case, we're in a single-split-view mode, i.e. a window is
      // snapped to one side of the split view, while the other side has
      // overview active. We need to exit split view as well as exiting overview
      // mode, otherwise we'll be in an invalid state.
      split_view_controller->EndSplitView(
          SplitViewController::EndReason::kNormal);
    }

    overview_controller->ToggleOverview();
  }

  if (new_enabled) {
    // Enabling the Docked Magnifier disables the Fullscreen Magnifier.
    SetFullscreenMagnifierEnabled(false);
    // Calling refresh will result in the creation of the magnifier viewport and
    // its associated layers.
    Refresh();
    // Make sure we are in front of the fullscreen magnifier which also handles
    // scroll events.
    shell->AddPreTargetHandler(this, ui::EventTarget::Priority::kSystem);
    shell->window_tree_host_manager()->AddObserver(this);
  } else {
    shell->window_tree_host_manager()->RemoveObserver(this);
    shell->RemovePreTargetHandler(this);

    // Setting the current root window to |nullptr| will remove the viewport and
    // all its associated layers.
    SwitchCurrentSourceRootWindowIfNeeded(nullptr,
                                          true /* update_old_root_workarea */);
  }

  // Update the green checkmark status in the accessibility menu in the system
  // tray.
  shell->accessibility_controller()->NotifyAccessibilityStatusChanged();

  // We use software composited mouse cursor so that it can be mirrored into the
  // magnifier viewport.
  shell->UpdateCursorCompositingEnabled();
}

void DockedMagnifierController::OnScalePrefChanged() {
  if (GetEnabled()) {
    // Invalidate the cached minimum height of the point of interest since the
    // change in scale changes that height.
    is_minimum_point_of_interest_height_valid_ = false;
    Refresh();
  }
}

void DockedMagnifierController::OnFullscreenMagnifierEnabledPrefChanged() {
  // Enabling the Fullscreen Magnifier disables the Docked Magnifier.
  if (GetFullscreenMagnifierEnabled())
    SetEnabled(false);
}

void DockedMagnifierController::OnHighContrastEnabledPrefChanged() {
  if (!GetEnabled())
    return;

  viewport_magnifier_layer_->SetLayerInverted(IsHighContrastEnabled());
}

void DockedMagnifierController::Refresh() {
  DCHECK(GetEnabled());
  CenterOnPoint(GetCursorScreenPoint());
}

void DockedMagnifierController::CreateMagnifierViewport() {
  DCHECK(GetEnabled());
  DCHECK(current_source_root_window_);
  DCHECK(!reflector_);

  const auto viewport_bounds =
      GetViewportWidgetBoundsInRoot(current_source_root_window_);

  // 1- Create the viewport widget.
  viewport_widget_ = new views::Widget;
  views::Widget::InitParams params(
      views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
  params.activatable = views::Widget::InitParams::ACTIVATABLE_NO;
  params.accept_events = false;
  params.bounds = viewport_bounds;
  params.opacity = views::Widget::InitParams::OPAQUE_WINDOW;
  params.parent =
      GetViewportParentContainerForRoot(current_source_root_window_);
  params.name = kDockedMagnifierViewportWindowName;
  viewport_widget_->Init(params);
  viewport_widget_->Show();
  viewport_widget_->AddObserver(this);

  // 2- Create the separator layer right below the viwport widget, parented to
  //    the layer of the root window.
  separator_layer_ = std::make_unique<ui::Layer>(ui::LAYER_SOLID_COLOR);
  separator_layer_->SetColor(SK_ColorBLACK);
  separator_layer_->SetBounds(
      SeparatorBoundsFromViewportBounds(viewport_bounds));
  params.parent->layer()->Add(separator_layer_.get());

  // 3- Create a background layer that will show a dark gray color behind the
  //    magnifier layer. It has the same bounds as the viewport.
  viewport_background_layer_ =
      std::make_unique<ui::Layer>(ui::LAYER_SOLID_COLOR);
  viewport_background_layer_->SetColor(SK_ColorDKGRAY);
  viewport_background_layer_->SetBounds(viewport_bounds);
  aura::Window* viewport_window = viewport_widget_->GetNativeView();
  ui::Layer* viewport_layer = viewport_window->layer();
  viewport_layer->Add(viewport_background_layer_.get());

  // 4- Create the layer in which the contents of the screen will be mirrored
  //    and magnified.
  viewport_magnifier_layer_ =
      std::make_unique<ui::Layer>(ui::LAYER_SOLID_COLOR);
  viewport_magnifier_layer_->SetLayerInverted(IsHighContrastEnabled());
  viewport_layer->Add(viewport_magnifier_layer_.get());
  viewport_layer->SetMasksToBounds(true);

  // 5- Update the workarea of the current screen such that an area enough to
  //    contain the viewport and the separator is allocated at the top of the
  //    screen.
  SetViewportHeightInWorkArea(current_source_root_window_,
                              GetTotalMagnifierHeight());

  // 6- Confine the mouse cursor within the remaining part of the display.
  ConfineMouseCursorOutsideViewport();
}

void DockedMagnifierController::MaybeCachePointOfInterestMinimumHeight(
    aura::WindowTreeHost* host) {
  DCHECK(GetEnabled());
  DCHECK(current_source_root_window_);
  DCHECK(host);

  if (is_minimum_point_of_interest_height_valid_)
    return;

  // Adjust the point of interest so that we don't end up magnifying the
  // magnifier. This means we don't allow the point of interest to go beyond a
  // minimum y-coordinate value. Here's how we find that minimum value:
  //
  // +-----------------+     +-----------------------------------+
  // |     Viewport    |     |                                   |
  // +====separator====+     |        Magnified Viewport         |
  // |                (+) b  |                                   |
  // |                 |     +==============separator===========(+) A
  // |                 |     |                  Distance (D) --> |
  // |                 |     |                                  (+) B
  // +-----------------+     |                                   |
  //    Screen in Non        |                                   |
  //   Magnified Space       |                                   |
  //                         |                                   |
  //                         |                                   |
  //                         +-----------------------------------+
  //                               Screen in Magnified Space
  //                     (the contents of |viewport_magnifier_layer_|)
  //
  // Problem: Find the height of the point of interest (b) in the non-magnified
  //          coordinates space, which corresponds to the height of point (B) in
  //          the magnified coordinates space, such that when point (A) is
  //          translated from the magnified coordinates space to the non-
  //          magnified coordinates space, its y coordinate is 0 (i.e. aligns
  //          with the top of the magnifier viewport).
  //
  // 1- The height of Point (A) in the magnified space is the bottom of the
  //    entire magnifier (which is actually the bottom of the separator) in the
  //    magnified coordinates space.
  //    Note that the magnified space is in pixels. This point should be
  //    translated such that its y-coordiante is not greater than 0 (in the non-
  //    magnified coordinates space), otherwise the magnifier will magnify and
  //    mirror itself.
  // 2- Point (B) is the scaled point of interest in the magnified space. The
  //    point of interest is always translated to the center point of the
  //    viewport. Hence, if point (A) goes to y = 0, and point (B) goes to a
  //    height equals to the height of the center point of the viewport,
  //    therefore means distance (D) = viewport_center_point.y().
  // 3- Now that we found the height of point (B) in the magnified space,
  //    find the the height of point (b) which is the corresponding height in
  //    the non-magnified space. This height is the minimum height below which
  //    the point of interest may not go.

  const gfx::Rect viewport_bounds =
      GetViewportWidgetBoundsInRoot(current_source_root_window_);

  // 1- Point (A)'s height.
  // Note we use a Vector3dF to actually represent a 2D point. The reason is
  // Vector3dF provides an API to get the Length() of the vector without
  // converting the object to another temporary object. We need to get the
  // Length() rather than y() because screen rotation transform can make the
  // height we are interested in either x() or y() depending on the rotation
  // angle, so we just simply use Length().
  // Note: Why transform the point to the magnified scale and back? The reason
  // is that we need to go through the root window transform to go to the pixel
  // space (the reflector copies pixels). This will account for device scale
  // factors, screen rotations, and any other transforms that we cannot
  // anticipate ourselves.
  gfx::Vector3dF scaled_magnifier_bottom_in_pixels(
      0.0f, viewport_bounds.bottom() + kSeparatorHeight, 0.0f);
  host->GetRootTransform().TransformVector(&scaled_magnifier_bottom_in_pixels);
  const float scale = GetScale();
  scaled_magnifier_bottom_in_pixels.Scale(scale);

  // 2- Point (B)'s height.
  const gfx::PointF viewport_center_point(viewport_bounds.CenterPoint());
  gfx::Vector3dF minimum_height_vector(
      0.0f,
      viewport_center_point.y() + scaled_magnifier_bottom_in_pixels.Length(),
      0.0f);

  // 3- Back to non-magnified space to get point (b)'s height.
  minimum_height_vector.Scale(1 / scale);
  host->GetInverseRootTransform().TransformVector(&minimum_height_vector);
  minimum_point_of_interest_height_ = minimum_height_vector.Length();
  is_minimum_point_of_interest_height_valid_ = true;
}

void DockedMagnifierController::ConfineMouseCursorOutsideViewport() {
  DCHECK(current_source_root_window_);

  gfx::Rect confine_bounds =
      current_source_root_window_->GetBoundsInRootWindow();
  const int docked_height = separator_layer_->bounds().bottom();
  confine_bounds.Offset(0, docked_height);
  confine_bounds.set_height(confine_bounds.height() - docked_height);
  RootWindowController::ForWindow(current_source_root_window_)
      ->ash_host()
      ->ConfineCursorToBoundsInRoot(confine_bounds);
}

}  // namespace ash
