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 "nsString.h"
12 
13 namespace mozilla {
14 
15 namespace dom {
16 class Document;
17 }
18 
19 struct DecoderDoctorEvent {
20   enum Domain {
21     eAudioSinkStartup,
22   } mDomain;
23   nsresult mResult;
24 };
25 
26 // DecoderDoctorDiagnostics class, used to gather data from PDMs/DecoderTraits,
27 // and then notify the user about issues preventing (or worsening) playback.
28 //
29 // The expected usage is:
30 // 1. Instantiate a DecoderDoctorDiagnostics in a function (close to the point
31 //    where a webpage is trying to know whether some MIME types can be played,
32 //    or trying to play a media file).
33 // 2. Pass a pointer to the DecoderDoctorDiagnostics structure to one of the
34 //    CanPlayStatus/IsTypeSupported/(others?). During that call, some PDMs may
35 //    add relevant diagnostic information.
36 // 3. Analyze the collected diagnostics, and optionally dispatch an event to the
37 //    UX, to notify the user about potential playback issues and how to resolve
38 //    them.
39 //
40 // This class' methods must be called from the main thread.
41 
42 class DecoderDoctorDiagnostics {
43  public:
44   // Store the diagnostic information collected so far on a document for a
45   // given format. All diagnostics for a document will be analyzed together
46   // within a short timeframe.
47   // Should only be called once.
48   void StoreFormatDiagnostics(dom::Document* aDocument,
49                               const nsAString& aFormat, bool aCanPlay,
50                               const char* aCallSite);
51 
52   void StoreMediaKeySystemAccess(dom::Document* aDocument,
53                                  const nsAString& aKeySystem, bool aIsSupported,
54                                  const char* aCallSite);
55 
56   void StoreEvent(dom::Document* aDocument, const DecoderDoctorEvent& aEvent,
57                   const char* aCallSite);
58 
59   void StoreDecodeError(dom::Document* aDocument, const MediaResult& aError,
60                         const nsString& aMediaSrc, const char* aCallSite);
61 
62   void StoreDecodeWarning(dom::Document* aDocument, const MediaResult& aWarning,
63                           const nsString& aMediaSrc, const char* aCallSite);
64 
65   enum DiagnosticsType {
66     eUnsaved,
67     eFormatSupportCheck,
68     eMediaKeySystemAccessRequest,
69     eEvent,
70     eDecodeError,
71     eDecodeWarning
72   };
Type()73   DiagnosticsType Type() const { return mDiagnosticsType; }
74 
75   // Description string, for logging purposes; only call on stored diags.
76   nsCString GetDescription() const;
77 
78   // Methods to record diagnostic information:
79 
Format()80   const nsAString& Format() const { return mFormat; }
CanPlay()81   bool CanPlay() const { return mCanPlay; }
82 
SetWMFFailedToLoad()83   void SetWMFFailedToLoad() { mWMFFailedToLoad = true; }
DidWMFFailToLoad()84   bool DidWMFFailToLoad() const { return mWMFFailedToLoad; }
85 
SetFFmpegFailedToLoad()86   void SetFFmpegFailedToLoad() { mFFmpegFailedToLoad = true; }
DidFFmpegFailToLoad()87   bool DidFFmpegFailToLoad() const { return mFFmpegFailedToLoad; }
88 
SetGMPPDMFailedToStartup()89   void SetGMPPDMFailedToStartup() { mGMPPDMFailedToStartup = true; }
DidGMPPDMFailToStartup()90   bool DidGMPPDMFailToStartup() const { return mGMPPDMFailedToStartup; }
91 
SetVideoNotSupported()92   void SetVideoNotSupported() { mVideoNotSupported = true; }
SetAudioNotSupported()93   void SetAudioNotSupported() { mAudioNotSupported = true; }
94 
SetGMP(const nsACString & aGMP)95   void SetGMP(const nsACString& aGMP) { mGMP = aGMP; }
GMP()96   const nsACString& GMP() const { return mGMP; }
97 
KeySystem()98   const nsAString& KeySystem() const { return mKeySystem; }
IsKeySystemSupported()99   bool IsKeySystemSupported() const { return mIsKeySystemSupported; }
100   enum KeySystemIssue { eUnset, eWidevineWithNoWMF };
SetKeySystemIssue(KeySystemIssue aKeySystemIssue)101   void SetKeySystemIssue(KeySystemIssue aKeySystemIssue) {
102     mKeySystemIssue = aKeySystemIssue;
103   }
GetKeySystemIssue()104   KeySystemIssue GetKeySystemIssue() const { return mKeySystemIssue; }
105 
event()106   DecoderDoctorEvent event() const { return mEvent; }
107 
DecodeIssue()108   const MediaResult& DecodeIssue() const { return mDecodeIssue; }
DecodeIssueMediaSrc()109   const nsString& DecodeIssueMediaSrc() const { return mDecodeIssueMediaSrc; }
110 
111  private:
112   // Currently-known type of diagnostics. Set from one of the 'Store...'
113   // methods. This helps ensure diagnostics are only stored once, and makes it
114   // easy to know what information they contain.
115   DiagnosticsType mDiagnosticsType = eUnsaved;
116 
117   nsString mFormat;
118   // True if there is at least one decoder that can play that format.
119   bool mCanPlay = false;
120 
121   bool mWMFFailedToLoad = false;
122   bool mFFmpegFailedToLoad = false;
123   bool mGMPPDMFailedToStartup = false;
124   bool mVideoNotSupported = false;
125   bool mAudioNotSupported = false;
126   nsCString mGMP;
127 
128   nsString mKeySystem;
129   bool mIsKeySystemSupported = false;
130   KeySystemIssue mKeySystemIssue = eUnset;
131 
132   DecoderDoctorEvent mEvent;
133 
134   MediaResult mDecodeIssue = NS_OK;
135   nsString mDecodeIssueMediaSrc;
136 };
137 
138 }  // namespace mozilla
139 
140 #endif
141