[ElementCapture] Do not produce frames if media player is tainted

This prevents potential cross-origin mid-stream redirects from
braking the cross-origin restrictions.

(cherry picked from commit abc6ab85e704f599fa366344f9c5ce35585f3217)

Bug: 1111149
Change-Id: I18d05a5836b9a390dec50e10c43d3d2b9ec5915a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2377811
Commit-Queue: Guido Urdaneta <guidou@chromium.org>
Reviewed-by: Dan Sanders <sandersd@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#803036}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2388382
Reviewed-by: Guido Urdaneta <guidou@chromium.org>
Cr-Commit-Position: refs/branch-heads/4183@{#1738}
Cr-Branched-From: 740e9e8a40505392ba5c8e022a8024b3d018ca65-refs/heads/master@{#782793}
diff --git a/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source.cc b/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source.cc
index 900d453..a712281 100644
--- a/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source.cc
+++ b/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source.cc
@@ -116,8 +116,10 @@
   TRACE_EVENT0("media", "HtmlVideoElementCapturerSource::sendNewFrame");
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 
-  if (!web_media_player_ || new_frame_callback_.is_null())
+  if (!web_media_player_ || new_frame_callback_.is_null() ||
+      web_media_player_->WouldTaintOrigin()) {
     return;
+  }
 
   const base::TimeTicks current_time = base::TimeTicks::Now();
   if (start_capture_time_.is_null())
diff --git a/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source_unittest.cc b/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source_unittest.cc
index 2afb51fa..13c693f8 100644
--- a/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source_unittest.cc
+++ b/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source_unittest.cc
@@ -72,7 +72,7 @@
   WebString GetErrorMessage() const override { return WebString(); }
 
   bool DidLoadingProgress() override { return true; }
-  bool WouldTaintOrigin() const override { return false; }
+  bool WouldTaintOrigin() const override { return would_taint_origin_; }
   double MediaTimeForTimeValue(double timeValue) const override { return 0.0; }
   unsigned DecodedFrameCount() const override { return 0; }
   unsigned DroppedFrameCount() const override { return 0; }
@@ -80,6 +80,8 @@
   uint64_t AudioDecodedByteCount() const override { return 0; }
   uint64_t VideoDecodedByteCount() const override { return 0; }
 
+  void SetWouldTaintOrigin(bool taint) { would_taint_origin_ = taint; }
+
   void Paint(cc::PaintCanvas* canvas,
              const WebRect& rect,
              cc::PaintFlags&,
@@ -99,6 +101,7 @@
 
   bool is_video_opaque_ = true;
   gfx::Size size_ = gfx::Size(16, 10);
+  bool would_taint_origin_ = false;
 
   base::WeakPtrFactory<MockWebMediaPlayer> weak_factory_{this};
 };
@@ -327,4 +330,36 @@
   Mock::VerifyAndClearExpectations(this);
 }
 
+// Checks that the usual sequence of GetPreferredFormats() ->
+// StartCapture() -> StopCapture() works as expected and let it capture two
+// frames, that are tested for format vs the expected source opacity.
+TEST_F(HTMLVideoElementCapturerSourceTest, TaintedPlayerDoesNotDeliverFrames) {
+  InSequence s;
+  media::VideoCaptureFormats formats =
+      html_video_capturer_->GetPreferredFormats();
+  ASSERT_EQ(1u, formats.size());
+  EXPECT_EQ(web_media_player_->NaturalSize(), formats[0].frame_size);
+  web_media_player_->SetWouldTaintOrigin(true);
+
+  media::VideoCaptureParams params;
+  params.requested_format = formats[0];
+
+  EXPECT_CALL(*this, DoOnRunning(true)).Times(1);
+
+  // No frames should be delivered.
+  EXPECT_CALL(*this, DoOnDeliverFrame(_, _)).Times(0);
+  html_video_capturer_->StartCapture(
+      params,
+      WTF::BindRepeating(&HTMLVideoElementCapturerSourceTest::OnDeliverFrame,
+                         base::Unretained(this)),
+      WTF::BindRepeating(&HTMLVideoElementCapturerSourceTest::OnRunning,
+                         base::Unretained(this)));
+
+  // Wait for frames to be potentially sent in a follow-up task.
+  base::RunLoop().RunUntilIdle();
+
+  html_video_capturer_->StopCapture();
+  Mock::VerifyAndClearExpectations(this);
+}
+
 }  // namespace blink