Bug 1208371 - Hook up DecodedStream with PrincipalHandle. r?mt,jwwang draft
authorAndreas Pehrson <pehrsons@gmail.com>
Tue, 02 Feb 2016 13:14:13 +0800
changeset 347660 600c27cd585f9c191fec2c6c35d8a0deb95a184f
parent 347659 ccf85fe39b56a8e6c503c6d89ed2f46d6b394edf
child 347661 cf4378875f23b6d644d40ecf8b2fa5c4528fc219
push id14642
push userpehrsons@gmail.com
push dateTue, 05 Apr 2016 16:45:34 +0000
reviewersmt, jwwang
bugs1208371
milestone47.0a1
Bug 1208371 - Hook up DecodedStream with PrincipalHandle. r?mt,jwwang MozReview-Commit-ID: 1LmiFyfjhsr
dom/media/MediaDecoder.cpp
dom/media/MediaDecoder.h
dom/media/MediaDecoderStateMachine.cpp
dom/media/MediaDecoderStateMachine.h
dom/media/mediasink/DecodedStream.cpp
dom/media/mediasink/DecodedStream.h
--- a/dom/media/MediaDecoder.cpp
+++ b/dom/media/MediaDecoder.cpp
@@ -547,16 +547,18 @@ MediaDecoder::MediaDecoder(MediaDecoderO
   , mPlayState(AbstractThread::MainThread(), PLAY_STATE_LOADING,
                "MediaDecoder::mPlayState (Canonical)")
   , mNextState(AbstractThread::MainThread(), PLAY_STATE_PAUSED,
                "MediaDecoder::mNextState (Canonical)")
   , mLogicallySeeking(AbstractThread::MainThread(), false,
                       "MediaDecoder::mLogicallySeeking (Canonical)")
   , mSameOriginMedia(AbstractThread::MainThread(), false,
                      "MediaDecoder::mSameOriginMedia (Canonical)")
+  , mMediaPrincipalHandle(AbstractThread::MainThread(), PRINCIPAL_HANDLE_NONE,
+                          "MediaDecoder::mMediaPrincipalHandle (Canonical)")
   , mPlaybackBytesPerSecond(AbstractThread::MainThread(), 0.0,
                             "MediaDecoder::mPlaybackBytesPerSecond (Canonical)")
   , mPlaybackRateReliable(AbstractThread::MainThread(), true,
                           "MediaDecoder::mPlaybackRateReliable (Canonical)")
   , mDecoderPosition(AbstractThread::MainThread(), 0,
                      "MediaDecoder::mDecoderPosition (Canonical)")
   , mMediaSeekable(AbstractThread::MainThread(), true,
                    "MediaDecoder::mMediaSeekable (Canonical)")
@@ -1183,16 +1185,18 @@ MediaDecoder::NotifyDownloadEnded(nsresu
   }
 }
 
 void
 MediaDecoder::NotifyPrincipalChanged()
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(!mShuttingDown);
+  nsCOMPtr<nsIPrincipal> newPrincipal = GetCurrentPrincipal();
+  mMediaPrincipalHandle = MakePrincipalHandle(newPrincipal);
   mOwner->NotifyDecoderPrincipalChanged();
 }
 
 void
 MediaDecoder::NotifyBytesConsumed(int64_t aBytes, int64_t aOffset)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(!mShuttingDown);
--- a/dom/media/MediaDecoder.h
+++ b/dom/media/MediaDecoder.h
@@ -772,16 +772,20 @@ protected:
 
   // True if the decoder is seeking.
   Canonical<bool> mLogicallySeeking;
 
   // True if the media is same-origin with the element. Data can only be
   // passed to MediaStreams when this is true.
   Canonical<bool> mSameOriginMedia;
 
+  // An identifier for the principal of the media. Used to track when
+  // main-thread induced principal changes get reflected on MSG thread.
+  Canonical<PrincipalHandle> mMediaPrincipalHandle;
+
   // Estimate of the current playback rate (bytes/second).
   Canonical<double> mPlaybackBytesPerSecond;
 
   // True if mPlaybackBytesPerSecond is a reliable estimate.
   Canonical<bool> mPlaybackRateReliable;
 
   // Current decoding position in the stream. This is where the decoder
   // is up to consuming the stream. This is not adjusted during decoder
@@ -816,16 +820,19 @@ public:
     return &mNextState;
   }
   AbstractCanonical<bool>* CanonicalLogicallySeeking() {
     return &mLogicallySeeking;
   }
   AbstractCanonical<bool>* CanonicalSameOriginMedia() {
     return &mSameOriginMedia;
   }
+  AbstractCanonical<PrincipalHandle>* CanonicalMediaPrincipalHandle() {
+    return &mMediaPrincipalHandle;
+  }
   AbstractCanonical<double>* CanonicalPlaybackBytesPerSecond() {
     return &mPlaybackBytesPerSecond;
   }
   AbstractCanonical<bool>* CanonicalPlaybackRateReliable() {
     return &mPlaybackRateReliable;
   }
   AbstractCanonical<int64_t>* CanonicalDecoderPosition() {
     return &mDecoderPosition;
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -256,16 +256,18 @@ MediaDecoderStateMachine::MediaDecoderSt
                     "MediaDecoderStateMachine::mLogicallySeeking (Mirror)"),
   mVolume(mTaskQueue, 1.0, "MediaDecoderStateMachine::mVolume (Mirror)"),
   mLogicalPlaybackRate(mTaskQueue, 1.0,
                        "MediaDecoderStateMachine::mLogicalPlaybackRate (Mirror)"),
   mPreservesPitch(mTaskQueue, true,
                   "MediaDecoderStateMachine::mPreservesPitch (Mirror)"),
   mSameOriginMedia(mTaskQueue, false,
                    "MediaDecoderStateMachine::mSameOriginMedia (Mirror)"),
+  mMediaPrincipalHandle(mTaskQueue, PRINCIPAL_HANDLE_NONE,
+                        "MediaDecoderStateMachine::mMediaPrincipalHandle (Mirror)"),
   mPlaybackBytesPerSecond(mTaskQueue, 0.0,
                           "MediaDecoderStateMachine::mPlaybackBytesPerSecond (Mirror)"),
   mPlaybackRateReliable(mTaskQueue, true,
                         "MediaDecoderStateMachine::mPlaybackRateReliable (Mirror)"),
   mDecoderPosition(mTaskQueue, 0,
                    "MediaDecoderStateMachine::mDecoderPosition (Mirror)"),
   mMediaSeekable(mTaskQueue, true,
                  "MediaDecoderStateMachine::mMediaSeekable (Mirror)"),
@@ -342,16 +344,17 @@ MediaDecoderStateMachine::Initialization
   mExplicitDuration.Connect(aDecoder->CanonicalExplicitDuration());
   mPlayState.Connect(aDecoder->CanonicalPlayState());
   mNextPlayState.Connect(aDecoder->CanonicalNextPlayState());
   mLogicallySeeking.Connect(aDecoder->CanonicalLogicallySeeking());
   mVolume.Connect(aDecoder->CanonicalVolume());
   mLogicalPlaybackRate.Connect(aDecoder->CanonicalPlaybackRate());
   mPreservesPitch.Connect(aDecoder->CanonicalPreservesPitch());
   mSameOriginMedia.Connect(aDecoder->CanonicalSameOriginMedia());
+  mMediaPrincipalHandle.Connect(aDecoder->CanonicalMediaPrincipalHandle());
   mPlaybackBytesPerSecond.Connect(aDecoder->CanonicalPlaybackBytesPerSecond());
   mPlaybackRateReliable.Connect(aDecoder->CanonicalPlaybackRateReliable());
   mDecoderPosition.Connect(aDecoder->CanonicalDecoderPosition());
   mMediaSeekable.Connect(aDecoder->CanonicalMediaSeekable());
 
   // Initialize watchers.
   mWatchManager.Watch(mBuffered, &MediaDecoderStateMachine::BufferedRangeUpdated);
   mWatchManager.Watch(mState, &MediaDecoderStateMachine::UpdateNextFrameStatus);
@@ -380,17 +383,18 @@ MediaDecoderStateMachine::CreateAudioSin
   return new AudioSinkWrapper(mTaskQueue, audioSinkCreator);
 }
 
 already_AddRefed<media::MediaSink>
 MediaDecoderStateMachine::CreateMediaSink(bool aAudioCaptured)
 {
   RefPtr<media::MediaSink> audioSink = aAudioCaptured
     ? new DecodedStream(mTaskQueue, mAudioQueue, mVideoQueue,
-                        mOutputStreamManager, mSameOriginMedia.Ref())
+                        mOutputStreamManager, mSameOriginMedia.Ref(),
+                        mMediaPrincipalHandle.Ref())
     : CreateAudioSink();
 
   RefPtr<media::MediaSink> mediaSink =
     new VideoSink(mTaskQueue, audioSink, mVideoQueue,
                   mVideoFrameContainer, *mFrameStats,
                   sVideoQueueSendToCompositorSize);
   return mediaSink.forget();
 }
@@ -2191,16 +2195,17 @@ MediaDecoderStateMachine::FinishShutdown
   mExplicitDuration.DisconnectIfConnected();
   mPlayState.DisconnectIfConnected();
   mNextPlayState.DisconnectIfConnected();
   mLogicallySeeking.DisconnectIfConnected();
   mVolume.DisconnectIfConnected();
   mLogicalPlaybackRate.DisconnectIfConnected();
   mPreservesPitch.DisconnectIfConnected();
   mSameOriginMedia.DisconnectIfConnected();
+  mMediaPrincipalHandle.DisconnectIfConnected();
   mPlaybackBytesPerSecond.DisconnectIfConnected();
   mPlaybackRateReliable.DisconnectIfConnected();
   mDecoderPosition.DisconnectIfConnected();
   mMediaSeekable.DisconnectIfConnected();
 
   mDuration.DisconnectAll();
   mIsShutdown.DisconnectAll();
   mNextFrameStatus.DisconnectAll();
--- a/dom/media/MediaDecoderStateMachine.h
+++ b/dom/media/MediaDecoderStateMachine.h
@@ -1223,16 +1223,20 @@ private:
 
   // Pitch preservation for the playback rate.
   Mirror<bool> mPreservesPitch;
 
   // True if the media is same-origin with the element. Data can only be
   // passed to MediaStreams when this is true.
   Mirror<bool> mSameOriginMedia;
 
+  // An identifier for the principal of the media. Used to track when
+  // main-thread induced principal changes get reflected on MSG thread.
+  Mirror<PrincipalHandle> mMediaPrincipalHandle;
+
   // Estimate of the current playback rate (bytes/second).
   Mirror<double> mPlaybackBytesPerSecond;
 
   // True if mPlaybackBytesPerSecond is a reliable estimate.
   Mirror<bool> mPlaybackRateReliable;
 
   // Current decoding position in the stream.
   Mirror<int64_t> mDecoderPosition;
--- a/dom/media/mediasink/DecodedStream.cpp
+++ b/dom/media/mediasink/DecodedStream.cpp
@@ -205,21 +205,23 @@ DecodedStreamData::SetPlaying(bool aPlay
     UpdateStreamSuspended(mStream, !mPlaying);
   }
 }
 
 DecodedStream::DecodedStream(AbstractThread* aOwnerThread,
                              MediaQueue<MediaData>& aAudioQueue,
                              MediaQueue<MediaData>& aVideoQueue,
                              OutputStreamManager* aOutputStreamManager,
-                             const bool& aSameOrigin)
+                             const bool& aSameOrigin,
+                             const PrincipalHandle& aPrincipalHandle)
   : mOwnerThread(aOwnerThread)
   , mOutputStreamManager(aOutputStreamManager)
   , mPlaying(false)
   , mSameOrigin(aSameOrigin)
+  , mPrincipalHandle(aPrincipalHandle)
   , mAudioQueue(aAudioQueue)
   , mVideoQueue(aVideoQueue)
 {
 }
 
 DecodedStream::~DecodedStream()
 {
   MOZ_ASSERT(mStartTime.isNothing(), "playback should've ended.");
@@ -448,17 +450,17 @@ DecodedStream::SetPreservesPitch(bool aP
 {
   AssertOwnerThread();
   mParams.mPreservesPitch = aPreservesPitch;
 }
 
 static void
 SendStreamAudio(DecodedStreamData* aStream, int64_t aStartTime,
                 MediaData* aData, AudioSegment* aOutput,
-                uint32_t aRate, double aVolume)
+                uint32_t aRate, double aVolume, const PrincipalHandle& aPrincipalHandle)
 {
   // The amount of audio frames that is used to fuzz rounding errors.
   static const int64_t AUDIO_FUZZ_FRAMES = 1;
 
   MOZ_ASSERT(aData);
   AudioData* audio = aData->As<AudioData>();
   // This logic has to mimic AudioSink closely to make sure we write
   // the exact same silences
@@ -487,25 +489,26 @@ SendStreamAudio(DecodedStreamData* aStre
   // DecodedAudioDataSink::PlayFromAudioQueue()
   audio->EnsureAudioBuffer();
   RefPtr<SharedBuffer> buffer = audio->mAudioBuffer;
   AudioDataValue* bufferData = static_cast<AudioDataValue*>(buffer->Data());
   AutoTArray<const AudioDataValue*, 2> channels;
   for (uint32_t i = 0; i < audio->mChannels; ++i) {
     channels.AppendElement(bufferData + i * audio->mFrames);
   }
-  aOutput->AppendFrames(buffer.forget(), channels, audio->mFrames, PRINCIPAL_HANDLE_NONE /* Fixed in later patch */);
+  aOutput->AppendFrames(buffer.forget(), channels, audio->mFrames, aPrincipalHandle);
   aStream->mAudioFramesWritten += audio->mFrames;
   aOutput->ApplyVolume(aVolume);
 
   aStream->mNextAudioTime = audio->GetEndTime();
 }
 
 void
-DecodedStream::SendAudio(double aVolume, bool aIsSameOrigin)
+DecodedStream::SendAudio(double aVolume, bool aIsSameOrigin,
+                         const PrincipalHandle& aPrincipalHandle)
 {
   AssertOwnerThread();
 
   if (!mInfo.HasAudio()) {
     return;
   }
 
   AudioSegment output;
@@ -513,17 +516,18 @@ DecodedStream::SendAudio(double aVolume,
   AutoTArray<RefPtr<MediaData>,10> audio;
   TrackID audioTrackId = mInfo.mAudio.mTrackId;
   SourceMediaStream* sourceStream = mData->mStream;
 
   // It's OK to hold references to the AudioData because AudioData
   // is ref-counted.
   mAudioQueue.GetElementsAfter(mData->mNextAudioTime, &audio);
   for (uint32_t i = 0; i < audio.Length(); ++i) {
-    SendStreamAudio(mData.get(), mStartTime.ref(), audio[i], &output, rate, aVolume);
+    SendStreamAudio(mData.get(), mStartTime.ref(), audio[i], &output, rate,
+                    aVolume, aPrincipalHandle);
   }
 
   if (!aIsSameOrigin) {
     output.ReplaceWithDisabled();
   }
 
   // |mNextAudioTime| is updated as we process each audio sample in
   // SendStreamAudio(). This is consistent with how |mNextVideoTime|
@@ -539,38 +543,39 @@ DecodedStream::SendAudio(double aVolume,
 }
 
 static void
 WriteVideoToMediaStream(MediaStream* aStream,
                         layers::Image* aImage,
                         int64_t aEndMicroseconds,
                         int64_t aStartMicroseconds,
                         const mozilla::gfx::IntSize& aIntrinsicSize,
-                        VideoSegment* aOutput)
+                        VideoSegment* aOutput,
+                        const PrincipalHandle& aPrincipalHandle)
 {
   RefPtr<layers::Image> image = aImage;
   StreamTime duration =
       aStream->MicrosecondsToStreamTimeRoundDown(aEndMicroseconds) -
       aStream->MicrosecondsToStreamTimeRoundDown(aStartMicroseconds);
-  aOutput->AppendFrame(image.forget(), duration, aIntrinsicSize, PRINCIPAL_HANDLE_NONE /* Fixed in later patch */);
+  aOutput->AppendFrame(image.forget(), duration, aIntrinsicSize, aPrincipalHandle);
 }
 
 static bool
 ZeroDurationAtLastChunk(VideoSegment& aInput)
 {
   // Get the last video frame's start time in VideoSegment aInput.
   // If the start time is equal to the duration of aInput, means the last video
   // frame's duration is zero.
   StreamTime lastVideoStratTime;
   aInput.GetLastFrame(&lastVideoStratTime);
   return lastVideoStratTime == aInput.GetDuration();
 }
 
 void
-DecodedStream::SendVideo(bool aIsSameOrigin)
+DecodedStream::SendVideo(bool aIsSameOrigin, const PrincipalHandle& aPrincipalHandle)
 {
   AssertOwnerThread();
 
   if (!mInfo.HasVideo()) {
     return;
   }
 
   VideoSegment output;
@@ -591,23 +596,24 @@ DecodedStream::SendVideo(bool aIsSameOri
 
       // TODO: |mLastVideoImage| should come from the last image rendered
       // by the state machine. This will avoid the black frame when capture
       // happens in the middle of playback (especially in th middle of a
       // video frame). E.g. if we have a video frame that is 30 sec long
       // and capture happens at 15 sec, we'll have to append a black frame
       // that is 15 sec long.
       WriteVideoToMediaStream(sourceStream, mData->mLastVideoImage, v->mTime,
-          mData->mNextVideoTime, mData->mLastVideoImageDisplaySize, &output);
+          mData->mNextVideoTime, mData->mLastVideoImageDisplaySize, &output,
+          aPrincipalHandle);
       mData->mNextVideoTime = v->mTime;
     }
 
     if (mData->mNextVideoTime < v->GetEndTime()) {
-      WriteVideoToMediaStream(sourceStream, v->mImage,
-          v->GetEndTime(), mData->mNextVideoTime, v->mDisplay, &output);
+      WriteVideoToMediaStream(sourceStream, v->mImage, v->GetEndTime(),
+          mData->mNextVideoTime, v->mDisplay, &output, aPrincipalHandle);
       mData->mNextVideoTime = v->GetEndTime();
       mData->mLastVideoImage = v->mImage;
       mData->mLastVideoImageDisplaySize = v->mDisplay;
     }
   }
 
   // Check the output is not empty.
   if (output.GetLastFrame()) {
@@ -624,17 +630,17 @@ DecodedStream::SendVideo(bool aIsSameOri
 
   if (mVideoQueue.IsFinished() && !mData->mHaveSentFinishVideo) {
     if (mData->mEOSVideoCompensation) {
       VideoSegment endSegment;
       // Calculate the deviation clock time from DecodedStream.
       int64_t deviation_usec = sourceStream->StreamTimeToMicroseconds(1);
       WriteVideoToMediaStream(sourceStream, mData->mLastVideoImage,
           mData->mNextVideoTime + deviation_usec, mData->mNextVideoTime,
-          mData->mLastVideoImageDisplaySize, &endSegment);
+          mData->mLastVideoImageDisplaySize, &endSegment, aPrincipalHandle);
       mData->mNextVideoTime += deviation_usec;
       MOZ_ASSERT(endSegment.GetDuration() > 0);
       if (!aIsSameOrigin) {
         endSegment.ReplaceWithDisabled();
       }
       sourceStream->AppendToTrack(videoTrackId, &endSegment);
     }
     sourceStream->EndTrack(videoTrackId);
@@ -677,18 +683,18 @@ DecodedStream::SendData()
     return;
   }
 
   // Nothing to do when the stream is finished.
   if (mData->mHaveSentFinish) {
     return;
   }
 
-  SendAudio(mParams.mVolume, mSameOrigin);
-  SendVideo(mSameOrigin);
+  SendAudio(mParams.mVolume, mSameOrigin, mPrincipalHandle);
+  SendVideo(mSameOrigin, mPrincipalHandle);
   AdvanceTracks();
 
   bool finished = (!mInfo.HasAudio() || mAudioQueue.IsFinished()) &&
                   (!mInfo.HasVideo() || mVideoQueue.IsFinished());
 
   if (finished && !mData->mHaveSentFinish) {
     mData->mHaveSentFinish = true;
     mData->mStream->Finish();
--- a/dom/media/mediasink/DecodedStream.h
+++ b/dom/media/mediasink/DecodedStream.h
@@ -32,17 +32,18 @@ template <class T> class MediaQueue;
 class DecodedStream : public media::MediaSink {
   using media::MediaSink::PlaybackParams;
 
 public:
   DecodedStream(AbstractThread* aOwnerThread,
                 MediaQueue<MediaData>& aAudioQueue,
                 MediaQueue<MediaData>& aVideoQueue,
                 OutputStreamManager* aOutputStreamManager,
-                const bool& aSameOrigin);
+                const bool& aSameOrigin,
+                const PrincipalHandle& aPrincipalHandle);
 
   // MediaSink functions.
   const PlaybackParams& GetPlaybackParams() const override;
   void SetPlaybackParams(const PlaybackParams& aParams) override;
 
   RefPtr<GenericPromise> OnEnded(TrackType aType) override;
   int64_t GetEndTime(TrackType aType) const override;
   int64_t GetPosition(TimeStamp* aTimeStamp = nullptr) const override;
@@ -65,18 +66,18 @@ public:
 protected:
   virtual ~DecodedStream();
 
 private:
   void CreateData(PlaybackInfoInit&& aInit, MozPromiseHolder<GenericPromise>&& aPromise);
   void DestroyData(UniquePtr<DecodedStreamData> aData);
   void OnDataCreated(UniquePtr<DecodedStreamData> aData);
   void AdvanceTracks();
-  void SendAudio(double aVolume, bool aIsSameOrigin);
-  void SendVideo(bool aIsSameOrigin);
+  void SendAudio(double aVolume, bool aIsSameOrigin, const PrincipalHandle& aPrincipalHandle);
+  void SendVideo(bool aIsSameOrigin, const PrincipalHandle& aPrincipalHandle);
   void SendData();
 
   void AssertOwnerThread() const {
     MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
   }
 
   void ConnectListener();
   void DisconnectListener();
@@ -92,16 +93,18 @@ private:
   /*
    * Worker thread only members.
    */
   UniquePtr<DecodedStreamData> mData;
   RefPtr<GenericPromise> mFinishPromise;
 
   bool mPlaying;
   const bool& mSameOrigin; // valid until Shutdown() is called.
+  const PrincipalHandle& mPrincipalHandle; // valid until Shutdown() is called.
+
   PlaybackParams mParams;
 
   Maybe<int64_t> mStartTime;
   MediaInfo mInfo;
 
   MediaQueue<MediaData>& mAudioQueue;
   MediaQueue<MediaData>& mVideoQueue;