[DL]: Make sure to notify observers on all frames when lifecycle happens.

This patch ensures that we notify local frames that have display locks
when lifecycle advances. Otherwise, those frame never get the notifications
and locks seem to "freeze" on acquire or commit.

R=chrishtr@chromium.org

Bug: 882663
Change-Id: I4269364ea5095e9f5eb0f4b2239105be74a3684b
Reviewed-on: https://chromium-review.googlesource.com/c/1474683
Commit-Queue: vmpstr <vmpstr@chromium.org>
Reviewed-by: Chris Harrelson <chrishtr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#632651}
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc
index 73a5ea3..5f4e0bd0 100644
--- a/third_party/blink/renderer/core/frame/local_frame_view.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -2171,8 +2171,10 @@
     return Lifecycle().GetState() == target_state;
   }
 
-  for (auto& observer : lifecycle_observers_)
-    observer->WillStartLifecycleUpdate();
+  ForAllNonThrottledLocalFrameViews([](LocalFrameView& frame_view) {
+    for (auto& observer : frame_view.lifecycle_observers_)
+      observer->WillStartLifecycleUpdate();
+  });
 
   // If we're in PrintBrowser mode, setup a print context.
   // TODO(vmpstr): It doesn't seem like we need to do this every lifecycle
@@ -2196,8 +2198,10 @@
 
   UpdateThrottlingStatusForSubtree();
 
-  for (auto& observer : lifecycle_observers_)
-    observer->DidFinishLifecycleUpdate();
+  ForAllNonThrottledLocalFrameViews([](LocalFrameView& frame_view) {
+    for (auto& observer : frame_view.lifecycle_observers_)
+      observer->DidFinishLifecycleUpdate();
+  });
 
   return Lifecycle().GetState() == target_state;
 }
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-in-iframe-expected.html b/third_party/blink/web_tests/display-lock/lock-after-append/acquire-in-iframe-expected.html
new file mode 100644
index 0000000..53621ec
--- /dev/null
+++ b/third_party/blink/web_tests/display-lock/lock-after-append/acquire-in-iframe-expected.html
@@ -0,0 +1,4 @@
+<!doctype HTML>
+
+<div id="log">PASS</div>
+<iframe></iframe>
diff --git a/third_party/blink/web_tests/display-lock/lock-after-append/acquire-in-iframe.html b/third_party/blink/web_tests/display-lock/lock-after-append/acquire-in-iframe.html
new file mode 100644
index 0000000..e348b10
--- /dev/null
+++ b/third_party/blink/web_tests/display-lock/lock-after-append/acquire-in-iframe.html
@@ -0,0 +1,36 @@
+<!doctype HTML>
+
+<div id="log"></div>
+<iframe id="frame" srcdoc='
+  <style>
+  #container {
+    contain: style layout;
+    width: 100px;
+    height: 100px;
+    background: lightblue;
+  }
+  </style>
+  <div id="container"></div>
+'></iframe>
+
+<script>
+// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait.
+if (window.testRunner)
+  window.testRunner.waitUntilDone();
+
+function finishTest(status_string) {
+  if (document.getElementById("log").innerHTML === "")
+    document.getElementById("log").innerHTML = status_string;
+  if (window.testRunner)
+    window.testRunner.notifyDone();
+}
+
+function runTest() {
+  let container = document.getElementById("frame").contentDocument.getElementById("container");
+  container.displayLock.acquire({ timeout: Infinity }).then(
+    () => { finishTest("PASS"); },
+    (e) => { finishTest("FAIL " + e.message); });
+}
+
+window.onload = runTest;
+</script>