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