New issue
Advanced search Search tips

Issue 917162 link

Starred by 1 user

Issue metadata

Status: Verified
Owner:
Closed: Dec 21
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: iOS
Pri: 2
Type: Bug



Sign in to add a comment

Loading bar does not go away when navigating forward

Project Member Reported by danyao@chromium.org, Dec 20

Issue description

A weird edge case exposed by https://crrev.com/c/1370374 and restoring session when some pages cannot be reached.

How to reproduce:
1. load http://localhost:8009/somepage in new tab
2. load https://wikipedia.org
3. Tap Back button
4. Force kill Chrome
5. Kill the local test server
6. restart app => error page is displayed, because localhost is no longer reachable
7. Tap Forward button => wikipedia is loaded
8. Tap Back button => error page is shown
9. Tap Forward button => notice loading bar is visible and never goes away, even after wikipedia is loaded

The specific localhost or wikipedia URLs don't matter. The key is to have a entry that is not reachable after session restoration, and an entry that is.
 
Cc: eugene...@chromium.org
The problem is in [CRWWebController -webViewLoadingStateDidChange]. The back/forward navigation from step 9 triggers the following KVO and WKNavigationDelegate callbacks:

- webViewLoadingStateDidChange => webView.loading 1
- webView:didStartProvisionalNavigation
- webView:didCommitProvisionalNavigation
- webViewLoadingStateDidChange => webView.loading 0
- webView:didFinishNavigation

The first |webViewLoadingStateDidChange| call early exits because webView.loading is 1. In the second call, we try to look up the navigation context associated with the pending navigation. However, since the navigation is already committed, |existingContext| is null. Just before this method returns, we call [self didFinishNavigation:nil], which calls [_navigationStates contextForNavigation:nil]. This ends up finding the NavigationContext associated with the back/forward navigation in Step 8. That navigation context was associated with nil in |_navigationStates| because it was a same-document navigation, and it was never cleared from |_navigationStates| because nil entries need to be removed explicitly.

Since the context from step 8 is used in |didFinishNavigation:| call for step 9, and the step 8 context has a restore session URL, we set |_loadingPhase| to web::PAGE_LOADED, but skips the |loadCompleteWithSuccess:| call, which would call webStateImpl->SetIsLoading(false), and causes the loading bar to disappear.

To sum up, there are two bugs here:
1. incorrect context is looked up in step 9, due to ambiguous interface of |didFinishNavigation|
2. |webViewLoadingStateDidChange| does not find the correct navigation context, because the back/forward navigation is already committed (so not returned by [self contextForPendingMainFrameNavigationWithURL}. This affects back/forward navigation that is not cached in WKWebView's page cache.
Project Member

Comment 2 by bugdroid1@chromium.org, Dec 21

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/8f2187bd41d8aa8ef5b2027d6beffcb25f48f7ea

commit 8f2187bd41d8aa8ef5b2027d6beffcb25f48f7ea
Author: Danyao Wang <danyao@chromium.org>
Date: Fri Dec 21 20:52:39 2018

[iOS] Switch |didFinishNavigation| to operate on NavigationContext.

This change prevents an edge case where |_navigationStates| contains a
non-null NavigationContext for the key |nil|, which can happen in
same-document back/forward navigation. This NavigationContext is
incorrectly used later when calling [self didFinishNavigation:nil],
when the caller expects there to be no navigation context.

Outside of this pathological case, this refactor is a no-op as it
simply extracted the lookup of NavigationContext from WKNavigation*
from this method to the caller.

Change-Id: If900a7cbed92d68a415ab2be8575f3e866f742ca
Bug:  917162 
Reviewed-on: https://chromium-review.googlesource.com/c/1387951
Commit-Queue: Danyao Wang <danyao@chromium.org>
Reviewed-by: Eugene But <eugenebut@chromium.org>
Cr-Commit-Position: refs/heads/master@{#618589}
[modify] https://crrev.com/8f2187bd41d8aa8ef5b2027d6beffcb25f48f7ea/ios/web/web_state/ui/crw_web_controller.mm

Status: Fixed (was: Started)
Status: Verified (was: Fixed)
Verified on 73.0.3672.0 Canary,  iPhoneXR  iOS 12.1.2

Looks good.

Sign in to add a comment