Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / history / history_tab_helper.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/history/history_tab_helper.h"
6
7 #include <utility>
8
9 #include "chrome/browser/history/history_service.h"
10 #include "chrome/browser/history/history_service_factory.h"
11 #include "chrome/browser/prerender/prerender_contents.h"
12 #include "chrome/browser/prerender/prerender_manager.h"
13 #include "chrome/browser/prerender/prerender_manager_factory.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/common/render_messages.h"
16 #include "content/public/browser/navigation_details.h"
17 #include "content/public/browser/navigation_entry.h"
18 #include "content/public/browser/web_contents.h"
19 #include "content/public/browser/web_contents_delegate.h"
20 #include "content/public/common/frame_navigate_params.h"
21
22 #if !defined(OS_ANDROID)
23 #include "chrome/browser/ui/browser.h"
24 #include "chrome/browser/ui/browser_finder.h"
25 #endif
26
27 using content::NavigationEntry;
28 using content::WebContents;
29
30 DEFINE_WEB_CONTENTS_USER_DATA_KEY(HistoryTabHelper);
31
32 HistoryTabHelper::HistoryTabHelper(WebContents* web_contents)
33     : content::WebContentsObserver(web_contents),
34       received_page_title_(false) {
35 }
36
37 HistoryTabHelper::~HistoryTabHelper() {
38 }
39
40 void HistoryTabHelper::UpdateHistoryForNavigation(
41     const history::HistoryAddPageArgs& add_page_args) {
42   HistoryService* hs = GetHistoryService();
43   if (hs)
44     GetHistoryService()->AddPage(add_page_args);
45 }
46
47 void HistoryTabHelper::UpdateHistoryPageTitle(const NavigationEntry& entry) {
48   HistoryService* hs = GetHistoryService();
49   if (hs)
50     hs->SetPageTitle(entry.GetVirtualURL(),
51                      entry.GetTitleForDisplay(std::string()));
52 }
53
54 history::HistoryAddPageArgs
55 HistoryTabHelper::CreateHistoryAddPageArgs(
56     const GURL& virtual_url,
57     base::Time timestamp,
58     bool did_replace_entry,
59     const content::FrameNavigateParams& params) {
60   history::HistoryAddPageArgs add_page_args(
61       params.url, timestamp, web_contents(), params.page_id,
62       params.referrer.url, params.redirects, params.transition,
63       history::SOURCE_BROWSED, did_replace_entry);
64   if (content::PageTransitionIsMainFrame(params.transition) &&
65       virtual_url != params.url) {
66     // Hack on the "virtual" URL so that it will appear in history. For some
67     // types of URLs, we will display a magic URL that is different from where
68     // the page is actually navigated. We want the user to see in history what
69     // they saw in the URL bar, so we add the virtual URL as a redirect.  This
70     // only applies to the main frame, as the virtual URL doesn't apply to
71     // sub-frames.
72     add_page_args.url = virtual_url;
73     if (!add_page_args.redirects.empty())
74       add_page_args.redirects.back() = virtual_url;
75   }
76   return add_page_args;
77 }
78
79 void HistoryTabHelper::DidNavigateMainFrame(
80     const content::LoadCommittedDetails& details,
81     const content::FrameNavigateParams& params) {
82   // Allow the new page to set the title again.
83   received_page_title_ = false;
84 }
85
86 void HistoryTabHelper::DidNavigateAnyFrame(
87     const content::LoadCommittedDetails& details,
88     const content::FrameNavigateParams& params) {
89   // Update history. Note that this needs to happen after the entry is complete,
90   // which WillNavigate[Main,Sub]Frame will do before this function is called.
91   if (!params.should_update_history)
92     return;
93
94   // Most of the time, the displayURL matches the loaded URL, but for about:
95   // URLs, we use a data: URL as the real value.  We actually want to save the
96   // about: URL to the history db and keep the data: URL hidden. This is what
97   // the WebContents' URL getter does.
98   const history::HistoryAddPageArgs& add_page_args =
99       CreateHistoryAddPageArgs(
100           web_contents()->GetURL(), details.entry->GetTimestamp(),
101           details.did_replace_entry, params);
102
103   prerender::PrerenderManager* prerender_manager =
104       prerender::PrerenderManagerFactory::GetForProfile(
105           Profile::FromBrowserContext(web_contents()->GetBrowserContext()));
106   if (prerender_manager) {
107     prerender::PrerenderContents* prerender_contents =
108         prerender_manager->GetPrerenderContents(web_contents());
109     if (prerender_contents) {
110       prerender_contents->DidNavigate(add_page_args);
111       return;
112     }
113   }
114
115 #if !defined(OS_ANDROID)
116   // Don't update history if this web contents isn't associatd with a tab.
117   Browser* browser = chrome::FindBrowserWithWebContents(web_contents());
118   if (!browser || browser->is_app())
119     return;
120 #endif
121
122   UpdateHistoryForNavigation(add_page_args);
123 }
124
125 void HistoryTabHelper::TitleWasSet(NavigationEntry* entry, bool explicit_set) {
126   if (received_page_title_)
127     return;
128
129   if (entry) {
130     UpdateHistoryPageTitle(*entry);
131     received_page_title_ = explicit_set;
132   }
133 }
134
135 HistoryService* HistoryTabHelper::GetHistoryService() {
136   Profile* profile =
137       Profile::FromBrowserContext(web_contents()->GetBrowserContext());
138   if (profile->IsOffTheRecord())
139     return NULL;
140
141   return HistoryServiceFactory::GetForProfile(profile,
142                                               Profile::IMPLICIT_ACCESS);
143 }
144
145 void HistoryTabHelper::WebContentsDestroyed() {
146   // We update the history for this URL.
147   WebContents* tab = web_contents();
148   Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
149   if (profile->IsOffTheRecord())
150     return;
151
152   HistoryService* hs =
153       HistoryServiceFactory::GetForProfile(profile, Profile::IMPLICIT_ACCESS);
154   if (hs) {
155     NavigationEntry* entry = tab->GetController().GetLastCommittedEntry();
156     if (entry) {
157       hs->UpdateWithPageEndTime(tab, entry->GetPageID(), tab->GetURL(),
158                                 base::Time::Now());
159     }
160     hs->ClearCachedDataForContextID(tab);
161   }
162 }