[DL] Reject the promise if it's acquired while connected.

This patch ensures that we don't accidentally use display locking in
mode 1, which isn't currently supported.

R=chrishtr@chromium.org

Bug: 882663
Change-Id: I2be26e2573ebe93a97bd6df4c8fcb7cd6221b28c
Reviewed-on: https://chromium-review.googlesource.com/c/1347102
Reviewed-by: Chris Harrelson <chrishtr@chromium.org>
Commit-Queue: vmpstr <vmpstr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#611859}
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_context.h b/third_party/blink/renderer/core/display_lock/display_lock_context.h
index e969928..64019e8 100644
--- a/third_party/blink/renderer/core/display_lock/display_lock_context.h
+++ b/third_party/blink/renderer/core/display_lock/display_lock_context.h
@@ -78,6 +78,10 @@
   // Called when the connected state may have changed.
   void NotifyConnectedMayHaveChanged();
 
+  // Rejects the associated promise if one exists, and clears the current queue.
+  // This effectively makes the context finalized.
+  void RejectAndCleanUp();
+
   // JavaScript interface implementation.
   void schedule(V8DisplayLockCallback*);
   DisplayLockSuspendedHandle* suspend();
@@ -106,10 +110,6 @@
   // Processes the current queue of callbacks.
   void ProcessQueue();
 
-  // Rejects the associated promise if one exists, and clears the current queue.
-  // This effectively makes the context finalized.
-  void RejectAndCleanUp();
-
   // Called by the suspended handle in order to resume context operations.
   void Resume();
 
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc
index 56dfd51b..2763a40 100644
--- a/third_party/blink/renderer/core/dom/element.cc
+++ b/third_party/blink/renderer/core/dom/element.cc
@@ -3566,7 +3566,16 @@
   auto* context = EnsureElementRareData().EnsureDisplayLockContext(
       this, GetExecutionContext());
   context->RequestLock(callback, script_state);
-  return context->Promise();
+  auto lock_promise = context->Promise();
+
+  // Only support "mode 2" display locking, which requires that the lock is
+  // acquired before the element is connected. Note that we need to call this
+  // after actually getting the promise to avoid ScriptPromiseResolver asserts.
+  // TODO(vmpstr): Implement mode 1.
+  if (isConnected())
+    context->RejectAndCleanUp();
+
+  return lock_promise;
 }
 
 DisplayLockContext* Element::GetDisplayLockContext() const {