[ios] Don't resize overlay presentation container if insignificant

Upon layout, the container view of the Infobar banner view is resized
to match the size of the banner. But then a subsequently triggered
relayout may have a new banner frame size that is small enough to cause
an infinite loop. Thus, container resizing is only done if the height
and width of the new calculated banner frame are different by more
than 0.01.

[email protected]

(cherry picked from commit 7c051ee54d889fdc605f3718a15f8b01413cf925)

Bug: 1129761
Change-Id: I0b397c63763c392e021bcf54fb7c7a2df8f872eb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2432661
Reviewed-by: Mike Dougherty <[email protected]>
Reviewed-by: Rohit Rao <[email protected]>
Commit-Queue: Chris Lu <[email protected]>
Cr-Original-Commit-Position: refs/heads/master@{#814502}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2463645
Reviewed-by: Chris Lu <[email protected]>
Cr-Commit-Position: refs/branch-heads/4280@{#191}
Cr-Branched-From: ea420fb963f9658c9969b6513c56b8f47efa1a2a-refs/heads/master@{#812852}
diff --git a/ios/chrome/browser/ui/infobars/presentation/infobar_banner_presentation_controller.mm b/ios/chrome/browser/ui/infobars/presentation/infobar_banner_presentation_controller.mm
index 0f6c63ff..a1b01f258f 100644
--- a/ios/chrome/browser/ui/infobars/presentation/infobar_banner_presentation_controller.mm
+++ b/ios/chrome/browser/ui/infobars/presentation/infobar_banner_presentation_controller.mm
@@ -19,6 +19,9 @@
 const CGFloat kContainerMaxWidth = 398;
 // The presented view maximum height.
 const CGFloat kContainerMaxHeight = 230;
+// Minimum height or width frame change that should warrant a resizing of the
+// container view in response to a relayout.
+const CGFloat kMinimumSizeChange = 0.01;
 }
 
 @interface InfobarBannerPresentationController ()
@@ -104,8 +107,18 @@
   CGRect bannerFrame = self.bannerFrame;
   UIView* containerView = self.containerView;
   UIWindow* window = containerView.window;
-  containerView.frame = [containerView.superview convertRect:bannerFrame
-                                                    fromView:window];
+
+  CGRect newFrame = [containerView.superview convertRect:bannerFrame
+                                                fromView:window];
+  // Make sure new calculate frame has changed enough to warrant a rerender.
+  // Otherwise, an infinite loop is possible.
+  if (std::fabs(newFrame.size.height - containerView.frame.size.height) >
+          kMinimumSizeChange ||
+      std::fabs(newFrame.size.width - containerView.frame.size.width) >
+          kMinimumSizeChange) {
+    containerView.frame = newFrame;
+  }
+
   UIView* bannerView = self.presentedView;
   bannerView.frame = [bannerView.superview convertRect:bannerFrame
                                               fromView:window];