content/media/DOMMediaStream.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
michael@0 4 * You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #ifndef NSDOMMEDIASTREAM_H_
michael@0 7 #define NSDOMMEDIASTREAM_H_
michael@0 8
michael@0 9 #include "nsIDOMMediaStream.h"
michael@0 10 #include "nsCycleCollectionParticipant.h"
michael@0 11 #include "nsWrapperCache.h"
michael@0 12 #include "StreamBuffer.h"
michael@0 13 #include "nsIDOMWindow.h"
michael@0 14
michael@0 15 class nsXPCClassInfo;
michael@0 16 class nsIPrincipal;
michael@0 17
michael@0 18 // GetCurrentTime is defined in winbase.h as zero argument macro forwarding to
michael@0 19 // GetTickCount() and conflicts with NS_DECL_NSIDOMMEDIASTREAM, containing
michael@0 20 // currentTime getter.
michael@0 21 #ifdef GetCurrentTime
michael@0 22 #undef GetCurrentTime
michael@0 23 #endif
michael@0 24 // X11 has a #define for CurrentTime. Unbelievable :-(.
michael@0 25 // See content/media/webaudio/AudioContext.h for more fun!
michael@0 26 #ifdef CurrentTime
michael@0 27 #undef CurrentTime
michael@0 28 #endif
michael@0 29
michael@0 30 namespace mozilla {
michael@0 31
michael@0 32 class MediaStream;
michael@0 33
michael@0 34 namespace dom {
michael@0 35 class AudioNode;
michael@0 36 class MediaStreamTrack;
michael@0 37 class AudioStreamTrack;
michael@0 38 class VideoStreamTrack;
michael@0 39 }
michael@0 40
michael@0 41 class MediaStreamDirectListener;
michael@0 42
michael@0 43 /**
michael@0 44 * DOM wrapper for MediaStreams.
michael@0 45 */
michael@0 46 class DOMMediaStream : public nsIDOMMediaStream,
michael@0 47 public nsWrapperCache
michael@0 48 {
michael@0 49 friend class DOMLocalMediaStream;
michael@0 50 typedef dom::MediaStreamTrack MediaStreamTrack;
michael@0 51 typedef dom::AudioStreamTrack AudioStreamTrack;
michael@0 52 typedef dom::VideoStreamTrack VideoStreamTrack;
michael@0 53
michael@0 54 public:
michael@0 55 typedef uint8_t TrackTypeHints;
michael@0 56
michael@0 57 DOMMediaStream();
michael@0 58 virtual ~DOMMediaStream();
michael@0 59
michael@0 60 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMMediaStream)
michael@0 61 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
michael@0 62
michael@0 63 nsIDOMWindow* GetParentObject() const
michael@0 64 {
michael@0 65 return mWindow;
michael@0 66 }
michael@0 67 virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
michael@0 68
michael@0 69 // WebIDL
michael@0 70 double CurrentTime();
michael@0 71
michael@0 72 void GetAudioTracks(nsTArray<nsRefPtr<AudioStreamTrack> >& aTracks);
michael@0 73 void GetVideoTracks(nsTArray<nsRefPtr<VideoStreamTrack> >& aTracks);
michael@0 74
michael@0 75 MediaStream* GetStream() const { return mStream; }
michael@0 76
michael@0 77 /**
michael@0 78 * Overridden in DOMLocalMediaStreams to allow getUserMedia to pass
michael@0 79 * data directly to RTCPeerConnection without going through graph queuing.
michael@0 80 * Returns a bool to let us know if direct data will be delivered.
michael@0 81 */
michael@0 82 virtual bool AddDirectListener(MediaStreamDirectListener *aListener) { return false; }
michael@0 83 virtual void RemoveDirectListener(MediaStreamDirectListener *aListener) {}
michael@0 84
michael@0 85 /**
michael@0 86 * Overridden in DOMLocalMediaStreams to allow getUserMedia to disable
michael@0 87 * media at the SourceMediaStream.
michael@0 88 */
michael@0 89 virtual void SetTrackEnabled(TrackID aTrackID, bool aEnabled);
michael@0 90
michael@0 91 bool IsFinished();
michael@0 92 /**
michael@0 93 * Returns a principal indicating who may access this stream. The stream contents
michael@0 94 * can only be accessed by principals subsuming this principal.
michael@0 95 */
michael@0 96 nsIPrincipal* GetPrincipal() { return mPrincipal; }
michael@0 97
michael@0 98 /**
michael@0 99 * Indicate that data will be contributed to this stream from origin aPrincipal.
michael@0 100 * If aPrincipal is null, this is ignored. Otherwise, from now on the contents
michael@0 101 * of this stream can only be accessed by principals that subsume aPrincipal.
michael@0 102 * Returns true if the stream's principal changed.
michael@0 103 */
michael@0 104 bool CombineWithPrincipal(nsIPrincipal* aPrincipal);
michael@0 105
michael@0 106 /**
michael@0 107 * Called when this stream's MediaStreamGraph has been shut down. Normally
michael@0 108 * MSGs are only shut down when all streams have been removed, so this
michael@0 109 * will only be called during a forced shutdown due to application exit.
michael@0 110 */
michael@0 111 void NotifyMediaStreamGraphShutdown();
michael@0 112 /**
michael@0 113 * Called when the main-thread state of the MediaStream changed.
michael@0 114 */
michael@0 115 void NotifyStreamStateChanged();
michael@0 116
michael@0 117 // Indicate what track types we eventually expect to add to this stream
michael@0 118 enum {
michael@0 119 HINT_CONTENTS_AUDIO = 1 << 0,
michael@0 120 HINT_CONTENTS_VIDEO = 1 << 1
michael@0 121 };
michael@0 122 TrackTypeHints GetHintContents() const { return mHintContents; }
michael@0 123 void SetHintContents(TrackTypeHints aHintContents) { mHintContents = aHintContents; }
michael@0 124
michael@0 125 /**
michael@0 126 * Create an nsDOMMediaStream whose underlying stream is a SourceMediaStream.
michael@0 127 */
michael@0 128 static already_AddRefed<DOMMediaStream>
michael@0 129 CreateSourceStream(nsIDOMWindow* aWindow, TrackTypeHints aHintContents);
michael@0 130
michael@0 131 /**
michael@0 132 * Create an nsDOMMediaStream whose underlying stream is a TrackUnionStream.
michael@0 133 */
michael@0 134 static already_AddRefed<DOMMediaStream>
michael@0 135 CreateTrackUnionStream(nsIDOMWindow* aWindow, TrackTypeHints aHintContents = 0);
michael@0 136
michael@0 137 void SetLogicalStreamStartTime(StreamTime aTime)
michael@0 138 {
michael@0 139 mLogicalStreamStartTime = aTime;
michael@0 140 }
michael@0 141
michael@0 142 // Notifications from StreamListener.
michael@0 143 // CreateDOMTrack should only be called when it's safe to run script.
michael@0 144 MediaStreamTrack* CreateDOMTrack(TrackID aTrackID, MediaSegment::Type aType);
michael@0 145 MediaStreamTrack* GetDOMTrackFor(TrackID aTrackID);
michael@0 146
michael@0 147 class OnTracksAvailableCallback {
michael@0 148 public:
michael@0 149 OnTracksAvailableCallback(uint8_t aExpectedTracks = 0)
michael@0 150 : mExpectedTracks(aExpectedTracks) {}
michael@0 151 virtual ~OnTracksAvailableCallback() {}
michael@0 152 virtual void NotifyTracksAvailable(DOMMediaStream* aStream) = 0;
michael@0 153 TrackTypeHints GetExpectedTracks() { return mExpectedTracks; }
michael@0 154 void SetExpectedTracks(TrackTypeHints aExpectedTracks) { mExpectedTracks = aExpectedTracks; }
michael@0 155 private:
michael@0 156 TrackTypeHints mExpectedTracks;
michael@0 157 };
michael@0 158 // When one track of the appropriate type has been added for each bit set
michael@0 159 // in aCallback->GetExpectedTracks(), run aCallback->NotifyTracksAvailable.
michael@0 160 // It is allowed to do anything, including run script.
michael@0 161 // aCallback may run immediately during this call if tracks are already
michael@0 162 // available!
michael@0 163 // We only care about track additions, we'll fire the notification even if
michael@0 164 // some of the tracks have been removed.
michael@0 165 // Takes ownership of aCallback.
michael@0 166 // If GetExpectedTracks() returns 0, the callback will be fired as soon as there are any tracks.
michael@0 167 void OnTracksAvailable(OnTracksAvailableCallback* aCallback);
michael@0 168
michael@0 169 /**
michael@0 170 * Add an nsISupports object that this stream will keep alive as long as
michael@0 171 * the stream is not finished.
michael@0 172 */
michael@0 173 void AddConsumerToKeepAlive(nsISupports* aConsumer)
michael@0 174 {
michael@0 175 if (!IsFinished() && !mNotifiedOfMediaStreamGraphShutdown) {
michael@0 176 mConsumersToKeepAlive.AppendElement(aConsumer);
michael@0 177 }
michael@0 178 }
michael@0 179
michael@0 180 protected:
michael@0 181 void Destroy();
michael@0 182 void InitSourceStream(nsIDOMWindow* aWindow, TrackTypeHints aHintContents);
michael@0 183 void InitTrackUnionStream(nsIDOMWindow* aWindow, TrackTypeHints aHintContents);
michael@0 184 void InitStreamCommon(MediaStream* aStream);
michael@0 185
michael@0 186 void CheckTracksAvailable();
michael@0 187
michael@0 188 class StreamListener;
michael@0 189 friend class StreamListener;
michael@0 190
michael@0 191 // StreamTime at which the currentTime attribute would return 0.
michael@0 192 StreamTime mLogicalStreamStartTime;
michael@0 193
michael@0 194 // We need this to track our parent object.
michael@0 195 nsCOMPtr<nsIDOMWindow> mWindow;
michael@0 196
michael@0 197 // MediaStream is owned by the graph, but we tell it when to die, and it won't
michael@0 198 // die until we let it.
michael@0 199 MediaStream* mStream;
michael@0 200 // Principal identifying who may access the contents of this stream.
michael@0 201 // If null, this stream can be used by anyone because it has no content yet.
michael@0 202 nsCOMPtr<nsIPrincipal> mPrincipal;
michael@0 203
michael@0 204 nsAutoTArray<nsRefPtr<MediaStreamTrack>,2> mTracks;
michael@0 205 nsRefPtr<StreamListener> mListener;
michael@0 206
michael@0 207 nsTArray<nsAutoPtr<OnTracksAvailableCallback> > mRunOnTracksAvailable;
michael@0 208
michael@0 209 // Keep these alive until the stream finishes
michael@0 210 nsTArray<nsCOMPtr<nsISupports> > mConsumersToKeepAlive;
michael@0 211
michael@0 212 // Indicate what track types we eventually expect to add to this stream
michael@0 213 uint8_t mHintContents;
michael@0 214 // Indicate what track types have been added to this stream
michael@0 215 uint8_t mTrackTypesAvailable;
michael@0 216 bool mNotifiedOfMediaStreamGraphShutdown;
michael@0 217 };
michael@0 218
michael@0 219 class DOMLocalMediaStream : public DOMMediaStream,
michael@0 220 public nsIDOMLocalMediaStream
michael@0 221 {
michael@0 222 public:
michael@0 223 DOMLocalMediaStream() {}
michael@0 224 virtual ~DOMLocalMediaStream();
michael@0 225
michael@0 226 NS_DECL_ISUPPORTS_INHERITED
michael@0 227
michael@0 228 virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
michael@0 229
michael@0 230 virtual void Stop();
michael@0 231
michael@0 232 /**
michael@0 233 * Create an nsDOMLocalMediaStream whose underlying stream is a SourceMediaStream.
michael@0 234 */
michael@0 235 static already_AddRefed<DOMLocalMediaStream>
michael@0 236 CreateSourceStream(nsIDOMWindow* aWindow, TrackTypeHints aHintContents);
michael@0 237
michael@0 238 /**
michael@0 239 * Create an nsDOMLocalMediaStream whose underlying stream is a TrackUnionStream.
michael@0 240 */
michael@0 241 static already_AddRefed<DOMLocalMediaStream>
michael@0 242 CreateTrackUnionStream(nsIDOMWindow* aWindow, TrackTypeHints aHintContents = 0);
michael@0 243 };
michael@0 244
michael@0 245 class DOMAudioNodeMediaStream : public DOMMediaStream
michael@0 246 {
michael@0 247 typedef dom::AudioNode AudioNode;
michael@0 248 public:
michael@0 249 DOMAudioNodeMediaStream(AudioNode* aNode);
michael@0 250
michael@0 251 NS_DECL_ISUPPORTS_INHERITED
michael@0 252 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DOMAudioNodeMediaStream, DOMMediaStream)
michael@0 253
michael@0 254 /**
michael@0 255 * Create a DOMAudioNodeMediaStream whose underlying stream is a TrackUnionStream.
michael@0 256 */
michael@0 257 static already_AddRefed<DOMAudioNodeMediaStream>
michael@0 258 CreateTrackUnionStream(nsIDOMWindow* aWindow,
michael@0 259 AudioNode* aNode,
michael@0 260 TrackTypeHints aHintContents = 0);
michael@0 261
michael@0 262 private:
michael@0 263 // If this object wraps a stream owned by an AudioNode, we need to ensure that
michael@0 264 // the node isn't cycle-collected too early.
michael@0 265 nsRefPtr<AudioNode> mStreamNode;
michael@0 266 };
michael@0 267
michael@0 268 }
michael@0 269
michael@0 270 #endif /* NSDOMMEDIASTREAM_H_ */

mercurial