OpenBookmarkApp() may no longer preserve window.opener in non-initial navigations |
|
Issue descriptionI'm filing this as a followup to https://chromium-review.googlesource.com/c/chromium/src/+/881836. Once that CL lands, we will swap BrowsingInstances on certain browser-initiated navigations, such as via the omnibox or bookmarks. A new BrowsingInstance means that scripting relationships with other tabs (e.g., window.opener) will be severed. This is desirable to prevent unwanted process sharing in issue 803367 . I noticed that some code used by bookmark apps / desktop PWA in BookmarkAppNavigationThrottle::OpenInAppWindowAndCloseTabIfNecessary may be problematic after my CL lands [1]. If an existing tab/app does a window.open() to a URL covered by a bookmark app, and the window.open() targets a new window, we're ok: ReparentWebContentsAndResume() will reparent the new WebContents into an app Browser and continue the existing renderer-initiated navigation there. (In fact, this was just recently fixed by ortuno@'s https://chromium-review.googlesource.com/923902.) However, I think we should check what happens if window.open() targets an *existing* window (e.g., by name as in window.open(url, "name")), in which case we call OpenBookmarkApp(), which cancels the existing renderer-initiated navigation and restarts it as a browser-initiated, AUTO_BOOKMARK navigation in a new (app) WebContents. (Page transition set here: [2].) As a result, we can't distinguish this from a user clicking on a regular bookmark and swap BrowsingInstances, which breaks window.opener. I'm not actually sure if we want to preserve the opener in that case -- I saw issue 804881, but the scenario here is a bit different: maybe something like a tab trying to navigate a window with app1 to another app2, which results in opening a new window for app2. I'm not sure if there are other scenarios in which OpenBookmarkApp() needs to be used - currently this isn't covered by any tests. But if it's desirable app2 to preserve the window.opener, we'll need to find a way to tell RenderFrameHostManager::IsBrowsingInstanceSwapAllowedForPageTransition() to not swap BrowsingInstances in this case. The latter might be tricky: we could skips BrowsingInstance swaps in app windows, but at the time this function is called (as part of chrome::Navigate()), the is_app() bit on Browser is not updated yet -- that happens later when Browser actually adds the WebContents to its tab strip, which happens after navigating. Changing those navigations to something other than AUTO_BOOKMARK is probably undesirable per https://chromium.googlesource.com/chromium/src/+/f3a29a53dd05161c7e9a36f1cd55497cc2ab0239. Bookmark app URLs don't use app/extension processes so we can't check for effective URLs either. So some investigation is needed to find a good way to plumb information about these cases, if we care about them. Ideally, we would just get rid of OpenBookmarkApp() altogether, and always use the path in ReparentWebContentsAndResume(). Restarting a renderer-initiated navigation as a browser-initiated navigation seems fishy, so ideally we would just never do it. Not sure if that's feasible though. [1] https://cs.chromium.org/chromium/src/chrome/browser/extensions/bookmark_app_experimental_navigation_throttle.cc?l=473&rcl=ef8c76c0202de4b984bccf82e67a6b21329a81be [2] https://cs.chromium.org/chromium/src/chrome/browser/ui/extensions/application_launch.cc?l=212&rcl=8292a417e26eb076cbbbbe7403edc1e6b994ba35
,
Mar 6 2018
Thanks for the additional context! > That is strange. I was under the impression that setting a Browser as an "App Browser" could only be done at Browser construction time. is_app() is implemented as Sorry, I was not precise. You're right that the Browser app_name_ is set at creation time (in this case, in OpenApplicationWindow()), and this is what is_app() is based on. What I observed was that during chrome::Navigate(), when we make the decision about which process to use for the navigation (RenderFrameHostManager::DetermineSiteInstanceForURL), calling out to Browser from the WebContents (via WebContentsDelegate) and then checking is_app() there returns *false* for the OpenBookmarkApp() path. This seemed strange, and I haven't looksed closely, but I suspect that's because the WebContents created in chrome::Navigate is initially owned by a ScopedTargetContentsOwner inside that function, and it only becomes associated with the app Browser when it calls params->browser->tab_strip_model()->AddWebContents() (probably here: [1]), which happens after the navigation has already been kicked off by LoadURLInContents(). [1] https://cs.chromium.org/chromium/src/chrome/browser/ui/browser.cc?l=971&rcl=caf69fed21cab23246f1c7c4940154ea21f7641f |
|
►
Sign in to add a comment |
|
Comment 1 by ortuno@chromium.org
, Mar 5 2018Components: UI>Browser>WebAppInstalls