// Copyright 2016 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/core/html/media/autoplay_uma_helper.h"

#include "base/metrics/histogram_functions.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/metrics/public/cpp/ukm_recorder.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/settings.h"
#include "third_party/blink/renderer/core/html/media/autoplay_policy.h"
#include "third_party/blink/renderer/core/html/media/html_media_element.h"
#include "third_party/blink/renderer/core/intersection_observer/intersection_observer.h"
#include "third_party/blink/renderer/core/intersection_observer/intersection_observer_entry.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/network/network_state_notifier.h"

namespace blink {

namespace {

constexpr base::TimeDelta kMaxOffscreenDurationUma =
    base::TimeDelta::FromHours(1);
constexpr int32_t kOffscreenDurationUmaBucketCount = 50;

// Returns a int64_t with the following structure:
// 0b0001 set if there is a user gesture on the stack.
// 0b0010 set if there was a user gesture on the page.
// 0b0100 set if there was a user gesture propagated after navigation.
int64_t GetUserGestureStatusForUkmMetric(LocalFrame* frame) {
  DCHECK(frame);

  int64_t result = 0;

  if (LocalFrame::HasTransientUserActivation(frame))
    result |= 0x01;
  if (frame->HasStickyUserActivation())
    result |= 0x02;
  if (frame->HadStickyUserActivationBeforeNavigation())
    result |= 0x04;

  return result;
}

}  // namespace

AutoplayUmaHelper::AutoplayUmaHelper(HTMLMediaElement* element)
    : ExecutionContextLifecycleObserver(
          static_cast<ExecutionContext*>(nullptr)),
      element_(element),
      muted_video_play_method_intersection_observer_(nullptr),
      is_visible_(false),
      muted_video_offscreen_duration_intersection_observer_(nullptr) {}

AutoplayUmaHelper::~AutoplayUmaHelper() = default;

static void RecordAutoplaySourceMetrics(HTMLMediaElement* element,
                                        AutoplaySource source) {
  if (IsA<HTMLVideoElement>(element)) {
    base::UmaHistogramEnumeration("Media.Video.Autoplay", source);
    if (element->muted())
      base::UmaHistogramEnumeration("Media.Video.Autoplay.Muted", source);
    return;
  }
  base::UmaHistogramEnumeration("Media.Audio.Autoplay", source);
}

void AutoplayUmaHelper::OnAutoplayInitiated(AutoplaySource source) {

  // Autoplay already initiated
  if (sources_.Contains(source))
    return;

  sources_.insert(source);

  // Record the source.
  RecordAutoplaySourceMetrics(element_.Get(), source);

  // Record dual source.
  if (sources_.size() == kDualSourceSize)
    RecordAutoplaySourceMetrics(element_.Get(), AutoplaySource::kDualSource);

  element_->addEventListener(event_type_names::kPlaying, this, false);

  // Record UKM autoplay event.
  if (!element_->GetDocument().IsActive())
    return;
  LocalFrame* frame = element_->GetDocument().GetFrame();
  DCHECK(frame);
  DCHECK(element_->GetDocument().GetPage());

  ukm::UkmRecorder* ukm_recorder = element_->GetDocument().UkmRecorder();
  DCHECK(ukm_recorder);
  ukm::builders::Media_Autoplay_Attempt(element_->GetDocument().UkmSourceID())
      .SetSource(source == AutoplaySource::kMethod)
      .SetAudioTrack(element_->HasAudio())
      .SetVideoTrack(element_->HasVideo())
      .SetUserGestureRequired(
          element_->GetAutoplayPolicy().IsGestureNeededForPlayback())
      .SetMuted(element_->muted())
      .SetHighMediaEngagement(AutoplayPolicy::DocumentHasHighMediaEngagement(
          element_->GetDocument()))
      .SetUserGestureStatus(GetUserGestureStatusForUkmMetric(frame))
      .Record(ukm_recorder);
}

void AutoplayUmaHelper::RecordAutoplayUnmuteStatus(
    AutoplayUnmuteActionStatus status) {
  base::UmaHistogramEnumeration("Media.Video.Autoplay.Muted.UnmuteAction",
                                status);

  // Record UKM event for unmute muted autoplay.
  if (element_->GetDocument().IsInMainFrame()) {
    int source = static_cast<int>(AutoplaySource::kAttribute);
    if (sources_.size() == kDualSourceSize) {
      source = static_cast<int>(AutoplaySource::kDualSource);
    } else if (sources_.Contains(AutoplaySource::kMethod)) {
      source = static_cast<int>(AutoplaySource::kAttribute);
    }

    ukm::UkmRecorder* ukm_recorder = element_->GetDocument().UkmRecorder();
    DCHECK(ukm_recorder);
    ukm::builders::Media_Autoplay_Muted_UnmuteAction(
        element_->GetDocument().UkmSourceID())
        .SetSource(source)
        .SetResult(status == AutoplayUnmuteActionStatus::kSuccess)
        .Record(ukm_recorder);
  }
}

void AutoplayUmaHelper::VideoWillBeDrawnToCanvas() {
  if (HasSource() && !IsVisible()) {
    UseCounter::Count(element_->GetDocument(),
                      WebFeature::kHiddenAutoplayedVideoInCanvas);
  }
}

void AutoplayUmaHelper::DidMoveToNewDocument(Document& old_document) {
  if (!ShouldListenToContextDestroyed())
    return;

  SetExecutionContext(element_->GetExecutionContext());
}

void AutoplayUmaHelper::
    OnIntersectionChangedForMutedVideoPlayMethodBecomeVisible(
        const HeapVector<Member<IntersectionObserverEntry>>& entries) {
  bool is_visible = (entries.back()->intersectionRatio() > 0);
  if (!is_visible || !muted_video_play_method_intersection_observer_)
    return;

  MaybeStopRecordingMutedVideoPlayMethodBecomeVisible(true);
}

void AutoplayUmaHelper::OnIntersectionChangedForMutedVideoOffscreenDuration(
    const HeapVector<Member<IntersectionObserverEntry>>& entries) {
  bool is_visible = (entries.back()->intersectionRatio() > 0);
  if (is_visible == is_visible_)
    return;

  if (is_visible) {
    muted_video_autoplay_offscreen_duration_ +=
        base::TimeTicks::Now() - muted_video_autoplay_offscreen_start_time_;
  } else {
    muted_video_autoplay_offscreen_start_time_ = base::TimeTicks::Now();
  }

  is_visible_ = is_visible;
}

void AutoplayUmaHelper::Invoke(ExecutionContext* execution_context,
                               Event* event) {
  if (event->type() == event_type_names::kPlaying)
    HandlePlayingEvent();
  else if (event->type() == event_type_names::kPause)
    HandlePauseEvent();
  else
    NOTREACHED();
}

void AutoplayUmaHelper::HandlePlayingEvent() {
  MaybeStartRecordingMutedVideoPlayMethodBecomeVisible();
  MaybeStartRecordingMutedVideoOffscreenDuration();

  element_->removeEventListener(event_type_names::kPlaying, this, false);
}

void AutoplayUmaHelper::HandlePauseEvent() {
  MaybeStopRecordingMutedVideoOffscreenDuration();
}

void AutoplayUmaHelper::ContextDestroyed() {
  HandleContextDestroyed();
}

void AutoplayUmaHelper::HandleContextDestroyed() {
  MaybeStopRecordingMutedVideoPlayMethodBecomeVisible(false);
  MaybeStopRecordingMutedVideoOffscreenDuration();
}

void AutoplayUmaHelper::MaybeStartRecordingMutedVideoPlayMethodBecomeVisible() {
  if (!sources_.Contains(AutoplaySource::kMethod) ||
      !IsA<HTMLVideoElement>(element_.Get()) || !element_->muted())
    return;

  muted_video_play_method_intersection_observer_ = IntersectionObserver::Create(
      {}, {IntersectionObserver::kMinimumThreshold}, &element_->GetDocument(),
      WTF::BindRepeating(
          &AutoplayUmaHelper::
              OnIntersectionChangedForMutedVideoPlayMethodBecomeVisible,
          WrapWeakPersistent(this)),
      LocalFrameUkmAggregator::kMediaIntersectionObserver);
  muted_video_play_method_intersection_observer_->observe(element_);
  SetExecutionContext(element_->GetExecutionContext());
}

void AutoplayUmaHelper::MaybeStopRecordingMutedVideoPlayMethodBecomeVisible(
    bool visible) {
  if (!muted_video_play_method_intersection_observer_)
    return;

  base::UmaHistogramBoolean(
      "Media.Video.Autoplay.Muted.PlayMethod.BecomesVisible", visible);

  muted_video_play_method_intersection_observer_->disconnect();
  muted_video_play_method_intersection_observer_ = nullptr;
  MaybeUnregisterContextDestroyedObserver();
}

void AutoplayUmaHelper::MaybeStartRecordingMutedVideoOffscreenDuration() {
  if (!IsA<HTMLVideoElement>(element_.Get()) || !element_->muted() ||
      !sources_.Contains(AutoplaySource::kMethod))
    return;

  // Start recording muted video playing offscreen duration.
  muted_video_autoplay_offscreen_start_time_ = base::TimeTicks::Now();
  is_visible_ = false;
  muted_video_offscreen_duration_intersection_observer_ =
      IntersectionObserver::Create(
          {}, {IntersectionObserver::kMinimumThreshold},
          &element_->GetDocument(),
          WTF::BindRepeating(
              &AutoplayUmaHelper::
                  OnIntersectionChangedForMutedVideoOffscreenDuration,
              WrapWeakPersistent(this)),
          LocalFrameUkmAggregator::kMediaIntersectionObserver);
  muted_video_offscreen_duration_intersection_observer_->observe(element_);
  element_->addEventListener(event_type_names::kPause, this, false);
  SetExecutionContext(element_->GetExecutionContext());
}

void AutoplayUmaHelper::MaybeStopRecordingMutedVideoOffscreenDuration() {
  if (!muted_video_offscreen_duration_intersection_observer_)
    return;

  if (!is_visible_) {
    muted_video_autoplay_offscreen_duration_ +=
        base::TimeTicks::Now() - muted_video_autoplay_offscreen_start_time_;
  }

  DCHECK(sources_.Contains(AutoplaySource::kMethod));

  UMA_HISTOGRAM_CUSTOM_TIMES(
      "Media.Video.Autoplay.Muted.PlayMethod.OffscreenDuration",
      muted_video_autoplay_offscreen_duration_,
      base::TimeDelta::FromMilliseconds(1), kMaxOffscreenDurationUma,
      kOffscreenDurationUmaBucketCount);

  muted_video_offscreen_duration_intersection_observer_->disconnect();
  muted_video_offscreen_duration_intersection_observer_ = nullptr;
  muted_video_autoplay_offscreen_duration_ = base::TimeDelta();
  MaybeUnregisterMediaElementPauseListener();
  MaybeUnregisterContextDestroyedObserver();
}

void AutoplayUmaHelper::MaybeUnregisterContextDestroyedObserver() {
  // TODO(keishi): Remove IsIteratingOverObservers() check when
  // HeapObserverSet() supports removal while iterating.
  if (!ShouldListenToContextDestroyed() && !GetExecutionContext()
                                                ->ContextLifecycleObserverSet()
                                                .IsIteratingOverObservers()) {
    SetExecutionContext(nullptr);
  }
}

void AutoplayUmaHelper::MaybeUnregisterMediaElementPauseListener() {
  if (muted_video_offscreen_duration_intersection_observer_)
    return;
  element_->removeEventListener(event_type_names::kPause, this, false);
}

bool AutoplayUmaHelper::ShouldListenToContextDestroyed() const {
  return muted_video_play_method_intersection_observer_ ||
         muted_video_offscreen_duration_intersection_observer_;
}

void AutoplayUmaHelper::Trace(Visitor* visitor) const {
  NativeEventListener::Trace(visitor);
  ExecutionContextLifecycleObserver::Trace(visitor);
  visitor->Trace(element_);
  visitor->Trace(muted_video_play_method_intersection_observer_);
  visitor->Trace(muted_video_offscreen_duration_intersection_observer_);
}

}  // namespace blink
