OOPIF: Stop using HistoryController and refactor UpdateState.

In OOPIF-enabled builds, we no longer need to track the current
HistoryEntry or use HistoryController.  Instead, the current
WebHistoryItem is stored on each RenderFrame.

This also moves UpdateState to RenderFrame{Host}, ensuring that
PageState objects can be stored on each frame's FrameNavigationEntry.

These changes only affect Chrome with --site-per-process or
--isolate-extensions.

BUG=545219, 236848

Review URL: https://codereview.chromium.org/1425303002

Cr-Commit-Position: refs/heads/master@{#357921}
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index ea91c32..0a9956f 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -3872,6 +3872,8 @@
 void WebContentsImpl::UpdateState(RenderViewHost* rvh,
                                   int32 page_id,
                                   const PageState& page_state) {
+  DCHECK(!SiteIsolationPolicy::UseSubframeNavigationEntries());
+
   // Ensure that this state update comes from a RenderViewHost that belongs to
   // this WebContents.
   // TODO(nasko): This should go through RenderFrameHost.
@@ -3892,14 +3894,7 @@
   NavigationEntryImpl* new_entry = controller_.GetEntryWithUniqueID(
       static_cast<RenderFrameHostImpl*>(rvhi->GetMainFrame())->nav_entry_id());
 
-  if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
-    // TODO(creis): We can't properly update state for cross-process subframes
-    // until PageState is decomposed into FrameStates. Until then, use the new
-    // method.
-    entry = new_entry;
-  } else {
-    DCHECK_EQ(entry, new_entry);
-  }
+  DCHECK_EQ(entry, new_entry);
 
   if (page_state == entry->GetPageState())
     return;  // Nothing to update.
@@ -4061,6 +4056,34 @@
       NotificationService::NoDetails());
 }
 
+void WebContentsImpl::UpdateStateForFrame(RenderFrameHost* render_frame_host,
+                                          const PageState& page_state) {
+  DCHECK(SiteIsolationPolicy::UseSubframeNavigationEntries());
+
+  // The state update affects the last NavigationEntry associated with the given
+  // |render_frame_host|. This may not be the last committed NavigationEntry (as
+  // in the case of an UpdateState from a frame being swapped out). We track
+  // which entry this is in the RenderFrameHost's nav_entry_id.
+  RenderFrameHostImpl* rfhi =
+      static_cast<RenderFrameHostImpl*>(render_frame_host);
+  NavigationEntryImpl* entry =
+      controller_.GetEntryWithUniqueID(rfhi->nav_entry_id());
+  if (!entry)
+    return;
+
+  FrameNavigationEntry* frame_entry =
+      entry->GetFrameEntry(rfhi->frame_tree_node());
+  if (!frame_entry)
+    return;
+
+  CHECK_EQ(frame_entry->site_instance(), rfhi->GetSiteInstance());
+  if (page_state == frame_entry->page_state())
+    return;  // Nothing to update.
+
+  frame_entry->set_page_state(page_state);
+  controller_.NotifyEntryChanged(entry);
+}
+
 void WebContentsImpl::UpdateTitle(RenderFrameHost* render_frame_host,
                                   int32 page_id,
                                   const base::string16& title,