| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/tabs/tab_finder.h" | 5 #include "chrome/browser/tabs/tab_finder.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 #include "content/public/browser/notification_source.h" | 21 #include "content/public/browser/notification_source.h" |
| 22 #include "content/public/browser/notification_types.h" | 22 #include "content/public/browser/notification_types.h" |
| 23 #include "content/public/browser/web_contents_observer.h" | 23 #include "content/public/browser/web_contents_observer.h" |
| 24 #include "content/public/common/frame_navigate_params.h" | 24 #include "content/public/common/frame_navigate_params.h" |
| 25 #include "content/public/common/page_transition_types.h" | 25 #include "content/public/common/page_transition_types.h" |
| 26 | 26 |
| 27 using content::WebContents; | 27 using content::WebContents; |
| 28 | 28 |
| 29 class TabFinder::WebContentsObserverImpl : public content::WebContentsObserver { | 29 class TabFinder::WebContentsObserverImpl : public content::WebContentsObserver { |
| 30 public: | 30 public: |
| 31 WebContentsObserverImpl(TabContents* tab, TabFinder* finder); | 31 WebContentsObserverImpl(WebContents* tab, TabFinder* finder); |
| 32 virtual ~WebContentsObserverImpl(); | 32 virtual ~WebContentsObserverImpl(); |
| 33 | 33 |
| 34 TabContents* tab_contents() { | 34 WebContents* web_contents() { |
| 35 return content::WebContentsObserver::tab_contents(); | 35 return content::WebContentsObserver::web_contents(); |
| 36 } | 36 } |
| 37 | 37 |
| 38 // content::WebContentsObserver overrides: | 38 // content::WebContentsObserver overrides: |
| 39 virtual void DidNavigateAnyFrame( | 39 virtual void DidNavigateAnyFrame( |
| 40 const content::LoadCommittedDetails& details, | 40 const content::LoadCommittedDetails& details, |
| 41 const content::FrameNavigateParams& params) OVERRIDE; | 41 const content::FrameNavigateParams& params) OVERRIDE; |
| 42 virtual void WebContentsDestroyed(WebContents* tab) OVERRIDE; | 42 virtual void WebContentsDestroyed(WebContents* tab) OVERRIDE; |
| 43 | 43 |
| 44 private: | 44 private: |
| 45 TabFinder* finder_; | 45 TabFinder* finder_; |
| 46 | 46 |
| 47 DISALLOW_COPY_AND_ASSIGN(WebContentsObserverImpl); | 47 DISALLOW_COPY_AND_ASSIGN(WebContentsObserverImpl); |
| 48 }; | 48 }; |
| 49 | 49 |
| 50 TabFinder::WebContentsObserverImpl::WebContentsObserverImpl( | 50 TabFinder::WebContentsObserverImpl::WebContentsObserverImpl( |
| 51 TabContents* tab, | 51 WebContents* tab, |
| 52 TabFinder* finder) | 52 TabFinder* finder) |
| 53 : content::WebContentsObserver(tab), | 53 : content::WebContentsObserver(tab), |
| 54 finder_(finder) { | 54 finder_(finder) { |
| 55 } | 55 } |
| 56 | 56 |
| 57 TabFinder::WebContentsObserverImpl::~WebContentsObserverImpl() { | 57 TabFinder::WebContentsObserverImpl::~WebContentsObserverImpl() { |
| 58 } | 58 } |
| 59 | 59 |
| 60 void TabFinder::WebContentsObserverImpl::DidNavigateAnyFrame( | 60 void TabFinder::WebContentsObserverImpl::DidNavigateAnyFrame( |
| 61 const content::LoadCommittedDetails& details, | 61 const content::LoadCommittedDetails& details, |
| 62 const content::FrameNavigateParams& params) { | 62 const content::FrameNavigateParams& params) { |
| 63 finder_->DidNavigateAnyFrame(tab_contents(), details, params); | 63 finder_->DidNavigateAnyFrame(web_contents(), details, params); |
| 64 } | 64 } |
| 65 | 65 |
| 66 void TabFinder::WebContentsObserverImpl::WebContentsDestroyed( | 66 void TabFinder::WebContentsObserverImpl::WebContentsDestroyed( |
| 67 WebContents* tab) { | 67 WebContents* tab) { |
| 68 finder_->TabDestroyed(this); | 68 finder_->TabDestroyed(this); |
| 69 delete this; | 69 delete this; |
| 70 } | 70 } |
| 71 | 71 |
| 72 // static | 72 // static |
| 73 TabFinder* TabFinder::GetInstance() { | 73 TabFinder* TabFinder::GetInstance() { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 return NULL; | 115 return NULL; |
| 116 } | 116 } |
| 117 | 117 |
| 118 void TabFinder::Observe(int type, | 118 void TabFinder::Observe(int type, |
| 119 const content::NotificationSource& source, | 119 const content::NotificationSource& source, |
| 120 const content::NotificationDetails& details) { | 120 const content::NotificationDetails& details) { |
| 121 DCHECK_EQ(type, content::NOTIFICATION_TAB_PARENTED); | 121 DCHECK_EQ(type, content::NOTIFICATION_TAB_PARENTED); |
| 122 | 122 |
| 123 // The tab was added to a browser. Query for its state now. | 123 // The tab was added to a browser. Query for its state now. |
| 124 TabContentsWrapper* tab = content::Source<TabContentsWrapper>(source).ptr(); | 124 TabContentsWrapper* tab = content::Source<TabContentsWrapper>(source).ptr(); |
| 125 TrackTab(tab->tab_contents()); | 125 TrackTab(tab->web_contents()); |
| 126 } | 126 } |
| 127 | 127 |
| 128 TabFinder::TabFinder() { | 128 TabFinder::TabFinder() { |
| 129 registrar_.Add(this, content::NOTIFICATION_TAB_PARENTED, | 129 registrar_.Add(this, content::NOTIFICATION_TAB_PARENTED, |
| 130 content::NotificationService::AllSources()); | 130 content::NotificationService::AllSources()); |
| 131 } | 131 } |
| 132 | 132 |
| 133 TabFinder::~TabFinder() { | 133 TabFinder::~TabFinder() { |
| 134 STLDeleteElements(&tab_contents_observers_); | 134 STLDeleteElements(&tab_contents_observers_); |
| 135 } | 135 } |
| 136 | 136 |
| 137 void TabFinder::DidNavigateAnyFrame( | 137 void TabFinder::DidNavigateAnyFrame( |
| 138 TabContents* source, | 138 WebContents* source, |
| 139 const content::LoadCommittedDetails& details, | 139 const content::LoadCommittedDetails& details, |
| 140 const content::FrameNavigateParams& params) { | 140 const content::FrameNavigateParams& params) { |
| 141 CancelRequestsFor(source); | 141 CancelRequestsFor(source); |
| 142 | 142 |
| 143 if (content::PageTransitionIsRedirect(params.transition)) { | 143 if (content::PageTransitionIsRedirect(params.transition)) { |
| 144 // If this is a redirect, we need to go to the db to get the start. | 144 // If this is a redirect, we need to go to the db to get the start. |
| 145 FetchRedirectStart(source); | 145 FetchRedirectStart(source); |
| 146 } else if (params.redirects.size() > 1 || | 146 } else if (params.redirects.size() > 1 || |
| 147 params.redirects[0] != details.entry->GetURL()) { | 147 params.redirects[0] != details.entry->GetURL()) { |
| 148 tab_contents_to_url_[source] = params.redirects[0]; | 148 web_contents_to_url_[source] = params.redirects[0]; |
| 149 } | 149 } |
| 150 } | 150 } |
| 151 | 151 |
| 152 bool TabFinder::TabMatchesURL(TabContents* tab_contents, const GURL& url) { | 152 bool TabFinder::TabMatchesURL(WebContents* tab_contents, const GURL& url) { |
| 153 if (tab_contents->GetURL() == url) | 153 if (tab_contents->GetURL() == url) |
| 154 return true; | 154 return true; |
| 155 | 155 |
| 156 TabContentsToURLMap::const_iterator i = | 156 WebContentsToURLMap::const_iterator i = |
| 157 tab_contents_to_url_.find(tab_contents); | 157 web_contents_to_url_.find(tab_contents); |
| 158 return i != tab_contents_to_url_.end() && i->second == url; | 158 return i != web_contents_to_url_.end() && i->second == url; |
| 159 } | 159 } |
| 160 | 160 |
| 161 TabContents* TabFinder::FindTabInBrowser(Browser* browser, const GURL& url) { | 161 TabContents* TabFinder::FindTabInBrowser(Browser* browser, const GURL& url) { |
| 162 if (!browser->is_type_tabbed()) | 162 if (!browser->is_type_tabbed()) |
| 163 return NULL; | 163 return NULL; |
| 164 | 164 |
| 165 for (int i = 0; i < browser->tab_count(); ++i) { | 165 for (int i = 0; i < browser->tab_count(); ++i) { |
| 166 if (TabMatchesURL(browser->GetTabContentsAt(i), url)) | 166 if (TabMatchesURL(browser->GetTabContentsAt(i), url)) |
| 167 return browser->GetTabContentsAt(i); | 167 return browser->GetTabContentsAt(i); |
| 168 } | 168 } |
| 169 return NULL; | 169 return NULL; |
| 170 } | 170 } |
| 171 | 171 |
| 172 void TabFinder::TrackTab(TabContents* tab) { | 172 void TabFinder::TrackTab(WebContents* tab) { |
| 173 for (WebContentsObservers::const_iterator i = tab_contents_observers_.begin(); | 173 for (WebContentsObservers::const_iterator i = tab_contents_observers_.begin(); |
| 174 i != tab_contents_observers_.end(); ++i) { | 174 i != tab_contents_observers_.end(); ++i) { |
| 175 if ((*i)->tab_contents() == tab) { | 175 if ((*i)->web_contents() == tab) { |
| 176 // Already tracking the tab. | 176 // Already tracking the tab. |
| 177 return; | 177 return; |
| 178 } | 178 } |
| 179 } | 179 } |
| 180 WebContentsObserverImpl* observer = new WebContentsObserverImpl(tab, this); | 180 WebContentsObserverImpl* observer = new WebContentsObserverImpl(tab, this); |
| 181 tab_contents_observers_.insert(observer); | 181 tab_contents_observers_.insert(observer); |
| 182 FetchRedirectStart(tab); | 182 FetchRedirectStart(tab); |
| 183 } | 183 } |
| 184 | 184 |
| 185 void TabFinder::TabDestroyed(WebContentsObserverImpl* observer) { | 185 void TabFinder::TabDestroyed(WebContentsObserverImpl* observer) { |
| 186 DCHECK_GT(tab_contents_observers_.count(observer), 0u); | 186 DCHECK_GT(tab_contents_observers_.count(observer), 0u); |
| 187 tab_contents_observers_.erase(observer); | 187 tab_contents_observers_.erase(observer); |
| 188 } | 188 } |
| 189 | 189 |
| 190 void TabFinder::CancelRequestsFor(TabContents* tab_contents) { | 190 void TabFinder::CancelRequestsFor(WebContents* web_contents) { |
| 191 Profile* profile = | 191 Profile* profile = |
| 192 Profile::FromBrowserContext(tab_contents->GetBrowserContext()); | 192 Profile::FromBrowserContext(web_contents->GetBrowserContext()); |
| 193 if (profile->IsOffTheRecord()) | 193 if (profile->IsOffTheRecord()) |
| 194 return; | 194 return; |
| 195 | 195 |
| 196 tab_contents_to_url_.erase(tab_contents); | 196 web_contents_to_url_.erase(web_contents); |
| 197 | 197 |
| 198 HistoryService* history = profile->GetHistoryService( | 198 HistoryService* history = profile->GetHistoryService( |
| 199 Profile::EXPLICIT_ACCESS); | 199 Profile::EXPLICIT_ACCESS); |
| 200 if (history) { | 200 if (history) { |
| 201 CancelableRequestProvider::Handle request_handle; | 201 CancelableRequestProvider::Handle request_handle; |
| 202 if (callback_consumer_.GetFirstHandleForClientData(tab_contents, | 202 if (callback_consumer_.GetFirstHandleForClientData(web_contents, |
| 203 &request_handle)) { | 203 &request_handle)) { |
| 204 history->CancelRequest(request_handle); | 204 history->CancelRequest(request_handle); |
| 205 } | 205 } |
| 206 } | 206 } |
| 207 } | 207 } |
| 208 | 208 |
| 209 void TabFinder::FetchRedirectStart(TabContents* tab) { | 209 void TabFinder::FetchRedirectStart(WebContents* tab) { |
| 210 Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext()); | 210 Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext()); |
| 211 if (profile->IsOffTheRecord()) | 211 if (profile->IsOffTheRecord()) |
| 212 return; | 212 return; |
| 213 | 213 |
| 214 NavigationEntry* committed_entry = | 214 NavigationEntry* committed_entry = |
| 215 tab->GetController().GetLastCommittedEntry(); | 215 tab->GetController().GetLastCommittedEntry(); |
| 216 if (!committed_entry || committed_entry->GetURL().is_empty()) | 216 if (!committed_entry || committed_entry->GetURL().is_empty()) |
| 217 return; | 217 return; |
| 218 | 218 |
| 219 HistoryService* history = profile->GetHistoryService( | 219 HistoryService* history = profile->GetHistoryService( |
| 220 Profile::EXPLICIT_ACCESS); | 220 Profile::EXPLICIT_ACCESS); |
| 221 if (history) { | 221 if (history) { |
| 222 CancelableRequestProvider::Handle request_handle = | 222 CancelableRequestProvider::Handle request_handle = |
| 223 history->QueryRedirectsTo( | 223 history->QueryRedirectsTo( |
| 224 committed_entry->GetURL(), | 224 committed_entry->GetURL(), |
| 225 &callback_consumer_, | 225 &callback_consumer_, |
| 226 base::Bind(&TabFinder::QueryRedirectsToComplete, | 226 base::Bind(&TabFinder::QueryRedirectsToComplete, |
| 227 base::Unretained(this))); | 227 base::Unretained(this))); |
| 228 callback_consumer_.SetClientData(history, request_handle, tab); | 228 callback_consumer_.SetClientData(history, request_handle, tab); |
| 229 } | 229 } |
| 230 } | 230 } |
| 231 | 231 |
| 232 void TabFinder::QueryRedirectsToComplete(HistoryService::Handle handle, | 232 void TabFinder::QueryRedirectsToComplete(HistoryService::Handle handle, |
| 233 GURL url, | 233 GURL url, |
| 234 bool success, | 234 bool success, |
| 235 history::RedirectList* redirects) { | 235 history::RedirectList* redirects) { |
| 236 if (success && !redirects->empty()) { | 236 if (success && !redirects->empty()) { |
| 237 TabContents* tab_contents = | 237 WebContents* web_contents = |
| 238 callback_consumer_.GetClientDataForCurrentRequest(); | 238 callback_consumer_.GetClientDataForCurrentRequest(); |
| 239 DCHECK(tab_contents); | 239 DCHECK(web_contents); |
| 240 tab_contents_to_url_[tab_contents] = redirects->back(); | 240 web_contents_to_url_[web_contents] = redirects->back(); |
| 241 } | 241 } |
| 242 } | 242 } |
| OLD | NEW |