1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Use of this source code is governed by a BSD-style license that can be
3dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// found in the LICENSE file.
4dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
5dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/tabs/tab_finder.h"
6dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
7dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "base/command_line.h"
8dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "base/stl_util-inl.h"
9dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/history/history.h"
10dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/profiles/profile.h"
11dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/ui/browser.h"
12dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/ui/browser_list.h"
13dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/common/chrome_switches.h"
14dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/navigation_entry.h"
15dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents.h"
16dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents_observer.h"
17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_service.h"
18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_source.h"
19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_type.h"
20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/page_transition_types.h"
21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/view_messages.h"
22dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
23dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenclass TabFinder::TabContentsObserverImpl : public TabContentsObserver {
24dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen public:
25dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  TabContentsObserverImpl(TabContents* tab, TabFinder* finder);
26dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  virtual ~TabContentsObserverImpl();
27dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
28dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  TabContents* tab_contents() { return TabContentsObserver::tab_contents(); }
29dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
30dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // TabContentsObserver overrides:
31dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  virtual void DidNavigateAnyFramePostCommit(
32dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      const NavigationController::LoadCommittedDetails& details,
33dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      const ViewHostMsg_FrameNavigate_Params& params) OVERRIDE;
34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void TabContentsDestroyed(TabContents* tab) OVERRIDE;
35dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
36dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen private:
37dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  TabFinder* finder_;
38dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
39dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DISALLOW_COPY_AND_ASSIGN(TabContentsObserverImpl);
40dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen};
41dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
42dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenTabFinder::TabContentsObserverImpl::TabContentsObserverImpl(
43dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    TabContents* tab,
44dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    TabFinder* finder)
45dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    : TabContentsObserver(tab),
46dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      finder_(finder) {
47dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
48dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
49dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenTabFinder::TabContentsObserverImpl::~TabContentsObserverImpl() {
50dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
51dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
52dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid TabFinder::TabContentsObserverImpl::DidNavigateAnyFramePostCommit(
53dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    const NavigationController::LoadCommittedDetails& details,
54dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    const ViewHostMsg_FrameNavigate_Params& params) {
55dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  finder_->DidNavigateAnyFramePostCommit(tab_contents(), details, params);
56dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
57dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid TabFinder::TabContentsObserverImpl::TabContentsDestroyed(
59dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    TabContents* tab) {
60dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  finder_->TabDestroyed(this);
61dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  delete this;
62dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
63dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
64dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// static
65dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenTabFinder* TabFinder::GetInstance() {
66dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  return IsEnabled() ? Singleton<TabFinder>::get() : NULL;
67dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
68dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
69dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// static
70dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool TabFinder::IsEnabled() {
71dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  return CommandLine::ForCurrentProcess()->HasSwitch(
72dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      switches::kFocusExistingTabOnOpen);
73dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
74dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
75dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenTabContents* TabFinder::FindTab(Browser* browser,
76dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                const GURL& url,
77dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                Browser** existing_browser) {
78dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (browser->profile()->IsOffTheRecord())
79dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    return NULL;
80dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
81dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // If the current tab matches the url, ignore it and let the user reload the
82dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // existing tab.
83dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  TabContents* selected_tab = browser->GetSelectedTabContents();
84dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (TabMatchesURL(selected_tab, url))
85dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    return NULL;
86dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
87dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // See if the current browser has a tab matching the specified url.
88dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  TabContents* tab_in_browser = FindTabInBrowser(browser, url);
89dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (tab_in_browser) {
90dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    *existing_browser = browser;
91dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    return tab_in_browser;
92dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
93dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
94dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Then check other browsers.
95dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  for (BrowserList::const_iterator i = BrowserList::begin();
96dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen       i != BrowserList::end(); ++i) {
97dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    if (!(*i)->profile()->IsOffTheRecord()) {
98dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      tab_in_browser = FindTabInBrowser(*i, url);
99dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      if (tab_in_browser) {
100dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        *existing_browser = *i;
101dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        return tab_in_browser;
102dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      }
103dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    }
104dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
105dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
106dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  return NULL;
107dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
108dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
109dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid TabFinder::Observe(NotificationType type,
110dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                        const NotificationSource& source,
111dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                        const NotificationDetails& details) {
112dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK_EQ(type.value, NotificationType::TAB_PARENTED);
113dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
114dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // The tab was added to a browser. Query for its state now.
115dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  NavigationController* controller =
116dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      Source<NavigationController>(source).ptr();
117dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  TrackTab(controller->tab_contents());
118dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
119dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
120dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenTabFinder::TabFinder() {
121dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  registrar_.Add(this, NotificationType::TAB_PARENTED,
122dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                 NotificationService::AllSources());
123dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
124dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
125dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenTabFinder::~TabFinder() {
126dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  STLDeleteElements(&tab_contents_observers_);
127dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
128dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
129dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid TabFinder::Init() {
130dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  for (BrowserList::const_iterator i = BrowserList::begin();
131dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen       i != BrowserList::end(); ++i) {
132dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    if (!(*i)->profile()->IsOffTheRecord())
133dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      TrackBrowser(*i);
134dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
135dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
136dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
137dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid TabFinder::DidNavigateAnyFramePostCommit(
138dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    TabContents* source,
139dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    const NavigationController::LoadCommittedDetails& details,
140dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    const ViewHostMsg_FrameNavigate_Params& params) {
141dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  CancelRequestsFor(source);
142dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
143dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (PageTransition::IsRedirect(params.transition)) {
144dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // If this is a redirect, we need to go to the db to get the start.
145dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    FetchRedirectStart(source);
146dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  } else if (params.redirects.size() > 1 ||
147dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen             params.redirects[0] != details.entry->url()) {
148dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    tab_contents_to_url_[source] = params.redirects[0];
149dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
150dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
151dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
152dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool TabFinder::TabMatchesURL(TabContents* tab_contents, const GURL& url) {
153dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (tab_contents->GetURL() == url)
154dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    return true;
155dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
156dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  TabContentsToURLMap::const_iterator i =
157dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      tab_contents_to_url_.find(tab_contents);
158dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  return i != tab_contents_to_url_.end() && i->second == url;
159dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
160dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
161dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenTabContents* TabFinder::FindTabInBrowser(Browser* browser, const GURL& url) {
162dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (browser->type() != Browser::TYPE_NORMAL)
163dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    return NULL;
164dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
165dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  for (int i = 0; i < browser->tab_count(); ++i) {
166dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    if (TabMatchesURL(browser->GetTabContentsAt(i), url))
167dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      return browser->GetTabContentsAt(i);
168dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
169dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  return NULL;
170dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
171dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
172dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid TabFinder::TrackTab(TabContents* tab) {
173dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  for (TabContentsObservers::const_iterator i = tab_contents_observers_.begin();
174dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen       i != tab_contents_observers_.end(); ++i) {
175dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    if ((*i)->tab_contents() == tab) {
176dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      // Already tracking the tab.
177dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      return;
178dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    }
179dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
180dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  TabContentsObserverImpl* observer = new TabContentsObserverImpl(tab, this);
181dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  tab_contents_observers_.insert(observer);
182dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  FetchRedirectStart(tab);
183dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
184dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
185dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid TabFinder::TrackBrowser(Browser* browser) {
186dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  for (int i = 0; i < browser->tab_count(); ++i)
187dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    FetchRedirectStart(browser->GetTabContentsAt(i));
188dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
189dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
190dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid TabFinder::TabDestroyed(TabContentsObserverImpl* observer) {
191dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK_GT(tab_contents_observers_.count(observer), 0u);
192dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  tab_contents_observers_.erase(observer);
193dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
194dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
195dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid TabFinder::CancelRequestsFor(TabContents* tab_contents) {
196dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (tab_contents->profile()->IsOffTheRecord())
197dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    return;
198dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
199dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  tab_contents_to_url_.erase(tab_contents);
200dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
201dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  HistoryService* history = tab_contents->profile()->GetHistoryService(
202dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      Profile::EXPLICIT_ACCESS);
203dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (history) {
204dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    CancelableRequestProvider::Handle request_handle;
205dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    if (callback_consumer_.GetFirstHandleForClientData(tab_contents,
206dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                                       &request_handle)) {
207dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      history->CancelRequest(request_handle);
208dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    }
209dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
210dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
211dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
212dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid TabFinder::FetchRedirectStart(TabContents* tab) {
213dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (tab->profile()->IsOffTheRecord())
214dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    return;
215dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
216dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  NavigationEntry* committed_entry = tab->controller().GetLastCommittedEntry();
217dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (!committed_entry || committed_entry->url().is_empty())
218dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    return;
219dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
220dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  HistoryService* history =tab->profile()->GetHistoryService(
221dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      Profile::EXPLICIT_ACCESS);
222dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (history) {
223dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    CancelableRequestProvider::Handle request_handle =
224dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        history->QueryRedirectsTo(
225dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen            committed_entry->url(),
226dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen            &callback_consumer_,
227dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen            NewCallback(this, &TabFinder::QueryRedirectsToComplete));
228dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    callback_consumer_.SetClientData(history, request_handle, tab);
229dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
230dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
231dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
232dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid TabFinder::QueryRedirectsToComplete(HistoryService::Handle handle,
233dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                         GURL url,
234dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                         bool success,
235dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                         history::RedirectList* redirects) {
236dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (success && !redirects->empty()) {
237dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    TabContents* tab_contents =
238dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        callback_consumer_.GetClientDataForCurrentRequest();
239dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    DCHECK(tab_contents);
240dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    tab_contents_to_url_[tab_contents] = redirects->back();
241dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
242dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
243