LCOV - code coverage report
Current view: top level - dom/media - MediaManager.h (source / functions) Hit Total Coverage
Test: output.info Lines: 2 22 9.1 %
Date: 2017-07-14 16:53:18 Functions: 1 17 5.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* This Source Code Form is subject to the terms of the Mozilla Public
       2             :  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
       3             :  * You can obtain one at http://mozilla.org/MPL/2.0/. */
       4             : 
       5             : #ifndef MOZILLA_MEDIAMANAGER_H
       6             : #define MOZILLA_MEDIAMANAGER_H
       7             : 
       8             : #include "MediaEngine.h"
       9             : #include "mozilla/media/DeviceChangeCallback.h"
      10             : #include "mozilla/dom/GetUserMediaRequest.h"
      11             : #include "mozilla/Services.h"
      12             : #include "mozilla/Unused.h"
      13             : #include "nsAutoPtr.h"
      14             : #include "nsIMediaManager.h"
      15             : 
      16             : #include "nsHashKeys.h"
      17             : #include "nsGlobalWindow.h"
      18             : #include "nsClassHashtable.h"
      19             : #include "nsRefPtrHashtable.h"
      20             : #include "nsIObserver.h"
      21             : #include "nsIPrefService.h"
      22             : #include "nsIPrefBranch.h"
      23             : 
      24             : #include "nsPIDOMWindow.h"
      25             : #include "nsIDOMNavigatorUserMedia.h"
      26             : #include "nsXULAppAPI.h"
      27             : #include "mozilla/Attributes.h"
      28             : #include "mozilla/Preferences.h"
      29             : #include "mozilla/StaticPtr.h"
      30             : #include "mozilla/dom/MediaStreamBinding.h"
      31             : #include "mozilla/dom/MediaStreamTrackBinding.h"
      32             : #include "mozilla/dom/MediaStreamError.h"
      33             : #include "mozilla/media/MediaChild.h"
      34             : #include "mozilla/media/MediaParent.h"
      35             : #include "mozilla/Logging.h"
      36             : #include "mozilla/UniquePtr.h"
      37             : #include "DOMMediaStream.h"
      38             : 
      39             : #ifdef MOZ_WEBRTC
      40             : #include "mtransport/runnable_utils.h"
      41             : #endif
      42             : 
      43             : // Note, these suck in Windows headers, unfortunately.
      44             : #include "base/thread.h"
      45             : #include "base/task.h"
      46             : 
      47             : namespace mozilla {
      48             : namespace dom {
      49             : struct MediaStreamConstraints;
      50             : struct MediaTrackConstraints;
      51             : struct MediaTrackConstraintSet;
      52             : enum class CallerType : uint32_t;
      53             : } // namespace dom
      54             : 
      55             : namespace ipc {
      56             : class PrincipalInfo;
      57             : }
      58             : 
      59             : class GetUserMediaTask;
      60             : class GetUserMediaWindowListener;
      61             : class MediaManager;
      62             : class SourceListener;
      63             : 
      64             : class MediaDevice : public nsIMediaDevice
      65             : {
      66             : public:
      67             :   typedef MediaEngineSource Source;
      68             : 
      69             :   NS_DECL_THREADSAFE_ISUPPORTS
      70             :   NS_DECL_NSIMEDIADEVICE
      71             : 
      72             :   void SetId(const nsAString& aID);
      73             :   void SetRawId(const nsAString& aID);
      74             :   virtual uint32_t GetBestFitnessDistance(
      75             :       const nsTArray<const NormalizedConstraintSet*>& aConstraintSets,
      76             :       bool aIsChrome);
      77             :   virtual Source* GetSource() = 0;
      78             :   nsresult Allocate(const dom::MediaTrackConstraints &aConstraints,
      79             :                     const MediaEnginePrefs &aPrefs,
      80             :                     const mozilla::ipc::PrincipalInfo& aPrincipalInfo,
      81             :                     const char** aOutBadConstraint);
      82             :   nsresult Restart(const dom::MediaTrackConstraints &aConstraints,
      83             :                    const MediaEnginePrefs &aPrefs,
      84             :                    const char** aOutBadConstraint);
      85             :   nsresult Deallocate();
      86             : protected:
      87           0 :   virtual ~MediaDevice() {}
      88             :   explicit MediaDevice(MediaEngineSource* aSource, bool aIsVideo);
      89             : 
      90             :   static uint32_t FitnessDistance(nsString aN,
      91             :     const dom::OwningStringOrStringSequenceOrConstrainDOMStringParameters& aConstraint);
      92             : private:
      93             :   static bool StringsContain(const dom::OwningStringOrStringSequence& aStrings,
      94             :                              nsString aN);
      95             :   static uint32_t FitnessDistance(nsString aN,
      96             :       const dom::ConstrainDOMStringParameters& aParams);
      97             : protected:
      98             :   nsString mName;
      99             :   nsString mID;
     100             :   nsString mRawID;
     101             :   bool mScary;
     102             :   dom::MediaSourceEnum mMediaSource;
     103             :   RefPtr<MediaEngineSource> mSource;
     104             :   RefPtr<MediaEngineSource::AllocationHandle> mAllocationHandle;
     105             : public:
     106           0 :   dom::MediaSourceEnum GetMediaSource() {
     107           0 :     return mMediaSource;
     108             :   }
     109             :   bool mIsVideo;
     110             : };
     111             : 
     112           0 : class VideoDevice : public MediaDevice
     113             : {
     114             : public:
     115             :   typedef MediaEngineVideoSource Source;
     116             : 
     117             :   explicit VideoDevice(Source* aSource);
     118             :   NS_IMETHOD GetType(nsAString& aType) override;
     119             :   Source* GetSource() override;
     120             : };
     121             : 
     122           0 : class AudioDevice : public MediaDevice
     123             : {
     124             : public:
     125             :   typedef MediaEngineAudioSource Source;
     126             : 
     127             :   explicit AudioDevice(Source* aSource);
     128             :   NS_IMETHOD GetType(nsAString& aType) override;
     129             :   Source* GetSource() override;
     130             : };
     131             : 
     132             : class GetUserMediaNotificationEvent: public Runnable
     133             : {
     134             :   public:
     135             :     enum GetUserMediaStatus {
     136             :       STARTING,
     137             :       STOPPING,
     138             :     };
     139             :     GetUserMediaNotificationEvent(GetUserMediaStatus aStatus,
     140             :                                   uint64_t aWindowID);
     141             : 
     142             :     GetUserMediaNotificationEvent(GetUserMediaStatus aStatus,
     143             :                                   already_AddRefed<DOMMediaStream> aStream,
     144             :                                   already_AddRefed<media::Refcountable<UniquePtr<OnTracksAvailableCallback>>> aOnTracksAvailableCallback,
     145             :                                   uint64_t aWindowID,
     146             :                                   already_AddRefed<nsIDOMGetUserMediaErrorCallback> aError);
     147             :     virtual ~GetUserMediaNotificationEvent();
     148             : 
     149             :     NS_IMETHOD Run() override;
     150             : 
     151             :   protected:
     152             :     RefPtr<GetUserMediaWindowListener> mListener; // threadsafe
     153             :     RefPtr<DOMMediaStream> mStream;
     154             :     RefPtr<media::Refcountable<UniquePtr<OnTracksAvailableCallback>>> mOnTracksAvailableCallback;
     155             :     GetUserMediaStatus mStatus;
     156             :     uint64_t mWindowID;
     157             :     RefPtr<nsIDOMGetUserMediaErrorCallback> mOnFailure;
     158             : };
     159             : 
     160             : typedef enum {
     161             :   MEDIA_STOP,
     162             :   MEDIA_STOP_TRACK,
     163             :   MEDIA_DIRECT_LISTENERS,
     164             : } MediaOperation;
     165             : 
     166           0 : class ReleaseMediaOperationResource : public Runnable
     167             : {
     168             : public:
     169           0 :   ReleaseMediaOperationResource(
     170             :     already_AddRefed<DOMMediaStream> aStream,
     171             :     already_AddRefed<media::Refcountable<UniquePtr<OnTracksAvailableCallback>>>
     172             :       aOnTracksAvailableCallback)
     173           0 :     : Runnable("ReleaseMediaOperationResource")
     174             :     , mStream(aStream)
     175           0 :     , mOnTracksAvailableCallback(aOnTracksAvailableCallback)
     176             :   {
     177           0 :   }
     178           0 :   NS_IMETHOD Run() override {return NS_OK;}
     179             : private:
     180             :   RefPtr<DOMMediaStream> mStream;
     181             :   RefPtr<media::Refcountable<UniquePtr<OnTracksAvailableCallback>>> mOnTracksAvailableCallback;
     182             : };
     183             : 
     184             : typedef nsRefPtrHashtable<nsUint64HashKey, GetUserMediaWindowListener> WindowTable;
     185             : 
     186             : // we could add MediaManager if needed
     187             : typedef void (*WindowListenerCallback)(MediaManager *aThis,
     188             :                                        uint64_t aWindowID,
     189             :                                        GetUserMediaWindowListener *aListener,
     190             :                                        void *aData);
     191             : 
     192             : class MediaManager final : public nsIMediaManagerService,
     193             :                            public nsIObserver
     194             :                           ,public DeviceChangeCallback
     195             : {
     196             :   friend SourceListener;
     197             : public:
     198             :   static already_AddRefed<MediaManager> GetInstance();
     199             : 
     200             :   // NOTE: never Dispatch(....,NS_DISPATCH_SYNC) to the MediaManager
     201             :   // thread from the MainThread, as we NS_DISPATCH_SYNC to MainThread
     202             :   // from MediaManager thread.
     203             :   static MediaManager* Get();
     204             :   static MediaManager* GetIfExists();
     205             :   static void StartupInit();
     206             :   static void PostTask(already_AddRefed<Runnable> task);
     207             : #ifdef DEBUG
     208             :   static bool IsInMediaThread();
     209             : #endif
     210             : 
     211           4 :   static bool Exists()
     212             :   {
     213           4 :     return !!sSingleton;
     214             :   }
     215             : 
     216             :   static nsresult NotifyRecordingStatusChange(nsPIDOMWindowInner* aWindow,
     217             :                                               const nsString& aMsg);
     218             : 
     219             :   NS_DECL_THREADSAFE_ISUPPORTS
     220             :   NS_DECL_NSIOBSERVER
     221             :   NS_DECL_NSIMEDIAMANAGERSERVICE
     222             : 
     223             :   media::Parent<media::NonE10s>* GetNonE10sParent();
     224             :   MediaEngine* GetBackend(uint64_t aWindowId = 0);
     225             : 
     226           0 :   WindowTable *GetActiveWindows() {
     227           0 :     MOZ_ASSERT(NS_IsMainThread());
     228           0 :     return &mActiveWindows;
     229             :   }
     230           0 :   GetUserMediaWindowListener *GetWindowListener(uint64_t aWindowId) {
     231           0 :     MOZ_ASSERT(NS_IsMainThread());
     232           0 :     return mActiveWindows.GetWeak(aWindowId);
     233             :   }
     234             :   void AddWindowID(uint64_t aWindowId, GetUserMediaWindowListener *aListener);
     235             :   void RemoveWindowID(uint64_t aWindowId);
     236             :   void SendPendingGUMRequest();
     237           0 :   bool IsWindowStillActive(uint64_t aWindowId) {
     238           0 :     return !!GetWindowListener(aWindowId);
     239             :   }
     240             :   // Note: also calls aListener->Remove(), even if inactive
     241             :   void RemoveFromWindowList(uint64_t aWindowID,
     242             :     GetUserMediaWindowListener *aListener);
     243             : 
     244             :   nsresult GetUserMedia(
     245             :     nsPIDOMWindowInner* aWindow,
     246             :     const dom::MediaStreamConstraints& aConstraints,
     247             :     nsIDOMGetUserMediaSuccessCallback* onSuccess,
     248             :     nsIDOMGetUserMediaErrorCallback* onError,
     249             :     dom::CallerType aCallerType);
     250             : 
     251             :   nsresult GetUserMediaDevices(nsPIDOMWindowInner* aWindow,
     252             :                                const dom::MediaStreamConstraints& aConstraints,
     253             :                                nsIGetUserMediaDevicesSuccessCallback* onSuccess,
     254             :                                nsIDOMGetUserMediaErrorCallback* onError,
     255             :                                uint64_t aInnerWindowID = 0,
     256             :                                const nsAString& aCallID = nsString());
     257             : 
     258             :   nsresult EnumerateDevices(nsPIDOMWindowInner* aWindow,
     259             :                             nsIGetUserMediaDevicesSuccessCallback* aOnSuccess,
     260             :                             nsIDOMGetUserMediaErrorCallback* aOnFailure);
     261             : 
     262             :   nsresult EnumerateDevices(nsPIDOMWindowInner* aWindow, dom::Promise& aPromise);
     263             :   void OnNavigation(uint64_t aWindowID);
     264             :   bool IsActivelyCapturingOrHasAPermission(uint64_t aWindowId);
     265             : 
     266             :   MediaEnginePrefs mPrefs;
     267             : 
     268             :   typedef nsTArray<RefPtr<MediaDevice>> SourceSet;
     269             : 
     270             :   virtual int AddDeviceChangeCallback(DeviceChangeCallback* aCallback) override;
     271             :   virtual void OnDeviceChange() override;
     272             : private:
     273             :   typedef media::Pledge<SourceSet*, dom::MediaStreamError*> PledgeSourceSet;
     274             :   typedef media::Pledge<const char*, dom::MediaStreamError*> PledgeChar;
     275             :   typedef media::Pledge<bool, dom::MediaStreamError*> PledgeVoid;
     276             : 
     277             :   static nsresult GenerateUUID(nsAString& aResult);
     278             :   static nsresult AnonymizeId(nsAString& aId, const nsACString& aOriginKey);
     279             : public: // TODO: make private once we upgrade to GCC 4.8+ on linux.
     280             :   static void AnonymizeDevices(SourceSet& aDevices, const nsACString& aOriginKey);
     281             :   static already_AddRefed<nsIWritableVariant> ToJSArray(SourceSet& aDevices);
     282             : private:
     283             :   already_AddRefed<PledgeSourceSet>
     284             :   EnumerateRawDevices(uint64_t aWindowId,
     285             :                       dom::MediaSourceEnum aVideoType,
     286             :                       dom::MediaSourceEnum aAudioType,
     287             :                       bool aFake);
     288             :   already_AddRefed<PledgeSourceSet>
     289             :   EnumerateDevicesImpl(uint64_t aWindowId,
     290             :                        dom::MediaSourceEnum aVideoSrcType,
     291             :                        dom::MediaSourceEnum aAudioSrcType,
     292             :                        bool aFake = false);
     293             :   already_AddRefed<PledgeChar>
     294             :   SelectSettings(
     295             :       dom::MediaStreamConstraints& aConstraints,
     296             :       bool aIsChrome,
     297             :       RefPtr<media::Refcountable<UniquePtr<SourceSet>>>& aSources);
     298             : 
     299             :   void GetPref(nsIPrefBranch *aBranch, const char *aPref,
     300             :                const char *aData, int32_t *aVal);
     301             :   void GetPrefBool(nsIPrefBranch *aBranch, const char *aPref,
     302             :                    const char *aData, bool *aVal);
     303             :   void GetPrefs(nsIPrefBranch *aBranch, const char *aData);
     304             : 
     305             :   // Make private because we want only one instance of this class
     306             :   MediaManager();
     307             : 
     308           0 :   ~MediaManager() {}
     309             :   void Shutdown();
     310             : 
     311             :   void StopScreensharing(uint64_t aWindowID);
     312             :   void IterateWindowListeners(nsPIDOMWindowInner *aWindow,
     313             :                               WindowListenerCallback aCallback,
     314             :                               void *aData);
     315             : 
     316             :   void StopMediaStreams();
     317             :   void RemoveMediaDevicesCallback(uint64_t aWindowID);
     318             : 
     319             :   // ONLY access from MainThread so we don't need to lock
     320             :   WindowTable mActiveWindows;
     321             :   nsRefPtrHashtable<nsStringHashKey, GetUserMediaTask> mActiveCallbacks;
     322             :   nsClassHashtable<nsUint64HashKey, nsTArray<nsString>> mCallIds;
     323             :   nsTArray<RefPtr<dom::GetUserMediaRequest>> mPendingGUMRequest;
     324             : 
     325             :   // Always exists
     326             :   nsAutoPtr<base::Thread> mMediaThread;
     327             :   nsCOMPtr<nsIAsyncShutdownBlocker> mShutdownBlocker;
     328             : 
     329             :   // ONLY accessed from MediaManagerThread
     330             :   RefPtr<MediaEngine> mBackend;
     331             : 
     332             :   static StaticRefPtr<MediaManager> sSingleton;
     333             : 
     334             :   media::CoatCheck<PledgeSourceSet> mOutstandingPledges;
     335             :   media::CoatCheck<PledgeChar> mOutstandingCharPledges;
     336             :   media::CoatCheck<PledgeVoid> mOutstandingVoidPledges;
     337             : public:
     338             :   media::CoatCheck<media::Pledge<nsCString>> mGetPrincipalKeyPledges;
     339             :   RefPtr<media::Parent<media::NonE10s>> mNonE10sParent;
     340             : };
     341             : 
     342             : } // namespace mozilla
     343             : 
     344             : #endif // MOZILLA_MEDIAMANAGER_H

Generated by: LCOV version 1.13