// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/wm/splitview/split_view_controller.h"

#include <algorithm>
#include <cmath>
#include <cstdint>
#include <limits>
#include <optional>
#include <vector>

#include "ash/accessibility/accessibility_controller.h"
#include "ash/constants/app_types.h"
#include "ash/constants/ash_features.h"
#include "ash/display/screen_orientation_controller.h"
#include "ash/display/window_tree_host_manager.h"
#include "ash/keyboard/ui/keyboard_ui_controller.h"
#include "ash/public/cpp/metrics_util.h"
#include "ash/public/cpp/window_properties.h"
#include "ash/root_window_controller.h"
#include "ash/root_window_settings.h"
#include "ash/screen_util.h"
#include "ash/session/session_controller_impl.h"
#include "ash/shell.h"
#include "ash/style/ash_color_provider.h"
#include "ash/wm/desks/desks_controller.h"
#include "ash/wm/desks/desks_util.h"
#include "ash/wm/float/float_controller.h"
#include "ash/wm/mru_window_tracker.h"
#include "ash/wm/overview/delayed_animation_observer_impl.h"
#include "ash/wm/overview/overview_controller.h"
#include "ash/wm/overview/overview_grid.h"
#include "ash/wm/overview/overview_item.h"
#include "ash/wm/overview/overview_metrics.h"
#include "ash/wm/overview/overview_types.h"
#include "ash/wm/overview/overview_utils.h"
#include "ash/wm/snap_group/snap_group.h"
#include "ash/wm/snap_group/snap_group_controller.h"
#include "ash/wm/splitview/auto_snap_controller.h"
#include "ash/wm/splitview/split_view_constants.h"
#include "ash/wm/splitview/split_view_divider.h"
#include "ash/wm/splitview/split_view_metrics_controller.h"
#include "ash/wm/splitview/split_view_observer.h"
#include "ash/wm/splitview/split_view_overview_session.h"
#include "ash/wm/splitview/split_view_utils.h"
#include "ash/wm/tablet_mode/tablet_mode_window_state.h"
#include "ash/wm/window_positioning_utils.h"
#include "ash/wm/window_properties.h"
#include "ash/wm/window_resizer.h"
#include "ash/wm/window_restore/window_restore_controller.h"
#include "ash/wm/window_state.h"
#include "ash/wm/window_transient_descendant_iterator.h"
#include "ash/wm/window_util.h"
#include "ash/wm/wm_metrics.h"
#include "base/auto_reset.h"
#include "base/containers/flat_map.h"
#include "base/debug/crash_logging.h"
#include "base/functional/bind.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/user_metrics.h"
#include "base/notreached.h"
#include "base/ranges/algorithm.h"
#include "base/time/time.h"
#include "chromeos/ui/base/window_properties.h"
#include "chromeos/ui/base/window_state_type.h"
#include "chromeos/ui/frame/caption_buttons/snap_controller.h"
#include "components/app_restore/desk_template_read_handler.h"
#include "components/app_restore/window_properties.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/window_delegate.h"
#include "ui/base/ime/ash/ime_bridge.h"
#include "ui/base/ime/input_method.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/layer_animator.h"
#include "ui/compositor/presentation_time_recorder.h"
#include "ui/compositor/throughput_tracker.h"
#include "ui/display/screen.h"
#include "ui/display/types/display_constants.h"
#include "ui/gfx/animation/slide_animation.h"
#include "ui/gfx/animation/tween.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/transform_util.h"
#include "ui/views/animation/compositor_animation_runner.h"
#include "ui/views/widget/widget.h"
#include "ui/wm/core/coordinate_conversion.h"
#include "ui/wm/core/shadow_controller.h"
#include "ui/wm/core/window_util.h"
#include "ui/wm/public/activation_client.h"

namespace ash {

namespace {

using chromeos::WindowStateType;

// Five fixed position ratios of the divider, which means the divider can
// always be moved to these five positions.
constexpr float kFixedPositionRatios[] = {0.f, chromeos::kOneThirdSnapRatio,
                                          chromeos::kDefaultSnapRatio,
                                          chromeos::kTwoThirdSnapRatio, 1.0f};

// The black scrim starts to fade in when the divider is moved past the two
// optional positions (`chromeos::kOneThirdSnapRatio`,
// `chromeos::kTwoThirdSnapRatio`) and reaches to its maximum opacity
// (`kBlackScrimOpacity`) after moving `kBlackScrimFadeInRatio` of the screen
// width. See https://crbug.com/827730 for details.
constexpr float kBlackScrimFadeInRatio = 0.1f;
constexpr float kBlackScrimOpacity = 0.4f;

// The speed at which the divider is moved controls whether windows are scaled
// or translated. If the divider is moved more than this many pixels per second,
// the "fast" mode is enabled.
constexpr int kSplitViewThresholdPixelsPerSec = 72;

// This is how often the divider drag speed is checked.
constexpr base::TimeDelta kSplitViewChunkTime = base::Milliseconds(500);

// Records the animation smoothness when the divider is released during a resize
// and animated to a fixed position ratio.
constexpr char kDividerAnimationSmoothness[] =
    "Ash.SplitViewResize.AnimationSmoothness.DividerAnimation";

// Histogram names that record presentation time of resize operation with
// following conditions:
// a) tablet split view, one snapped window, empty overview grid;
// b) tablet split view, two snapped windows;
// c) tablet split view, one snapped window, nonempty overview grid;
constexpr char kTabletSplitViewResizeSingleHistogram[] =
    "Ash.SplitViewResize.PresentationTime.TabletMode.SingleWindow";
constexpr char kTabletSplitViewResizeMultiHistogram[] =
    "Ash.SplitViewResize.PresentationTime.TabletMode.MultiWindow";
constexpr char kTabletSplitViewResizeWithOverviewHistogram[] =
    "Ash.SplitViewResize.PresentationTime.TabletMode.WithOverview";

constexpr char kTabletSplitViewResizeSingleMaxLatencyHistogram[] =
    "Ash.SplitViewResize.PresentationTime.MaxLatency.TabletMode.SingleWindow";
constexpr char kTabletSplitViewResizeMultiMaxLatencyHistogram[] =
    "Ash.SplitViewResize.PresentationTime.MaxLatency.TabletMode.MultiWindow";
constexpr char kTabletSplitViewResizeWithOverviewMaxLatencyHistogram[] =
    "Ash.SplitViewResize.PresentationTime.MaxLatency.TabletMode.WithOverview";

// The time when the number of roots in split view changes from one to two. Used
// for the purpose of metric collection.
base::Time g_multi_display_split_view_start_time;

bool InTabletMode() {
  return display::Screen::GetScreen()->InTabletMode();
}

bool IsExactlyOneRootInSplitView() {
  const aura::Window::Windows all_root_windows = Shell::GetAllRootWindows();
  return 1 ==
         base::ranges::count_if(
             all_root_windows, [](aura::Window* root_window) {
               return SplitViewController::Get(root_window)->InSplitViewMode();
             });
}

ui::InputMethod* GetCurrentInputMethod() {
  if (auto* bridge = IMEBridge::Get()) {
    if (auto* handler = bridge->GetInputContextHandler())
      return handler->GetInputMethod();
  }
  return nullptr;
}

WindowStateType GetStateTypeFromSnapPosition(SnapPosition snap_position) {
  switch (snap_position) {
    case SnapPosition::kPrimary:
      return WindowStateType::kPrimarySnapped;
    case SnapPosition::kSecondary:
      return WindowStateType::kSecondarySnapped;
    default:
      NOTREACHED_NORETURN();
  }
}

// Returns true if |window| is currently snapped.
bool IsSnapped(aura::Window* window) {
  if (!window)
    return false;
  return WindowState::Get(window)->IsSnapped();
}

void RemoveSnappingWindowFromOverviewIfApplicable(
    OverviewSession* overview_session,
    aura::Window* window) {
  if (!overview_session) {
    return;
  }

  OverviewItemBase* item = overview_session->GetOverviewItemForWindow(window);
  if (!item) {
    return;
  }

  // Remove it from overview. The transform will be reset later after the window
  // is snapped. Note the remaining windows in overview don't need to be
  // repositioned in this case as they have been positioned to the right place
  // during dragging.
  item->EnsureVisible();
  item->RestoreWindow(/*reset_transform=*/false, /*animate=*/true);
  overview_session->RemoveItem(item);
}

// If there is a window in the snap position, trigger a WMEvent to snap it in
// the corresponding position.
void TriggerWMEventToSnapWindow(WindowState* window_state,
                                WMEventType event_type) {
  CHECK(event_type == WM_EVENT_SNAP_PRIMARY ||
        event_type == WM_EVENT_SNAP_SECONDARY);

  const WindowSnapWMEvent window_event(
      event_type,
      window_state->snap_ratio().value_or(chromeos::kDefaultSnapRatio));
  window_state->OnWMEvent(&window_event);
}

// Returns true if the snap state of the `window` has changed if it's already in
// split view mode.
bool DidInSplitViewWindowChange(aura::Window* window,
                                SplitViewController* split_view_controller,
                                SnapPosition snap_position) {
  if (!split_view_controller->IsWindowInSplitView(window)) {
    return false;
  }

  const auto* window_state = WindowState::Get(window);
  if (window_state->GetStateType() !=
      GetStateTypeFromSnapPosition(snap_position)) {
    return true;
  }

  // For the current tablet mode split view design, we can assume that the
  // `window` is being snapped to the same `snap_position` it was snapped since
  // it's single layer design. We need to check if the snap ratio is the same.
  std::optional<float> snap_ratio = window_state->snap_ratio();
  // Get the snap ratio for the window that is currently occupying the
  // `snap_position`.
  const auto* window_state_in_current_snap_position =
      WindowState::Get(split_view_controller->GetSnappedWindow(snap_position));
  const bool same_snap_ratio =
      snap_ratio && window_state_in_current_snap_position &&
      *snap_ratio == window_state_in_current_snap_position->snap_ratio();
  return !same_snap_ratio;
}

}  // namespace

// -----------------------------------------------------------------------------
// DividerSnapAnimation:

// Animates the divider to its closest fixed position.
// `SplitViewController::IsResizingWithDivider()` is assumed to be already false
// before this animation starts, but some resizing logic is delayed until this
// animation ends.
class SplitViewController::DividerSnapAnimation
    : public gfx::SlideAnimation,
      public gfx::AnimationDelegate {
 public:
  DividerSnapAnimation(SplitViewController* split_view_controller,
                       int starting_position,
                       int ending_position,
                       base::TimeDelta duration,
                       gfx::Tween::Type tween_type)
      : gfx::SlideAnimation(this),
        split_view_controller_(split_view_controller),
        starting_position_(starting_position),
        ending_position_(ending_position) {
    SetSlideDuration(duration);
    SetTweenType(tween_type);

    aura::Window* window = split_view_controller->primary_window()
                               ? split_view_controller->primary_window()
                               : split_view_controller->secondary_window();
    DCHECK(window);

    // |widget| may be null in tests. It will use the default animation
    // container in this case.
    views::Widget* widget = views::Widget::GetWidgetForNativeWindow(window);
    if (!widget)
      return;

    gfx::AnimationContainer* container = new gfx::AnimationContainer();
    container->SetAnimationRunner(
        std::make_unique<views::CompositorAnimationRunner>(widget, FROM_HERE));
    SetContainer(container);

    tracker_.emplace(widget->GetCompositor()->RequestNewThroughputTracker());
    tracker_->Start(
        metrics_util::ForSmoothnessV3(base::BindRepeating([](int smoothness) {
          UMA_HISTOGRAM_PERCENTAGE(kDividerAnimationSmoothness, smoothness);
        })));
  }
  DividerSnapAnimation(const DividerSnapAnimation&) = delete;
  DividerSnapAnimation& operator=(const DividerSnapAnimation&) = delete;
  ~DividerSnapAnimation() override = default;

  int ending_position() const { return ending_position_; }

 private:
  // gfx::AnimationDelegate:
  void AnimationEnded(const gfx::Animation* animation) override {
    DCHECK(split_view_controller_->InSplitViewMode());
    DCHECK(!split_view_controller_->IsResizingWithDivider());
    DCHECK_EQ(ending_position_, split_view_controller_->GetDividerPosition());

    split_view_controller_->EndResizeWithDividerImpl();
    split_view_controller_->EndSplitViewAfterResizingAtEdgeIfAppropriate();

    if (tracker_)
      tracker_->Stop();
  }

  void AnimationProgressed(const gfx::Animation* animation) override {
    DCHECK(split_view_controller_->InSplitViewMode());
    DCHECK(!split_view_controller_->IsResizingWithDivider());

    // TODO(b/327685487): Remove these when the crash is fixed.
    const int divider_position_before_tween =
        split_view_controller_->GetDividerPosition();
    split_view_controller_->split_view_divider()->SetDividerPosition(
        CurrentValueBetween(starting_position_, ending_position_));
    const int divider_position_after_tween =
        split_view_controller_->GetDividerPosition();
    split_view_controller_->NotifyDividerPositionChanged();
    const int divider_position_after_notify =
        split_view_controller_->GetDividerPosition();
    split_view_controller_->UpdateSnappedWindowsAndDividerBounds();
    const int divider_position_after_update =
        split_view_controller_->GetDividerPosition();

    // Updating the window may stop animation.
    if (is_animating()) {
      // Map the tablet resize mode to a string.
      base::flat_map<SplitViewController::TabletResizeMode, std::string>
          resize_mode_as_string = {
              {SplitViewController::TabletResizeMode::kNormal, "kNormal"},
              {SplitViewController::TabletResizeMode::kFast, "kFast"},
          };
      SCOPED_CRASH_KEY_STRING32(
          "b327685487", "tablet_resize_mode",
          resize_mode_as_string[split_view_controller_->tablet_resize_mode_]);
      SCOPED_CRASH_KEY_BOOL("b327685487", "in_tablet_mode", InTabletMode());
      SCOPED_CRASH_KEY_BOOL(
          "b327685487", "has_divider_widget",
          !!split_view_controller_->split_view_divider()->divider_widget());
      SCOPED_CRASH_KEY_BOOL("b327685487", "in_split_view",
                            split_view_controller_->InSplitViewMode());
      SCOPED_CRASH_KEY_BOOL("b327685487", "is_divider_resizing",
                            split_view_controller_->IsResizingWithDivider());
      SCOPED_CRASH_KEY_NUMBER("b327685487", "before_tween",
                              divider_position_before_tween);
      SCOPED_CRASH_KEY_NUMBER("b327685487", "after_tween",
                              divider_position_after_tween);
      SCOPED_CRASH_KEY_NUMBER("b327685487", "after_notify",
                              divider_position_after_notify);
      SCOPED_CRASH_KEY_NUMBER("b327685487", "after_update",
                              divider_position_after_update);
      SCOPED_CRASH_KEY_NUMBER("b327685487", "starting_position",
                              starting_position_);
      SCOPED_CRASH_KEY_NUMBER("b327685487", "ending_position",
                              ending_position_);
      split_view_controller_->UpdateResizeBackdrop();
      split_view_controller_->SetWindowsTransformDuringResizing();
    }
  }

  void AnimationCanceled(const gfx::Animation* animation) override {
    if (tracker_)
      tracker_->Cancel();
  }

  raw_ptr<SplitViewController> split_view_controller_;
  int starting_position_;
  int ending_position_;
  std::optional<ui::ThroughputTracker> tracker_;
};

// -----------------------------------------------------------------------------
// ToBeSnappedWindowsObserver:

// Helper class that prepares windows that are changing to snapped window state.
// This allows async window state type changes and handles calls to
// SplitViewController when necessary.
class SplitViewController::ToBeSnappedWindowsObserver
    : public aura::WindowObserver,
      public WindowStateObserver {
 public:
  explicit ToBeSnappedWindowsObserver(
      SplitViewController* split_view_controller)
      : split_view_controller_(split_view_controller) {}
  ToBeSnappedWindowsObserver(const ToBeSnappedWindowsObserver&) = delete;
  ToBeSnappedWindowsObserver& operator=(const ToBeSnappedWindowsObserver&) =
      delete;
  ~ToBeSnappedWindowsObserver() override {
    for (auto& to_be_snapped_window : to_be_snapped_windows_) {
      if (aura::Window* window = to_be_snapped_window.second.window) {
        window->RemoveObserver(this);
        WindowState::Get(window)->RemoveObserver(this);
      }
    }
    to_be_snapped_windows_.clear();
  }

  void AddToBeSnappedWindow(aura::Window* window,
                            SnapPosition snap_position,
                            WindowSnapActionSource snap_action_source) {
    if (DidInSplitViewWindowChange(window, split_view_controller_,
                                   snap_position)) {
      split_view_controller_->AttachToBeSnappedWindow(window, snap_position,
                                                      snap_action_source);
      return;
    }

    aura::Window* old_window = to_be_snapped_windows_[snap_position].window;
    if (old_window == window) {
      return;
    }

    // Stop observing any previous to-be-snapped window in `snap_position`. This
    // can happen to Android windows as its window state and bounds change are
    // async, so it's possible to snap another window to the same position while
    // waiting for the snapping of the previous window.
    if (old_window) {
      to_be_snapped_windows_.erase(snap_position);
      WindowState::Get(old_window)->RemoveObserver(this);
      old_window->RemoveObserver(this);
    }

    // If the to-be-snapped window already has the desired snapped window state,
    // no need to listen to the state change notification (there will be none
    // anyway), instead just attach the window to split screen directly.
    WindowState* window_state = WindowState::Get(window);
    if (window_state->GetStateType() ==
        GetStateTypeFromSnapPosition(snap_position)) {
      split_view_controller_->AttachToBeSnappedWindow(window, snap_position,
                                                      snap_action_source);
      split_view_controller_->OnWindowSnapped(window,
                                              /*previous_state=*/std::nullopt,
                                              snap_action_source);
    } else {
      to_be_snapped_windows_[snap_position] =
          WindowAndSnapSourceInfo{window, snap_action_source};
      window_state->AddObserver(this);
      window->AddObserver(this);
    }
  }

  bool IsObserving(const aura::Window* window) const {
    return FindWindow(window) != to_be_snapped_windows_.end();
  }

  // aura::WindowObserver:
  void OnWindowDestroying(aura::Window* window) override {
    auto iter = FindWindow(window);
    DCHECK(iter != to_be_snapped_windows_.end());
    window->RemoveObserver(this);
    WindowState::Get(window)->RemoveObserver(this);
    to_be_snapped_windows_.erase(iter);
  }

  // WindowStateObserver:
  void OnPreWindowStateTypeChange(WindowState* window_state,
                                  WindowStateType old_type) override {
    aura::Window* window = window_state->window();
    // When arriving here, we know the to-be-snapped window's state has just
    // changed and its bounds will be changed soon.
    auto iter = FindWindow(window);
    DCHECK(iter != to_be_snapped_windows_.end());
    SnapPosition snap_position = iter->first;

    // If the new window type is the target snapped state, remove the window
    // from `to_be_snapped_windows_` and do some prep work for snapping it in
    // split screen. Otherwise (i.e. if the new window type is not the target
    // one) just ignore the event and keep waiting for the next event.
    if (window_state->GetStateType() ==
        GetStateTypeFromSnapPosition(snap_position)) {
      const auto cached_snap_action_source = iter->second.snap_action_source;
      to_be_snapped_windows_.erase(iter);
      window_state->RemoveObserver(this);
      window->RemoveObserver(this);
      split_view_controller_->AttachToBeSnappedWindow(
          window, snap_position, cached_snap_action_source);
    }
  }

 private:
  // Contains the info of the window to be snapped and its corresponding snap
  // action source.
  struct WindowAndSnapSourceInfo {
    raw_ptr<aura::Window> window = nullptr;
    WindowSnapActionSource snap_action_source =
        WindowSnapActionSource::kNotSpecified;
  };

  base::flat_map<SnapPosition, WindowAndSnapSourceInfo>::const_iterator
  FindWindow(const aura::Window* window) const {
    for (auto iter = to_be_snapped_windows_.begin();
         iter != to_be_snapped_windows_.end(); iter++) {
      if (iter->second.window == window) {
        return iter;
      }
    }
    return to_be_snapped_windows_.end();
  }

  const raw_ptr<SplitViewController> split_view_controller_;

  // Maps the snap position to the to-be-snapped window with its corresponding
  // snap action source.
  base::flat_map<SnapPosition, WindowAndSnapSourceInfo> to_be_snapped_windows_;
};

// static
SplitViewController* SplitViewController::Get(const aura::Window* window) {
  DCHECK(window);
  DCHECK(window->GetRootWindow());
  DCHECK(RootWindowController::ForWindow(window));
  return RootWindowController::ForWindow(window)->split_view_controller();
}

// -----------------------------------------------------------------------------
// SplitViewController:

SplitViewController::SplitViewController(aura::Window* root_window)
    : root_window_(root_window),
      to_be_snapped_windows_observer_(
          std::make_unique<ToBeSnappedWindowsObserver>(this)),
      split_view_divider_(this),
      split_view_metrics_controller_(
          std::make_unique<SplitViewMetricsController>(this)) {
  Shell::Get()->accessibility_controller()->AddObserver(this);
}

SplitViewController::~SplitViewController() {
  if (AccessibilityController* a11y_controller =
          Shell::Get()->accessibility_controller()) {
    a11y_controller->RemoveObserver(this);
  }

  EndSplitView(EndReason::kRootWindowDestroyed);
}

int SplitViewController::GetDividerPosition() const {
  return split_view_divider_.divider_position();
}

bool SplitViewController::IsResizingWithDivider() const {
  return split_view_divider_.HasDividerWidget() &&
         split_view_divider_.is_resizing_with_divider();
}

bool SplitViewController::InSplitViewMode() const {
  return state_ != State::kNoSnap;
}

bool SplitViewController::InClamshellSplitViewMode() const {
  return InSplitViewMode() && !InTabletMode();
}

bool SplitViewController::InTabletSplitViewMode() const {
  return InSplitViewMode() && InTabletMode();
}

bool SplitViewController::CanSnapWindow(aura::Window* window,
                                        float snap_ratio) const {
  if (!ShouldAllowSplitView())
    return false;

  if (!WindowState::Get(window)->CanSnapOnDisplay(
          display::Screen::GetScreen()->GetDisplayNearestWindow(
              const_cast<aura::Window*>(root_window_.get())))) {
    return false;
  }

  // Windows created by window restore are not activatable while being restored.
  // However, we still want to be able to snap these windows at this point.
  const bool is_to_be_restored_window =
      window == WindowRestoreController::Get()->to_be_snapped_window();

  // TODO(sammiequon): Investigate if we need to check for window activation.
  if (!is_to_be_restored_window && !wm::CanActivateWindow(window))
    return false;

  // We only need to consider the divider width in tablet mode or Snap Groups.
  const int divider_delta =
      ShouldConsiderDivider() ? kSplitviewDividerShortSideLength / 2 : 0;

  return GetMinimumWindowLength(window, IsLayoutHorizontal(window)) <=
         GetDividerPositionUpperLimit(root_window_) * snap_ratio -
             divider_delta;
}

bool SplitViewController::CanKeepCurrentSnapRatio(
    aura::Window* snapped_window) const {
  return CanSnapWindow(snapped_window,
                       WindowState::Get(snapped_window)
                           ->snap_ratio()
                           .value_or(chromeos::kDefaultSnapRatio));
}

std::optional<float> SplitViewController::ComputeAutoSnapRatio(
    aura::Window* window) {
  // If there is no default snapped window, or it doesn't have a stored snap
  // ratio try snapping it to 1/2.
  aura::Window* default_window = GetDefaultSnappedWindow();
  std::optional<float> default_window_snap_ratio =
      default_window ? WindowState::Get(default_window)->snap_ratio()
                     : std::nullopt;
  if (!default_window_snap_ratio) {
    return CanSnapWindow(window, chromeos::kDefaultSnapRatio)
               ? std::make_optional(chromeos::kDefaultSnapRatio)
               : std::nullopt;
  }

  // Maps the snap ratio of the default window to the snap ratio of the opposite
  // window.
  static constexpr auto kOppositeRatiosMap =
      base::MakeFixedFlatMap<float, float>(
          {{chromeos::kOneThirdSnapRatio, chromeos::kTwoThirdSnapRatio},
           {chromeos::kDefaultSnapRatio, chromeos::kDefaultSnapRatio},
           {chromeos::kTwoThirdSnapRatio, chromeos::kOneThirdSnapRatio}});
  auto it = kOppositeRatiosMap.find(*default_window_snap_ratio);
  // TODO(sammiequon): Investigate if this check is needed. It may be needed for
  // rounding errors (i.e. 2/3 may be 0.67).
  if (it == kOppositeRatiosMap.end()) {
    return CanSnapWindow(window, chromeos::kDefaultSnapRatio)
               ? std::make_optional(chromeos::kDefaultSnapRatio)
               : std::nullopt;
  }

  // If `window` can be snapped to the ideal snap ratio, we are done.
  float snap_ratio = it->second;
  if (CanSnapWindow(window, snap_ratio)) {
    return snap_ratio;
  }

  // Reaching here, we cannot snap `window` to its ideal snap ratio. If the
  // ideal snap ratio was 1/3, we try snapping to 1/2, but only if the default
  // window can be snapped to 1/2 as well.
  if (snap_ratio == chromeos::kOneThirdSnapRatio &&
      CanSnapWindow(window, chromeos::kDefaultSnapRatio) &&
      CanSnapWindow(default_window, chromeos::kDefaultSnapRatio)) {
    return chromeos::kDefaultSnapRatio;
  }

  return std::nullopt;
}

bool SplitViewController::WillStartPartialOverview(aura::Window* window) const {
  const bool can_start_in_tablet = InTabletMode() && !IsInOverviewSession();
  const bool can_start_in_clamshell =
      CanStartSplitViewOverviewSessionInClamshell(
          window, WindowState::Get(window)->snap_action_source().value_or(
                      WindowSnapActionSource::kNotSpecified));

  // Note that at this point `state_` may not have been updated yet, so check if
  // only one of `primary_window_` or `secondary_window_` is snapped.
  return (can_start_in_tablet || can_start_in_clamshell) &&
         !DesksController::Get()->animation() &&
         !!primary_window_ != !!secondary_window_;
}

void SplitViewController::SnapWindow(aura::Window* window,
                                     SnapPosition snap_position,
                                     WindowSnapActionSource snap_action_source,
                                     bool activate_window,
                                     float snap_ratio) {
  DCHECK(window && CanSnapWindow(window, snap_ratio));
  DCHECK_NE(snap_position, SnapPosition::kNone);
  if (IsDividerAnimating()) {
    StopSnapAnimation();
  }

  OverviewSession* overview_session = GetOverviewSession();
  if (activate_window ||
      (overview_session &&
       overview_session->IsWindowActiveWindowBeforeOverview(window))) {
    to_be_activated_window_ = window;
  }

  to_be_snapped_windows_observer_->AddToBeSnappedWindow(window, snap_position,
                                                        snap_action_source);
  // Move |window| to the display of |root_window_| first before sending the
  // WMEvent. Otherwise it may be snapped to the wrong display.
  if (root_window_ != window->GetRootWindow()) {
    window_util::MoveWindowToDisplay(window,
                                     display::Screen::GetScreen()
                                         ->GetDisplayNearestWindow(root_window_)
                                         .id());
  }
  const WindowSnapWMEvent event(snap_position == SnapPosition::kPrimary
                                    ? WM_EVENT_SNAP_PRIMARY
                                    : WM_EVENT_SNAP_SECONDARY,
                                snap_ratio, snap_action_source);
  WindowState::Get(window)->OnWMEvent(&event);

  base::RecordAction(base::UserMetricsAction("SplitView_SnapWindow"));
}

void SplitViewController::OnSnapEvent(
    aura::Window* window,
    WMEventType event_type,
    WindowSnapActionSource snap_action_source) {
  CHECK(event_type == WM_EVENT_SNAP_PRIMARY ||
        event_type == WM_EVENT_SNAP_SECONDARY);

  // If split view can't be enabled at the moment, do nothing.
  if (!ShouldAllowSplitView()) {
    return;
  }

  const bool in_overview = IsInOverviewSession();

  // In clamshell mode, only if overview is active on window snapped or in
  // faster split screen setup session, the window should be managed by
  // `SplitViewController`. Otherwise, the window should be managed by
  // `WindowState`.
  if (!InTabletMode() &&
      !(in_overview ||
        ShouldConsiderWindowForFasterSplitView(window, snap_action_source))) {
    return;
  }

  // If the snap wm event is from desk template launch when in overview, do not
  // try to snap the window in split screen. Otherwise, overview might be exited
  // because of window snapping.
  const int32_t window_id =
      window->GetProperty(app_restore::kRestoreWindowIdKey);
  if (in_overview &&
      window == WindowRestoreController::Get()->to_be_snapped_window() &&
      app_restore::DeskTemplateReadHandler::Get()->GetWindowInfo(window_id)) {
    return;
  }

  // Do nothing if `window` is already waiting to be snapped in split screen.
  // Order here matters: this must return for auto-snap windows before they try
  // to override `GetDividerPosition()` from a `new_snap_ratio` below.
  if (to_be_snapped_windows_observer_->IsObserving(window)) {
    return;
  }

  const SnapPosition to_snap_position = event_type == WM_EVENT_SNAP_PRIMARY
                                            ? SnapPosition::kPrimary
                                            : SnapPosition::kSecondary;
  // Start observing the to-be-snapped window.
  to_be_snapped_windows_observer_->AddToBeSnappedWindow(
      window, to_snap_position, snap_action_source);
}

void SplitViewController::AttachToBeSnappedWindow(
    aura::Window* window,
    SnapPosition snap_position,
    WindowSnapActionSource snap_action_source) {
  // Save the transformed bounds in preparation for the snapping animation.
  UpdateSnappingWindowTransformedBounds(window);

  OverviewSession* overview_session = GetOverviewSession();
  RemoveSnappingWindowFromOverviewIfApplicable(overview_session, window);

  if (state_ == State::kNoSnap) {
    Shell* shell = Shell::Get();
    // Add observers when the split view mode starts.
    shell->AddShellObserver(this);
    OverviewController::Get()->AddObserver(this);
    keyboard::KeyboardUIController::Get()->AddObserver(this);
    shell->activation_client()->AddObserver(this);

    auto_snap_controller_ = std::make_unique<AutoSnapController>(root_window_);

    default_snap_position_ = snap_position;

    splitview_start_time_ = base::Time::Now();
    // We are about to enter split view on |root_window_|. If split view is
    // already active on exactly one root, then |root_window_| will be the
    // second root, and so multi-display split view begins now.
    if (IsExactlyOneRootInSplitView()) {
      base::RecordAction(
          base::UserMetricsAction("SplitView_MultiDisplaySplitView"));
      g_multi_display_split_view_start_time = splitview_start_time_;
    }
  }

  aura::Window* previous_snapped_window = nullptr;
  aura::Window* other_window = nullptr;
  if (snap_position == SnapPosition::kPrimary) {
    if (primary_window_ != window) {
      previous_snapped_window = primary_window_;
      StopObserving(SnapPosition::kPrimary);
      primary_window_ = window;
    }
    if (secondary_window_ == window) {
      // Remove `window` from `secondary_window_` if it was previously snapped
      // there, i.e. during cycle snap or swap windows.
      secondary_window_ = nullptr;
      default_snap_position_ = SnapPosition::kPrimary;
    }
    // `other_window` must be set last, since we may have removed
    // `secondary_window_`.
    other_window = secondary_window_;
  } else if (snap_position == SnapPosition::kSecondary) {
    // See above comments.
    if (secondary_window_ != window) {
      previous_snapped_window = secondary_window_;
      StopObserving(SnapPosition::kSecondary);
      secondary_window_ = window;
    }
    if (primary_window_ == window) {
      primary_window_ = nullptr;
      default_snap_position_ = SnapPosition::kSecondary;
    }
    other_window = primary_window_;
  }

  StartObserving(window);

  // Insert the previous snapped window to overview if overview is active.
  DCHECK_EQ(overview_session, GetOverviewSession());
  if (previous_snapped_window && overview_session) {
    InsertWindowToOverview(previous_snapped_window);
    // Ensure that the close icon will fade in. This part is redundant for
    // dragging from overview, but necessary for dragging from the top. For
    // dragging from overview, |OverviewItem::OnSelectorItemDragEnded| will be
    // called on all overview items including the |previous_snapped_window|
    // item anyway, whereas for dragging from the top,
    // |OverviewItem::OnSelectorItemDragEnded| already was called on all
    // overview items and |previous_snapped_window| was not yet among them.
    overview_session->GetOverviewItemForWindow(previous_snapped_window)
        ->OnOverviewItemDragEnded(/*snap=*/true);
  }

  // Get the divider position given by `snap_ratio` if exists, or if there is
  // pre-set `divider_position_`, use it, which can happen during tablet <->
  // clamshell transition or multi-user transition. If neither `snap_ratio` nor
  // `divider_position_` exists, calculate the divider position with the default
  // snap ratio i.e. `chromeos::kDefaultSnapRatio`.
  // TODO(michelefan): See if it is a valid case to not having `snap_ratio`
  // while `divider_position` is less than 0.
  bool do_snap_animation = false;
  int divider_position =
      split_view_divider_.divider_widget() ? GetDividerPosition() : -1;
  if (std::optional<float> snap_ratio = WindowState::Get(window)->snap_ratio();
      snap_ratio) {
    divider_position = CalculateDividerPosition(
        root_window_, snap_position, *snap_ratio, ShouldConsiderDivider());
    // If `other_window` can't fit in the requested snap ratio, show a snap
    // animation below.
    do_snap_animation =
        other_window && !CanSnapWindow(other_window, 1.f - *snap_ratio);
  } else if (divider_position < 0) {
    divider_position = CalculateDividerPosition(root_window_, snap_position,
                                                chromeos::kDefaultSnapRatio,
                                                ShouldConsiderDivider());
  }

  // In clamshell mode we simply update `divider_position`. In tablet mode we
  // will show the divider widget below.
  split_view_divider_.SetDividerPosition(divider_position);
  base::RecordAction(base::UserMetricsAction("SplitView_SnapWindow"));
  if (!InTabletMode()) {
    return;
  }

  split_view_divider_.SetVisible(true);
  CHECK(split_view_divider_.HasDividerWidget());

  const int fixed_divider_position =
      GetClosestFixedDividerPosition(divider_position);
  // This must be done before we update `split_view_divider_.divider_position_`
  // to `fixed_divider_position`, since the minimum size will be respected
  // there.
  if (do_snap_animation) {
    // When `window` is re-snapped, i.e. from 1/2 to 2/3, but `other_window`
    // can't fit in the requested snap ratio, set `divider_snap_animation_` to
    // Hide then Show, to give off the impression of bouncing the divider back
    // to `old_divider_position`. Note the duration is 2 *
    // `kBouncingAnimationOneWayDuration` to bounce out then in.
    tablet_resize_mode_ = TabletResizeMode::kFast;
    divider_snap_animation_ = std::make_unique<DividerSnapAnimation>(
        this, /*starting_position=*/divider_position,
        /*ending_position=*/fixed_divider_position,
        2 * kBouncingAnimationOneWayDuration, gfx::Tween::FAST_OUT_SLOW_IN_3);
    divider_snap_animation_->Hide();
    divider_snap_animation_->Show();
  }

  split_view_divider_.SetDividerPosition(fixed_divider_position);
}

aura::Window* SplitViewController::GetSnappedWindow(SnapPosition position) {
  DCHECK_NE(SnapPosition::kNone, position);
  return position == SnapPosition::kPrimary ? primary_window_.get()
                                            : secondary_window_.get();
}

aura::Window* SplitViewController::GetDefaultSnappedWindow() {
  if (default_snap_position_ == SnapPosition::kPrimary)
    return primary_window_;
  if (default_snap_position_ == SnapPosition::kSecondary)
    return secondary_window_;
  return nullptr;
}

gfx::Rect SplitViewController::GetSnappedWindowBoundsInParent(
    SnapPosition snap_position,
    aura::Window* window_for_minimum_size,
    float snap_ratio) {
  gfx::Rect bounds =
      GetSnappedWindowBoundsInScreen(snap_position, window_for_minimum_size,
                                     snap_ratio, ShouldConsiderDivider());
  wm::ConvertRectFromScreen(root_window_, &bounds);
  return bounds;
}

bool SplitViewController::ShouldConsiderDivider() const {
  // The divider may be visible in tablet mode, or between two windows in a
  // snap group in clamshell mode.
  // In tablet mode, we always consider the divider width even if
  // `split_view_divider_` is not initialized yet because
  // `ClientControlledState` may need to know the snapped bounds before
  // actually snapping the windows.
  // TODO(b/309856199): Currently need to pipe `account_for_divider_width` since
  // the divider is still created in `SplitViewController` for Snap Groups.
  // Refactor this when `split_view_divider_` is moved out.
  return split_view_divider_.HasDividerWidget() || InTabletMode();
}

bool SplitViewController::IsDividerAnimating() const {
  return divider_snap_animation_ && divider_snap_animation_->is_animating();
}

void SplitViewController::EndSplitView(EndReason end_reason) {
  if (!InSplitViewMode()) {
    return;
  }

  end_reason_ = end_reason;

  // If we are currently in a resize but split view is ending, make sure to end
  // the resize. This can happen, for example, on the transition back to
  // clamshell mode or when a task is minimized during a resize. Likewise, if
  // split view is ending during the divider snap animation, then clean that up.
  // But if the split view is ending due to the destroy of `root_window_`, we
  // should skip the resize.
  const bool is_divider_animating = IsDividerAnimating();
  if ((IsResizingWithDivider() || is_divider_animating) &&
      end_reason != EndReason::kRootWindowDestroyed) {
    if (is_divider_animating) {
      // Don't call StopAndShoveAnimatedDivider as it will call observers.
      StopSnapAnimation();
    }
    EndResizeWithDividerImpl();
  }

  // There is at least one case where this line of code is needed: if the user
  // presses Ctrl+W while resizing a clamshell split view window.
  presentation_time_recorder_.reset();

  // Remove observers when the split view mode ends.
  Shell* shell = Shell::Get();
  shell->RemoveShellObserver(this);
  OverviewController::Get()->RemoveObserver(this);
  keyboard::KeyboardUIController::Get()->RemoveObserver(this);
  shell->activation_client()->RemoveObserver(this);

  auto_snap_controller_.reset();

  if (end_reason != EndReason::kRootWindowDestroyed) {
    // `EndSplitView()` is also called upon `~RootWindowController()` and
    // `~SplitViewController()`, during which `root_window_` would have been
    // destroyed.
    RootWindowController::ForWindow(root_window_)
        ->EndSplitViewOverviewSession(
            SplitViewOverviewSessionExitPoint::kShutdown);
  }

  StopObserving(SnapPosition::kPrimary);
  StopObserving(SnapPosition::kSecondary);
  black_scrim_layer_.reset();
  default_snap_position_ = SnapPosition::kNone;
  divider_closest_ratio_ = std::numeric_limits<float>::quiet_NaN();
  snapping_window_transformed_bounds_map_.clear();

  UpdateStateAndNotifyObservers();

  // Close splitview divider widget after updating state so that
  // OnDisplayMetricsChanged triggered by the widget closing correctly
  // finds out !InSplitViewMode().
  split_view_divider_.SetVisible(false);
  base::RecordAction(base::UserMetricsAction("SplitView_EndSplitView"));
  const base::Time now = base::Time::Now();
  UMA_HISTOGRAM_LONG_TIMES("Ash.SplitView.TimeInSplitView",
                           now - splitview_start_time_);
  // We just ended split view on |root_window_|. If there is exactly one root
  // where split view is still active, then multi-display split view ends now.
  if (IsExactlyOneRootInSplitView()) {
    UMA_HISTOGRAM_LONG_TIMES("Ash.SplitView.TimeInMultiDisplaySplitView",
                             now - g_multi_display_split_view_start_time);
  }
}

bool SplitViewController::IsWindowInSplitView(
    const aura::Window* window) const {
  return window && (window == primary_window_ || window == secondary_window_);
}

bool SplitViewController::IsWindowInTransitionalState(
    const aura::Window* window) const {
  return to_be_snapped_windows_observer_->IsObserving(window);
}

void SplitViewController::OnOverviewButtonTrayLongPressed(
    const gfx::Point& event_location) {
  // Do nothing if split view is not enabled.
  if (!ShouldAllowSplitView())
    return;

  // If in split view: The active snapped window becomes maximized. If overview
  // was seen alongside a snapped window, then overview mode ends.
  //
  // Otherwise: Enter split view iff the cycle list has at least one window, and
  // the first one is snappable.
  MruWindowTracker::WindowList mru_window_list =
      Shell::Get()->mru_window_tracker()->BuildWindowForCycleList(kActiveDesk);
  // Do nothing if there is one or less windows in the MRU list.
  if (mru_window_list.empty())
    return;

  auto* overview_controller = Shell::Get()->overview_controller();
  aura::Window* target_window = mru_window_list[0];

  // Exit split view mode if we are already in it.
  if (InSplitViewMode()) {
    DCHECK(IsWindowInSplitView(target_window));
    DCHECK(target_window);
    EndSplitView();
    overview_controller->EndOverview(
        OverviewEndAction::kOverviewButtonLongPress);
    MaximizeIfSnapped(target_window);
    wm::ActivateWindow(target_window);
    base::RecordAction(
        base::UserMetricsAction("Tablet_LongPressOverviewButtonExitSplitView"));
    return;
  }

  // Show a toast if the window cannot be snapped.
  if (!CanSnapWindow(target_window, chromeos::kDefaultSnapRatio)) {
    ShowAppCannotSnapToast();
    return;
  }

  // Save the overview enter/exit types to be used if the window is snapped.
  overview_start_action_ = OverviewStartAction::kOverviewButtonLongPress;
  enter_exit_overview_type_ = OverviewEnterExitType::kImmediateEnter;
  SnapWindow(target_window, SnapPosition::kPrimary,
             WindowSnapActionSource::kLongPressOverviewButtonToSnap,
             /*activate_window=*/true);

  base::RecordAction(
      base::UserMetricsAction("Tablet_LongPressOverviewButtonEnterSplitView"));
}

void SplitViewController::OnWindowDragStarted(aura::Window* dragged_window) {
  DCHECK(dragged_window);

  // OnSnappedWindowDetached() may end split view mode.
  if (IsWindowInSplitView(dragged_window)) {
    OnSnappedWindowDetached(dragged_window,
                            WindowDetachedReason::kWindowDragged);
  }

  if (split_view_divider_.divider_widget()) {
    split_view_divider_.OnWindowDragStarted(dragged_window);
  }
}

void SplitViewController::OnWindowDragEnded(
    aura::Window* dragged_window,
    SnapPosition desired_snap_position,
    const gfx::Point& last_location_in_screen,
    WindowSnapActionSource snap_action_source) {
  DCHECK(!window_util::IsDraggingTabs(dragged_window));
  EndWindowDragImpl(dragged_window, dragged_window->is_destroying(),
                    desired_snap_position, last_location_in_screen,
                    snap_action_source);
}

void SplitViewController::OnWindowDragCanceled() {
  if (split_view_divider_.divider_widget()) {
    split_view_divider_.OnWindowDragEnded();
  }
}

SnapPosition SplitViewController::ComputeSnapPosition(
    const gfx::Point& last_location_in_screen) {
  const int divider_position =
      InSplitViewMode()
          ? GetDividerPosition()
          : CalculateDividerPosition(root_window_, SnapPosition::kPrimary,
                                     chromeos::kDefaultSnapRatio,
                                     ShouldConsiderDivider());
  const int position = IsLayoutHorizontal(root_window_)
                           ? last_location_in_screen.x()
                           : last_location_in_screen.y();
  return (position <= divider_position) == IsLayoutPrimary(root_window_)
             ? SnapPosition::kPrimary
             : SnapPosition::kSecondary;
}

bool SplitViewController::BoundsChangeIsFromVKAndAllowed(
    aura::Window* window) const {
  // Make sure that it is the bottom window who is requiring bounds change.
  return changing_bounds_by_vk_ &&
         window == (IsLayoutPrimary(window) ? secondary_window_.get()
                                            : primary_window_.get());
}

void SplitViewController::AddObserver(SplitViewObserver* observer) {
  observers_.AddObserver(observer);
}

void SplitViewController::RemoveObserver(SplitViewObserver* observer) {
  observers_.RemoveObserver(observer);
}

void SplitViewController::OnWindowPropertyChanged(aura::Window* window,
                                                  const void* key,
                                                  intptr_t old) {
  // If the window's resizibility property changes (must be from resizable ->
  // unresizable), end the split view mode and also end overview mode if
  // overview mode is active at the moment.
  if (key != aura::client::kResizeBehaviorKey)
    return;

  // It is possible the property gets updated and is still the same value.
  if (window->GetProperty(aura::client::kResizeBehaviorKey) ==
      static_cast<int>(old)) {
    return;
  }

  if (CanKeepCurrentSnapRatio(window)) {
    return;
  }

  EndSplitView();
  Shell::Get()->overview_controller()->EndOverview(
      OverviewEndAction::kSplitView);
  ShowAppCannotSnapToast();
}

void SplitViewController::OnWindowBoundsChanged(
    aura::Window* window,
    const gfx::Rect& old_bounds,
    const gfx::Rect& new_bounds,
    ui::PropertyChangeReason reason) {
  if (!InClamshellSplitViewMode() || split_view_divider_.divider_widget()) {
    // Divider width is not taken into consideration in the calculation below.
    // Early exit if `split_view_divider_` exists in clamshell mode.
    return;
  }

  if (WindowState* window_state = WindowState::Get(window);
      window_state->is_dragged()) {
    if (presentation_time_recorder_) {
      presentation_time_recorder_->RequestNext();
    }
  }

  // During clamshell split view, we resize the window + overview at the same
  // time. `overview_utils` will do the work to calculate the overview grid
  // bounds from the window snapped in split view.
}

void SplitViewController::OnWindowDestroyed(aura::Window* window) {
  DCHECK(InSplitViewMode());
  DCHECK(IsWindowInSplitView(window));

  OnSnappedWindowDetached(window, WindowDetachedReason::kWindowDestroyed);
}

void SplitViewController::OnWindowRemovingFromRootWindow(
    aura::Window* window,
    aura::Window* new_root) {
  if (new_root) {
    // Detach the window first to stop ongoing divider animations.
    OnSnappedWindowDetached(window,
                            WindowDetachedReason::kWindowMovedToAnotherDisplay);
  }
}

void SplitViewController::OnPostWindowStateTypeChange(
    WindowState* window_state,
    WindowStateType old_type) {
  DCHECK_EQ(
      window_state->GetDisplay().id(),
      display::Screen::GetScreen()->GetDisplayNearestWindow(root_window_).id());

  aura::Window* window = window_state->window();

  if (window_state->IsSnapped()) {
    OnWindowSnapped(window, old_type,
                    window_state->snap_action_source().value_or(
                        WindowSnapActionSource::kNotSpecified));
  } else if (window_state->IsNormalStateType() || window_state->IsMaximized() ||
             window_state->IsFullscreen() || window_state->IsFloated()) {
    // End split view, and also overview if overview is active, in these cases:
    // 1. A left clamshell split view window gets unsnapped by Alt+[.
    // 2. A right clamshell split view window gets unsnapped by Alt+].
    // 3. A (clamshell or tablet) split view window gets maximized.
    // 4. A (clamshell or tablet) split view window becomes full screen.
    // 5. A split view window becomes floated.
    EndSplitView();
    Shell::Get()->overview_controller()->EndOverview(
        OverviewEndAction::kSplitView);
  } else if (window_state->IsMinimized()) {
    OnSnappedWindowDetached(window, WindowDetachedReason::kWindowMinimized);

    if (!InSplitViewMode()) {
      // We have different behaviors for a minimized window: in tablet splitview
      // mode, we'll insert the minimized window back to overview, as normally
      // the window is not supposed to be minmized in tablet mode. And in
      // clamshell splitview mode, we respect the minimization of the window
      // and end overview instead.
      if (InTabletMode()) {
        InsertWindowToOverview(window);
      } else {
        Shell::Get()->overview_controller()->EndOverview(
            OverviewEndAction::kSplitView);
      }
    }
  }
}

void SplitViewController::OnPinnedStateChanged(aura::Window* pinned_window) {
  // Disable split view for pinned windows.
  if (WindowState::Get(pinned_window)->IsPinned() && InSplitViewMode())
    EndSplitView(EndReason::kUnsnappableWindowActivated);
}

void SplitViewController::OnOverviewModeStarting() {
  CHECK(InSplitViewMode());

  // While in clamshell split view mode without being in a snap group
  // creation session, a full overview session should be triggered. In this
  // case, split view should end.
  if (InClamshellSplitViewMode() &&
      !RootWindowController::ForWindow(root_window_)
           ->split_view_overview_session()) {
    EndSplitView();
    return;
  }

  // If split view mode is active, reset |state_| to make it be able to select
  // another window from overview window grid.
  if (default_snap_position_ == SnapPosition::kPrimary) {
    StopObserving(SnapPosition::kSecondary);
  } else if (default_snap_position_ == SnapPosition::kSecondary) {
    StopObserving(SnapPosition::kPrimary);
  }
  UpdateStateAndNotifyObservers();
}

void SplitViewController::OnOverviewModeEnding(
    OverviewSession* overview_session) {
  DCHECK(InSplitViewMode());

  // If overview is ended because of a window getting snapped, suppress the
  // overview exiting animation.
  if (state_ == State::kBothSnapped)
    overview_session->SetWindowListNotAnimatedWhenExiting(root_window_);

  // If clamshell split view mode is active, bail out. `OnOverviewModeEnded`
  // will end split view. We do not end split view here, because that would mess
  // up histograms of overview exit animation smoothness.
  if (!InTabletMode()) {
    return;
  }

  // Tablet split view mode is active. If it still only has one snapped window,
  // snap the first snappable window in the overview grid on the other side.
  if (state_ == State::kBothSnapped) {
    return;
  }

  OverviewGrid* current_grid =
      overview_session->GetGridWithRootWindow(root_window_);
  if (!current_grid || current_grid->empty()) {
    return;
  }

  for (const auto& overview_item : current_grid->window_list()) {
    for (aura::Window* window : overview_item->GetWindows()) {
      CHECK(window);

      if (window == GetDefaultSnappedWindow()) {
        continue;
      }

      std::optional<float> snap_ratio = ComputeAutoSnapRatio(window);
      if (!snap_ratio.has_value()) {
        continue;
      }

      const bool was_active =
          overview_session->IsWindowActiveWindowBeforeOverview(window);
      // Remove the overview item before snapping because the overview session
      // is unavailable to retrieve outside this function after
      // OnOverviewEnding is notified.
      overview_item->RestoreWindow(/*reset_transform=*/false,
                                   /*animate=*/true);
      overview_session->RemoveItem(overview_item.get());

      SnapWindow(window,
                 (default_snap_position_ == SnapPosition::kPrimary)
                     ? SnapPosition::kSecondary
                     : SnapPosition::kPrimary,
                 WindowSnapActionSource::kAutoSnapInSplitView,
                 /*activate_window=*/false, *snap_ratio);
      if (was_active) {
        wm::ActivateWindow(window);
      }

      // If ending overview causes a window to snap, also do not do exiting
      // overview animation.
      overview_session->SetWindowListNotAnimatedWhenExiting(root_window_);
      return;
    }
  }

  // The overview grid has at least one window, but has none that can be snapped
  // in split view. If overview is ending because of switching between virtual
  // desks, then there is no need to do anything here. Otherwise, end split view
  // and show the cannot snap toast.
  if (DesksController::Get()->AreDesksBeingModified()) {
    return;
  }

  EndSplitView();
  ShowAppCannotSnapToast();
}

void SplitViewController::OnOverviewModeEnded() {
  DCHECK(InSplitViewMode());
  if (InClamshellSplitViewMode()) {
    EndSplitView();
  }
}

void SplitViewController::OnDisplayRemoved(
    const display::Display& old_display) {
  // If the `root_window_`is the root window of the display which is going to
  // be removed, there's no need to start overview.
  if (GetRootWindowSettings(root_window_)->display_id ==
      display::kInvalidDisplayId) {
    // Explicitly destroy the metrics controller here. If the display is removed
    // while a desk switch is in progress, the metrics controller will try to
    // access the non-existent root window in its desk activation obserer. Note
    // that `this` is soon going to be destroyed anyway.
    split_view_metrics_controller_.reset();
    return;
  }

  // If we are in tablet split view with only one snapped window, make sure we
  // are in overview (see https://crbug.com/1027179).
  if (state_ == State::kPrimarySnapped || state_ == State::kSecondarySnapped) {
    aura::Window* window =
        primary_window_ ? primary_window_ : secondary_window_;
    // `WindowSnapActionSource::kNotSpecified` is used as the snap source since
    // this is not user-initiated action.
    RootWindowController::ForWindow(window)->StartSplitViewOverviewSession(
        window, OverviewStartAction::kSplitView,
        OverviewEnterExitType::kImmediateEnter,
        WindowSnapActionSource::kNotSpecified);
  }
}

void SplitViewController::OnDisplayMetricsChanged(
    const display::Display& display,
    uint32_t metrics) {
  // Avoid |ScreenAsh::GetDisplayNearestWindow|, which has a |DCHECK| that fails
  // if the display is being deleted. Use |GetRootWindowSettings| directly, and
  // if the display is being deleted, we will get |display::kInvalidDisplayId|.
  if (GetRootWindowSettings(root_window_)->display_id != display.id())
    return;

  // We need to update |is_previous_layout_right_side_up_| even if split view
  // mode is not active.
  const bool is_previous_layout_right_side_up =
      is_previous_layout_right_side_up_;
  is_previous_layout_right_side_up_ = IsLayoutPrimary(display);

  if (!InSplitViewMode())
    return;

  // If one of the snapped windows becomes unsnappable, end the split view mode
  // directly if `IsUserSessionBlocked()`.
  if ((primary_window_ && !CanKeepCurrentSnapRatio(primary_window_)) ||
      (secondary_window_ && !CanKeepCurrentSnapRatio(secondary_window_))) {
    if (!Shell::Get()->session_controller()->IsUserSessionBlocked())
      EndSplitView();
    return;
  }

  // In clamshell split view mode, the divider position will be adjusted in
  // `OnWindowBoundsChanged`. Also when we first enter tablet mode, the divider
  // has not been created yet but there may be a work area change.
  if (!InTabletMode() || !split_view_divider_.divider_widget()) {
    return;
  }

  // Before adjusting the divider position for the new display metrics, if the
  // divider is animating to a snap position, then stop it and shove it there.
  // Postpone `EndSplitViewAfterResizingAtEdgeIfAppropriate()` until after the
  // adjustment, because the new display metrics will be used to compare the
  // divider position against the edges of the screen.
  if (IsDividerAnimating()) {
    StopAndShoveAnimatedDivider();
    EndResizeWithDividerImpl();
  }

  // If we ended split view in `EndSplitViewAfterResizingAtEdgeIfAppropriate()`,
  // no need to update the divider position.
  // TODO(b/329325825): Consider refactoring clamshell display change here.
  if (!InTabletSplitViewMode()) {
    return;
  }

  if ((metrics & display::DisplayObserver::DISPLAY_METRIC_ROTATION) ||
      (metrics & display::DisplayObserver::DISPLAY_METRIC_WORK_AREA)) {
    // Set default `divider_closest_ratio_` to kFixedPositionRatios[1].
    if (std::isnan(divider_closest_ratio_))
      divider_closest_ratio_ = kFixedPositionRatios[1];

    // Reverse the position ratio if top/left window changes.
    if (is_previous_layout_right_side_up != IsLayoutPrimary(display))
      divider_closest_ratio_ = 1.f - divider_closest_ratio_;
    split_view_divider_.SetDividerPosition(
        static_cast<int>(divider_closest_ratio_ *
                         GetDividerPositionUpperLimit(root_window_)) -
        kSplitviewDividerShortSideLength / 2);
  }

  // For other display configuration changes, we only move the divider to the
  // closest fixed position.
  if (!IsResizingWithDivider()) {
    split_view_divider_.SetDividerPosition(
        GetClosestFixedDividerPosition(GetDividerPosition()));
  }

  EndSplitViewAfterResizingAtEdgeIfAppropriate();
  NotifyDividerPositionChanged();
  UpdateSnappedWindowsAndDividerBounds();
}

void SplitViewController::OnDisplayTabletStateChanged(
    display::TabletState state) {
  switch (state) {
    case display::TabletState::kInClamshellMode:
      OnTabletModeEnded();
      break;
    case display::TabletState::kEnteringTabletMode:
      break;
    case display::TabletState::kInTabletMode:
      OnTabletModeStarted();
      break;
    case display::TabletState::kExitingTabletMode:
      OnTabletModeEnding();
      break;
  }
}

void SplitViewController::OnAccessibilityStatusChanged() {
  // TODO(crubg.com/853588): Exit split screen if ChromeVox is turned on until
  // they are compatible.
  if (InTabletMode() &&
      Shell::Get()->accessibility_controller()->spoken_feedback().enabled()) {
    EndSplitView();
  }
}

void SplitViewController::OnAccessibilityControllerShutdown() {
  Shell::Get()->accessibility_controller()->RemoveObserver(this);
}

void SplitViewController::OnKeyboardOccludedBoundsChanged(
    const gfx::Rect& screen_bounds) {
  // The window only needs to be moved if it is in the portrait mode.
  if (IsLayoutHorizontal(root_window_))
    return;

  // We only modify the bottom window if there is one and the current active
  // input field is in the bottom window.
  aura::Window* bottom_window = GetPhysicalRightOrBottomWindow();
  if (!bottom_window &&
      !bottom_window->Contains(window_util::GetActiveWindow())) {
    return;
  }

  // If the virtual keyboard is disabled, restore to original layout.
  if (screen_bounds.IsEmpty()) {
    UpdateSnappedWindowsAndDividerBounds();
    return;
  }

  // Get current active input field.
  auto* text_input_client = GetCurrentInputMethod()->GetTextInputClient();
  if (!text_input_client) {
    return;
  }

  const gfx::Rect caret_bounds = text_input_client->GetCaretBounds();
  if (caret_bounds == gfx::Rect()) {
    return;
  }

  // Move the bottom window if the caret is less than `kMinCaretKeyboardDist`
  // dip above the upper bounds of the virtual keyboard.
  const int keyboard_occluded_y = screen_bounds.y();
  if (keyboard_occluded_y - caret_bounds.bottom() > kMinCaretKeyboardDist)
    return;

  // Move bottom window above the virtual keyboard but the upper bounds cannot
  // exceeds `kMinDividerPositionRatio` of the screen height.
  gfx::Rect bottom_bounds = bottom_window->GetBoundsInScreen();
  const gfx::Rect work_area =
      screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer(
          root_window_);
  const int y =
      std::max(keyboard_occluded_y - bottom_bounds.height(),
               static_cast<int>(work_area.y() +
                                work_area.height() * kMinDividerPositionRatio));
  bottom_bounds.set_y(y);
  bottom_bounds.set_height(keyboard_occluded_y - y);

  // Set bottom window bounds.
  {
    base::AutoReset<bool> enable_bounds_change(&changing_bounds_by_vk_, true);
    bottom_window->SetBoundsInScreen(
        bottom_bounds,
        display::Screen::GetScreen()->GetDisplayNearestWindow(root_window_));
  }

  split_view_divider_.OnKeyboardOccludedBoundsChangedInPortrait(work_area, y);
}

void SplitViewController::OnWindowActivated(ActivationReason reason,
                                            aura::Window* gained_active,
                                            aura::Window* lost_active) {
  // If the bottom window is moved for the virtual keyboard (the split view
  // divider bar is unadjustable), when the bottom window lost active, restore
  // to the original layout.
  if (!split_view_divider_.divider_widget() ||
      split_view_divider_.IsAdjustable()) {
    return;
  }

  if (IsLayoutHorizontal(root_window_)) {
    return;
  }

  aura::Window* bottom_window = GetPhysicalRightOrBottomWindow();
  if (!bottom_window)
    return;

  if (bottom_window->Contains(lost_active) &&
      !bottom_window->Contains(gained_active)) {
    UpdateSnappedWindowsAndDividerBounds();
  }
}

aura::Window* SplitViewController::GetRootWindow() {
  return root_window_;
}

void SplitViewController::StartResizeWithDivider(
    const gfx::Point& location_in_screen) {
  base::RecordAction(base::UserMetricsAction("SplitView_ResizeWindows"));
  if (state_ == State::kBothSnapped) {
    presentation_time_recorder_ = CreatePresentationTimeHistogramRecorder(
        split_view_divider_.divider_widget()->GetCompositor(),
        kTabletSplitViewResizeMultiHistogram,
        kTabletSplitViewResizeMultiMaxLatencyHistogram);
    return;
  }
  // TODO(b/337283677): Remove these crash logs when the crash is fixed.
  SCOPED_CRASH_KEY_NUMBER("b337283677", "state", base::to_underlying(state_));
  SCOPED_CRASH_KEY_BOOL("b337283677", "in_overview_session",
                        IsInOverviewSession());
  SCOPED_CRASH_KEY_BOOL(
      "b337283677", "is_overview_shutting_down",
      GetOverviewSession() && GetOverviewSession()->is_shutting_down());
  SCOPED_CRASH_KEY_BOOL("b337283677", "is_divider_animating",
                        IsDividerAnimating());

  std::string primary_title =
      primary_window_ ? base::UTF16ToUTF8(primary_window_->GetTitle())
                      : std::string();
  std::string secondary_title =
      secondary_window_ ? base::UTF16ToUTF8(secondary_window_->GetTitle())
                        : std::string();
  SCOPED_CRASH_KEY_STRING256("b337283677", "primary_title", primary_title);
  SCOPED_CRASH_KEY_STRING256("b337283677", "secondary_title", secondary_title);

  auto primary_state_type =
      primary_window_ ? base::to_underlying(
                            WindowState::Get(primary_window_)->GetStateType())
                      : -1;
  auto secondary_state_type =
      secondary_window_
          ? base::to_underlying(
                WindowState::Get(secondary_window_)->GetStateType())
          : -1;
  SCOPED_CRASH_KEY_NUMBER("b337283677", "primary_state_type",
                          primary_state_type);
  SCOPED_CRASH_KEY_NUMBER("b337283677", "secondary_state_type",
                          secondary_state_type);

  auto primary_window_type =
      primary_window_ ? primary_window_->GetProperty(aura::client::kAppType)
                      : -1;
  auto secondary_window_type =
      secondary_window_ ? secondary_window_->GetProperty(aura::client::kAppType)
                        : -1;
  SCOPED_CRASH_KEY_NUMBER("b337283677", "primary_window_type",
                          primary_window_type);
  SCOPED_CRASH_KEY_NUMBER("b337283677", "secondary_window_type",
                          secondary_window_type);

  CHECK(IsInOverviewSession());
  if (GetOverviewSession()->GetGridWithRootWindow(root_window_)->empty()) {
    presentation_time_recorder_ = CreatePresentationTimeHistogramRecorder(
        split_view_divider_.divider_widget()->GetCompositor(),
        kTabletSplitViewResizeSingleHistogram,
        kTabletSplitViewResizeSingleMaxLatencyHistogram);
  } else {
    presentation_time_recorder_ = CreatePresentationTimeHistogramRecorder(
        split_view_divider_.divider_widget()->GetCompositor(),
        kTabletSplitViewResizeWithOverviewHistogram,
        kTabletSplitViewResizeWithOverviewMaxLatencyHistogram);
  }
  accumulated_drag_time_ticks_ = base::TimeTicks::Now();
  accumulated_drag_distance_ = 0;

  tablet_resize_mode_ = TabletResizeMode::kNormal;
}

void SplitViewController::UpdateResizeWithDivider(
    const gfx::Point& location_in_screen) {
  // This updates `tablet_resize_mode_` based on drag speed.
  UpdateTabletResizeMode(base::TimeTicks::Now(), location_in_screen);

  NotifyDividerPositionChanged();
  UpdateSnappedWindowsBounds();

  // Update the resize backdrop, as well as the black scrim layer's bounds and
  // opacity.
  // TODO(b/298515546): Add performant resizing pattern.
  UpdateResizeBackdrop();
  UpdateBlackScrim(location_in_screen);

  // Apply window transform if necessary.
  SetWindowsTransformDuringResizing();
}

bool SplitViewController::EndResizeWithDivider(
    const gfx::Point& location_in_screen) {
  NotifyDividerPositionChanged();

  // Need to update snapped windows bounds even if the split view mode may have
  // to exit. Otherwise it's possible for a snapped window stuck in the edge of
  // of the screen while overview mode is active.
  UpdateSnappedWindowsBounds();
  NotifyWindowResized();

  presentation_time_recorder_.reset();

  // TODO(xdai): Use fade out animation instead of just removing it.
  black_scrim_layer_.reset();

  resize_timer_.Stop();
  tablet_resize_mode_ = TabletResizeMode::kNormal;

  const int divider_position = GetDividerPosition();
  const int target_divider_position =
      GetClosestFixedDividerPosition(divider_position);
  // TODO(b/298515283): Separate Snap Group and tablet resize.
  if (divider_position == target_divider_position ||
      IsSnapGroupEnabledInClamshellMode()) {
    return true;
  }
    divider_snap_animation_ = std::make_unique<DividerSnapAnimation>(
        this, divider_position, target_divider_position,
        base::Milliseconds(300), gfx::Tween::EASE_IN);
    divider_snap_animation_->Show();
    return false;
}

void SplitViewController::OnResizeEnding() {
  CHECK(InSplitViewMode());

  // The backdrop layers are removed here (rather than in
  // `EndResizeWithDivider()`) since they may be used while the divider is
  // animating to a snapped position.
  left_resize_backdrop_layer_.reset();
  right_resize_backdrop_layer_.reset();

  // Resize may not end with `EndResizeWithDivider()`, so make sure to clear
  // here too.
  resize_timer_.Stop();
  presentation_time_recorder_.reset();
  RestoreWindowsTransformAfterResizing();
}

void SplitViewController::OnResizeEnded() {
  EndSplitViewAfterResizingAtEdgeIfAppropriate();
}

void SplitViewController::SwapWindows() {
  DCHECK(InSplitViewMode());

  // Ignore `IsResizingWithDivider()` because it will be true in case of
  // double tapping (not double clicking) the divider without ever actually
  // dragging it anywhere. Double tapping the divider triggers
  // StartResizeWithDivider(), EndResizeWithDivider(), StartResizeWithDivider(),
  // SwapWindows(), EndResizeWithDivider(). Double clicking the divider
  // (possible by using the emulator or chrome://flags/#force-tablet-mode)
  // triggers StartResizeWithDivider(), EndResizeWithDivider(),
  // StartResizeWithDivider(), EndResizeWithDivider(), SwapWindows(). Those two
  // sequences of function calls are what were mainly considered in writing the
  // condition for bailing out here, to disallow swapping windows when the
  // divider is being dragged or is animating.
  if (IsDividerAnimating()) {
    return;
  }

  SwapWindowsAndUpdateBounds();
  if (IsSnapped(primary_window_)) {
    TriggerWMEventToSnapWindow(WindowState::Get(primary_window_),
                               WM_EVENT_SNAP_PRIMARY);
  }
  if (IsSnapped(secondary_window_)) {
    TriggerWMEventToSnapWindow(WindowState::Get(secondary_window_),
                               WM_EVENT_SNAP_SECONDARY);
  }

  // Update `default_snap_position_` if necessary.
  if (!primary_window_ || !secondary_window_) {
    default_snap_position_ =
        primary_window_ ? SnapPosition::kPrimary : SnapPosition::kSecondary;
  }

  split_view_divider_.SetDividerPosition(
      GetClosestFixedDividerPosition(GetDividerPosition()));
  UpdateStateAndNotifyObservers();
  NotifyWindowSwapped();

  base::RecordAction(
      base::UserMetricsAction("SplitView_DoubleTapDividerSwapWindows"));
}

gfx::Rect SplitViewController::GetSnappedWindowBoundsInScreen(
    SnapPosition snap_position,
    aura::Window* window_for_minimum_size,
    float snap_ratio,
    bool account_for_divider_width) const {
  if (snap_position == SnapPosition::kNone) {
    return screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer(
        root_window_);
  }

  const bool should_use_window_bounds_in_fast_resize =
      IsResizingWithDivider() && tablet_resize_mode_ == TabletResizeMode::kFast;
  if (window_for_minimum_size && should_use_window_bounds_in_fast_resize) {
    return window_for_minimum_size->GetBoundsInScreen();
  }

  const int divider_position =
      split_view_divider_.HasDividerWidget()
          ? GetDividerPosition()
          : CalculateDividerPosition(root_window_, snap_position, snap_ratio,
                                     account_for_divider_width);
  return CalculateSnappedWindowBoundsInScreen(
      snap_position, root_window_, window_for_minimum_size,
      account_for_divider_width, divider_position, IsResizingWithDivider());
}

SnapPosition SplitViewController::GetPositionOfSnappedWindow(
    const aura::Window* window) const {
  DCHECK(IsWindowInSplitView(window));
  return window == primary_window_ ? SnapPosition::kPrimary
                                   : SnapPosition::kSecondary;
}

aura::Window* SplitViewController::GetPhysicalLeftOrTopWindow() {
  DCHECK(root_window_);
  return IsLayoutPrimary(root_window_) ? primary_window_.get()
                                       : secondary_window_.get();
}

aura::Window* SplitViewController::GetPhysicalRightOrBottomWindow() {
  DCHECK(root_window_);
  return IsLayoutPrimary(root_window_) ? secondary_window_.get()
                                       : primary_window_.get();
}

void SplitViewController::StartObserving(aura::Window* window) {
  if (window && !window->HasObserver(this)) {
    Shell::Get()->shadow_controller()->UpdateShadowForWindow(window);
    window->AddObserver(this);
    WindowState::Get(window)->AddObserver(this);
  }
  // Note `this` may already be observing `window`, but the divider isn't, i.e.
  // during clamshell <-> tablet split view transition.
  if (InTabletMode()) {
    split_view_divider_.MaybeAddObservedWindow(window);
  }
}

void SplitViewController::StopObserving(SnapPosition snap_position) {
  aura::Window* window = GetSnappedWindow(snap_position);
  if (window == primary_window_) {
    primary_window_ = nullptr;
  } else {
    secondary_window_ = nullptr;
  }

  if (window && window->HasObserver(this)) {
    window->RemoveObserver(this);
    WindowState::Get(window)->RemoveObserver(this);
    // Must be called after we reset `primary_window_|secondary_window_`.
    split_view_divider_.MaybeRemoveObservedWindow(window);
    Shell::Get()->shadow_controller()->UpdateShadowForWindow(window);

    // It's possible that when we try to snap an ARC app window, while we are
    // waiting for its state/bounds to the expected state/bounds, another window
    // snap request comes in and causing the previous to-be-snapped window to
    // be un-observed, in this case we should restore the previous to-be-snapped
    // window's transform if it's unidentity.
    RestoreTransformIfApplicable(window);
  }
}

void SplitViewController::UpdateStateAndNotifyObservers() {
  State previous_state = state_;
  if (IsSnapped(primary_window_) && IsSnapped(secondary_window_)) {
    state_ = State::kBothSnapped;
  } else if (IsSnapped(primary_window_)) {
    state_ = State::kPrimarySnapped;
  } else if (IsSnapped(secondary_window_)) {
    state_ = State::kSecondarySnapped;
  } else {
    state_ = State::kNoSnap;
  }

  // We still notify observers even if |state_| doesn't change as it's possible
  // to snap a window to a position that already has a snapped window. However,
  // |previous_state| and |state_| cannot both be |State::kNoSnap|.
  // When |previous_state| is |State::kNoSnap|, it indicates to
  // observers that split view mode started. Likewise, when |state_| is
  // |State::kNoSnap|, it indicates to observers that split view mode
  // ended.
  DCHECK(previous_state != State::kNoSnap || state_ != State::kNoSnap ||
         end_reason_ == EndReason::kSnapGroups);
  for (auto& observer : observers_) {
    observer.OnSplitViewStateChanged(previous_state, state_);
  }
}

void SplitViewController::NotifyDividerPositionChanged() {
  for (auto& observer : observers_) {
    observer.OnSplitViewDividerPositionChanged();
  }
}

void SplitViewController::NotifyWindowResized() {
  for (auto& observer : observers_) {
    observer.OnSplitViewWindowResized();
  }
}

void SplitViewController::NotifyWindowSwapped() {
  for (auto& observer : observers_)
    observer.OnSplitViewWindowSwapped();
}

bool SplitViewController::MaybeCreateSnapGroup() {
  // TODO(b/329893720): Clean up this function.
  if (primary_window_ && secondary_window_ &&
      IsSnapGroupEnabledInClamshellMode()) {
    SnapGroupController* snap_group_controller = SnapGroupController::Get();
    // TODO(b/286963080): Move this to SnapGroupController.
    if (snap_group_controller->AddSnapGroup(primary_window_,
                                            secondary_window_)) {
      // Ending split view will call `UpdateStateAndNotifyObservers()` that
      // state is now `kNoSnap` and end overview in
      // `OverviewGrid::OnSplitViewStateChanged()`.
      EndSplitView(EndReason::kSnapGroups);
      return true;
    }
  }
  return false;
}

void SplitViewController::UpdateBlackScrim(
    const gfx::Point& location_in_screen) {
  DCHECK(InSplitViewMode());

  if (!black_scrim_layer_) {
    // Create an invisible black scrim layer.
    black_scrim_layer_ = std::make_unique<ui::Layer>(ui::LAYER_SOLID_COLOR);
    black_scrim_layer_->SetColor(AshColorProvider::Get()->GetBackgroundColor());
    // Set the black scrim layer underneath split view divider.
    auto* divider_layer =
        split_view_divider_.divider_widget()->GetNativeWindow()->layer();
    auto* divider_parent_layer = divider_layer->parent();
    divider_parent_layer->Add(black_scrim_layer_.get());
    divider_parent_layer->StackBelow(black_scrim_layer_.get(), divider_layer);
  }

  // Decide where the black scrim should show and update its bounds.
  SnapPosition position = GetBlackScrimPosition(location_in_screen);
  if (position == SnapPosition::kNone) {
    black_scrim_layer_.reset();
    return;
  }
  black_scrim_layer_->SetBounds(GetSnappedWindowBoundsInScreen(
      position, /*window_for_minimum_size=*/nullptr,
      chromeos::kDefaultSnapRatio, ShouldConsiderDivider()));

  // Update its opacity. The opacity increases as it gets closer to the edge of
  // the screen.
  const int location = IsLayoutHorizontal(root_window_)
                           ? location_in_screen.x()
                           : location_in_screen.y();
  gfx::Rect work_area_bounds =
      screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer(
          root_window_);
  if (!IsLayoutHorizontal(root_window_))
    work_area_bounds.Transpose();
  float opacity = kBlackScrimOpacity;
  const float ratio = chromeos::kOneThirdSnapRatio - kBlackScrimFadeInRatio;
  const int distance = std::min(std::abs(location - work_area_bounds.x()),
                                std::abs(work_area_bounds.right() - location));
  if (distance > work_area_bounds.width() * ratio) {
    opacity -= kBlackScrimOpacity *
               (distance - work_area_bounds.width() * ratio) /
               (work_area_bounds.width() * kBlackScrimFadeInRatio);
    opacity = std::max(opacity, 0.f);
  }
  black_scrim_layer_->SetOpacity(opacity);
}

void SplitViewController::UpdateResizeBackdrop() {
  // Creates a backdrop layer. It is stacked below the snapped window.
  auto create_backdrop = [](aura::Window* window) {
    auto resize_backdrop_layer =
        std::make_unique<ui::Layer>(ui::LAYER_SOLID_COLOR);

    ui::Layer* parent = window->layer()->parent();
    ui::Layer* stacking_target = window->layer();
    parent->Add(resize_backdrop_layer.get());
    parent->StackBelow(resize_backdrop_layer.get(), stacking_target);

    return resize_backdrop_layer;
  };

  // Updates the bounds and color of a backdrop.
  auto update_backdrop = [this](SnapPosition position, aura::Window* window,
                                ui::Layer* backdrop) {
    backdrop->SetBounds(GetSnappedWindowBoundsInParent(
        position, nullptr, chromeos::kDefaultSnapRatio));
    backdrop->SetColor(window->GetProperty(
        wm::IsActiveWindow(window) ? chromeos::kFrameActiveColorKey
                                   : chromeos::kFrameInactiveColorKey));
  };

  if (state_ == State::kPrimarySnapped || state_ == State::kBothSnapped) {
    if (!left_resize_backdrop_layer_)
      left_resize_backdrop_layer_ = create_backdrop(primary_window_);
    update_backdrop(SnapPosition::kPrimary, primary_window_,
                    left_resize_backdrop_layer_.get());
  }
  if (state_ == State::kSecondarySnapped || state_ == State::kBothSnapped) {
    if (!right_resize_backdrop_layer_)
      right_resize_backdrop_layer_ = create_backdrop(secondary_window_);
    update_backdrop(SnapPosition::kSecondary, secondary_window_,
                    right_resize_backdrop_layer_.get());
  }
}

void SplitViewController::UpdateSnappedWindowBounds(aura::Window* window) {
  DCHECK(IsWindowInSplitView(window));
  WindowState* window_state = WindowState::Get(window);
  if (InTabletMode()) {
    if (window->GetProperty(aura::client::kAppType) ==
        static_cast<int>(AppType::ARC_APP)) {
      // TODO(b/264962634): Remove this workaround. Probably, we can rewrite
      // `TabletModeWindowState::UpdateWindowPosition` to include this logic.
      const gfx::Rect requested_bounds =
          TabletModeWindowState::GetBoundsInTabletMode(window_state);
      const SetBoundsWMEvent event(requested_bounds,
                                   /*animate=*/true);
      window_state->OnWMEvent(&event);
    } else {
      TabletModeWindowState::UpdateWindowPosition(
          window_state, WindowState::BoundsChangeAnimationType::kAnimate);
    }
  } else {
    const gfx::Rect requested_bounds = GetSnappedWindowBoundsInParent(
        GetPositionOfSnappedWindow(window), window,
        window_util::GetSnapRatioForWindow(window));
    const SetBoundsWMEvent event(requested_bounds, /*animate=*/true);
    window_state->OnWMEvent(&event);
  }
}

void SplitViewController::UpdateSnappedWindowsBounds() {
  // Update the snapped windows' bounds. If the window is already snapped in the
  // correct position, simply update the snap ratio.
  if (IsSnapped(primary_window_)) {
    UpdateSnappedWindowBounds(primary_window_);
  }
  if (IsSnapped(secondary_window_)) {
    UpdateSnappedWindowBounds(secondary_window_);
  }
}

void SplitViewController::UpdateSnappedWindowsAndDividerBounds() {
  UpdateSnappedWindowsBounds();

  // Update divider's bounds and make it adjustable.
  if (split_view_divider_.divider_widget()) {
    split_view_divider_.UpdateDividerBounds();

    // Make the split view divider adjustable.
    split_view_divider_.SetAdjustable(true);
  }
}

SnapPosition SplitViewController::GetBlackScrimPosition(
    const gfx::Point& location_in_screen) {
  const gfx::Rect work_area_bounds =
      screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer(
          root_window_);
  if (!work_area_bounds.Contains(location_in_screen))
    return SnapPosition::kNone;

  gfx::Size primary_window_min_size, secondary_window_min_size;
  if (primary_window_ && primary_window_->delegate())
    primary_window_min_size = primary_window_->delegate()->GetMinimumSize();
  if (secondary_window_ && secondary_window_->delegate())
    secondary_window_min_size = secondary_window_->delegate()->GetMinimumSize();

  bool right_side_up = IsLayoutPrimary(root_window_);
  int divider_upper_limit = GetDividerPositionUpperLimit(root_window_);
  // The distance from the current resizing position to the left or right side
  // of the screen. Note: left or right side here means the side of the
  // |primary_window_| or |secondary_window_|.
  int primary_window_distance = 0, secondary_window_distance = 0;
  int min_left_length = 0, min_right_length = 0;

  if (IsLayoutHorizontal(root_window_)) {
    int left_distance = location_in_screen.x() - work_area_bounds.x();
    int right_distance = work_area_bounds.right() - location_in_screen.x();
    primary_window_distance = right_side_up ? left_distance : right_distance;
    secondary_window_distance = right_side_up ? right_distance : left_distance;

    min_left_length = primary_window_min_size.width();
    min_right_length = secondary_window_min_size.width();
  } else {
    int top_distance = location_in_screen.y() - work_area_bounds.y();
    int bottom_distance = work_area_bounds.bottom() - location_in_screen.y();
    primary_window_distance = right_side_up ? top_distance : bottom_distance;
    secondary_window_distance = right_side_up ? bottom_distance : top_distance;

    min_left_length = primary_window_min_size.height();
    min_right_length = secondary_window_min_size.height();
  }

  if (primary_window_distance <
          divider_upper_limit * chromeos::kOneThirdSnapRatio ||
      primary_window_distance < min_left_length) {
    return SnapPosition::kPrimary;
  }
  if (secondary_window_distance <
          divider_upper_limit * chromeos::kOneThirdSnapRatio ||
      secondary_window_distance < min_right_length) {
    return SnapPosition::kSecondary;
  }

  return SnapPosition::kNone;
}

int SplitViewController::GetClosestFixedDividerPosition(int divider_position) {
  // The values in |kFixedPositionRatios| represent the fixed position of the
  // center of the divider while |GetDividerPosition()| represent the origin of
  // the divider rectangle. So, before calling FindClosestFixedPositionRatio,
  // extract the center from |GetDividerPosition()|. The result will also be the
  // center of the divider, so extract the origin, unless the result is on of
  // the endpoints.
  int divider_upper_limit = GetDividerPositionUpperLimit(root_window_);
  // TODO(b/319334795): Move this function and `divider_closest_ratio_` to
  // SplitViewDivider.
  divider_closest_ratio_ = FindClosestPositionRatio(
      float(divider_position + kSplitviewDividerShortSideLength / 2) /
      divider_upper_limit);
  int fixed_position = divider_upper_limit * divider_closest_ratio_;
  if (divider_closest_ratio_ > 0.f && divider_closest_ratio_ < 1.f) {
    fixed_position -= kSplitviewDividerShortSideLength / 2;
  }
  return std::clamp(fixed_position, 0, divider_upper_limit);
}

void SplitViewController::StopAndShoveAnimatedDivider() {
  CHECK(IsDividerAnimating());

  StopSnapAnimation();
  NotifyDividerPositionChanged();
  UpdateSnappedWindowsAndDividerBounds();
}

void SplitViewController::StopSnapAnimation() {
  divider_snap_animation_->Stop();
  split_view_divider_.SetDividerPosition(
      divider_snap_animation_->ending_position());
}

bool SplitViewController::ShouldEndSplitViewAfterResizingAtEdge() {
  if (!InTabletSplitViewMode()) {
    // `SplitViewDivider::CleanUpWindowResizing()` may be called after a display
    // change, after which we have ended split view.
    // TODO(sophiewen): Only call `SplitViewDivider::CleanUpWindowResizing()` if
    // we actually ended resizing.
    return false;
  }
  const int divider_position = GetDividerPosition();
  return divider_position == 0 ||
         divider_position == GetDividerPositionUpperLimit(root_window_);
}

void SplitViewController::EndSplitViewAfterResizingAtEdgeIfAppropriate() {
  if (!ShouldEndSplitViewAfterResizingAtEdge()) {
    return;
  }

  aura::Window* active_window = GetActiveWindowAfterResizingUponExit();

  // Track the window that needs to be put back into the overview list if we
  // remain in overview mode.
  aura::Window* insert_overview_window = nullptr;
  if (IsInOverviewSession()) {
    insert_overview_window = GetDefaultSnappedWindow();
  }

  EndSplitView();
  if (active_window) {
    Shell::Get()->overview_controller()->EndOverview(
        OverviewEndAction::kSplitView);
    wm::ActivateWindow(active_window);
  } else if (insert_overview_window) {
    InsertWindowToOverview(insert_overview_window, /*animate=*/false);
  }
}

aura::Window* SplitViewController::GetActiveWindowAfterResizingUponExit() {
  DCHECK(InSplitViewMode());

  if (!ShouldEndSplitViewAfterResizingAtEdge()) {
    return nullptr;
  }

  return GetDividerPosition() == 0 ? GetPhysicalRightOrBottomWindow()
                                   : GetPhysicalLeftOrTopWindow();
}

void SplitViewController::OnWindowSnapped(
    aura::Window* window,
    std::optional<chromeos::WindowStateType> previous_state,
    WindowSnapActionSource snap_action_source) {
  RestoreTransformIfApplicable(window);

  // We must add snap group and end split view before updating state. If
  // `MaybeCreateSnapGroup()` is true, we have ended split view so no need to
  // update state and notify observers again.
  if (MaybeCreateSnapGroup()) {
    return;
  }

  UpdateStateAndNotifyObservers();

  // If the snapped window was removed from overview and was the active window
  // before entering overview, it should be the active window after snapping in
  // splitview.
  if (to_be_activated_window_ == window) {
    to_be_activated_window_ = nullptr;
    wm::ActivateWindow(window);
  }

  // In tablet mode, if the window was previously floated, the other side is
  // available, and there is another non-minimized window, do not enter overview
  // but instead snap that window to the opposite side.
  if (InTabletMode() && previous_state &&
      *previous_state == chromeos::WindowStateType::kFloated &&
      state_ != State::kBothSnapped) {
    for (aura::Window* mru_window :
         Shell::Get()->mru_window_tracker()->BuildWindowForCycleList(
             kActiveDesk)) {
      auto* window_state = WindowState::Get(mru_window);
      if (mru_window != window && !window_state->IsMinimized() &&
          window_state->CanSnap()) {
        const SnapPosition snap_position =
            GetPositionOfSnappedWindow(window) == SnapPosition::kPrimary
                ? SnapPosition::kSecondary
                : SnapPosition::kPrimary;
        WindowSnapWMEvent event(snap_position == SnapPosition::kPrimary
                                    ? WM_EVENT_SNAP_PRIMARY
                                    : WM_EVENT_SNAP_SECONDARY,
                                WindowSnapActionSource::kAutoSnapInSplitView);
        WindowState::Get(mru_window)->OnWMEvent(&event);
        return;
      }
    }
  }

  if (auto* snap_group_controller = SnapGroupController::Get();
      snap_group_controller &&
      snap_group_controller->OnSnappingWindow(window, snap_action_source)) {
    // End split view is needed due to the inconsistent checks between
    // `ShouldConsiderWindowForFasterSplitView()` and
    // `CanStartSplitViewOverviewSessionInClamshell()`.
    // TODO(b/331965553): Have consistent checks between the two APIs.
    EndSplitView(EndReason::kSnapGroups);
    return;
  }

  if (WillStartPartialOverview(window)) {
    RootWindowController::ForWindow(window)->StartSplitViewOverviewSession(
        window, overview_start_action_, enter_exit_overview_type_,
        snap_action_source);
    overview_start_action_.reset();
    enter_exit_overview_type_.reset();
    return;
  }

  // If we are in clamshell and did *not* start partial overview, which may
  // happen if there is an opposite snapped window not in split view, end split
  // view, except for the following cases:
  // 1. Partial overview may already be in session, i.e. if the window snapped
  // in partial overview swaps snap positions via the window layout menu.
  // 2. During tablet -> clamshell transition, we do not end split view since
  // it may still be needed by `SnapGroupController` to create a `SnapGroup`.
  // Split view will be ended either in `MaybeCreateSnapGroup()` or
  // `MaybeEndSplitViewAndOverview()` in `TabletModeWindowManager`.
  // TODO(b/327269057): Refactor tablet <-> clamshell transition.
  if (!InTabletMode() &&
      !RootWindowController::ForWindow(window)->split_view_overview_session() &&
      snap_action_source !=
          WindowSnapActionSource::kSnapByClamshellTabletTransition) {
    EndSplitView(EndReason::kNormal);
    return;
  }

  UpdateSnappedWindowsAndDividerBounds();
}

void SplitViewController::OnSnappedWindowDetached(aura::Window* window,
                                                  WindowDetachedReason reason) {
  auto iter = snapping_window_transformed_bounds_map_.find(window);
  if (iter != snapping_window_transformed_bounds_map_.end()) {
    snapping_window_transformed_bounds_map_.erase(iter);
  }

  if (to_be_activated_window_ == window) {
    to_be_activated_window_ = nullptr;
  }

  const bool is_window_moved =
      reason == WindowDetachedReason::kWindowMovedToAnotherDisplay;
  const bool is_window_destroyed_or_moved =
      reason == WindowDetachedReason::kWindowDestroyed || is_window_moved;
  const SnapPosition position_of_snapped_window =
      GetPositionOfSnappedWindow(window);

  // Detach it from splitview first if the window is to be destroyed to prevent
  // unnecessary bounds/state update to it when ending splitview resizing. For
  // the window that is not going to be destroyed, we still need its bounds and
  // state to be updated to match the updated divider position before detaching
  // it from splitview.
  if (is_window_destroyed_or_moved) {
    StopObserving(position_of_snapped_window);
  }

  // Stop resizing if one of the snapped window is detached from split
  // view.
  const bool is_divider_animating = IsDividerAnimating();
  if (IsResizingWithDivider() || is_divider_animating) {
    if (is_divider_animating) {
      StopAndShoveAnimatedDivider();
    }
    EndResizeWithDividerImpl();
  }

  if (!is_window_destroyed_or_moved) {
    StopObserving(position_of_snapped_window);
  }

  // End the Split View mode for the following two cases:
  // 1. If there is no snapped window at this moment;
  // 2. In Clamshell partial overview, `SplitViewController` will no longer
  // manage the window on one window detached.
  auto should_end_split_view = [&]() -> bool {
    if (!primary_window_ && !secondary_window_) {
      return true;
    }

    return InClamshellSplitViewMode() &&
           (!primary_window_ || !secondary_window_);
  };
  if (should_end_split_view()) {
    EndSplitView(reason == WindowDetachedReason::kWindowDragged
                     ? EndReason::kWindowDragStarted
                     : EndReason::kNormal);
    if (is_window_moved) {
      // If the snapped window is being moved to another display, end overview.
      Shell::Get()->overview_controller()->EndOverview(
          OverviewEndAction::kSplitView);
    }
  } else {
    DCHECK(InTabletSplitViewMode());
    aura::Window* other_window =
        GetSnappedWindow(position_of_snapped_window == SnapPosition::kPrimary
                             ? SnapPosition::kSecondary
                             : SnapPosition::kPrimary);

    if (reason == WindowDetachedReason::kWindowFloated || is_window_moved) {
      // Maximize the other window, which will end split view.
      WMEvent event(WM_EVENT_MAXIMIZE);
      WindowState::Get(other_window)->OnWMEvent(&event);
      return;
    }

    // If there is still one snapped window after minimizing/closing one snapped
    // window, update its snap state and open overview window grid.
    default_snap_position_ =
        primary_window_ ? SnapPosition::kPrimary : SnapPosition::kSecondary;
    UpdateStateAndNotifyObservers();
    // `WindowSnapActionSource::kNotSpecified` is used as the snap source since
    // this is not user-initiated action.
    RootWindowController::ForWindow(other_window)
        ->StartSplitViewOverviewSession(
            other_window, OverviewStartAction::kFasterSplitScreenSetup,
            reason == WindowDetachedReason::kWindowDragged
                ? OverviewEnterExitType::kImmediateEnter
                : OverviewEnterExitType::kNormal,
            WindowSnapActionSource::kNotSpecified);
  }
}

void SplitViewController::ModifyPositionRatios(
    std::vector<float>& out_position_ratios) {
  const bool landscape = IsCurrentScreenOrientationLandscape();
  const int min_left_size =
      GetMinimumWindowLength(GetPhysicalLeftOrTopWindow(), landscape);
  const int min_right_size =
      GetMinimumWindowLength(GetPhysicalRightOrBottomWindow(), landscape);
  const int divider_upper_limit = GetDividerPositionUpperLimit(root_window_);
  const float min_size_left_ratio =
      static_cast<float>(min_left_size) / divider_upper_limit;
  const float min_size_right_ratio =
      static_cast<float>(min_right_size) / divider_upper_limit;
  if (min_size_left_ratio > chromeos::kOneThirdSnapRatio) {
    // If `primary_window_` can't fit in 1/3, remove 0.33f divider position.
    std::erase(out_position_ratios, chromeos::kOneThirdSnapRatio);
  }
  if (min_size_right_ratio > chromeos::kOneThirdSnapRatio) {
    // If `secondary_window_` can't fit in 1/3, remove 0.67f divider position.
    std::erase(out_position_ratios, chromeos::kTwoThirdSnapRatio);
  }
  // Remove 0.5f if a window cannot be snapped. We can get into this state by
  // snapping a window to two thirds.
  if (min_size_left_ratio > chromeos::kDefaultSnapRatio ||
      min_size_right_ratio > chromeos::kDefaultSnapRatio) {
    std::erase(out_position_ratios, chromeos::kDefaultSnapRatio);
  }
}

float SplitViewController::FindClosestPositionRatio(float current_ratio) {
  float closest_ratio = 0.f;
  std::vector<float> position_ratios(
      kFixedPositionRatios,
      kFixedPositionRatios + std::size(kFixedPositionRatios));
  ModifyPositionRatios(position_ratios);
  float min_ratio_diff = std::numeric_limits<float>::max();
  for (const float ratio : position_ratios) {
    const float ratio_diff = std::abs(current_ratio - ratio);
    if (ratio_diff < min_ratio_diff) {
      min_ratio_diff = ratio_diff;
      closest_ratio = ratio;
    }
  }
  return closest_ratio;
}

void SplitViewController::RestoreTransformIfApplicable(aura::Window* window) {
  // If the transform of the window has been changed, calculate a good starting
  // transform based on its transformed bounds before to be snapped.
  auto iter = snapping_window_transformed_bounds_map_.find(window);
  if (iter == snapping_window_transformed_bounds_map_.end())
    return;

  const gfx::Rect item_bounds = iter->second;
  snapping_window_transformed_bounds_map_.erase(iter);

  // Restore the window's transform first if it's not identity.
  if (!window->layer()->GetTargetTransform().IsIdentity()) {
    // Calculate the starting transform based on the window's expected snapped
    // bounds and its transformed bounds before to be snapped.
    const gfx::Rect snapped_bounds = GetSnappedWindowBoundsInScreen(
        GetPositionOfSnappedWindow(window), window,
        window_util::GetSnapRatioForWindow(window), ShouldConsiderDivider());
    const gfx::Transform starting_transform = gfx::TransformBetweenRects(
        gfx::RectF(snapped_bounds), gfx::RectF(item_bounds));
    SetTransformWithAnimation(window, starting_transform, gfx::Transform());
  }
}

void SplitViewController::SetWindowsTransformDuringResizing() {
  CHECK(InTabletSplitViewMode() || IsSnapGroupEnabledInClamshellMode());
  const int divider_position = GetDividerPosition();
  CHECK_GE(divider_position, 0);
  aura::Window* left_or_top_window = GetPhysicalLeftOrTopWindow();
  aura::Window* right_or_bottom_window = GetPhysicalRightOrBottomWindow();
  if (left_or_top_window) {
    SetWindowTransformDuringResizing(left_or_top_window, divider_position);
  }
  if (right_or_bottom_window) {
    SetWindowTransformDuringResizing(right_or_bottom_window, divider_position);
  }
}

void SplitViewController::RestoreWindowsTransformAfterResizing() {
  DCHECK(InSplitViewMode());
  if (primary_window_)
    window_util::SetTransform(primary_window_, gfx::Transform());
  if (secondary_window_)
    window_util::SetTransform(secondary_window_, gfx::Transform());
  if (black_scrim_layer_.get()) {
    black_scrim_layer_->SetTransform(gfx::Transform());
  }
}

void SplitViewController::SetTransformWithAnimation(
    aura::Window* window,
    const gfx::Transform& start_transform,
    const gfx::Transform& target_transform) {
  for (auto* window_iter : GetTransientTreeIterator(window)) {
    // Adjust `start_transform` and `target_transform` for the transient child.
    const gfx::PointF target_origin =
        GetUnionScreenBoundsForWindow(window).origin();
    gfx::RectF original_bounds(window_iter->GetTargetBounds());
    wm::TranslateRectToScreen(window_iter->parent(), &original_bounds);
    const gfx::PointF pivot(target_origin.x() - original_bounds.x(),
                            target_origin.y() - original_bounds.y());
    const gfx::Transform new_start_transform =
        TransformAboutPivot(pivot, start_transform);
    const gfx::Transform new_target_transform =
        TransformAboutPivot(pivot, target_transform);
    if (new_start_transform != window_iter->layer()->GetTargetTransform())
      window_iter->SetTransform(new_start_transform);

    std::vector<ui::ImplicitAnimationObserver*> animation_observers;
    if (window_iter == window) {
      animation_observers.push_back(
          new WindowTransformAnimationObserver(window));

      // If the overview exit animation is in progress or is about to start, add
      // the |window| snap animation as one of the animations to be completed
      // before |OverviewController::OnEndingAnimationComplete| should be called
      // to unpause occlusion tracking, unblur the wallpaper, etc.
      OverviewController* overview_controller = OverviewController::Get();
      OverviewSession* overview_session =
          overview_controller->overview_session();
      if (overview_controller->IsCompletingShutdownAnimations() ||
          (overview_session && overview_session->is_shutting_down() &&
           overview_session->enter_exit_overview_type() !=
               OverviewEnterExitType::kImmediateExit)) {
        auto overview_exit_animation_observer =
            std::make_unique<ExitAnimationObserver>();
        animation_observers.push_back(overview_exit_animation_observer.get());
        overview_controller->AddExitAnimationObserver(
            std::move(overview_exit_animation_observer));
      }
    }
    DoSplitviewTransformAnimation(window_iter->layer(),
                                  SPLITVIEW_ANIMATION_SET_WINDOW_TRANSFORM,
                                  new_target_transform, animation_observers);
  }
}

void SplitViewController::UpdateSnappingWindowTransformedBounds(
    aura::Window* window) {
  if (!window->layer()->GetTargetTransform().IsIdentity()) {
    snapping_window_transformed_bounds_map_[window] = gfx::ToEnclosedRect(
        window_util::GetTransformedBounds(window, /*top_inset=*/0));
  }
}

void SplitViewController::InsertWindowToOverview(aura::Window* window,
                                                 bool animate) {
  if (!window || !GetOverviewSession())
    return;
  GetOverviewSession()->AddItemInMruOrder(window, /*reposition=*/true, animate,
                                          /*restack=*/true,
                                          /*use_spawn_animation=*/false);
}

void SplitViewController::EndResizeWithDividerImpl() {
  split_view_divider_.CleanUpWindowResizing();
}

void SplitViewController::OnResizeTimer() {
  if (InSplitViewMode() && split_view_divider_.divider_widget()) {
    split_view_divider_.ResizeWithDivider(
        split_view_divider_.previous_event_location());
  }
}

void SplitViewController::UpdateTabletResizeMode(
    base::TimeTicks event_time_ticks,
    const gfx::Point& event_location) {
  CHECK(presentation_time_recorder_);
  presentation_time_recorder_->RequestNext();

  if (IsLayoutHorizontal(root_window_)) {
    accumulated_drag_distance_ += std::abs(
        event_location.x() - split_view_divider_.previous_event_location().x());
  } else {
    accumulated_drag_distance_ += std::abs(
        event_location.y() - split_view_divider_.previous_event_location().y());
  }

  const base::TimeDelta chunk_time_ticks =
      event_time_ticks - accumulated_drag_time_ticks_;
  // We switch between fast and normal resize mode depending on how fast the
  // divider is dragged. This is done in "chunks" by keeping track of how far
  // the divider has been dragged. When the chunk gone on for long enough, we
  // calculate the drag speed based on `accumulated_drag_distance_` and update
  // the resize mode accordingly.
  if (chunk_time_ticks >= kSplitViewChunkTime) {
    int drag_per_second =
        accumulated_drag_distance_ / chunk_time_ticks.InSecondsF();
    tablet_resize_mode_ = drag_per_second > kSplitViewThresholdPixelsPerSec
                              ? TabletResizeMode::kFast
                              : TabletResizeMode::kNormal;

    accumulated_drag_time_ticks_ = event_time_ticks;
    accumulated_drag_distance_ = 0;
  }

  // If we are in the fast mode, start a timer that automatically invokes
  // `ResizeWithDivider()` after a timeout. This ensure that we can switch back
  // to the normal mode if the user stops dragging. Note: if the timer is
  // already active, this will simply move the deadline forward.
  if (tablet_resize_mode_ == TabletResizeMode::kFast) {
    resize_timer_.Start(FROM_HERE, kSplitViewChunkTime, this,
                        &SplitViewController::OnResizeTimer);
  }
}

void SplitViewController::OnTabletModeStarted() {
  is_previous_layout_right_side_up_ = IsCurrentScreenOrientationPrimary();
  // If splitview is active when tablet mode is starting, create the split view
  // divider if not exists and adjust the `GetDividerPosition()` to be one
  // of the fixed positions.
  if (InSplitViewMode()) {
    // The windows would already have been attached before transition, in
    // `TabletModeWindowManager::ArrangeWindowsForTabletMode()`.
    CHECK(primary_window_ || secondary_window_);
    // Take divider width into calculation since divider will always be
    // available for tablet split view. Tablet mode only supports the fixed
    // divider positions in `kFixedPositionRatios`, so push `divider_position_`
    // to the closest fixed ratio.
    const int divider_position =
        GetClosestFixedDividerPosition(GetEquivalentDividerPosition(
            primary_window_ ? primary_window_ : secondary_window_,
            /*account_for_divider_width=*/true));
    split_view_divider_.SetDividerPosition(divider_position);

    UpdateSnappedWindowsAndDividerBounds();
    NotifyDividerPositionChanged();

    // Ends `SplitViewOverviewSession` if it is currently alive, as
    // `SplitViewOverviewSession` is for clamshell only.
    RootWindowController* root_window_controller =
        RootWindowController::ForWindow(root_window_);
    if (root_window_controller->split_view_overview_session()) {
      root_window_controller->EndSplitViewOverviewSession(
          SplitViewOverviewSessionExitPoint::kTabletConversion);
    }
  }
}

void SplitViewController::OnTabletModeEnding() {
  // `OnTabletModeEnding()` can also be called during test teardown.
  const bool is_divider_animating = IsDividerAnimating();
  if (IsResizingWithDivider() || is_divider_animating) {
    if (is_divider_animating) {
      StopAndShoveAnimatedDivider();
    }

    EndResizeWithDividerImpl();
  }

  split_view_divider_.SetVisible(false);
}

void SplitViewController::OnTabletModeEnded() {
  is_previous_layout_right_side_up_ = true;
}

void SplitViewController::EndWindowDragImpl(
    aura::Window* window,
    bool is_being_destroyed,
    SnapPosition desired_snap_position,
    const gfx::Point& last_location_in_screen,
    WindowSnapActionSource snap_action_source) {
  if (split_view_divider_.divider_widget()) {
    split_view_divider_.OnWindowDragEnded();
  }

  // If the dragged window is to be destroyed, do not try to snap it.
  if (is_being_destroyed)
    return;

  // If dragged window was in overview before or it has been added to overview
  // window by dropping on the new selector item, do nothing.
  if (GetOverviewSession() && GetOverviewSession()->IsWindowInOverview(window))
    return;

  if (WindowState::Get(window)->IsFloated()) {
    // If a floated window was dragged from shelf and released, don't snap.
    return;
  }

  DCHECK_EQ(root_window_, window->GetRootWindow());

  const bool was_splitview_active = InSplitViewMode();
  if (desired_snap_position == SnapPosition::kNone) {
    if (was_splitview_active) {
      // Even though |snap_position| equals |SnapPosition::kNone|, the dragged
      // window still needs to be snapped if splitview mode is active at the
      // moment.
      // Calculate the expected snap position based on the last event
      // location. Note if there is already a window at |desired_snap_postion|,
      // SnapWindow() will put the previous snapped window in overview.
      SnapWindow(window, ComputeSnapPosition(last_location_in_screen),
                 snap_action_source,
                 /*activate_window=*/true);
    } else {
      // Restore the dragged window's transform first if it's not identity. It
      // needs to be called before the transformed window's bounds change so
      // that its transient children are layout'ed properly (the layout happens
      // when window's bounds change).
      SetTransformWithAnimation(window, window->layer()->GetTargetTransform(),
                                gfx::Transform());

      OverviewSession* overview_session = GetOverviewSession();
      if (overview_session) {
        overview_session->SetWindowListNotAnimatedWhenExiting(root_window_);
        // Set the overview exit type to kImmediateExit to avoid update bounds
        // animation of the windows in overview grid.
        overview_session->set_enter_exit_overview_type(
            OverviewEnterExitType::kImmediateExit);
      }
      // Activate the dragged window and end the overview. The dragged window
      // will be restored back to its previous state before dragging.
      wm::ActivateWindow(window);
      Shell::Get()->overview_controller()->EndOverview(
          OverviewEndAction::kSplitView);

      // Update the dragged window's bounds. It's possible that the dragged
      // window's bounds was changed during dragging. Update its bounds after
      // the drag ends to ensure it has the right bounds.
      TabletModeWindowState::UpdateWindowPosition(
          WindowState::Get(window),
          WindowState::BoundsChangeAnimationType::kAnimate);
    }
  } else {
    // Note SnapWindow() might put the previous window that was snapped at the
    // |desired_snap_position| in overview.
    SnapWindow(window, desired_snap_position, snap_action_source,
               /*activate_window=*/true);
  }
}

void SplitViewController::SwapWindowsAndUpdateBounds() {
  gfx::Rect primary_window_bounds =
      primary_window_ ? primary_window_->GetBoundsInScreen() : gfx::Rect();
  gfx::Rect secondary_window_bounds =
      secondary_window_ ? secondary_window_->GetBoundsInScreen() : gfx::Rect();
  aura::Window* cached_window = primary_window_;
  primary_window_ = secondary_window_;
  secondary_window_ = cached_window;

  const auto dst_display =
      display::Screen::GetScreen()->GetDisplayNearestWindow(root_window_);

  if (primary_window_) {
    primary_window_->SetBoundsInScreen(secondary_window_bounds, dst_display);
  }

  if (secondary_window_) {
    secondary_window_->SetBoundsInScreen(primary_window_bounds, dst_display);
  }
}

}  // namespace ash
