Cherrypick #29783 and #29862 to flutter-2.8-candidate.7 (#29898)

Request from b/207432361
diff --git a/.ci.yaml b/.ci.yaml
index 12abdde..2c8d231 100644
--- a/.ci.yaml
+++ b/.ci.yaml
@@ -11,6 +11,7 @@
   - dev
   - beta
   - stable
+  - flutter-2.8-candidate.7
 
 platform_properties:
   linux:
diff --git a/flow/layers/physical_shape_layer.cc b/flow/layers/physical_shape_layer.cc
index d443448..8215f3d 100644
--- a/flow/layers/physical_shape_layer.cc
+++ b/flow/layers/physical_shape_layer.cc
@@ -46,7 +46,8 @@
 
   context->AddLayerBounds(bounds);
 
-  if (context->PushCullRect(bounds)) {
+  // Only push cull rect if there is clip.
+  if (clip_behavior_ == Clip::none || context->PushCullRect(bounds)) {
     DiffChildren(context, prev);
   }
   context->SetLayerPaintRegion(this, context->CurrentSubtreeRegion());
diff --git a/flow/layers/physical_shape_layer_unittests.cc b/flow/layers/physical_shape_layer_unittests.cc
index e81c280..9a9bafb 100644
--- a/flow/layers/physical_shape_layer_unittests.cc
+++ b/flow/layers/physical_shape_layer_unittests.cc
@@ -4,6 +4,7 @@
 
 #include "flutter/flow/layers/physical_shape_layer.h"
 
+#include "flutter/flow/testing/diff_context_test.h"
 #include "flutter/flow/testing/layer_test.h"
 #include "flutter/flow/testing/mock_layer.h"
 #include "flutter/fml/macros.h"
@@ -350,5 +351,43 @@
   EXPECT_TRUE(ReadbackResult(context, save_layer, reader, true));
 }
 
+using PhysicalShapeLayerDiffTest = DiffContextTest;
+
+TEST_F(PhysicalShapeLayerDiffTest, NoClipPaintRegion) {
+  MockLayerTree tree1;
+  const SkPath layer_path = SkPath().addRect(SkRect::MakeXYWH(0, 0, 100, 100));
+  auto layer =
+      std::make_shared<PhysicalShapeLayer>(SK_ColorGREEN, SK_ColorBLACK,
+                                           0.0f,  // elevation
+                                           layer_path, Clip::none);
+
+  const SkPath layer_path2 =
+      SkPath().addRect(SkRect::MakeXYWH(200, 200, 200, 200));
+  auto layer2 = std::make_shared<MockLayer>(layer_path2);
+  layer->Add(layer2);
+  tree1.root()->Add(layer);
+
+  auto damage = DiffLayerTree(tree1, MockLayerTree());
+  EXPECT_EQ(damage.frame_damage, SkIRect::MakeLTRB(0, 0, 400, 400));
+}
+
+TEST_F(PhysicalShapeLayerDiffTest, ClipPaintRegion) {
+  MockLayerTree tree1;
+  const SkPath layer_path = SkPath().addRect(SkRect::MakeXYWH(0, 0, 100, 100));
+  auto layer =
+      std::make_shared<PhysicalShapeLayer>(SK_ColorGREEN, SK_ColorBLACK,
+                                           0.0f,  // elevation
+                                           layer_path, Clip::hardEdge);
+
+  const SkPath layer_path2 =
+      SkPath().addRect(SkRect::MakeXYWH(200, 200, 200, 200));
+  auto layer2 = std::make_shared<MockLayer>(layer_path2);
+  layer->Add(layer2);
+  tree1.root()->Add(layer);
+
+  auto damage = DiffLayerTree(tree1, MockLayerTree());
+  EXPECT_EQ(damage.frame_damage, SkIRect::MakeLTRB(0, 0, 100, 100));
+}
+
 }  // namespace testing
 }  // namespace flutter
diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm
index 5b789d0..c38cb4c 100644
--- a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm
+++ b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm
@@ -1193,9 +1193,10 @@
       }
       completion:^(BOOL finished) {
         if (self.displayLink == currentDisplayLink) {
+          // Indicates the displaylink captured by this block is the original one,which also
+          // indicates the animation has not been interrupted from its beginning. Moreover,indicates
+          // the animation is over and there is no more animation about to exectute.
           [self invalidateDisplayLink];
-        }
-        if (finished) {
           [self removeKeyboardAnimationView];
           [self ensureViewportMetricsIsCorrect];
         }
diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm
index 84abb4b..9e27a13 100644
--- a/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm
+++ b/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm
@@ -173,9 +173,17 @@
                     @"UIKeyboardAnimationDurationUserInfoKey" : [NSNumber numberWithDouble:0.25],
                     @"UIKeyboardIsLocalUserInfoKey" : [NSNumber numberWithBool:isLocal]
                   }];
+
+  XCTestExpectation* expectation = [self expectationWithDescription:@"update viewport"];
+  OCMStub([mockEngine updateViewportMetrics:flutter::ViewportMetrics()])
+      .ignoringNonObjectArgs()
+      .andDo(^(NSInvocation* invocation) {
+        [expectation fulfill];
+      });
   id viewControllerMock = OCMPartialMock(viewController);
   [viewControllerMock keyboardWillChangeFrame:notification];
   OCMVerify([viewControllerMock startKeyBoardAnimation:0.25]);
+  [self waitForExpectationsWithTimeout:5.0 handler:nil];
 }
 
 - (void)testEnsureViewportMetricsWillInvokeAndDisplayLinkWillInvalidateInViewDidDisappear {