Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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/sessions/tab_restore_service_helper.h" | 5 #include "chrome/browser/sessions/tab_restore_service_helper.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <iterator> | 8 #include <iterator> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 163 if (observer_) | 163 if (observer_) |
| 164 observer_->OnClearEntries(); | 164 observer_->OnClearEntries(); |
| 165 STLDeleteElements(&entries_); | 165 STLDeleteElements(&entries_); |
| 166 NotifyTabsChanged(); | 166 NotifyTabsChanged(); |
| 167 } | 167 } |
| 168 | 168 |
| 169 const TabRestoreService::Entries& TabRestoreServiceHelper::entries() const { | 169 const TabRestoreService::Entries& TabRestoreServiceHelper::entries() const { |
| 170 return entries_; | 170 return entries_; |
| 171 } | 171 } |
| 172 | 172 |
| 173 void TabRestoreServiceHelper::RestoreMostRecentEntry( | 173 std::vector<content::WebContents*> |
| 174 TabRestoreServiceDelegate* delegate, | 174 TabRestoreServiceHelper::RestoreMostRecentEntry( |
|
sky
2013/08/05 16:16:17
Same indentation comment.
Kristen Dwan
2013/08/05 18:01:38
Done.
| |
| 175 chrome::HostDesktopType host_desktop_type) { | 175 TabRestoreServiceDelegate* delegate, |
| 176 chrome::HostDesktopType host_desktop_type) { | |
| 176 if (entries_.empty()) | 177 if (entries_.empty()) |
| 177 return; | 178 return std::vector<WebContents*>(); |
| 178 | 179 |
| 179 RestoreEntryById(delegate, entries_.front()->id, host_desktop_type, UNKNOWN); | 180 return RestoreEntryById(delegate, entries_.front()->id, host_desktop_type, |
| 181 UNKNOWN); | |
| 180 } | 182 } |
| 181 | 183 |
| 182 TabRestoreService::Tab* TabRestoreServiceHelper::RemoveTabEntryById( | 184 TabRestoreService::Tab* TabRestoreServiceHelper::RemoveTabEntryById( |
| 183 SessionID::id_type id) { | 185 SessionID::id_type id) { |
| 184 Entries::iterator i = GetEntryIteratorById(id); | 186 Entries::iterator i = GetEntryIteratorById(id); |
| 185 if (i == entries_.end()) | 187 if (i == entries_.end()) |
| 186 return NULL; | 188 return NULL; |
| 187 | 189 |
| 188 Entry* entry = *i; | 190 Entry* entry = *i; |
| 189 if (entry->type != TabRestoreService::TAB) | 191 if (entry->type != TabRestoreService::TAB) |
| 190 return NULL; | 192 return NULL; |
| 191 | 193 |
| 192 Tab* tab = static_cast<Tab*>(entry); | 194 Tab* tab = static_cast<Tab*>(entry); |
| 193 entries_.erase(i); | 195 entries_.erase(i); |
| 194 return tab; | 196 return tab; |
| 195 } | 197 } |
| 196 | 198 |
| 197 void TabRestoreServiceHelper::RestoreEntryById( | 199 std::vector<content::WebContents*> TabRestoreServiceHelper::RestoreEntryById( |
| 198 TabRestoreServiceDelegate* delegate, | 200 TabRestoreServiceDelegate* delegate, |
| 199 SessionID::id_type id, | 201 SessionID::id_type id, |
| 200 chrome::HostDesktopType host_desktop_type, | 202 chrome::HostDesktopType host_desktop_type, |
| 201 WindowOpenDisposition disposition) { | 203 WindowOpenDisposition disposition) { |
| 202 Entries::iterator entry_iterator = GetEntryIteratorById(id); | 204 Entries::iterator entry_iterator = GetEntryIteratorById(id); |
| 203 if (entry_iterator == entries_.end()) | 205 if (entry_iterator == entries_.end()) |
| 204 // Don't hoark here, we allow an invalid id. | 206 // Don't hoark here, we allow an invalid id. |
| 205 return; | 207 return std::vector<WebContents*>(); |
| 206 | 208 |
| 207 if (observer_) | 209 if (observer_) |
| 208 observer_->OnRestoreEntryById(id, entry_iterator); | 210 observer_->OnRestoreEntryById(id, entry_iterator); |
| 209 restoring_ = true; | 211 restoring_ = true; |
| 210 Entry* entry = *entry_iterator; | 212 Entry* entry = *entry_iterator; |
| 211 | 213 |
| 212 // If the entry's ID does not match the ID that is being restored, then the | 214 // If the entry's ID does not match the ID that is being restored, then the |
| 213 // entry is a window from which a single tab will be restored. | 215 // entry is a window from which a single tab will be restored. |
| 214 bool restoring_tab_in_window = entry->id != id; | 216 bool restoring_tab_in_window = entry->id != id; |
| 215 | 217 |
| 216 if (!restoring_tab_in_window) { | 218 if (!restoring_tab_in_window) { |
| 217 entries_.erase(entry_iterator); | 219 entries_.erase(entry_iterator); |
| 218 entry_iterator = entries_.end(); | 220 entry_iterator = entries_.end(); |
| 219 } | 221 } |
| 220 | 222 |
| 221 // |delegate| will be NULL in cases where one isn't already available (eg, | 223 // |delegate| will be NULL in cases where one isn't already available (eg, |
| 222 // when invoked on Mac OS X with no windows open). In this case, create a | 224 // when invoked on Mac OS X with no windows open). In this case, create a |
| 223 // new browser into which we restore the tabs. | 225 // new browser into which we restore the tabs. |
| 226 std::vector<WebContents*> web_contents; | |
| 224 if (entry->type == TabRestoreService::TAB) { | 227 if (entry->type == TabRestoreService::TAB) { |
| 225 Tab* tab = static_cast<Tab*>(entry); | 228 Tab* tab = static_cast<Tab*>(entry); |
| 226 delegate = RestoreTab(*tab, delegate, host_desktop_type, disposition); | 229 web_contents.resize(1); |
|
sky
2013/08/05 16:16:17
Assuming no one else modifies web_contents before
Kristen Dwan
2013/08/05 18:01:38
Done.
| |
| 230 delegate = RestoreTab(*tab, delegate, host_desktop_type, disposition, | |
| 231 &web_contents[0]); | |
| 227 delegate->ShowBrowserWindow(); | 232 delegate->ShowBrowserWindow(); |
| 228 } else if (entry->type == TabRestoreService::WINDOW) { | 233 } else if (entry->type == TabRestoreService::WINDOW) { |
| 229 TabRestoreServiceDelegate* current_delegate = delegate; | 234 TabRestoreServiceDelegate* current_delegate = delegate; |
| 230 Window* window = static_cast<Window*>(entry); | 235 Window* window = static_cast<Window*>(entry); |
| 231 | 236 |
| 232 // When restoring a window, either the entire window can be restored, or a | 237 // When restoring a window, either the entire window can be restored, or a |
| 233 // single tab within it. If the entry's ID matches the one to restore, then | 238 // single tab within it. If the entry's ID matches the one to restore, then |
| 234 // the entire window will be restored. | 239 // the entire window will be restored. |
| 235 if (!restoring_tab_in_window) { | 240 if (!restoring_tab_in_window) { |
| 236 delegate = TabRestoreServiceDelegate::Create(profile_, host_desktop_type, | 241 delegate = TabRestoreServiceDelegate::Create(profile_, host_desktop_type, |
| 237 window->app_name); | 242 window->app_name); |
| 238 for (size_t tab_i = 0; tab_i < window->tabs.size(); ++tab_i) { | 243 for (size_t tab_i = 0; tab_i < window->tabs.size(); ++tab_i) { |
| 239 const Tab& tab = window->tabs[tab_i]; | 244 const Tab& tab = window->tabs[tab_i]; |
| 240 WebContents* restored_tab = delegate->AddRestoredTab( | 245 WebContents* restored_tab = delegate->AddRestoredTab( |
| 241 tab.navigations, | 246 tab.navigations, |
| 242 delegate->GetTabCount(), | 247 delegate->GetTabCount(), |
| 243 tab.current_navigation_index, | 248 tab.current_navigation_index, |
| 244 tab.extension_app_id, | 249 tab.extension_app_id, |
| 245 static_cast<int>(tab_i) == window->selected_tab_index, | 250 static_cast<int>(tab_i) == window->selected_tab_index, |
| 246 tab.pinned, | 251 tab.pinned, |
| 247 tab.from_last_session, | 252 tab.from_last_session, |
| 248 tab.session_storage_namespace.get(), | 253 tab.session_storage_namespace.get(), |
| 249 tab.user_agent_override); | 254 tab.user_agent_override); |
| 250 if (restored_tab) { | 255 if (restored_tab) { |
| 251 restored_tab->GetController().LoadIfNecessary(); | 256 restored_tab->GetController().LoadIfNecessary(); |
| 252 RecordAppLaunch(profile_, tab); | 257 RecordAppLaunch(profile_, tab); |
| 258 web_contents.push_back(restored_tab); | |
| 253 } | 259 } |
| 254 } | 260 } |
| 255 // All the window's tabs had the same former browser_id. | 261 // All the window's tabs had the same former browser_id. |
| 256 if (window->tabs[0].has_browser()) { | 262 if (window->tabs[0].has_browser()) { |
| 257 UpdateTabBrowserIDs(window->tabs[0].browser_id, | 263 UpdateTabBrowserIDs(window->tabs[0].browser_id, |
| 258 delegate->GetSessionID().id()); | 264 delegate->GetSessionID().id()); |
| 259 } | 265 } |
| 260 } else { | 266 } else { |
| 261 // Restore a single tab from the window. Find the tab that matches the ID | 267 // Restore a single tab from the window. Find the tab that matches the ID |
| 262 // in the window and restore it. | 268 // in the window and restore it. |
| 263 for (std::vector<Tab>::iterator tab_i = window->tabs.begin(); | 269 for (std::vector<Tab>::iterator tab_i = window->tabs.begin(); |
| 264 tab_i != window->tabs.end(); ++tab_i) { | 270 tab_i != window->tabs.end(); ++tab_i) { |
| 265 const Tab& tab = *tab_i; | 271 const Tab& tab = *tab_i; |
| 266 if (tab.id == id) { | 272 if (tab.id == id) { |
| 267 delegate = RestoreTab(tab, delegate, host_desktop_type, disposition); | 273 web_contents.resize(1); |
| 274 delegate = RestoreTab(tab, delegate, host_desktop_type, disposition, | |
| 275 &web_contents[0]); | |
| 268 window->tabs.erase(tab_i); | 276 window->tabs.erase(tab_i); |
| 269 // If restoring the tab leaves the window with nothing else, delete it | 277 // If restoring the tab leaves the window with nothing else, delete it |
| 270 // as well. | 278 // as well. |
| 271 if (!window->tabs.size()) { | 279 if (!window->tabs.size()) { |
| 272 entries_.erase(entry_iterator); | 280 entries_.erase(entry_iterator); |
| 273 delete entry; | 281 delete entry; |
| 274 } else { | 282 } else { |
| 275 // Update the browser ID of the rest of the tabs in the window so if | 283 // Update the browser ID of the rest of the tabs in the window so if |
| 276 // any one is restored, it goes into the same window as the tab | 284 // any one is restored, it goes into the same window as the tab |
| 277 // being restored now. | 285 // being restored now. |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 295 } else { | 303 } else { |
| 296 NOTREACHED(); | 304 NOTREACHED(); |
| 297 } | 305 } |
| 298 | 306 |
| 299 if (!restoring_tab_in_window) { | 307 if (!restoring_tab_in_window) { |
| 300 delete entry; | 308 delete entry; |
| 301 } | 309 } |
| 302 | 310 |
| 303 restoring_ = false; | 311 restoring_ = false; |
| 304 NotifyTabsChanged(); | 312 NotifyTabsChanged(); |
| 313 return web_contents; | |
| 305 } | 314 } |
| 306 | 315 |
| 307 void TabRestoreServiceHelper::NotifyTabsChanged() { | 316 void TabRestoreServiceHelper::NotifyTabsChanged() { |
| 308 FOR_EACH_OBSERVER(TabRestoreServiceObserver, observer_list_, | 317 FOR_EACH_OBSERVER(TabRestoreServiceObserver, observer_list_, |
| 309 TabRestoreServiceChanged(tab_restore_service_)); | 318 TabRestoreServiceChanged(tab_restore_service_)); |
| 310 } | 319 } |
| 311 | 320 |
| 312 void TabRestoreServiceHelper::NotifyLoaded() { | 321 void TabRestoreServiceHelper::NotifyLoaded() { |
| 313 FOR_EACH_OBSERVER(TabRestoreServiceObserver, observer_list_, | 322 FOR_EACH_OBSERVER(TabRestoreServiceObserver, observer_list_, |
| 314 TabRestoreServiceLoaded(tab_restore_service_)); | 323 TabRestoreServiceLoaded(tab_restore_service_)); |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 430 if (delegate) { | 439 if (delegate) { |
| 431 tab->browser_id = delegate->GetSessionID().id(); | 440 tab->browser_id = delegate->GetSessionID().id(); |
| 432 tab->pinned = delegate->IsTabPinned(tab->tabstrip_index); | 441 tab->pinned = delegate->IsTabPinned(tab->tabstrip_index); |
| 433 } | 442 } |
| 434 } | 443 } |
| 435 | 444 |
| 436 TabRestoreServiceDelegate* TabRestoreServiceHelper::RestoreTab( | 445 TabRestoreServiceDelegate* TabRestoreServiceHelper::RestoreTab( |
| 437 const Tab& tab, | 446 const Tab& tab, |
| 438 TabRestoreServiceDelegate* delegate, | 447 TabRestoreServiceDelegate* delegate, |
| 439 chrome::HostDesktopType host_desktop_type, | 448 chrome::HostDesktopType host_desktop_type, |
| 440 WindowOpenDisposition disposition) { | 449 WindowOpenDisposition disposition, |
| 450 WebContents** contents) { | |
| 451 WebContents* web_contents; | |
| 441 if (disposition == CURRENT_TAB && delegate) { | 452 if (disposition == CURRENT_TAB && delegate) { |
| 442 delegate->ReplaceRestoredTab(tab.navigations, | 453 web_contents = delegate->ReplaceRestoredTab( |
| 443 tab.current_navigation_index, | 454 tab.navigations, |
| 444 tab.from_last_session, | 455 tab.current_navigation_index, |
| 445 tab.extension_app_id, | 456 tab.from_last_session, |
| 446 tab.session_storage_namespace.get(), | 457 tab.extension_app_id, |
| 447 tab.user_agent_override); | 458 tab.session_storage_namespace.get(), |
| 459 tab.user_agent_override); | |
| 448 } else { | 460 } else { |
| 449 // We only respsect the tab's original browser if there's no disposition. | 461 // We only respsect the tab's original browser if there's no disposition. |
| 450 if (disposition == UNKNOWN && tab.has_browser()) { | 462 if (disposition == UNKNOWN && tab.has_browser()) { |
| 451 delegate = TabRestoreServiceDelegate::FindDelegateWithID( | 463 delegate = TabRestoreServiceDelegate::FindDelegateWithID( |
| 452 tab.browser_id, host_desktop_type); | 464 tab.browser_id, host_desktop_type); |
| 453 } | 465 } |
| 454 | 466 |
| 455 int tab_index = -1; | 467 int tab_index = -1; |
| 456 | 468 |
| 457 // |delegate| will be NULL in cases where one isn't already available (eg, | 469 // |delegate| will be NULL in cases where one isn't already available (eg, |
| 458 // when invoked on Mac OS X with no windows open). In this case, create a | 470 // when invoked on Mac OS X with no windows open). In this case, create a |
| 459 // new browser into which we restore the tabs. | 471 // new browser into which we restore the tabs. |
| 460 if (delegate && disposition != NEW_WINDOW) { | 472 if (delegate && disposition != NEW_WINDOW) { |
| 461 tab_index = tab.tabstrip_index; | 473 tab_index = tab.tabstrip_index; |
| 462 } else { | 474 } else { |
| 463 delegate = TabRestoreServiceDelegate::Create(profile_, host_desktop_type, | 475 delegate = TabRestoreServiceDelegate::Create(profile_, host_desktop_type, |
| 464 std::string()); | 476 std::string()); |
| 465 if (tab.has_browser()) | 477 if (tab.has_browser()) |
| 466 UpdateTabBrowserIDs(tab.browser_id, delegate->GetSessionID().id()); | 478 UpdateTabBrowserIDs(tab.browser_id, delegate->GetSessionID().id()); |
| 467 } | 479 } |
| 468 | 480 |
| 469 // Place the tab at the end if the tab index is no longer valid or | 481 // Place the tab at the end if the tab index is no longer valid or |
| 470 // we were passed a specific disposition. | 482 // we were passed a specific disposition. |
| 471 if (tab_index < 0 || tab_index > delegate->GetTabCount() || | 483 if (tab_index < 0 || tab_index > delegate->GetTabCount() || |
| 472 disposition != UNKNOWN) { | 484 disposition != UNKNOWN) { |
| 473 tab_index = delegate->GetTabCount(); | 485 tab_index = delegate->GetTabCount(); |
| 474 } | 486 } |
| 475 | 487 |
| 476 WebContents* web_contents = | 488 web_contents = delegate->AddRestoredTab(tab.navigations, |
| 477 delegate->AddRestoredTab(tab.navigations, | 489 tab_index, |
| 478 tab_index, | 490 tab.current_navigation_index, |
| 479 tab.current_navigation_index, | 491 tab.extension_app_id, |
| 480 tab.extension_app_id, | 492 disposition != NEW_BACKGROUND_TAB, |
| 481 disposition != NEW_BACKGROUND_TAB, | 493 tab.pinned, |
| 482 tab.pinned, | 494 tab.from_last_session, |
| 483 tab.from_last_session, | 495 tab.session_storage_namespace.get(), |
| 484 tab.session_storage_namespace.get(), | 496 tab.user_agent_override); |
| 485 tab.user_agent_override); | |
| 486 web_contents->GetController().LoadIfNecessary(); | 497 web_contents->GetController().LoadIfNecessary(); |
| 487 } | 498 } |
| 488 RecordAppLaunch(profile_, tab); | 499 RecordAppLaunch(profile_, tab); |
| 500 if (contents) | |
| 501 *contents = web_contents; | |
| 502 | |
| 489 return delegate; | 503 return delegate; |
| 490 } | 504 } |
| 491 | 505 |
| 492 | 506 |
| 493 bool TabRestoreServiceHelper::ValidateTab(Tab* tab) { | 507 bool TabRestoreServiceHelper::ValidateTab(Tab* tab) { |
| 494 if (tab->navigations.empty()) | 508 if (tab->navigations.empty()) |
| 495 return false; | 509 return false; |
| 496 | 510 |
| 497 tab->current_navigation_index = | 511 tab->current_navigation_index = |
| 498 std::max(0, std::min(tab->current_navigation_index, | 512 std::max(0, std::min(tab->current_navigation_index, |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 570 Tab* tab = static_cast<Tab*>(entry); | 584 Tab* tab = static_cast<Tab*>(entry); |
| 571 if (tab->browser_id == old_id) | 585 if (tab->browser_id == old_id) |
| 572 tab->browser_id = new_id; | 586 tab->browser_id = new_id; |
| 573 } | 587 } |
| 574 } | 588 } |
| 575 } | 589 } |
| 576 | 590 |
| 577 base::Time TabRestoreServiceHelper::TimeNow() const { | 591 base::Time TabRestoreServiceHelper::TimeNow() const { |
| 578 return time_factory_ ? time_factory_->TimeNow() : base::Time::Now(); | 592 return time_factory_ ? time_factory_->TimeNow() : base::Time::Now(); |
| 579 } | 593 } |
| OLD | NEW |