tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

DecoderDoctorDiagnostics.h (6071B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef DecoderDoctorDiagnostics_h_
      8 #define DecoderDoctorDiagnostics_h_
      9 
     10 #include "MediaResult.h"
     11 #include "mozilla/DefineEnum.h"
     12 #include "mozilla/EnumSet.h"
     13 #include "mozilla/EnumTypeTraits.h"
     14 #include "mozilla/dom/DecoderDoctorNotificationBinding.h"
     15 #include "nsString.h"
     16 
     17 namespace IPC {
     18 template <typename T>
     19 struct ParamTraits;
     20 }  // namespace IPC
     21 
     22 namespace mozilla {
     23 
     24 namespace dom {
     25 class Document;
     26 }
     27 
     28 struct DecoderDoctorEvent {
     29  enum Domain {
     30    eAudioSinkStartup,
     31  } mDomain;
     32  nsresult mResult;
     33 };
     34 
     35 // DecoderDoctorDiagnostics class, used to gather data from PDMs/DecoderTraits,
     36 // and then notify the user about issues preventing (or worsening) playback.
     37 //
     38 // The expected usage is:
     39 // 1. Instantiate a DecoderDoctorDiagnostics in a function (close to the point
     40 //    where a webpage is trying to know whether some MIME types can be played,
     41 //    or trying to play a media file).
     42 // 2. Pass a pointer to the DecoderDoctorDiagnostics structure to one of the
     43 //    CanPlayStatus/IsTypeSupported/(others?). During that call, some PDMs may
     44 //    add relevant diagnostic information.
     45 // 3. Analyze the collected diagnostics, and optionally dispatch an event to the
     46 //    UX, to notify the user about potential playback issues and how to resolve
     47 //    them.
     48 //
     49 // This class' methods must be called from the main thread.
     50 
     51 class DecoderDoctorDiagnostics {
     52  friend struct IPC::ParamTraits<mozilla::DecoderDoctorDiagnostics>;
     53 
     54 public:
     55  // Store the diagnostic information collected so far on a document for a
     56  // given format. All diagnostics for a document will be analyzed together
     57  // within a short timeframe.
     58  // Should only be called once.
     59  void StoreFormatDiagnostics(dom::Document* aDocument,
     60                              const nsAString& aFormat, bool aCanPlay,
     61                              const char* aCallSite);
     62 
     63  void StoreMediaKeySystemAccess(dom::Document* aDocument,
     64                                 const nsAString& aKeySystem, bool aIsSupported,
     65                                 const char* aCallSite);
     66 
     67  void StoreEvent(dom::Document* aDocument, const DecoderDoctorEvent& aEvent,
     68                  const char* aCallSite);
     69 
     70  void StoreDecodeError(dom::Document* aDocument, const MediaResult& aError,
     71                        const nsString& aMediaSrc, const char* aCallSite);
     72 
     73  void StoreDecodeWarning(dom::Document* aDocument, const MediaResult& aWarning,
     74                          const nsString& aMediaSrc, const char* aCallSite);
     75 
     76  enum DiagnosticsType {
     77    eUnsaved,
     78    eFormatSupportCheck,
     79    eMediaKeySystemAccessRequest,
     80    eEvent,
     81    eDecodeError,
     82    eDecodeWarning
     83  };
     84  DiagnosticsType Type() const { return mDiagnosticsType; }
     85 
     86  // Description string, for logging purposes; only call on stored diags.
     87  nsCString GetDescription() const;
     88 
     89  // Methods to record diagnostic information:
     90 
     91  MOZ_DEFINE_ENUM_CLASS_AT_CLASS_SCOPE(
     92      Flags, (CanPlay, WMFFailedToLoad, FFmpegNotFound, LibAVCodecUnsupported,
     93              GMPPDMFailedToStartup, VideoNotSupported, AudioNotSupported));
     94  using FlagsSet = mozilla::EnumSet<Flags>;
     95 
     96  const nsAString& Format() const { return mFormat; }
     97  bool CanPlay() const { return mFlags.contains(Flags::CanPlay); }
     98 
     99  void SetFailureFlags(const FlagsSet& aFlags) { mFlags = aFlags; }
    100  void SetWMFFailedToLoad() { mFlags += Flags::WMFFailedToLoad; }
    101  bool DidWMFFailToLoad() const {
    102    return mFlags.contains(Flags::WMFFailedToLoad);
    103  }
    104 
    105  void SetFFmpegNotFound() { mFlags += Flags::FFmpegNotFound; }
    106  bool DidFFmpegNotFound() const {
    107    return mFlags.contains(Flags::FFmpegNotFound);
    108  }
    109 
    110  void SetLibAVCodecUnsupported() { mFlags += Flags::LibAVCodecUnsupported; }
    111  bool IsLibAVCodecUnsupported() const {
    112    return mFlags.contains(Flags::LibAVCodecUnsupported);
    113  }
    114 
    115  void SetGMPPDMFailedToStartup() { mFlags += Flags::GMPPDMFailedToStartup; }
    116  bool DidGMPPDMFailToStartup() const {
    117    return mFlags.contains(Flags::GMPPDMFailedToStartup);
    118  }
    119 
    120  void SetVideoNotSupported() { mFlags += Flags::VideoNotSupported; }
    121  void SetAudioNotSupported() { mFlags += Flags::AudioNotSupported; }
    122 
    123  void SetGMP(const nsACString& aGMP) { mGMP = aGMP; }
    124  const nsACString& GMP() const { return mGMP; }
    125 
    126  const nsAString& KeySystem() const { return mKeySystem; }
    127  bool IsKeySystemSupported() const { return mIsKeySystemSupported; }
    128  enum KeySystemIssue { eUnset, eWidevineWithNoWMF };
    129  void SetKeySystemIssue(KeySystemIssue aKeySystemIssue) {
    130    mKeySystemIssue = aKeySystemIssue;
    131  }
    132  KeySystemIssue GetKeySystemIssue() const { return mKeySystemIssue; }
    133 
    134  DecoderDoctorEvent event() const { return mEvent; }
    135 
    136  const MediaResult& DecodeIssue() const { return mDecodeIssue; }
    137  const nsString& DecodeIssueMediaSrc() const { return mDecodeIssueMediaSrc; }
    138 
    139  // This method is only used for testing.
    140  void SetDecoderDoctorReportType(const dom::DecoderDoctorReportType& aType);
    141 
    142 private:
    143  // Currently-known type of diagnostics. Set from one of the 'Store...'
    144  // methods. This helps ensure diagnostics are only stored once, and makes it
    145  // easy to know what information they contain.
    146  DiagnosticsType mDiagnosticsType = eUnsaved;
    147 
    148  nsString mFormat;
    149  FlagsSet mFlags;
    150  nsCString mGMP;
    151 
    152  nsString mKeySystem;
    153  bool mIsKeySystemSupported = false;
    154  KeySystemIssue mKeySystemIssue = eUnset;
    155 
    156  DecoderDoctorEvent mEvent;
    157 
    158  MediaResult mDecodeIssue = NS_OK;
    159  nsString mDecodeIssueMediaSrc;
    160 };
    161 
    162 // Used for IPDL serialization.
    163 // The 'value' have to be the biggest enum from DecoderDoctorDiagnostics::Flags.
    164 template <>
    165 struct MaxEnumValue<::mozilla::DecoderDoctorDiagnostics::Flags> {
    166  static constexpr unsigned int value =
    167      static_cast<unsigned int>(DecoderDoctorDiagnostics::sFlagsCount);
    168 };
    169 
    170 }  // namespace mozilla
    171 
    172 #endif