| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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.h" | 5 #include "chrome/browser/sessions/tab_restore_service.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <iterator> | 8 #include <iterator> |
| 9 #include <map> | 9 #include <map> |
| 10 | 10 |
| 11 #include "base/callback.h" | 11 #include "base/callback.h" |
| 12 #include "base/metrics/histogram.h" | 12 #include "base/metrics/histogram.h" |
| 13 #include "base/scoped_vector.h" | 13 #include "base/scoped_vector.h" |
| 14 #include "base/stl_util-inl.h" | 14 #include "base/stl_util-inl.h" |
| 15 #include "chrome/browser/browser_list.h" | |
| 16 #include "chrome/browser/browser_window.h" | |
| 17 #include "chrome/browser/extensions/extension_service.h" | 15 #include "chrome/browser/extensions/extension_service.h" |
| 18 #include "chrome/browser/profiles/profile.h" | 16 #include "chrome/browser/profiles/profile.h" |
| 19 #include "chrome/browser/sessions/session_service.h" | 17 #include "chrome/browser/sessions/session_service.h" |
| 20 #include "chrome/browser/sessions/session_command.h" | 18 #include "chrome/browser/sessions/session_command.h" |
| 21 #include "chrome/browser/sessions/session_types.h" | 19 #include "chrome/browser/sessions/session_types.h" |
| 20 #include "chrome/browser/sessions/tab_restore_service_delegate.h" |
| 22 #include "chrome/browser/sessions/tab_restore_service_observer.h" | 21 #include "chrome/browser/sessions/tab_restore_service_observer.h" |
| 23 #include "chrome/browser/tabs/tab_strip_model.h" | |
| 24 #include "chrome/common/extensions/extension.h" | 22 #include "chrome/common/extensions/extension.h" |
| 25 #include "chrome/common/extensions/extension_constants.h" | 23 #include "chrome/common/extensions/extension_constants.h" |
| 26 #include "content/browser/tab_contents/navigation_controller.h" | 24 #include "content/browser/tab_contents/navigation_controller.h" |
| 27 #include "content/browser/tab_contents/navigation_entry.h" | 25 #include "content/browser/tab_contents/navigation_entry.h" |
| 28 #include "content/browser/tab_contents/tab_contents.h" | 26 #include "content/browser/tab_contents/tab_contents.h" |
| 29 | 27 |
| 30 using base::Time; | 28 using base::Time; |
| 31 | 29 |
| 32 // TimeFactory----------------------------------------------------------------- | 30 // TimeFactory----------------------------------------------------------------- |
| 33 | 31 |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 145 // If the ID matches one of this window's tabs, remove it from the list. | 143 // If the ID matches one of this window's tabs, remove it from the list. |
| 146 if ((*j).id == id) { | 144 if ((*j).id == id) { |
| 147 window->tabs.erase(j); | 145 window->tabs.erase(j); |
| 148 return; | 146 return; |
| 149 } | 147 } |
| 150 } | 148 } |
| 151 } | 149 } |
| 152 } | 150 } |
| 153 } | 151 } |
| 154 | 152 |
| 155 void RecordAppLaunch(Browser* browser, const TabRestoreService::Tab& tab) { | 153 void RecordAppLaunch(Profile* profile, const TabRestoreService::Tab& tab) { |
| 156 GURL url = tab.navigations.at(tab.current_navigation_index).virtual_url(); | 154 GURL url = tab.navigations.at(tab.current_navigation_index).virtual_url(); |
| 157 Profile* profile = browser->profile(); | |
| 158 DCHECK(profile->GetExtensionService()); | 155 DCHECK(profile->GetExtensionService()); |
| 159 if (!profile->GetExtensionService()->IsInstalledApp(url)) | 156 if (!profile->GetExtensionService()->IsInstalledApp(url)) |
| 160 return; | 157 return; |
| 161 | 158 |
| 162 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppLaunchHistogram, | 159 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppLaunchHistogram, |
| 163 extension_misc::APP_LAUNCH_NTP_RECENTLY_CLOSED, | 160 extension_misc::APP_LAUNCH_NTP_RECENTLY_CLOSED, |
| 164 extension_misc::APP_LAUNCH_BUCKET_BOUNDARY); | 161 extension_misc::APP_LAUNCH_BUCKET_BOUNDARY); |
| 165 } | 162 } |
| 166 | 163 |
| 167 } // namespace | 164 } // namespace |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 207 } | 204 } |
| 208 | 205 |
| 209 void TabRestoreService::AddObserver(TabRestoreServiceObserver* observer) { | 206 void TabRestoreService::AddObserver(TabRestoreServiceObserver* observer) { |
| 210 observer_list_.AddObserver(observer); | 207 observer_list_.AddObserver(observer); |
| 211 } | 208 } |
| 212 | 209 |
| 213 void TabRestoreService::RemoveObserver(TabRestoreServiceObserver* observer) { | 210 void TabRestoreService::RemoveObserver(TabRestoreServiceObserver* observer) { |
| 214 observer_list_.RemoveObserver(observer); | 211 observer_list_.RemoveObserver(observer); |
| 215 } | 212 } |
| 216 | 213 |
| 217 void TabRestoreService::CreateHistoricalTab(NavigationController* tab) { | 214 void TabRestoreService::CreateHistoricalTab(NavigationController* tab, |
| 215 int index) { |
| 218 if (restoring_) | 216 if (restoring_) |
| 219 return; | 217 return; |
| 220 | 218 |
| 221 Browser* browser = Browser::GetBrowserForController(tab, NULL); | 219 TabRestoreServiceDelegate* delegate = |
| 222 if (closing_browsers_.find(browser) != closing_browsers_.end()) | 220 TabRestoreServiceDelegate::FindDelegateForController(tab, NULL); |
| 221 if (closing_delegates_.find(delegate) != closing_delegates_.end()) |
| 223 return; | 222 return; |
| 224 | 223 |
| 225 scoped_ptr<Tab> local_tab(new Tab()); | 224 scoped_ptr<Tab> local_tab(new Tab()); |
| 226 PopulateTab(local_tab.get(), browser, tab); | 225 PopulateTab(local_tab.get(), index, delegate, tab); |
| 227 if (local_tab->navigations.empty()) | 226 if (local_tab->navigations.empty()) |
| 228 return; | 227 return; |
| 229 | 228 |
| 230 AddEntry(local_tab.release(), true, true); | 229 AddEntry(local_tab.release(), true, true); |
| 231 } | 230 } |
| 232 | 231 |
| 233 void TabRestoreService::BrowserClosing(Browser* browser) { | 232 void TabRestoreService::BrowserClosing(TabRestoreServiceDelegate* delegate) { |
| 234 if (browser->type() != Browser::TYPE_NORMAL || | 233 closing_delegates_.insert(delegate); |
| 235 browser->tab_count() == 0) | |
| 236 return; | |
| 237 | |
| 238 closing_browsers_.insert(browser); | |
| 239 | 234 |
| 240 scoped_ptr<Window> window(new Window()); | 235 scoped_ptr<Window> window(new Window()); |
| 241 window->selected_tab_index = browser->selected_index(); | 236 window->selected_tab_index = delegate->GetSelectedIndex(); |
| 242 window->timestamp = TimeNow(); | 237 window->timestamp = TimeNow(); |
| 243 // Don't use std::vector::resize() because it will push copies of an empty tab | 238 // Don't use std::vector::resize() because it will push copies of an empty tab |
| 244 // into the vector, which will give all tabs in a window the same ID. | 239 // into the vector, which will give all tabs in a window the same ID. |
| 245 for (int i = 0; i < browser->tab_count(); ++i) { | 240 for (int i = 0; i < delegate->GetTabCount(); ++i) { |
| 246 window->tabs.push_back(Tab()); | 241 window->tabs.push_back(Tab()); |
| 247 } | 242 } |
| 248 size_t entry_index = 0; | 243 size_t entry_index = 0; |
| 249 for (int tab_index = 0; tab_index < browser->tab_count(); ++tab_index) { | 244 for (int tab_index = 0; tab_index < delegate->GetTabCount(); ++tab_index) { |
| 250 PopulateTab(&(window->tabs[entry_index]), | 245 PopulateTab(&(window->tabs[entry_index]), |
| 251 browser, | 246 tab_index, |
| 252 &browser->GetTabContentsAt(tab_index)->controller()); | 247 delegate, |
| 248 &delegate->GetTabContentsAt(tab_index)->controller()); |
| 253 if (window->tabs[entry_index].navigations.empty()) { | 249 if (window->tabs[entry_index].navigations.empty()) { |
| 254 window->tabs.erase(window->tabs.begin() + entry_index); | 250 window->tabs.erase(window->tabs.begin() + entry_index); |
| 255 } else { | 251 } else { |
| 256 window->tabs[entry_index].browser_id = browser->session_id().id(); | 252 window->tabs[entry_index].browser_id = delegate->GetSessionID().id(); |
| 257 entry_index++; | 253 entry_index++; |
| 258 } | 254 } |
| 259 } | 255 } |
| 260 if (window->tabs.size() == 1) { | 256 if (window->tabs.size() == 1) { |
| 261 // Short-circuit creating a Window if only 1 tab was present. This fixes | 257 // Short-circuit creating a Window if only 1 tab was present. This fixes |
| 262 // http://crbug.com/56744. Copy the Tab because it's owned by an object on | 258 // http://crbug.com/56744. Copy the Tab because it's owned by an object on |
| 263 // the stack. | 259 // the stack. |
| 264 AddEntry(new Tab(window->tabs[0]), true, true); | 260 AddEntry(new Tab(window->tabs[0]), true, true); |
| 265 } else if (!window->tabs.empty()) { | 261 } else if (!window->tabs.empty()) { |
| 266 window->selected_tab_index = | 262 window->selected_tab_index = |
| 267 std::min(static_cast<int>(window->tabs.size() - 1), | 263 std::min(static_cast<int>(window->tabs.size() - 1), |
| 268 window->selected_tab_index); | 264 window->selected_tab_index); |
| 269 AddEntry(window.release(), true, true); | 265 AddEntry(window.release(), true, true); |
| 270 } | 266 } |
| 271 } | 267 } |
| 272 | 268 |
| 273 void TabRestoreService::BrowserClosed(Browser* browser) { | 269 void TabRestoreService::BrowserClosed(TabRestoreServiceDelegate* delegate) { |
| 274 closing_browsers_.erase(browser); | 270 closing_delegates_.erase(delegate); |
| 275 } | 271 } |
| 276 | 272 |
| 277 void TabRestoreService::ClearEntries() { | 273 void TabRestoreService::ClearEntries() { |
| 278 // Mark all the tabs as closed so that we don't attempt to restore them. | 274 // Mark all the tabs as closed so that we don't attempt to restore them. |
| 279 for (Entries::iterator i = entries_.begin(); i != entries_.end(); ++i) | 275 for (Entries::iterator i = entries_.begin(); i != entries_.end(); ++i) |
| 280 ScheduleCommand(CreateRestoredEntryCommand((*i)->id)); | 276 ScheduleCommand(CreateRestoredEntryCommand((*i)->id)); |
| 281 | 277 |
| 282 entries_to_write_ = 0; | 278 entries_to_write_ = 0; |
| 283 | 279 |
| 284 // Schedule a pending reset so that we nuke the file on next write. | 280 // Schedule a pending reset so that we nuke the file on next write. |
| 285 set_pending_reset(true); | 281 set_pending_reset(true); |
| 286 | 282 |
| 287 // Schedule a command, otherwise if there are no pending commands Save does | 283 // Schedule a command, otherwise if there are no pending commands Save does |
| 288 // nothing. | 284 // nothing. |
| 289 ScheduleCommand(CreateRestoredEntryCommand(1)); | 285 ScheduleCommand(CreateRestoredEntryCommand(1)); |
| 290 | 286 |
| 291 STLDeleteElements(&entries_); | 287 STLDeleteElements(&entries_); |
| 292 NotifyTabsChanged(); | 288 NotifyTabsChanged(); |
| 293 } | 289 } |
| 294 | 290 |
| 295 const TabRestoreService::Entries& TabRestoreService::entries() const { | 291 const TabRestoreService::Entries& TabRestoreService::entries() const { |
| 296 return entries_; | 292 return entries_; |
| 297 } | 293 } |
| 298 | 294 |
| 299 void TabRestoreService::RestoreMostRecentEntry(Browser* browser) { | 295 void TabRestoreService::RestoreMostRecentEntry( |
| 296 TabRestoreServiceDelegate* delegate) { |
| 300 if (entries_.empty()) | 297 if (entries_.empty()) |
| 301 return; | 298 return; |
| 302 | 299 |
| 303 RestoreEntryById(browser, entries_.front()->id, false); | 300 RestoreEntryById(delegate, entries_.front()->id, false); |
| 304 } | 301 } |
| 305 | 302 |
| 306 void TabRestoreService::RestoreEntryById(Browser* browser, | 303 void TabRestoreService::RestoreEntryById(TabRestoreServiceDelegate* delegate, |
| 307 SessionID::id_type id, | 304 SessionID::id_type id, |
| 308 bool replace_existing_tab) { | 305 bool replace_existing_tab) { |
| 309 Entries::iterator i = GetEntryIteratorById(id); | 306 Entries::iterator i = GetEntryIteratorById(id); |
| 310 if (i == entries_.end()) { | 307 if (i == entries_.end()) { |
| 311 // Don't hoark here, we allow an invalid id. | 308 // Don't hoark here, we allow an invalid id. |
| 312 return; | 309 return; |
| 313 } | 310 } |
| 314 | 311 |
| 315 size_t index = 0; | 312 size_t index = 0; |
| 316 for (Entries::iterator j = entries_.begin(); j != i && j != entries_.end(); | 313 for (Entries::iterator j = entries_.begin(); j != i && j != entries_.end(); |
| 317 ++j, ++index) {} | 314 ++j, ++index) {} |
| 318 if (static_cast<int>(index) < entries_to_write_) | 315 if (static_cast<int>(index) < entries_to_write_) |
| 319 entries_to_write_--; | 316 entries_to_write_--; |
| 320 | 317 |
| 321 ScheduleCommand(CreateRestoredEntryCommand(id)); | 318 ScheduleCommand(CreateRestoredEntryCommand(id)); |
| 322 | 319 |
| 323 restoring_ = true; | 320 restoring_ = true; |
| 324 Entry* entry = *i; | 321 Entry* entry = *i; |
| 325 | 322 |
| 326 // If the entry's ID does not match the ID that is being restored, then the | 323 // If the entry's ID does not match the ID that is being restored, then the |
| 327 // entry is a window from which a single tab will be restored. | 324 // entry is a window from which a single tab will be restored. |
| 328 bool restoring_tab_in_window = entry->id != id; | 325 bool restoring_tab_in_window = entry->id != id; |
| 329 | 326 |
| 330 if (!restoring_tab_in_window) { | 327 if (!restoring_tab_in_window) { |
| 331 entries_.erase(i); | 328 entries_.erase(i); |
| 332 i = entries_.end(); | 329 i = entries_.end(); |
| 333 } | 330 } |
| 334 | 331 |
| 335 // |browser| will be NULL in cases where one isn't already available (eg, | 332 // |delegate| will be NULL in cases where one isn't already available (eg, |
| 336 // when invoked on Mac OS X with no windows open). In this case, create a | 333 // when invoked on Mac OS X with no windows open). In this case, create a |
| 337 // new browser into which we restore the tabs. | 334 // new browser into which we restore the tabs. |
| 338 if (entry->type == TAB) { | 335 if (entry->type == TAB) { |
| 339 Tab* tab = static_cast<Tab*>(entry); | 336 Tab* tab = static_cast<Tab*>(entry); |
| 340 browser = RestoreTab(*tab, browser, replace_existing_tab); | 337 delegate = RestoreTab(*tab, delegate, replace_existing_tab); |
| 341 browser->window()->Show(); | 338 delegate->ShowBrowserWindow(); |
| 342 } else if (entry->type == WINDOW) { | 339 } else if (entry->type == WINDOW) { |
| 343 Browser* current_browser = browser; | 340 TabRestoreServiceDelegate* current_delegate = delegate; |
| 344 Window* window = static_cast<Window*>(entry); | 341 Window* window = static_cast<Window*>(entry); |
| 345 | 342 |
| 346 // When restoring a window, either the entire window can be restored, or a | 343 // When restoring a window, either the entire window can be restored, or a |
| 347 // single tab within it. If the entry's ID matches the one to restore, then | 344 // single tab within it. If the entry's ID matches the one to restore, then |
| 348 // the entire window will be restored. | 345 // the entire window will be restored. |
| 349 if (!restoring_tab_in_window) { | 346 if (!restoring_tab_in_window) { |
| 350 browser = Browser::Create(profile()); | 347 delegate = TabRestoreServiceDelegate::Create(profile()); |
| 351 for (size_t tab_i = 0; tab_i < window->tabs.size(); ++tab_i) { | 348 for (size_t tab_i = 0; tab_i < window->tabs.size(); ++tab_i) { |
| 352 const Tab& tab = window->tabs[tab_i]; | 349 const Tab& tab = window->tabs[tab_i]; |
| 353 TabContents* restored_tab = | 350 TabContents* restored_tab = |
| 354 browser->AddRestoredTab(tab.navigations, browser->tab_count(), | 351 delegate->AddRestoredTab(tab.navigations, delegate->GetTabCount(), |
| 355 tab.current_navigation_index, | 352 tab.current_navigation_index, |
| 356 tab.extension_app_id, | 353 tab.extension_app_id, |
| 357 (static_cast<int>(tab_i) == | 354 (static_cast<int>(tab_i) == |
| 358 window->selected_tab_index), | 355 window->selected_tab_index), |
| 359 tab.pinned, tab.from_last_session, | 356 tab.pinned, tab.from_last_session, |
| 360 tab.session_storage_namespace); | 357 tab.session_storage_namespace); |
| 361 if (restored_tab) { | 358 if (restored_tab) { |
| 362 restored_tab->controller().LoadIfNecessary(); | 359 restored_tab->controller().LoadIfNecessary(); |
| 363 RecordAppLaunch(browser, tab); | 360 RecordAppLaunch(profile(), tab); |
| 364 } | 361 } |
| 365 } | 362 } |
| 366 // All the window's tabs had the same former browser_id. | 363 // All the window's tabs had the same former browser_id. |
| 367 if (window->tabs[0].has_browser()) { | 364 if (window->tabs[0].has_browser()) { |
| 368 UpdateTabBrowserIDs(window->tabs[0].browser_id, | 365 UpdateTabBrowserIDs(window->tabs[0].browser_id, |
| 369 browser->session_id().id()); | 366 delegate->GetSessionID().id()); |
| 370 } | 367 } |
| 371 } else { | 368 } else { |
| 372 // Restore a single tab from the window. Find the tab that matches the ID | 369 // Restore a single tab from the window. Find the tab that matches the ID |
| 373 // in the window and restore it. | 370 // in the window and restore it. |
| 374 for (std::vector<Tab>::iterator tab_i = window->tabs.begin(); | 371 for (std::vector<Tab>::iterator tab_i = window->tabs.begin(); |
| 375 tab_i != window->tabs.end(); ++tab_i) { | 372 tab_i != window->tabs.end(); ++tab_i) { |
| 376 const Tab& tab = *tab_i; | 373 const Tab& tab = *tab_i; |
| 377 if (tab.id == id) { | 374 if (tab.id == id) { |
| 378 browser = RestoreTab(tab, browser, replace_existing_tab); | 375 delegate = RestoreTab(tab, delegate, replace_existing_tab); |
| 379 window->tabs.erase(tab_i); | 376 window->tabs.erase(tab_i); |
| 380 // If restoring the tab leaves the window with nothing else, delete it | 377 // If restoring the tab leaves the window with nothing else, delete it |
| 381 // as well. | 378 // as well. |
| 382 if (!window->tabs.size()) { | 379 if (!window->tabs.size()) { |
| 383 entries_.erase(i); | 380 entries_.erase(i); |
| 384 delete entry; | 381 delete entry; |
| 385 } else { | 382 } else { |
| 386 // Update the browser ID of the rest of the tabs in the window so if | 383 // Update the browser ID of the rest of the tabs in the window so if |
| 387 // any one is restored, it goes into the same window as the tab | 384 // any one is restored, it goes into the same window as the tab |
| 388 // being restored now. | 385 // being restored now. |
| 389 UpdateTabBrowserIDs(tab.browser_id, | 386 UpdateTabBrowserIDs(tab.browser_id, |
| 390 browser->session_id().id()); | 387 delegate->GetSessionID().id()); |
| 391 for (std::vector<Tab>::iterator tab_j = window->tabs.begin(); | 388 for (std::vector<Tab>::iterator tab_j = window->tabs.begin(); |
| 392 tab_j != window->tabs.end(); ++tab_j) { | 389 tab_j != window->tabs.end(); ++tab_j) { |
| 393 (*tab_j).browser_id = browser->session_id().id(); | 390 (*tab_j).browser_id = delegate->GetSessionID().id(); |
| 394 } | 391 } |
| 395 } | 392 } |
| 396 break; | 393 break; |
| 397 } | 394 } |
| 398 } | 395 } |
| 399 } | 396 } |
| 400 browser->window()->Show(); | 397 delegate->ShowBrowserWindow(); |
| 401 | 398 |
| 402 if (replace_existing_tab && current_browser && | 399 if (replace_existing_tab && current_delegate && |
| 403 current_browser->GetSelectedTabContents()) { | 400 current_delegate->GetSelectedTabContents()) { |
| 404 current_browser->CloseTab(); | 401 current_delegate->CloseTab(); |
| 405 } | 402 } |
| 406 } else { | 403 } else { |
| 407 NOTREACHED(); | 404 NOTREACHED(); |
| 408 } | 405 } |
| 409 | 406 |
| 410 if (!restoring_tab_in_window) { | 407 if (!restoring_tab_in_window) { |
| 411 delete entry; | 408 delete entry; |
| 412 } | 409 } |
| 413 | 410 |
| 414 restoring_ = false; | 411 restoring_ = false; |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 469 } | 466 } |
| 470 entries_written_++; | 467 entries_written_++; |
| 471 } | 468 } |
| 472 } | 469 } |
| 473 if (pending_reset()) | 470 if (pending_reset()) |
| 474 entries_written_ = 0; | 471 entries_written_ = 0; |
| 475 BaseSessionService::Save(); | 472 BaseSessionService::Save(); |
| 476 } | 473 } |
| 477 | 474 |
| 478 void TabRestoreService::PopulateTab(Tab* tab, | 475 void TabRestoreService::PopulateTab(Tab* tab, |
| 479 Browser* browser, | 476 int index, |
| 477 TabRestoreServiceDelegate* delegate, |
| 480 NavigationController* controller) { | 478 NavigationController* controller) { |
| 481 const int pending_index = controller->pending_entry_index(); | 479 const int pending_index = controller->pending_entry_index(); |
| 482 int entry_count = controller->entry_count(); | 480 int entry_count = controller->entry_count(); |
| 483 if (entry_count == 0 && pending_index == 0) | 481 if (entry_count == 0 && pending_index == 0) |
| 484 entry_count++; | 482 entry_count++; |
| 485 tab->navigations.resize(static_cast<int>(entry_count)); | 483 tab->navigations.resize(static_cast<int>(entry_count)); |
| 486 for (int i = 0; i < entry_count; ++i) { | 484 for (int i = 0; i < entry_count; ++i) { |
| 487 NavigationEntry* entry = (i == pending_index) ? | 485 NavigationEntry* entry = (i == pending_index) ? |
| 488 controller->pending_entry() : controller->GetEntryAtIndex(i); | 486 controller->pending_entry() : controller->GetEntryAtIndex(i); |
| 489 tab->navigations[i].SetFromNavigationEntry(*entry); | 487 tab->navigations[i].SetFromNavigationEntry(*entry); |
| 490 } | 488 } |
| 491 tab->timestamp = TimeNow(); | 489 tab->timestamp = TimeNow(); |
| 492 tab->current_navigation_index = controller->GetCurrentEntryIndex(); | 490 tab->current_navigation_index = controller->GetCurrentEntryIndex(); |
| 493 if (tab->current_navigation_index == -1 && entry_count > 0) | 491 if (tab->current_navigation_index == -1 && entry_count > 0) |
| 494 tab->current_navigation_index = 0; | 492 tab->current_navigation_index = 0; |
| 493 tab->tabstrip_index = index; |
| 495 | 494 |
| 496 const Extension* extension = controller->tab_contents()->extension_app(); | 495 const Extension* extension = controller->tab_contents()->extension_app(); |
| 497 if (extension) | 496 if (extension) |
| 498 tab->extension_app_id = extension->id(); | 497 tab->extension_app_id = extension->id(); |
| 499 | 498 |
| 500 tab->session_storage_namespace = controller->session_storage_namespace(); | 499 tab->session_storage_namespace = controller->session_storage_namespace(); |
| 501 | 500 |
| 502 // Browser may be NULL during unit tests. | 501 // Delegate may be NULL during unit tests. |
| 503 if (browser) { | 502 if (delegate) { |
| 504 tab->browser_id = browser->session_id().id(); | 503 tab->browser_id = delegate->GetSessionID().id(); |
| 505 tab->tabstrip_index = | 504 tab->pinned = delegate->IsTabPinned(tab->tabstrip_index); |
| 506 browser->tabstrip_model()->GetIndexOfController(controller); | |
| 507 tab->pinned = browser->tabstrip_model()->IsTabPinned(tab->tabstrip_index); | |
| 508 } | 505 } |
| 509 } | 506 } |
| 510 | 507 |
| 511 void TabRestoreService::NotifyTabsChanged() { | 508 void TabRestoreService::NotifyTabsChanged() { |
| 512 FOR_EACH_OBSERVER(TabRestoreServiceObserver, observer_list_, | 509 FOR_EACH_OBSERVER(TabRestoreServiceObserver, observer_list_, |
| 513 TabRestoreServiceChanged(this)); | 510 TabRestoreServiceChanged(this)); |
| 514 } | 511 } |
| 515 | 512 |
| 516 void TabRestoreService::AddEntry(Entry* entry, bool notify, bool to_front) { | 513 void TabRestoreService::AddEntry(Entry* entry, bool notify, bool to_front) { |
| 517 if (to_front) | 514 if (to_front) |
| (...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 872 } | 869 } |
| 873 } | 870 } |
| 874 | 871 |
| 875 // If there was corruption some of the entries won't be valid. Prune any | 872 // If there was corruption some of the entries won't be valid. Prune any |
| 876 // entries with no navigations. | 873 // entries with no navigations. |
| 877 ValidateAndDeleteEmptyEntries(&(entries.get())); | 874 ValidateAndDeleteEmptyEntries(&(entries.get())); |
| 878 | 875 |
| 879 loaded_entries->swap(entries.get()); | 876 loaded_entries->swap(entries.get()); |
| 880 } | 877 } |
| 881 | 878 |
| 882 Browser* TabRestoreService::RestoreTab(const Tab& tab, | 879 TabRestoreServiceDelegate* TabRestoreService::RestoreTab( |
| 883 Browser* browser, | 880 const Tab& tab, |
| 884 bool replace_existing_tab) { | 881 TabRestoreServiceDelegate* delegate, |
| 882 bool replace_existing_tab) { |
| 885 // |browser| will be NULL in cases where one isn't already available (eg, | 883 // |browser| will be NULL in cases where one isn't already available (eg, |
| 886 // when invoked on Mac OS X with no windows open). In this case, create a | 884 // when invoked on Mac OS X with no windows open). In this case, create a |
| 887 // new browser into which we restore the tabs. | 885 // new browser into which we restore the tabs. |
| 888 if (replace_existing_tab && browser) { | 886 if (replace_existing_tab && delegate) { |
| 889 browser->ReplaceRestoredTab(tab.navigations, | 887 delegate->ReplaceRestoredTab(tab.navigations, |
| 890 tab.current_navigation_index, | 888 tab.current_navigation_index, |
| 891 tab.from_last_session, | 889 tab.from_last_session, |
| 892 tab.extension_app_id, | 890 tab.extension_app_id, |
| 893 tab.session_storage_namespace); | 891 tab.session_storage_namespace); |
| 894 } else { | 892 } else { |
| 895 if (tab.has_browser()) | 893 if (tab.has_browser()) |
| 896 browser = BrowserList::FindBrowserWithID(tab.browser_id); | 894 delegate = TabRestoreServiceDelegate::FindDelegateWithID(tab.browser_id); |
| 897 | 895 |
| 898 int tab_index = -1; | 896 int tab_index = -1; |
| 899 if (browser) { | 897 if (delegate) { |
| 900 tab_index = tab.tabstrip_index; | 898 tab_index = tab.tabstrip_index; |
| 901 } else { | 899 } else { |
| 902 browser = Browser::Create(profile()); | 900 delegate = TabRestoreServiceDelegate::Create(profile()); |
| 903 if (tab.has_browser()) { | 901 if (tab.has_browser()) { |
| 904 UpdateTabBrowserIDs(tab.browser_id, browser->session_id().id()); | 902 UpdateTabBrowserIDs(tab.browser_id, delegate->GetSessionID().id()); |
| 905 } | 903 } |
| 906 } | 904 } |
| 907 | 905 |
| 908 if (tab_index < 0 || tab_index > browser->tab_count()) { | 906 if (tab_index < 0 || tab_index > delegate->GetTabCount()) { |
| 909 tab_index = browser->tab_count(); | 907 tab_index = delegate->GetTabCount(); |
| 910 } | 908 } |
| 911 | 909 |
| 912 browser->AddRestoredTab(tab.navigations, | 910 delegate->AddRestoredTab(tab.navigations, |
| 913 tab_index, | 911 tab_index, |
| 914 tab.current_navigation_index, | 912 tab.current_navigation_index, |
| 915 tab.extension_app_id, | 913 tab.extension_app_id, |
| 916 true, tab.pinned, tab.from_last_session, | 914 true, tab.pinned, tab.from_last_session, |
| 917 tab.session_storage_namespace); | 915 tab.session_storage_namespace); |
| 918 } | 916 } |
| 919 RecordAppLaunch(browser, tab); | 917 RecordAppLaunch(profile(), tab); |
| 920 return browser; | 918 return delegate; |
| 921 } | 919 } |
| 922 | 920 |
| 923 | 921 |
| 924 bool TabRestoreService::ValidateTab(Tab* tab) { | 922 bool TabRestoreService::ValidateTab(Tab* tab) { |
| 925 if (tab->navigations.empty()) | 923 if (tab->navigations.empty()) |
| 926 return false; | 924 return false; |
| 927 | 925 |
| 928 tab->current_navigation_index = | 926 tab->current_navigation_index = |
| 929 std::max(0, std::min(tab->current_navigation_index, | 927 std::max(0, std::min(tab->current_navigation_index, |
| 930 static_cast<int>(tab->navigations.size()) - 1)); | 928 static_cast<int>(tab->navigations.size()) - 1)); |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1076 // correctly write out the entries when Save is invoked (Save starts from | 1074 // correctly write out the entries when Save is invoked (Save starts from |
| 1077 // the front, not the end and we just added the entries to the end). | 1075 // the front, not the end and we just added the entries to the end). |
| 1078 entries_to_write_ = staging_entries_.size(); | 1076 entries_to_write_ = staging_entries_.size(); |
| 1079 | 1077 |
| 1080 PruneAndNotify(); | 1078 PruneAndNotify(); |
| 1081 } | 1079 } |
| 1082 | 1080 |
| 1083 Time TabRestoreService::TimeNow() const { | 1081 Time TabRestoreService::TimeNow() const { |
| 1084 return time_factory_ ? time_factory_->TimeNow() : Time::Now(); | 1082 return time_factory_ ? time_factory_->TimeNow() : Time::Now(); |
| 1085 } | 1083 } |
| OLD | NEW |