Allow RenderWidgetHostViewMac::SyncGetFirstRectForRange to block.

This lets -[RenderWidgetHostViewCocoa
firstRectForCharacterRange:actualRange:] block, which currently DCHECKs
when the requested range isn't in the active selection.

Bug: 42434, 121917
Change-Id: I905650b33d065d68ceb13c1a73a74efcb41ecffa
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1614702
Reviewed-by: Mark Mentovai <mark@chromium.org>
Reviewed-by: Elly Fong-Jones <ellyjones@chromium.org>
Commit-Queue: Sidney San Martín <sdy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#661482}
diff --git a/base/threading/thread_restrictions.h b/base/threading/thread_restrictions.h
index f80d144..d328f05 100644
--- a/base/threading/thread_restrictions.h
+++ b/base/threading/thread_restrictions.h
@@ -140,6 +140,7 @@
 class DWriteFontLookupTableBuilder;
 class GpuProcessTransportFactory;
 class NestedMessagePumpAndroid;
+class RenderWidgetHostViewMac;
 class RTCVideoDecoder;
 class RTCVideoDecoderAdapter;
 class RTCVideoEncoder;
@@ -338,6 +339,7 @@
   friend class android_webview::ScopedAllowInitGLBindings;
   friend class content::BrowserProcessSubThread;
   friend class content::GpuProcessTransportFactory;
+  friend class content::RenderWidgetHostViewMac;  // http://crbug.com/121917
   friend class content::WebContentsViewMac;
   friend class cronet::CronetPrefsManager;
   friend class cronet::CronetURLRequestContext;
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm
index c1ec9d0..c6f096b 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -1801,6 +1801,8 @@
   *success = true;
   if (!GetCachedFirstRectForCharacterRange(requested_range, rect,
                                            actual_range)) {
+    // https://crbug.com/121917
+    base::ScopedAllowBlocking allow_wait;
     *rect = TextInputClientMac::GetInstance()->GetFirstRectForRange(
         GetFocusedWidget(), requested_range);
     // TODO(thakis): Pipe |actualRange| through TextInputClientMac machinery.
diff --git a/content/browser/renderer_host/render_widget_host_view_mac_browsertest.mm b/content/browser/renderer_host/render_widget_host_view_mac_browsertest.mm
index a3a01867..4c51146 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac_browsertest.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac_browsertest.mm
@@ -63,4 +63,24 @@
   EXPECT_EQ(base::ASCIIToUTF16("Hello\nWorld"), waiter.text());
 }
 
+// Test that -firstRectForCharacterRange:actualRange: works when the range
+// isn't in the active selection, which requres a sync IPC to the renderer.
+IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewMacTest,
+                       GetFirstRectForCharacterRangeUncached) {
+  GURL url("data:text/html,Hello");
+  EXPECT_TRUE(NavigateToURL(shell(), url));
+
+  RenderWidgetHostView* rwhv =
+      shell()->web_contents()->GetMainFrame()->GetView();
+  RenderWidgetHostViewMac* rwhv_mac =
+      static_cast<RenderWidgetHostViewMac*>(rwhv);
+
+  NSRect rect =
+      [rwhv_mac->cocoa_view() firstRectForCharacterRange:NSMakeRange(2, 1)
+                                             actualRange:nullptr];
+  EXPECT_GT(NSMinX(rect), 0);
+  EXPECT_GT(NSWidth(rect), 0);
+  EXPECT_GT(NSHeight(rect), 0);
+}
+
 }  // namespace content