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

#include "third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller_impl.h"

#include <memory>
#include <utility>
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/platform/web_screen_info.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/fullscreen/scoped_allow_fullscreen.h"
#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/modules/screen_orientation/screen_orientation.h"
#include "third_party/blink/renderer/modules/screen_orientation/screen_orientation_dispatcher.h"
#include "third_party/blink/renderer/platform/web_test_support.h"

namespace blink {

ScreenOrientationControllerImpl::~ScreenOrientationControllerImpl() = default;

void ScreenOrientationControllerImpl::ProvideTo(LocalFrame& frame) {
  ScreenOrientationController::ProvideTo(
      frame, MakeGarbageCollected<ScreenOrientationControllerImpl>(frame));
}

ScreenOrientationControllerImpl* ScreenOrientationControllerImpl::From(
    LocalFrame& frame) {
  return static_cast<ScreenOrientationControllerImpl*>(
      ScreenOrientationController::From(frame));
}

ScreenOrientationControllerImpl::ScreenOrientationControllerImpl(
    LocalFrame& frame)
    : ScreenOrientationController(frame),
      ContextLifecycleObserver(frame.GetDocument()),
      PlatformEventController(frame.GetDocument()),
      dispatch_event_timer_(
          frame.GetTaskRunner(TaskType::kMiscPlatformAPI),
          this,
          &ScreenOrientationControllerImpl::DispatchEventTimerFired) {
  AssociatedInterfaceProvider* provider =
      frame.GetRemoteNavigationAssociatedInterfaces();
  if (provider)
    provider->GetInterface(&screen_orientation_service_);
}

// Compute the screen orientation using the orientation angle and the screen
// width / height.
WebScreenOrientationType ScreenOrientationControllerImpl::ComputeOrientation(
    const IntRect& rect,
    uint16_t rotation) {
  // Bypass orientation detection in web tests to get consistent results.
  // FIXME: The screen dimension should be fixed when running the web tests
  // to avoid such issues.
  if (WebTestSupport::IsRunningWebTest())
    return kWebScreenOrientationPortraitPrimary;

  bool is_tall_display = rotation % 180 ? rect.Height() < rect.Width()
                                        : rect.Height() > rect.Width();

  // https://w3c.github.io/screen-orientation/#dfn-current-orientation-angle
  // allows the UA to associate *-primary and *-secondary values at will. Blink
  // arbitrarily chooses rotation 0 to always be portrait-primary or
  // landscape-primary, and portrait-primary + 90 to be landscape-primary, which
  // together fully determine the relationship.
  switch (rotation) {
    case 0:
      return is_tall_display ? kWebScreenOrientationPortraitPrimary
                             : kWebScreenOrientationLandscapePrimary;
    case 90:
      return is_tall_display ? kWebScreenOrientationLandscapePrimary
                             : kWebScreenOrientationPortraitSecondary;
    case 180:
      return is_tall_display ? kWebScreenOrientationPortraitSecondary
                             : kWebScreenOrientationLandscapeSecondary;
    case 270:
      return is_tall_display ? kWebScreenOrientationLandscapeSecondary
                             : kWebScreenOrientationPortraitPrimary;
    default:
      NOTREACHED();
      return kWebScreenOrientationPortraitPrimary;
  }
}

void ScreenOrientationControllerImpl::UpdateOrientation() {
  DCHECK(orientation_);
  DCHECK(GetFrame());
  DCHECK(GetFrame()->GetPage());
  ChromeClient& chrome_client = GetFrame()->GetPage()->GetChromeClient();
  WebScreenInfo screen_info = chrome_client.GetScreenInfo();
  WebScreenOrientationType orientation_type = screen_info.orientation_type;
  if (orientation_type == kWebScreenOrientationUndefined) {
    // The embedder could not provide us with an orientation, deduce it
    // ourselves.
    orientation_type = ComputeOrientation(chrome_client.GetScreenInfo().rect,
                                          screen_info.orientation_angle);
  }
  DCHECK(orientation_type != kWebScreenOrientationUndefined);

  orientation_->SetType(orientation_type);
  orientation_->SetAngle(screen_info.orientation_angle);
}

bool ScreenOrientationControllerImpl::IsActive() const {
  return orientation_ && screen_orientation_service_;
}

bool ScreenOrientationControllerImpl::IsVisible() const {
  return GetPage() && GetPage()->IsPageVisible();
}

bool ScreenOrientationControllerImpl::IsActiveAndVisible() const {
  return IsActive() && IsVisible();
}

void ScreenOrientationControllerImpl::PageVisibilityChanged() {
  NotifyDispatcher();

  if (!IsActiveAndVisible())
    return;

  DCHECK(GetFrame());
  DCHECK(GetFrame()->GetPage());

  // The orientation type and angle are tied in a way that if the angle has
  // changed, the type must have changed.
  unsigned short current_angle = GetFrame()
                                     ->GetPage()
                                     ->GetChromeClient()
                                     .GetScreenInfo()
                                     .orientation_angle;

  // FIXME: sendOrientationChangeEvent() currently send an event all the
  // children of the frame, so it should only be called on the frame on
  // top of the tree. We would need the embedder to call
  // sendOrientationChangeEvent on every WebFrame part of a WebView to be
  // able to remove this.
  if (GetFrame() == GetFrame()->LocalFrameRoot() &&
      orientation_->angle() != current_angle)
    NotifyOrientationChanged();
}

void ScreenOrientationControllerImpl::NotifyOrientationChanged() {
  if (!IsVisible() || !GetFrame())
    return;

  if (IsActive())
    UpdateOrientation();

  // Keep track of the frames that need to be notified before notifying the
  // current frame as it will prevent side effects from the change event
  // handlers.
  HeapVector<Member<LocalFrame>> child_frames;
  for (Frame* child = GetFrame()->Tree().FirstChild(); child;
       child = child->Tree().NextSibling()) {
    if (child->IsLocalFrame())
      child_frames.push_back(ToLocalFrame(child));
  }

  // Notify current orientation object.
  if (IsActive() && !dispatch_event_timer_.IsActive())
    dispatch_event_timer_.StartOneShot(TimeDelta(), FROM_HERE);

  // ... and child frames, if they have a ScreenOrientationControllerImpl.
  for (LocalFrame* child_frame : child_frames) {
    if (ScreenOrientationControllerImpl* controller =
            ScreenOrientationControllerImpl::From(*child_frame)) {
      controller->NotifyOrientationChanged();
    }
  }
}

void ScreenOrientationControllerImpl::SetOrientation(
    ScreenOrientation* orientation) {
  orientation_ = orientation;
  if (orientation_)
    UpdateOrientation();
  NotifyDispatcher();
}

void ScreenOrientationControllerImpl::lock(
    WebScreenOrientationLockType orientation,
    std::unique_ptr<WebLockOrientationCallback> callback) {
  // When detached, the |screen_orientation_service_| is no longer valid.
  if (!screen_orientation_service_)
    return;

  CancelPendingLocks();
  pending_callback_ = std::move(callback);
  screen_orientation_service_->LockOrientation(
      orientation,
      WTF::Bind(&ScreenOrientationControllerImpl::OnLockOrientationResult,
                WrapWeakPersistent(this), ++request_id_));

  active_lock_ = true;
}

void ScreenOrientationControllerImpl::unlock() {
  // When detached, the |screen_orientation_service_| is no longer valid.
  if (!screen_orientation_service_)
    return;

  CancelPendingLocks();
  screen_orientation_service_->UnlockOrientation();
  active_lock_ = false;
}

bool ScreenOrientationControllerImpl::MaybeHasActiveLock() const {
  return active_lock_;
}

void ScreenOrientationControllerImpl::DispatchEventTimerFired(TimerBase*) {
  if (!orientation_)
    return;

  ScopedAllowFullscreen allow_fullscreen(
      ScopedAllowFullscreen::kOrientationChange);
  orientation_->DispatchEvent(*Event::Create(event_type_names::kChange));
}

void ScreenOrientationControllerImpl::DidUpdateData() {
  // Do nothing.
}

void ScreenOrientationControllerImpl::RegisterWithDispatcher() {
  ScreenOrientationDispatcher::Instance().AddController(this);
}

void ScreenOrientationControllerImpl::UnregisterWithDispatcher() {
  ScreenOrientationDispatcher::Instance().RemoveController(this);
}

bool ScreenOrientationControllerImpl::HasLastData() {
  return true;
}

void ScreenOrientationControllerImpl::ContextDestroyed(ExecutionContext*) {
  StopUpdating();
  screen_orientation_service_ = nullptr;
  active_lock_ = false;
}

void ScreenOrientationControllerImpl::NotifyDispatcher() {
  if (orientation_ && GetPage()->IsPageVisible())
    StartUpdating();
  else
    StopUpdating();
}

void ScreenOrientationControllerImpl::Trace(blink::Visitor* visitor) {
  visitor->Trace(orientation_);
  ContextLifecycleObserver::Trace(visitor);
  Supplement<LocalFrame>::Trace(visitor);
  PlatformEventController::Trace(visitor);
}

void ScreenOrientationControllerImpl::SetScreenOrientationAssociatedPtrForTests(
    ScreenOrientationAssociatedPtr screen_orientation_associated_ptr) {
  screen_orientation_service_ = std::move(screen_orientation_associated_ptr);
}

void ScreenOrientationControllerImpl::OnLockOrientationResult(
    int request_id,
    ScreenOrientationLockResult result) {
  if (!pending_callback_ || request_id != request_id_)
    return;

  switch (result) {
    case ScreenOrientationLockResult::SCREEN_ORIENTATION_LOCK_RESULT_SUCCESS:
      pending_callback_->OnSuccess();
      break;
    case ScreenOrientationLockResult::
        SCREEN_ORIENTATION_LOCK_RESULT_ERROR_NOT_AVAILABLE:
      pending_callback_->OnError(kWebLockOrientationErrorNotAvailable);
      break;
    case ScreenOrientationLockResult::
        SCREEN_ORIENTATION_LOCK_RESULT_ERROR_FULLSCREEN_REQUIRED:
      pending_callback_->OnError(kWebLockOrientationErrorFullscreenRequired);
      break;
    case ScreenOrientationLockResult::
        SCREEN_ORIENTATION_LOCK_RESULT_ERROR_CANCELED:
      pending_callback_->OnError(kWebLockOrientationErrorCanceled);
      break;
    default:
      NOTREACHED();
      break;
  }

  pending_callback_.reset();
}

void ScreenOrientationControllerImpl::CancelPendingLocks() {
  if (!pending_callback_)
    return;

  pending_callback_->OnError(kWebLockOrientationErrorCanceled);
  pending_callback_.reset();
}

int ScreenOrientationControllerImpl::GetRequestIdForTests() {
  return pending_callback_ ? request_id_ : -1;
}

}  // namespace blink
