[Default Nav Transition] Implement the UX for BeforeUnload handler
The UX is: as long as the browser sends out the BeforeUnload IPC to the
renderer, we play the cancel animation to bring back the active page,
even if the renderer decides to not show the prompt at all (e.g., if
the page doesn't have a sticky user activation).
In real world testing, the IPC exchange is so fast (in the case where
the renderer doesn't show the prompt and acks to proceed) that the
cancel animation never gets to play a single frame (even on a debug
build). This is close the the ideal UX mentioned below.
Ideally we want to only play the cancel animation if the renderer
decides to show the prompt. While this is a better UX, it makes the
impl complicated as we need to decide what to show after the user lifts
the finger and before the renderer asks the browser to draw the prompt.
(presumably the invoke animation, then plays the cancel animation when
the renderer acks to show the prompt).
Alternatively, we could let the browser not send out the BeforeUnload
message if we know that the renderer for sure will always ack with
proceed. RFHI::HasStickyUserActivation already has the information,
though the source of truth is passed from the renderer. However we
don't really know the complication of changing the BeforeUnload flow
so this current impl is the best option for now.
Bug: 1421009
Low-Coverage-Reason: TRIVIAL_CHANGE
Change-Id: I993faba663075f5519321d69c26afa2b26404974
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5325441
Reviewed-by: Rakina Zata Amni <[email protected]>
Reviewed-by: Khushal Sagar <[email protected]>
Commit-Queue: William Liu <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1272861}
diff --git a/content/browser/renderer_host/navigator_delegate.h b/content/browser/renderer_host/navigator_delegate.h
index 4cff2fb..d89cb11 100644
--- a/content/browser/renderer_host/navigator_delegate.h
+++ b/content/browser/renderer_host/navigator_delegate.h
@@ -54,6 +54,16 @@
// of this call.
virtual void DidFinishNavigation(NavigationHandle* navigation_handle) = 0;
+ // Called when the navigation gets cancelled before it even starts (i.e.,
+ // the respective `NavigationRequest::StartNavigation()`). This can happen
+ // when the user decides to not leave the current page by interacting with the
+ // BeforeUnload dialog. Can also happen if `BeginNavigationImpl()` reaches an
+ // early out. If the navigation never starts, `DidFinishNavigation()` won't be
+ // fired. Use this API to observe the destruction of such a navigation
+ // request.
+ virtual void DidCancelNavigationBeforeStart(
+ NavigationHandle* navigation_handle) = 0;
+
// TODO(clamy): all methods below that are related to navigation
// events should go away in favor of the ones above.