Use ScreenCapturer to capture the whole and clip to the window rect when the shared window is on the top.

BUG=crbug/403703, crbug/316603
R=wez@chromium.org

Review URL: https://webrtc-codereview.appspot.com/22759004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@7684 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/webrtc/base/win32.h b/webrtc/base/win32.h
index bf5da25..07e1e1e 100644
--- a/webrtc/base/win32.h
+++ b/webrtc/base/win32.h
@@ -110,6 +110,13 @@
           (major == kWindows2000 && minor >= 1)));
 }
 
+inline bool IsWindows8OrLater() {
+  int major, minor;
+  return (GetOsVersion(&major, &minor, NULL) &&
+          (major > kWindowsVista ||
+          (major == kWindowsVista && minor >= 2)));
+}
+
 // Determine the current integrity level of the process.
 bool GetCurrentProcessIntegrityLevel(int* level);
 
@@ -125,5 +132,5 @@
 
 }  // namespace rtc
 
-#endif  // WEBRTC_WIN 
+#endif  // WEBRTC_WIN
 #endif  // WEBRTC_BASE_WIN32_H_
diff --git a/webrtc/modules/desktop_capture/BUILD.gn b/webrtc/modules/desktop_capture/BUILD.gn
index 9067177..6c8d9e2 100644
--- a/webrtc/modules/desktop_capture/BUILD.gn
+++ b/webrtc/modules/desktop_capture/BUILD.gn
@@ -14,6 +14,11 @@
 
 source_set("desktop_capture") {
   sources = [
+    "cropped_desktop_frame.cc",
+    "cropped_desktop_frame.h",
+    "cropping_window_capturer.cc",
+    "cropping_window_capturer.h",
+    "cropping_window_capturer_win.cc",
     "desktop_and_cursor_composer.cc",
     "desktop_and_cursor_composer.h",
     "desktop_capture_types.h",
diff --git a/webrtc/modules/desktop_capture/cropped_desktop_frame.cc b/webrtc/modules/desktop_capture/cropped_desktop_frame.cc
new file mode 100644
index 0000000..0216768
--- /dev/null
+++ b/webrtc/modules/desktop_capture/cropped_desktop_frame.cc
@@ -0,0 +1,45 @@
+/*
+ *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "webrtc/modules/desktop_capture/cropped_desktop_frame.h"
+
+namespace webrtc {
+
+// A DesktopFrame that is a sub-rect of another DesktopFrame.
+class CroppedDesktopFrame : public DesktopFrame {
+ public:
+  CroppedDesktopFrame(DesktopFrame* frame, const DesktopRect& rect);
+
+ private:
+  scoped_ptr<DesktopFrame> frame_;
+
+  DISALLOW_COPY_AND_ASSIGN(CroppedDesktopFrame);
+};
+
+DesktopFrame*
+CreateCroppedDesktopFrame(DesktopFrame* frame, const DesktopRect& rect) {
+  if (!DesktopRect::MakeSize(frame->size()).ContainsRect(rect)) {
+    delete frame;
+    return NULL;
+  }
+
+  return new CroppedDesktopFrame(frame, rect);
+}
+
+CroppedDesktopFrame::CroppedDesktopFrame(DesktopFrame* frame,
+                                         const DesktopRect& rect)
+    : DesktopFrame(rect.size(),
+                   frame->stride(),
+                   frame->GetFrameDataAtPos(rect.top_left()),
+                   frame->shared_memory()),
+      frame_(frame) {
+}
+
+}  // namespace webrtc
diff --git a/webrtc/modules/desktop_capture/cropped_desktop_frame.h b/webrtc/modules/desktop_capture/cropped_desktop_frame.h
new file mode 100644
index 0000000..29449e2
--- /dev/null
+++ b/webrtc/modules/desktop_capture/cropped_desktop_frame.h
@@ -0,0 +1,25 @@
+/*
+ *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_MODULES_DESKTOP_CAPTURE_CROPPED_DESKTOP_FRAME_H_
+#define WEBRTC_MODULES_DESKTOP_CAPTURE_CROPPED_DESKTOP_FRAME_H_
+
+#include "webrtc/modules/desktop_capture/desktop_frame.h"
+
+namespace webrtc {
+
+// Always takes ownership of |frame|. Returns NULL if |rect| is not contained
+// by the bounds of |frame|.
+DesktopFrame* CreateCroppedDesktopFrame(DesktopFrame* frame,
+                                        const DesktopRect& rect);
+}  // namespace webrtc
+
+#endif  // WEBRTC_MODULES_DESKTOP_CAPTURE_CROPPED_DESKTOP_FRAME_H_
+
diff --git a/webrtc/modules/desktop_capture/cropping_window_capturer.cc b/webrtc/modules/desktop_capture/cropping_window_capturer.cc
new file mode 100644
index 0000000..f78b26b
--- /dev/null
+++ b/webrtc/modules/desktop_capture/cropping_window_capturer.cc
@@ -0,0 +1,111 @@
+/*
+ *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "webrtc/modules/desktop_capture/cropping_window_capturer.h"
+
+#include "webrtc/modules/desktop_capture/cropped_desktop_frame.h"
+#include "webrtc/system_wrappers/interface/logging.h"
+
+namespace webrtc {
+
+CroppingWindowCapturer::CroppingWindowCapturer(
+    const DesktopCaptureOptions& options)
+    : options_(options),
+      callback_(NULL),
+      window_capturer_(WindowCapturer::Create(options)),
+      selected_window_(kNullWindowId),
+      excluded_window_(kNullWindowId) {
+}
+
+CroppingWindowCapturer::~CroppingWindowCapturer() {}
+
+void CroppingWindowCapturer::Start(DesktopCapturer::Callback* callback) {
+  callback_ = callback;
+  window_capturer_->Start(callback);
+}
+
+void CroppingWindowCapturer::Capture(const DesktopRegion& region) {
+  if (ShouldUseScreenCapturer()) {
+    if (!screen_capturer_.get()) {
+      screen_capturer_.reset(ScreenCapturer::Create(options_));
+      if (excluded_window_) {
+        screen_capturer_->SetExcludedWindow(excluded_window_);
+      }
+      screen_capturer_->Start(this);
+    }
+    screen_capturer_->Capture(region);
+  } else {
+    window_capturer_->Capture(region);
+  }
+}
+
+void CroppingWindowCapturer::SetExcludedWindow(WindowId window) {
+  excluded_window_ = window;
+  if (screen_capturer_.get()) {
+    screen_capturer_->SetExcludedWindow(window);
+  }
+}
+
+bool CroppingWindowCapturer::GetWindowList(WindowList* windows) {
+  return window_capturer_->GetWindowList(windows);
+}
+
+bool CroppingWindowCapturer::SelectWindow(WindowId id) {
+  if (window_capturer_->SelectWindow(id)) {
+    selected_window_ = id;
+    return true;
+  }
+  return false;
+}
+
+bool CroppingWindowCapturer::BringSelectedWindowToFront() {
+  return window_capturer_->BringSelectedWindowToFront();
+}
+
+SharedMemory* CroppingWindowCapturer::CreateSharedMemory(size_t size) {
+  return callback_->CreateSharedMemory(size);
+}
+
+void CroppingWindowCapturer::OnCaptureCompleted(DesktopFrame* frame) {
+  scoped_ptr<DesktopFrame> screen_frame(frame);
+
+  if (!ShouldUseScreenCapturer()) {
+    LOG(LS_INFO) << "Window no longer on top when ScreenCapturer finishes";
+    window_capturer_->Capture(DesktopRegion());
+    return;
+  }
+
+  if (!frame) {
+    LOG(LS_WARNING) << "ScreenCapturer failed to capture a frame";
+    callback_->OnCaptureCompleted(NULL);
+    return;
+  }
+
+  DesktopRect window_rect = GetWindowRectInVirtualScreen();
+  if (window_rect.is_empty()) {
+    LOG(LS_WARNING) << "Window rect is empty";
+    callback_->OnCaptureCompleted(NULL);
+    return;
+  }
+
+  scoped_ptr<DesktopFrame> window_frame(
+      CreateCroppedDesktopFrame(screen_frame.release(), window_rect));
+  callback_->OnCaptureCompleted(window_frame.release());
+}
+
+#if !defined(OS_WIN)
+// static
+WindowCapturer*
+CroppingWindowCapturer::Create(const DesktopCaptureOptions& options) {
+  return WindowCapturer::Create(options);
+}
+#endif
+
+}  // namespace webrtc
diff --git a/webrtc/modules/desktop_capture/cropping_window_capturer.h b/webrtc/modules/desktop_capture/cropping_window_capturer.h
new file mode 100644
index 0000000..2a5154e
--- /dev/null
+++ b/webrtc/modules/desktop_capture/cropping_window_capturer.h
@@ -0,0 +1,74 @@
+/*
+ *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_MODULES_DESKTOP_CAPTURE_CROPPING_WINDOW_CAPTURER_H_
+#define WEBRTC_MODULES_DESKTOP_CAPTURE_CROPPING_WINDOW_CAPTURER_H_
+
+#include "webrtc/modules/desktop_capture/desktop_capture_options.h"
+#include "webrtc/modules/desktop_capture/screen_capturer.h"
+#include "webrtc/modules/desktop_capture/window_capturer.h"
+#include "webrtc/system_wrappers/interface/scoped_ptr.h"
+
+namespace webrtc {
+
+// WindowCapturer implementation that uses a screen capturer to capture the
+// whole screen and crops the video frame to the window area when the captured
+// window is on top.
+class CroppingWindowCapturer : public WindowCapturer,
+                               public DesktopCapturer::Callback {
+ public:
+  static WindowCapturer* Create(const DesktopCaptureOptions& options);
+  virtual ~CroppingWindowCapturer();
+
+  // DesktopCapturer implementation.
+  virtual void Start(DesktopCapturer::Callback* callback) OVERRIDE;
+  virtual void Capture(const DesktopRegion& region) OVERRIDE;
+  virtual void SetExcludedWindow(WindowId window) OVERRIDE;
+
+  // WindowCapturer implementation.
+  virtual bool GetWindowList(WindowList* windows) OVERRIDE;
+  virtual bool SelectWindow(WindowId id) OVERRIDE;
+  virtual bool BringSelectedWindowToFront() OVERRIDE;
+
+  // DesktopCapturer::Callback implementation, passed to |screen_capturer_| to
+  // intercept the capture result.
+  virtual SharedMemory* CreateSharedMemory(size_t size) OVERRIDE;
+  virtual void OnCaptureCompleted(DesktopFrame* frame) OVERRIDE;
+
+ protected:
+  explicit CroppingWindowCapturer(const DesktopCaptureOptions& options);
+
+  // The platform implementation should override these methods.
+
+  // Returns true if it is OK to capture the whole screen and crop to the
+  // selected window, i.e. the selected window is opaque, rectangular, and not
+  // occluded.
+  virtual bool ShouldUseScreenCapturer() = 0;
+
+  // Returns the window area relative to the top left of the virtual screen
+  // within the bounds of the virtual screen.
+  virtual DesktopRect GetWindowRectInVirtualScreen() = 0;
+
+  WindowId selected_window() const { return selected_window_; }
+  WindowId excluded_window() const { return excluded_window_; }
+
+ private:
+  DesktopCaptureOptions options_;
+  DesktopCapturer::Callback* callback_;
+  scoped_ptr<WindowCapturer> window_capturer_;
+  scoped_ptr<ScreenCapturer> screen_capturer_;
+  WindowId selected_window_;
+  WindowId excluded_window_;
+};
+
+}  // namespace webrtc
+
+#endif  // WEBRTC_MODULES_DESKTOP_CAPTURE_CROPPING_WINDOW_CAPTURER_H_
+
diff --git a/webrtc/modules/desktop_capture/cropping_window_capturer_win.cc b/webrtc/modules/desktop_capture/cropping_window_capturer_win.cc
new file mode 100644
index 0000000..fc1858e
--- /dev/null
+++ b/webrtc/modules/desktop_capture/cropping_window_capturer_win.cc
@@ -0,0 +1,216 @@
+/*
+ *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "webrtc/modules/desktop_capture/cropping_window_capturer.h"
+
+#include "webrtc/base/win32.h"
+#include "webrtc/modules/desktop_capture/win/scoped_gdi_object.h"
+#include "webrtc/modules/desktop_capture/win/screen_capture_utils.h"
+#include "webrtc/modules/desktop_capture/win/window_capture_utils.h"
+#include "webrtc/system_wrappers/interface/logging.h"
+
+namespace webrtc {
+
+namespace {
+
+// Used to pass input/output data during the EnumWindow call for verifying if
+// the selected window is on top.
+struct TopWindowVerifierContext {
+  TopWindowVerifierContext(HWND selected_window, HWND excluded_window)
+      : selected_window(selected_window),
+        excluded_window(excluded_window),
+        is_top_window(false),
+        selected_window_process_id(0) {}
+
+  HWND selected_window;
+  HWND excluded_window;
+  bool is_top_window;
+  DWORD selected_window_process_id;
+  DesktopRect selected_window_rect;
+};
+
+// The function is called during EnumWindow for every window enumerated and is
+// responsible for verifying if the selected window is on top.
+BOOL CALLBACK TopWindowVerifier(HWND hwnd, LPARAM param) {
+  TopWindowVerifierContext* context =
+      reinterpret_cast<TopWindowVerifierContext*>(param);
+
+  if (hwnd == context->selected_window) {
+    context->is_top_window = true;
+    return FALSE;
+  }
+
+  // Ignore the excluded window.
+  if (hwnd == context->excluded_window) {
+    return TRUE;
+  }
+
+  // Ignore hidden or minimized window.
+  if (IsIconic(hwnd) || !IsWindowVisible(hwnd)) {
+    return TRUE;
+  }
+
+  // Ignore descendant/owned windows since we want to capture them.
+  // This check does not work for tooltips and context menus. Drop down menus
+  // and popup windows are fine.
+  if (GetAncestor(hwnd, GA_ROOTOWNER) == context->selected_window) {
+    return TRUE;
+  }
+
+  // If |hwnd| has no title and belongs to the same process, assume it's a
+  // tooltip or context menu from the selected window and ignore it.
+  const size_t kTitleLength = 32;
+  WCHAR window_title[kTitleLength];
+  GetWindowText(hwnd, window_title, kTitleLength);
+  if (wcsnlen_s(window_title, kTitleLength) == 0) {
+    DWORD enumerated_process;
+    GetWindowThreadProcessId(hwnd, &enumerated_process);
+    if (!context->selected_window_process_id) {
+      GetWindowThreadProcessId(context->selected_window,
+                               &context->selected_window_process_id);
+    }
+    if (context->selected_window_process_id == enumerated_process) {
+      return TRUE;
+    }
+  }
+
+  // Check if the enumerated window intersects with the selected window.
+  RECT enumerated_rect;
+  if (!GetWindowRect(hwnd, &enumerated_rect)) {
+    // Bail out if failed to get the window area.
+    context->is_top_window = false;
+    return FALSE;
+  }
+
+  DesktopRect intersect_rect = context->selected_window_rect;
+  DesktopRect enumerated_desktop_rect =
+      DesktopRect::MakeLTRB(enumerated_rect.left,
+                            enumerated_rect.top,
+                            enumerated_rect.right,
+                            enumerated_rect.bottom);
+  intersect_rect.IntersectWith(enumerated_desktop_rect);
+
+  // If intersection is not empty, the selected window is not on top.
+  if (!intersect_rect.is_empty()) {
+    context->is_top_window = false;
+    return FALSE;
+  }
+  // Otherwise, keep enumerating.
+  return TRUE;
+}
+
+class CroppingWindowCapturerWin : public CroppingWindowCapturer {
+ public:
+  CroppingWindowCapturerWin(
+      const DesktopCaptureOptions& options)
+      : CroppingWindowCapturer(options) {}
+
+ private:
+  virtual bool ShouldUseScreenCapturer() OVERRIDE;
+  virtual DesktopRect GetWindowRectInVirtualScreen() OVERRIDE;
+
+  // The region from GetWindowRgn in the desktop coordinate if the region is
+  // rectangular, or the rect from GetWindowRect if the region is not set.
+  DesktopRect window_region_rect_;
+};
+
+bool CroppingWindowCapturerWin::ShouldUseScreenCapturer() {
+  if (!rtc::IsWindows8OrLater())
+    return false;
+
+  // Check if the window is a translucent layered window.
+  HWND selected = reinterpret_cast<HWND>(selected_window());
+  LONG window_ex_style = GetWindowLong(selected, GWL_EXSTYLE);
+  if (window_ex_style & WS_EX_LAYERED) {
+    COLORREF color_ref_key = 0;
+    BYTE alpha = 0;
+    DWORD flags = 0;
+
+    // GetLayeredWindowAttributes fails if the window was setup with
+    // UpdateLayeredWindow. We have no way to know the opacity of the window in
+    // that case. This happens for Stiky Note (crbug/412726).
+    if (!GetLayeredWindowAttributes(selected, &color_ref_key, &alpha, &flags))
+      return false;
+
+    // UpdateLayeredWindow is the only way to set per-pixel alpha and will cause
+    // the previous GetLayeredWindowAttributes to fail. So we only need to check
+    // the window wide color key or alpha.
+    if ((flags & LWA_COLORKEY) || ((flags & LWA_ALPHA) && (alpha < 255)))
+      return false;
+  }
+
+  TopWindowVerifierContext context(
+      selected, reinterpret_cast<HWND>(excluded_window()));
+
+  RECT selected_window_rect;
+  if (!GetWindowRect(selected, &selected_window_rect)) {
+    return false;
+  }
+  context.selected_window_rect = DesktopRect::MakeLTRB(
+      selected_window_rect.left,
+      selected_window_rect.top,
+      selected_window_rect.right,
+      selected_window_rect.bottom);
+
+  // Get the window region and check if it is rectangular.
+  win::ScopedGDIObject<HRGN, win::DeleteObjectTraits<HRGN> >
+      scoped_hrgn(CreateRectRgn(0, 0, 0, 0));
+  int region_type = GetWindowRgn(selected, scoped_hrgn.Get());
+
+  // Do not use the screen capturer if the region is empty or not rectangular.
+  if (region_type == COMPLEXREGION || region_type == NULLREGION)
+    return false;
+
+  if (region_type == SIMPLEREGION) {
+    RECT region_rect;
+    GetRgnBox(scoped_hrgn.Get(), &region_rect);
+    DesktopRect rgn_rect =
+        DesktopRect::MakeLTRB(region_rect.left,
+                              region_rect.top,
+                              region_rect.right,
+                              region_rect.bottom);
+    rgn_rect.Translate(context.selected_window_rect.left(),
+                       context.selected_window_rect.top());
+    context.selected_window_rect.IntersectWith(rgn_rect);
+  }
+  window_region_rect_ = context.selected_window_rect;
+
+  // Check if the window is occluded by any other window, excluding the child
+  // windows, context menus, and |excluded_window_|.
+  EnumWindows(&TopWindowVerifier, reinterpret_cast<LPARAM>(&context));
+  return context.is_top_window;
+}
+
+DesktopRect CroppingWindowCapturerWin::GetWindowRectInVirtualScreen() {
+  DesktopRect original_rect;
+  DesktopRect window_rect;
+  HWND hwnd = reinterpret_cast<HWND>(selected_window());
+  if (!GetCroppedWindowRect(hwnd, &window_rect, &original_rect)) {
+    LOG(LS_WARNING) << "Failed to get window info: " << GetLastError();
+    return window_rect;
+  }
+  window_rect.IntersectWith(window_region_rect_);
+
+  // Convert |window_rect| to be relative to the top-left of the virtual screen.
+  DesktopRect screen_rect(GetScreenRect(kFullDesktopScreenId, L""));
+  window_rect.IntersectWith(screen_rect);
+  window_rect.Translate(-screen_rect.left(), -screen_rect.top());
+  return window_rect;
+}
+
+}  // namespace
+
+// static
+WindowCapturer*
+CroppingWindowCapturer::Create(const DesktopCaptureOptions& options) {
+  return new CroppingWindowCapturerWin(options);
+}
+
+}  // namespace webrtc
diff --git a/webrtc/modules/desktop_capture/desktop_capture.gypi b/webrtc/modules/desktop_capture/desktop_capture.gypi
index 1b702f2..49f9347 100644
--- a/webrtc/modules/desktop_capture/desktop_capture.gypi
+++ b/webrtc/modules/desktop_capture/desktop_capture.gypi
@@ -16,6 +16,11 @@
         '<(webrtc_root)/base/base.gyp:rtc_base',
       ],
       'sources': [
+        'cropped_desktop_frame.cc',
+        'cropped_desktop_frame.h',
+        'cropping_window_capturer.cc',
+        'cropping_window_capturer.h',
+        'cropping_window_capturer_win.cc',
         "desktop_and_cursor_composer.cc",
         "desktop_and_cursor_composer.h",
         "desktop_capture_types.h",
diff --git a/webrtc/modules/desktop_capture/desktop_frame.cc b/webrtc/modules/desktop_capture/desktop_frame.cc
index f26dc93..cb32ef7 100644
--- a/webrtc/modules/desktop_capture/desktop_frame.cc
+++ b/webrtc/modules/desktop_capture/desktop_frame.cc
@@ -32,8 +32,7 @@
                                   const DesktopRect& dest_rect) {
   assert(DesktopRect::MakeSize(size()).ContainsRect(dest_rect));
 
-  uint8_t* dest = data() + stride() * dest_rect.top() +
-                  DesktopFrame::kBytesPerPixel * dest_rect.left();
+  uint8_t* dest = GetFrameDataAtPos(dest_rect.top_left());
   for (int y = 0; y < dest_rect.height(); ++y) {
     memcpy(dest, src_buffer, DesktopFrame::kBytesPerPixel * dest_rect.width());
     src_buffer += src_stride;
@@ -47,11 +46,14 @@
   assert(DesktopRect::MakeSize(src_frame.size()).ContainsRect(
       DesktopRect::MakeOriginSize(src_pos, dest_rect.size())));
 
-  CopyPixelsFrom(src_frame.data() + src_frame.stride() * src_pos.y() +
-                     DesktopFrame::kBytesPerPixel * src_pos.x(),
+  CopyPixelsFrom(src_frame.GetFrameDataAtPos(src_pos),
                  src_frame.stride(), dest_rect);
 }
 
+uint8_t* DesktopFrame::GetFrameDataAtPos(const DesktopVector& pos) const {
+  return data() + stride() * pos.y() + DesktopFrame::kBytesPerPixel * pos.x();
+}
+
 BasicDesktopFrame::BasicDesktopFrame(DesktopSize size)
     : DesktopFrame(size, kBytesPerPixel * size.width(),
                    new uint8_t[kBytesPerPixel * size.width() * size.height()],
diff --git a/webrtc/modules/desktop_capture/desktop_frame.h b/webrtc/modules/desktop_capture/desktop_frame.h
index 781d108..7bcc346 100644
--- a/webrtc/modules/desktop_capture/desktop_frame.h
+++ b/webrtc/modules/desktop_capture/desktop_frame.h
@@ -67,6 +67,9 @@
                       const DesktopVector& src_pos,
                       const DesktopRect& dest_rect);
 
+  // A helper to return the data pointer of a frame at the specified position.
+  uint8_t* GetFrameDataAtPos(const DesktopVector& pos) const;
+
  protected:
   DesktopFrame(DesktopSize size,
                int stride,
diff --git a/webrtc/modules/desktop_capture/window_capturer.h b/webrtc/modules/desktop_capture/window_capturer.h
index ad75c88..9ba441a 100644
--- a/webrtc/modules/desktop_capture/window_capturer.h
+++ b/webrtc/modules/desktop_capture/window_capturer.h
@@ -52,11 +52,7 @@
 
   // Bring the selected window to the front. Returns false in case of a
   // failure or no window selected.
-  // TODO(jiayl): remove the default impl when FakeWindowCapturer is updated in
-  // Chromium.
-  virtual bool BringSelectedWindowToFront() {
-    return true;
-  }
+  virtual bool BringSelectedWindowToFront() = 0;
 };
 
 }  // namespace webrtc