Make CroppedWindowCapturer more resilient

Bug: chromium:1245272
Change-Id: I276c98ad0aea3dd0e614b935b9a7566c77d5026a
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/233720
Reviewed-by: Joe Downing <joedow@chromium.org>
Commit-Queue: Ilya Nikolaevskiy <ilnik@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#35132}
diff --git a/modules/desktop_capture/cropped_desktop_frame.cc b/modules/desktop_capture/cropped_desktop_frame.cc
index 1ab0355..3c5c994 100644
--- a/modules/desktop_capture/cropped_desktop_frame.cc
+++ b/modules/desktop_capture/cropped_desktop_frame.cc
@@ -36,7 +36,9 @@
     const DesktopRect& rect) {
   RTC_DCHECK(frame);
 
-  if (!DesktopRect::MakeSize(frame->size()).ContainsRect(rect)) {
+  DesktopRect intersection = DesktopRect::MakeSize(frame->size());
+  intersection.IntersectWith(rect);
+  if (intersection.is_empty()) {
     return nullptr;
   }
 
@@ -45,7 +47,7 @@
   }
 
   return std::unique_ptr<DesktopFrame>(
-      new CroppedDesktopFrame(std::move(frame), rect));
+      new CroppedDesktopFrame(std::move(frame), intersection));
 }
 
 CroppedDesktopFrame::CroppedDesktopFrame(std::unique_ptr<DesktopFrame> frame,
diff --git a/modules/desktop_capture/cropped_desktop_frame_unittest.cc b/modules/desktop_capture/cropped_desktop_frame_unittest.cc
index ff9b8ca..9becf69 100644
--- a/modules/desktop_capture/cropped_desktop_frame_unittest.cc
+++ b/modules/desktop_capture/cropped_desktop_frame_unittest.cc
@@ -32,9 +32,14 @@
   ASSERT_EQ(cropped.get(), raw_original);
 }
 
-TEST(CroppedDesktopFrameTest, ReturnNullptrIfSizeIsNotSufficient) {
-  ASSERT_EQ(nullptr, CreateCroppedDesktopFrame(CreateTestFrame(),
-                                               DesktopRect::MakeWH(11, 10)));
+TEST(CroppedDesktopFrameTest, CropWhenPartiallyOutOfBounds) {
+  std::unique_ptr<DesktopFrame> cropped =
+      CreateCroppedDesktopFrame(CreateTestFrame(), DesktopRect::MakeWH(11, 10));
+  ASSERT_NE(nullptr, cropped);
+  ASSERT_EQ(cropped->size().width(), 10);
+  ASSERT_EQ(cropped->size().height(), 10);
+  ASSERT_EQ(cropped->top_left().x(), 0);
+  ASSERT_EQ(cropped->top_left().y(), 0);
 }
 
 TEST(CroppedDesktopFrameTest, ReturnNullIfCropRegionIsOutOfBounds) {
diff --git a/modules/desktop_capture/cropping_window_capturer.cc b/modules/desktop_capture/cropping_window_capturer.cc
index bd1ba46..5e0faaa 100644
--- a/modules/desktop_capture/cropping_window_capturer.cc
+++ b/modules/desktop_capture/cropping_window_capturer.cc
@@ -99,9 +99,16 @@
     return;
   }
 
-  callback_->OnCaptureResult(
-      Result::SUCCESS,
-      CreateCroppedDesktopFrame(std::move(screen_frame), window_rect));
+  std::unique_ptr<DesktopFrame> cropped_frame =
+      CreateCroppedDesktopFrame(std::move(screen_frame), window_rect);
+
+  if (!cropped_frame) {
+    RTC_LOG(LS_WARNING) << "Window is outside of the captured display";
+    callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr);
+    return;
+  }
+
+  callback_->OnCaptureResult(Result::SUCCESS, std::move(cropped_frame));
 }
 
 bool CroppingWindowCapturer::IsOccluded(const DesktopVector& pos) {