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