From 5f8de423f190bbb79a62f804151bc24824fa32d8 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 2 Feb 2018 04:16:08 -0500 Subject: Add m-esr52 at 52.6.0 --- dom/media/MediaManager.h | 341 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 341 insertions(+) create mode 100644 dom/media/MediaManager.h (limited to 'dom/media/MediaManager.h') diff --git a/dom/media/MediaManager.h b/dom/media/MediaManager.h new file mode 100644 index 000000000..1255f6c90 --- /dev/null +++ b/dom/media/MediaManager.h @@ -0,0 +1,341 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef MOZILLA_MEDIAMANAGER_H +#define MOZILLA_MEDIAMANAGER_H + +#include "MediaEngine.h" +#include "mozilla/media/DeviceChangeCallback.h" +#include "mozilla/Services.h" +#include "mozilla/Unused.h" +#include "nsAutoPtr.h" +#include "nsIMediaManager.h" + +#include "nsHashKeys.h" +#include "nsGlobalWindow.h" +#include "nsClassHashtable.h" +#include "nsRefPtrHashtable.h" +#include "nsIObserver.h" +#include "nsIPrefService.h" +#include "nsIPrefBranch.h" + +#include "nsPIDOMWindow.h" +#include "nsIDOMNavigatorUserMedia.h" +#include "nsXULAppAPI.h" +#include "mozilla/Attributes.h" +#include "mozilla/Preferences.h" +#include "mozilla/StaticPtr.h" +#include "mozilla/dom/MediaStreamBinding.h" +#include "mozilla/dom/MediaStreamTrackBinding.h" +#include "mozilla/dom/MediaStreamError.h" +#include "mozilla/media/MediaChild.h" +#include "mozilla/media/MediaParent.h" +#include "mozilla/Logging.h" +#include "mozilla/UniquePtr.h" +#include "DOMMediaStream.h" + +#ifdef MOZ_WEBRTC +#include "mtransport/runnable_utils.h" +#endif + +// Note, these suck in Windows headers, unfortunately. +#include "base/thread.h" +#include "base/task.h" + +namespace mozilla { +namespace dom { +struct MediaStreamConstraints; +struct MediaTrackConstraints; +struct MediaTrackConstraintSet; +} // namespace dom + +class MediaManager; +class GetUserMediaCallbackMediaStreamListener; +class GetUserMediaTask; + +extern LogModule* GetMediaManagerLog(); +#define MM_LOG(msg) MOZ_LOG(GetMediaManagerLog(), mozilla::LogLevel::Debug, msg) + +class MediaDevice : public nsIMediaDevice +{ +public: + typedef MediaEngineSource Source; + + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIMEDIADEVICE + + void SetId(const nsAString& aID); + void SetRawId(const nsAString& aID); + virtual uint32_t GetBestFitnessDistance( + const nsTArray& aConstraintSets, + bool aIsChrome); + virtual Source* GetSource() = 0; + nsresult Allocate(const dom::MediaTrackConstraints &aConstraints, + const MediaEnginePrefs &aPrefs, + const nsACString& aOrigin, + const char** aOutBadConstraint); + nsresult Restart(const dom::MediaTrackConstraints &aConstraints, + const MediaEnginePrefs &aPrefs, + const char** aOutBadConstraint); + nsresult Deallocate(); +protected: + virtual ~MediaDevice() {} + explicit MediaDevice(MediaEngineSource* aSource, bool aIsVideo); + + static uint32_t FitnessDistance(nsString aN, + const dom::OwningStringOrStringSequenceOrConstrainDOMStringParameters& aConstraint); +private: + static bool StringsContain(const dom::OwningStringOrStringSequence& aStrings, + nsString aN); + static uint32_t FitnessDistance(nsString aN, + const dom::ConstrainDOMStringParameters& aParams); +protected: + nsString mName; + nsString mID; + nsString mRawID; + bool mScary; + dom::MediaSourceEnum mMediaSource; + RefPtr mSource; + RefPtr mAllocationHandle; +public: + dom::MediaSourceEnum GetMediaSource() { + return mMediaSource; + } + bool mIsVideo; +}; + +class VideoDevice : public MediaDevice +{ +public: + typedef MediaEngineVideoSource Source; + + explicit VideoDevice(Source* aSource); + NS_IMETHOD GetType(nsAString& aType) override; + Source* GetSource() override; +}; + +class AudioDevice : public MediaDevice +{ +public: + typedef MediaEngineAudioSource Source; + + explicit AudioDevice(Source* aSource); + NS_IMETHOD GetType(nsAString& aType) override; + Source* GetSource() override; +}; + +class GetUserMediaNotificationEvent: public Runnable +{ + public: + enum GetUserMediaStatus { + STARTING, + STOPPING, + STOPPED_TRACK, + }; + GetUserMediaNotificationEvent(GetUserMediaCallbackMediaStreamListener* aListener, + GetUserMediaStatus aStatus, + bool aIsAudio, bool aIsVideo, uint64_t aWindowID); + + GetUserMediaNotificationEvent(GetUserMediaStatus aStatus, + already_AddRefed aStream, + OnTracksAvailableCallback* aOnTracksAvailableCallback, + bool aIsAudio, bool aIsVideo, uint64_t aWindowID, + already_AddRefed aError); + virtual ~GetUserMediaNotificationEvent(); + + NS_IMETHOD Run() override; + + protected: + RefPtr mListener; // threadsafe + RefPtr mStream; + nsAutoPtr mOnTracksAvailableCallback; + GetUserMediaStatus mStatus; + bool mIsAudio; + bool mIsVideo; + uint64_t mWindowID; + RefPtr mOnFailure; +}; + +typedef enum { + MEDIA_START, + MEDIA_STOP, + MEDIA_STOP_TRACK, + MEDIA_DIRECT_LISTENERS, +} MediaOperation; + +class ReleaseMediaOperationResource : public Runnable +{ +public: + ReleaseMediaOperationResource(already_AddRefed aStream, + OnTracksAvailableCallback* aOnTracksAvailableCallback): + mStream(aStream), + mOnTracksAvailableCallback(aOnTracksAvailableCallback) {} + NS_IMETHOD Run() override {return NS_OK;} +private: + RefPtr mStream; + nsAutoPtr mOnTracksAvailableCallback; +}; + +typedef nsTArray > StreamListeners; +typedef nsClassHashtable WindowTable; + +// we could add MediaManager if needed +typedef void (*WindowListenerCallback)(MediaManager *aThis, + uint64_t aWindowID, + StreamListeners *aListeners, + void *aData); + +class MediaManager final : public nsIMediaManagerService, + public nsIObserver + ,public DeviceChangeCallback +{ + friend GetUserMediaCallbackMediaStreamListener; +public: + static already_AddRefed GetInstance(); + + // NOTE: never Dispatch(....,NS_DISPATCH_SYNC) to the MediaManager + // thread from the MainThread, as we NS_DISPATCH_SYNC to MainThread + // from MediaManager thread. + static MediaManager* Get(); + static MediaManager* GetIfExists(); + static void StartupInit(); + static void PostTask(already_AddRefed task); +#ifdef DEBUG + static bool IsInMediaThread(); +#endif + + static bool Exists() + { + return !!sSingleton; + } + + static nsresult NotifyRecordingStatusChange(nsPIDOMWindowInner* aWindow, + const nsString& aMsg, + const bool& aIsAudio, + const bool& aIsVideo); + + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIOBSERVER + NS_DECL_NSIMEDIAMANAGERSERVICE + + media::Parent* GetNonE10sParent(); + MediaEngine* GetBackend(uint64_t aWindowId = 0); + StreamListeners *GetWindowListeners(uint64_t aWindowId) { + MOZ_ASSERT(NS_IsMainThread()); + return mActiveWindows.Get(aWindowId); + } + void RemoveWindowID(uint64_t aWindowId); + bool IsWindowStillActive(uint64_t aWindowId) { + return !!GetWindowListeners(aWindowId); + } + // Note: also calls aListener->Remove(), even if inactive + void RemoveFromWindowList(uint64_t aWindowID, + GetUserMediaCallbackMediaStreamListener *aListener); + + nsresult GetUserMedia( + nsPIDOMWindowInner* aWindow, + const dom::MediaStreamConstraints& aConstraints, + nsIDOMGetUserMediaSuccessCallback* onSuccess, + nsIDOMGetUserMediaErrorCallback* onError); + + nsresult GetUserMediaDevices(nsPIDOMWindowInner* aWindow, + const dom::MediaStreamConstraints& aConstraints, + nsIGetUserMediaDevicesSuccessCallback* onSuccess, + nsIDOMGetUserMediaErrorCallback* onError, + uint64_t aInnerWindowID = 0, + const nsAString& aCallID = nsString()); + + nsresult EnumerateDevices(nsPIDOMWindowInner* aWindow, + nsIGetUserMediaDevicesSuccessCallback* aOnSuccess, + nsIDOMGetUserMediaErrorCallback* aOnFailure); + + nsresult EnumerateDevices(nsPIDOMWindowInner* aWindow, dom::Promise& aPromise); + void OnNavigation(uint64_t aWindowID); + bool IsActivelyCapturingOrHasAPermission(uint64_t aWindowId); + + MediaEnginePrefs mPrefs; + + typedef nsTArray> SourceSet; + static bool IsPrivateBrowsing(nsPIDOMWindowInner* window); + + virtual int AddDeviceChangeCallback(DeviceChangeCallback* aCallback) override; + virtual void OnDeviceChange() override; +private: + typedef media::Pledge PledgeSourceSet; + typedef media::Pledge PledgeChar; + typedef media::Pledge PledgeVoid; + + static nsresult GenerateUUID(nsAString& aResult); + static nsresult AnonymizeId(nsAString& aId, const nsACString& aOriginKey); +public: // TODO: make private once we upgrade to GCC 4.8+ on linux. + static void AnonymizeDevices(SourceSet& aDevices, const nsACString& aOriginKey); + static already_AddRefed ToJSArray(SourceSet& aDevices); +private: + already_AddRefed + EnumerateRawDevices(uint64_t aWindowId, + dom::MediaSourceEnum aVideoType, + dom::MediaSourceEnum aAudioType, + bool aFake); + already_AddRefed + EnumerateDevicesImpl(uint64_t aWindowId, + dom::MediaSourceEnum aVideoSrcType, + dom::MediaSourceEnum aAudioSrcType, + bool aFake = false); + already_AddRefed + SelectSettings( + dom::MediaStreamConstraints& aConstraints, + bool aIsChrome, + RefPtr>>& aSources); + + StreamListeners* AddWindowID(uint64_t aWindowId); + WindowTable *GetActiveWindows() { + MOZ_ASSERT(NS_IsMainThread()); + return &mActiveWindows; + } + + void GetPref(nsIPrefBranch *aBranch, const char *aPref, + const char *aData, int32_t *aVal); + void GetPrefBool(nsIPrefBranch *aBranch, const char *aPref, + const char *aData, bool *aVal); + void GetPrefs(nsIPrefBranch *aBranch, const char *aData); + + // Make private because we want only one instance of this class + MediaManager(); + + ~MediaManager() {} + void Shutdown(); + + void StopScreensharing(uint64_t aWindowID); + void IterateWindowListeners(nsPIDOMWindowInner *aWindow, + WindowListenerCallback aCallback, + void *aData); + + void StopMediaStreams(); + void RemoveMediaDevicesCallback(uint64_t aWindowID); + + // ONLY access from MainThread so we don't need to lock + WindowTable mActiveWindows; + nsRefPtrHashtable mActiveCallbacks; + nsClassHashtable> mCallIds; + + // Always exists + nsAutoPtr mMediaThread; + nsCOMPtr mShutdownBlocker; + + // ONLY accessed from MediaManagerThread + RefPtr mBackend; + + static StaticRefPtr sSingleton; + + media::CoatCheck mOutstandingPledges; + media::CoatCheck mOutstandingCharPledges; + media::CoatCheck mOutstandingVoidPledges; +public: + media::CoatCheck> mGetOriginKeyPledges; + RefPtr> mNonE10sParent; +}; + +} // namespace mozilla + +#endif // MOZILLA_MEDIAMANAGER_H -- cgit v1.2.3