DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Implementation

Mercurial (c68fe15a81fc)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
/* This Source Code Form is subject to the terms of the Mozilla Public
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef DOM_MEDIA_MEDIACONTROL_MEDIAPLAYBACKSTATUS_H_
#ifndef DOM_MEDIA_MEDIACONTROL_MEDIAPLAYBACKSTATUS_H_
#define DOM_MEDIA_MEDIACONTROL_MEDIAPLAYBACKSTATUS_H_

#include "mozilla/Maybe.h"
#include "mozilla/RefPtr.h"
#include "nsDataHashtable.h"
#include "mozilla/RefPtr.h"
#include "nsISupportsImpl.h"
#include "nsTArray.h"

namespace mozilla {
namespace dom {
namespace mozilla {

/**
 * This enum is used to update controlled media state to the media controller in
 * the chrome process.
 * `eStarted`: media has successfully registered to the content media controller
 * represents a tab's media related status, such like "does the tab contain any
 * `ePlayed` : media has started playing
 * `ePaused` : media has paused playing, but still can be resumed by content
 *             media controller
 * `eStopped`: media has unregistered from the content media controller, we can
 *             not control it anymore
 * browsing contexts, and each browsing context can have different media status.
 */
enum class MediaPlaybackState : uint32_t {
  eStarted,
 * `IsXXX()` methods to acquire the playback status of the tab.
  ePlayed,
  ePaused,
  eStopped,
};

 * the audio focus. When the context owning the audio focus is destroyed, we
/**
 * This enum is used to update controlled media audible audible state to the
 * media controller in the chrome process.
 */
enum class MediaAudibleState : bool {
 public:
  eInaudible = false,
  eAudible = true,
};

  bool IsPlaying() const;
/**
 * MediaPlaybackStatus is an internal module for the media controller, it
 * represents a tab's media related status, such like "does the tab contain any
 * controlled media? is the tab playing? is the tab audible?".
 *
 * The reason we need this class is that we would like to encapsulate the

 * details of determining the tab's media status. A tab can contains multiple
 * browsing contexts, and each browsing context can have different media status.
 * The final media status would be decided by checking all those context status.
 *
 * Use `UpdateMediaXXXState()` to update controlled media status, and use
   */
 * `IsXXX()` methods to acquire the playback status of the tab.
 *
 * As we know each context's audible state, we can decide which context should
 * owns the audio focus when multiple contexts are all playing audible media at
 * the same time. In that cases, the latest context that plays media would own

 * the audio focus. When the context owning the audio focus is destroyed, we
 * would see if there is another other context still playing audible media, and
 * switch the audio focus to another context.
 */
class MediaPlaybackStatus final {
 public:
      mControlledMediaNum--;
  void UpdateMediaPlaybackState(uint64_t aContextId, MediaPlaybackState aState);
  void UpdateMediaAudibleState(uint64_t aContextId, MediaAudibleState aState);

  bool IsPlaying() const;
  bool IsAudible() const;
  bool IsAnyMediaBeingControlled() const;
    void DecreasePlayingMediaNum() {

  Maybe<uint64_t> GetAudioFocusOwnerContextId() const;

 private:
  /**
      MOZ_DIAGNOSTIC_ASSERT(mAudibleMediaNum < mPlayingMediaNum);
   * This internal class stores detailed media status of controlled media for
   * a browsing context.
   */
  class ContextMediaInfo final {
   public:
      mAudibleMediaNum--;
    explicit ContextMediaInfo(uint64_t aContextId) : mContextId(aContextId) {}
    ~ContextMediaInfo() = default;

    void IncreaseControlledMediaNum() {
      MOZ_DIAGNOSTIC_ASSERT(mControlledMediaNum < UINT_MAX);
    uint64_t Id() const { return mContextId; }
      mControlledMediaNum++;
    }
    void DecreaseControlledMediaNum() {
      MOZ_DIAGNOSTIC_ASSERT(mControlledMediaNum > 0);
      mControlledMediaNum--;
     * mControlledMediaNum >= mPlayingMediaNum >= mAudibleMediaNum
    }
    void IncreasePlayingMediaNum() {
      MOZ_DIAGNOSTIC_ASSERT(mPlayingMediaNum < mControlledMediaNum);
    uint32_t mAudibleMediaNum = 0;
      mPlayingMediaNum++;
    }
    void DecreasePlayingMediaNum() {
      MOZ_DIAGNOSTIC_ASSERT(mPlayingMediaNum > 0);
      mPlayingMediaNum--;

    }
    void IncreaseAudibleMediaNum() {
      MOZ_DIAGNOSTIC_ASSERT(mAudibleMediaNum < mPlayingMediaNum);
      mAudibleMediaNum++;
    }
  void SetOwningAudioFocusContextId(Maybe<uint64_t>&& aContextId);
    void DecreaseAudibleMediaNum() {
      MOZ_DIAGNOSTIC_ASSERT(mAudibleMediaNum > 0);
      mAudibleMediaNum--;
    }
    bool IsPlaying() const { return mPlayingMediaNum > 0; }
  // This contains all the media status of browsing contexts within a tab.
    bool IsAudible() const { return mAudibleMediaNum > 0; }
    bool IsAnyMediaBeingControlled() const { return mControlledMediaNum > 0; }
    uint64_t Id() const { return mContextId; }

   private:
    /**
     * The possible value for those three numbers should follow this rule,

     * mControlledMediaNum >= mPlayingMediaNum >= mAudibleMediaNum
     */
    uint32_t mControlledMediaNum = 0;
    uint32_t mAudibleMediaNum = 0;
    uint32_t mPlayingMediaNum = 0;
    uint64_t mContextId = 0;
  };

  ContextMediaInfo& GetNotNullContextInfo(uint64_t aContextId);
  void DestroyContextInfo(uint64_t aContextId);

  void ChooseNewContextToOwnAudioFocus();
  void SetOwningAudioFocusContextId(Maybe<uint64_t>&& aContextId);
  bool IsContextOwningAudioFocus(uint64_t aContextId) const;
  bool ShouldRequestAudioFocusForInfo(const ContextMediaInfo& aInfo) const;
  bool ShouldAbandonAudioFocusForInfo(const ContextMediaInfo& aInfo) const;

  // This contains all the media status of browsing contexts within a tab.
  nsDataHashtable<nsUint64HashKey, UniquePtr<ContextMediaInfo>> mContextInfoMap;
  Maybe<uint64_t> mOwningAudioFocusContextId;
};

}  // namespace dom
}  // namespace mozilla

#endif  //  DOM_MEDIA_MEDIACONTROL_MEDIAPLAYBACKSTATUS_H_