[ios] Respect the safe area when presenting table view bubbles.

BUG=862255
TEST=On iPhoneX, rotate into landscape and open the Bookmarks.  The bubble should not overlap with the notch, in both LTR and RTL languages.

Cq-Include-Trybots: luci.chromium.try:ios-simulator-full-configs;master.tryserver.chromium.mac:ios-simulator-cronet
Change-Id: I07c2215e7b3b6e01ee8e39cae6d03054199cb205
Reviewed-on: https://chromium-review.googlesource.com/1140195
Reviewed-by: Mark Cogan <marq@chromium.org>
Commit-Queue: Rohit Rao <rohitrao@chromium.org>
Cr-Commit-Position: refs/heads/master@{#575656}
diff --git a/ios/chrome/browser/ui/table_view/table_view_presentation_controller.mm b/ios/chrome/browser/ui/table_view/table_view_presentation_controller.mm
index a5decc3..986d4d0 100644
--- a/ios/chrome/browser/ui/table_view/table_view_presentation_controller.mm
+++ b/ios/chrome/browser/ui/table_view/table_view_presentation_controller.mm
@@ -64,18 +64,36 @@
 @synthesize tableViewContainer = _tableViewContainer;
 
 - (CGRect)frameOfPresentedViewInContainerView {
-  // The tableview container should be pinned to the top, bottom, and trailing
-  // edges of the screen, with a fixed margin on those sides.
-  CGFloat containerWidth = CGRectGetWidth(self.containerView.bounds);
-  CGFloat containerHeight = CGRectGetHeight(self.containerView.bounds);
+  CGRect safeAreaBounds = self.containerView.bounds;
+  UIEdgeInsets safeAreaInsets = UIEdgeInsetsZero;
+  if (@available(iOS 11, *)) {
+    safeAreaBounds = self.containerView.safeAreaLayoutGuide.layoutFrame;
+    safeAreaInsets = self.containerView.safeAreaInsets;
+  }
 
-  CGFloat maxAvailableWidth = containerWidth - 2 * kTableViewEdgeMargin;
+  CGFloat safeAreaWidth = CGRectGetWidth(safeAreaBounds);
+  CGFloat safeAreaHeight = CGRectGetHeight(safeAreaBounds);
+
+  CGFloat maxAvailableWidth = safeAreaWidth - 2 * kTableViewEdgeMargin;
   CGFloat tableWidth = std::min(maxAvailableWidth, kTableViewMaxWidth);
 
+  // The leading edge of the bubble, in direction-independent coordinates, is
+  // equal to the width of the containerView's bounds minus:
+  // 1) The width of the safe area on the trailing edge.
+  // 2) The table view edge margin.
+  // 3) The width of the table view itself.
+  CGFloat tableLeadingX = CGRectGetWidth(self.containerView.bounds) -
+                          UIEdgeInsetsGetTrailing(safeAreaInsets) -
+                          kTableViewEdgeMargin - tableWidth;
+  CGFloat containerWidth = CGRectGetWidth(self.containerView.bounds);
+  CGFloat tableOriginY = CGRectGetMinY(safeAreaBounds) + kTableViewTopMargin;
+  CGFloat tableHeight =
+      safeAreaHeight - kTableViewTopMargin - kTableViewEdgeMargin;
+
+  // The tableview container should be pinned to the top, bottom, and trailing
+  // edges of the safe area, with a fixed margin on those sides.
   LayoutRect tableLayoutRect = LayoutRectMake(
-      containerWidth - tableWidth - kTableViewEdgeMargin, containerWidth,
-      kTableViewTopMargin, tableWidth,
-      containerHeight - kTableViewTopMargin - kTableViewEdgeMargin);
+      tableLeadingX, containerWidth, tableOriginY, tableWidth, tableHeight);
   return LayoutRectGetRect(tableLayoutRect);
 }