Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  AudioChannelService.h   Sprache: C

 
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */


#ifndef mozilla_dom_audiochannelservice_h__
#define mozilla_dom_audiochannelservice_h__

#include <functional>

#include "AudioChannelAgent.h"
#include "mozilla/DefineEnum.h"
#include "mozilla/Logging.h"
#include "mozilla/UniquePtr.h"
#include "nsAttrValue.h"
#include "nsIObserver.h"
#include "nsTArray.h"
#include "nsTObserverArray.h"

class nsPIDOMWindowOuter;
struct PRLogModuleInfo;

namespace mozilla::dom {

class AudioPlaybackConfig {
 public:
  AudioPlaybackConfig()
      : mVolume(1.0),
        mMuted(false),
        mSuspend(nsISuspendedTypes::NONE_SUSPENDED),
        mNumberOfAgents(0) {}

  AudioPlaybackConfig(float aVolume, bool aMuted, uint32_t aSuspended)
      : mVolume(aVolume),
        mMuted(aMuted),
        mSuspend(aSuspended),
        mNumberOfAgents(0) {}

  float mVolume;
  bool mMuted;
  uint32_t mSuspend;
  bool mCapturedAudio = false;
  uint32_t mNumberOfAgents;
};

class AudioChannelService final : public nsIObserver {
 public:
  NS_DECL_ISUPPORTS
  NS_DECL_NSIOBSERVER

  /**
   * We use `AudibleState` to represent the audible state of an owner of audio
   * channel agent. Those information in AudioChannelWindow could help us to
   * determine if a tab is being audible or not, in order to tell Chrome JS to
   * show the sound indicator or delayed autoplay icon on the tab bar.
   *
   * - Sound indicator
   * When a tab is playing sound, we would show the sound indicator on tab bar
   * to tell users that this tab is producing sound now. In addition, the sound
   * indicator also give users an ablility to mute or unmute tab.
   *
   * When an AudioChannelWindow first contains an agent with state `eAudible`,
   * or an AudioChannelWindow losts its last agent with state `eAudible`, we
   * would notify Chrome JS about those changes, to tell them that a tab has
   * been being audible or not, in order to display or remove the indicator for
   * a corresponding tab.
   *
   * - Delayed autoplay icon (Play Tab icon)
   * When we enable delaying autoplay, which is to postpone the autoplay media
   * for unvisited tab until it first goes to foreground, or user click the
   * play tab icon to resume the delayed media.
   *
   * When an AudioChannelWindow first contains an agent with state `eAudible` or
   * `eMaybeAudible`, we would notify Chrome JS about this change, in order to
   * show the delayed autoplay tab icon to user, which is used to notice user
   * there is a media being delayed starting, and then user can click the play
   * tab icon to resume the start of media, or visit that tab to resume delayed
   * media automatically.
   *
   * According to our UX design, we don't show this icon for inaudible media.
   * The reason of showing the icon for a tab, where the agent starts with state
   * `eMaybeAudible`, is because some video might be silent in the beginning
   * but would soon become audible later.
   *
   * ---------------------------------------------------------------------------
   *
   * eNotAudible : agent is not audible
   * eMaybeAudible : agent is not audible now, but it might be audible later
   * eAudible : agent is audible now
   */

  MOZ_DEFINE_ENUM_WITH_BASE_AND_TOSTRING_AT_CLASS_SCOPE(
      AudibleState, uint8_t, (eNotAudible, eMaybeAudible, eAudible));

  enum AudioCaptureState : bool { eCapturing = true, eNotCapturing = false };

  MOZ_DEFINE_ENUM_WITH_BASE_AND_TOSTRING_AT_CLASS_SCOPE(
      AudibleChangedReasons, uint32_t,
      (eVolumeChanged, eDataAudibleChanged, ePauseStateChanged));

  /**
   * Returns the AudioChannelServce singleton.
   * If AudioChannelService doesn't exist, create and return new one.
   * Only to be called from main thread.
   */

  static already_AddRefed<AudioChannelService> GetOrCreate();

  /**
   * Returns the AudioChannelService singleton if one exists.
   * If AudioChannelService doesn't exist, returns null.
   */

  static already_AddRefed<AudioChannelService> Get();

  static LogModule* GetAudioChannelLog();

  static bool IsEnableAudioCompeting();

  /**
   * Any audio channel agent that starts playing should register itself to
   * this service, sharing the AudioChannel.
   */

  void RegisterAudioChannelAgent(AudioChannelAgent* aAgent,
                                 AudibleState aAudible);

  /**
   * Any audio channel agent that stops playing should unregister itself to
   * this service.
   */

  void UnregisterAudioChannelAgent(AudioChannelAgent* aAgent);

  /**
   * Return the state to indicate this audioChannel for his window should keep
   * playing/muted/suspended.
   */

  AudioPlaybackConfig GetMediaConfig(nsPIDOMWindowOuter* aWindow) const;

  /**
   * Called this method when the audible state of the audio playback changed,
   * it would dispatch the playback event to observers which want to know the
   * actual audible state of the window.
   */

  void AudioAudibleChanged(AudioChannelAgent* aAgent, AudibleState aAudible,
                           AudibleChangedReasons aReason);

  bool IsWindowActive(nsPIDOMWindowOuter* aWindow);

  void RefreshAgentsVolume(nsPIDOMWindowOuter* aWindow, float aVolume,
                           bool aMuted);

  // This method needs to know the inner window that wants to capture audio. We
  // group agents per top outer window, but we can have multiple innerWindow per
  // top outerWindow (subiframes, etc.) and we have to identify all the agents
  // just for a particular innerWindow.
  void SetWindowAudioCaptured(nsPIDOMWindowOuter* aWindow,
                              uint64_t aInnerWindowID, bool aCapture);

  void NotifyResumingDelayedMedia(nsPIDOMWindowOuter* aWindow);

 private:
  AudioChannelService();
  ~AudioChannelService();

  void RefreshAgents(nsPIDOMWindowOuter* aWindow,
                     const std::function<void(AudioChannelAgent*)>& aFunc);

  void RefreshAgentsSuspend(nsPIDOMWindowOuter* aWindow,
                            nsSuspendedTypes aSuspend);

  static void CreateServiceIfNeeded();

  /**
   * Shutdown the singleton.
   */

  static void Shutdown();

  void RefreshAgentsAudioFocusChanged(AudioChannelAgent* aAgent);

  class AudioChannelWindow final {
   public:
    explicit AudioChannelWindow(uint64_t aWindowID)
        : mWindowID(aWindowID),
          mIsAudioCaptured(false),
          mShouldSendActiveMediaBlockStopEvent(false) {}

    void AudioAudibleChanged(AudioChannelAgent* aAgent, AudibleState aAudible,
                             AudibleChangedReasons aReason);

    void AppendAgent(AudioChannelAgent* aAgent, AudibleState aAudible);
    void RemoveAgent(AudioChannelAgent* aAgent);

    void NotifyMediaBlockStop(nsPIDOMWindowOuter* aWindow);

    uint64_t mWindowID;
    bool mIsAudioCaptured;
    AudioPlaybackConfig mConfig;

    // Raw pointer because the AudioChannelAgent must unregister itself.
    nsTObserverArray<AudioChannelAgent*> mAgents;
    nsTObserverArray<AudioChannelAgent*> mAudibleAgents;

    // If we've dispatched "activeMediaBlockStart" event, we must dispatch
    // another event "activeMediablockStop" when the window is resumed from
    // suspend-block.
    bool mShouldSendActiveMediaBlockStopEvent;

   private:
    void AppendAudibleAgentIfNotContained(AudioChannelAgent* aAgent,
                                          AudibleChangedReasons aReason);
    void RemoveAudibleAgentIfContained(AudioChannelAgent* aAgent,
                                       AudibleChangedReasons aReason);

    void AppendAgentAndIncreaseAgentsNum(AudioChannelAgent* aAgent);
    void RemoveAgentAndReduceAgentsNum(AudioChannelAgent* aAgent);

    bool IsFirstAudibleAgent() const;
    bool IsLastAudibleAgent() const;

    void NotifyAudioAudibleChanged(nsPIDOMWindowOuter* aWindow,
                                   AudibleState aAudible,
                                   AudibleChangedReasons aReason);

    void MaybeNotifyMediaBlockStart(AudioChannelAgent* aAgent);
  };

  AudioChannelWindow* GetOrCreateWindowData(nsPIDOMWindowOuter* aWindow);

  AudioChannelWindow* GetWindowData(uint64_t aWindowID) const;

  nsTObserverArray<UniquePtr<AudioChannelWindow>> mWindows;
};

const char* SuspendTypeToStr(const nsSuspendedTypes& aSuspend);

}  // namespace mozilla::dom

#endif

Messung V0.5
C=95 H=95 G=94

¤ Dauer der Verarbeitung: 0.15 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge