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

#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_AUTOPLAY_POLICY_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_AUTOPLAY_POLICY_H_

#include "base/optional.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/bindings/exception_code.h"
#include "third_party/blink/renderer/platform/heap/handle.h"

namespace blink {

class AutoplayUmaHelper;
class Document;
class HTMLMediaElement;
class IntersectionObserver;
class IntersectionObserverEntry;

// AutoplayPolicy is the class for handles autoplay logics.
class CORE_EXPORT AutoplayPolicy final
    : public GarbageCollected<AutoplayPolicy> {
 public:
  // Different autoplay policy types.
  enum class Type {
    kNoUserGestureRequired = 0,
    // A local user gesture on the element is required.
    kUserGestureRequired,
    // The document needs to have received a user activation or received one
    // before navigating.
    kDocumentUserActivationRequired,
  };

  static Type GetAutoplayPolicyForDocument(const Document&);

  // Return true if the given |document| is allowed to play.
  // This method may check parent frames if allow=autoplay (Feature Policy) was
  // used, in which case, the frame will be allowed to play if its parents are,
  // and so on.
  // Otherwise, frames are allowed to play if they have been activated or, for
  // the main frame, if it has a high MEI.
  static bool IsDocumentAllowedToPlay(const Document&);

  // Returns true if the given |document| has high media engagement.
  static bool DocumentHasHighMediaEngagement(const Document&);

  // Returns true if the given |document| should force allow autoplay.
  static bool DocumentHasForceAllowFlag(const Document&);

  // Returns true if the given |document| has the user exception flag.
  static bool DocumentHasUserExceptionFlag(const Document&);

  // Returns true if the given |document| should autoplay muted videos.
  static bool DocumentShouldAutoplayMutedVideos(const Document&);

  // Returns true if the given |document| is capturing user media.
  static bool DocumentIsCapturingUserMedia(const Document&);

  explicit AutoplayPolicy(HTMLMediaElement*);

  void VideoWillBeDrawnToCanvas() const;

  // Called when the media element is moved to a new document.
  void DidMoveToNewDocument(Document& old_document);

  // Stop autoplaying the video element whenever its visible.
  // TODO(mlamouri): hide these methods from HTMLMediaElement.
  void StopAutoplayMutedWhenVisible();

  // Request autoplay by attribute. This method will check the autoplay
  // restrictions and record metrics. This method can only be called once per
  // time the readyState changes to HAVE_ENOUGH_DATA.
  bool RequestAutoplayByAttribute();

  // Request the playback via play() method. This method will check the autoplay
  // restrictions and record metrics. This method can only be called once
  // per call of play().
  base::Optional<DOMExceptionCode> RequestPlay();

  // Returns whether an umute action should pause an autoplaying element. The
  // method will check autoplay restrictions and record metrics. This method can
  // only be called once per call of setMuted().
  bool RequestAutoplayUnmute();

  // Indicates the media element is or will autoplay because of being
  // muted.
  bool IsOrWillBeAutoplayingMuted() const;

  // Unlock user gesture if a user gesture can be utilized.
  void TryUnlockingUserGesture();

  // Return true if and only if a user gesture is requried for playback.  Even
  // if isLockedPendingUserGesture() return true, this might return false if
  // the requirement is currently overridden.  This does not check if a user
  // gesture is currently being processed.
  bool IsGestureNeededForPlayback() const;

  // Returns an error string to be used by the HTMLMediaElement when the play()
  // method fails because of autoplay restrictions.
  String GetPlayErrorMessage() const;

  // Returns whether the media element was initiated via autoplay.
  // In this context, autoplay means that it was initiated before any user
  // activation was received on the page and before a user initiated same-domain
  // navigation. In other words, with the unified autoplay policy applied, it
  // should only return `true` when MEI allowed autoplay.
  bool WasAutoplayInitiated() const;

  // Ensure that `autoplay_initiated_` has a value. It is set to `false` to
  // avoid false positives.
  void EnsureAutoplayInitiatedSet();

  virtual void Trace(Visitor*) const;

 private:
  friend class AutoplayUmaHelper;
  friend class AutoplayUmaHelperTest;

  // Start autoplaying the video element whenever its visible.
  void StartAutoplayMutedWhenVisible();

  // Returns whether the media element is eligible to autoplay muted.
  bool IsEligibleForAutoplayMuted() const;

  bool ShouldAutoplay();

  // Return true if and only if a user gesture is required to unlock this
  // media element for unrestricted autoplay/script control.  Don't confuse
  // this with isGestureNeededForPlayback().  The latter is usually what one
  // should use, if checking to see if an action is allowed.
  bool IsLockedPendingUserGesture() const;

  bool IsAutoplayingMutedInternal(bool muted) const;
  bool IsOrWillBeAutoplayingMutedInternal(bool muted) const;

  // Called when the video visibility changes while autoplaying muted, will
  // pause the video when invisible and resume the video when visible.
  void OnIntersectionChangedForAutoplay(
      const HeapVector<Member<IntersectionObserverEntry>>& entries);

  // Returns whether the current autoplay policy is
  // kDocumentUserActivationRequired. This is a helper method for readability.
  bool IsUsingDocumentUserActivationRequiredPolicy() const;

  // Sets `autoplay_initiated_` if it wasn't already set.
  void MaybeSetAutoplayInitiated();

  bool locked_pending_user_gesture_ : 1;

  Member<HTMLMediaElement> element_ = nullptr;
  Member<IntersectionObserver> autoplay_intersection_observer_ = nullptr;

  Member<AutoplayUmaHelper> autoplay_uma_helper_;

  base::Optional<bool> autoplay_initiated_;

  DISALLOW_COPY_AND_ASSIGN(AutoplayPolicy);
};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_AUTOPLAY_POLICY_H_
