| 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/session_service.h" | 5 #include "chrome/browser/sessions/session_service.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <set> | 8 #include <set> |
| 9 #include <utility> | 9 #include <utility> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 #if defined(OS_MACOSX) | 51 #if defined(OS_MACOSX) |
| 52 #include "chrome/browser/app_controller_mac.h" | 52 #include "chrome/browser/app_controller_mac.h" |
| 53 #endif | 53 #endif |
| 54 | 54 |
| 55 using base::Time; | 55 using base::Time; |
| 56 using content::NavigationEntry; | 56 using content::NavigationEntry; |
| 57 using content::WebContents; | 57 using content::WebContents; |
| 58 using sessions::ContentSerializedNavigationBuilder; | 58 using sessions::ContentSerializedNavigationBuilder; |
| 59 using sessions::SerializedNavigationEntry; | 59 using sessions::SerializedNavigationEntry; |
| 60 | 60 |
| 61 // Identifier for commands written to file. | |
| 62 static const SessionCommand::id_type kCommandSetTabWindow = 0; | |
| 63 // OBSOLETE Superseded by kCommandSetWindowBounds3. | |
| 64 // static const SessionCommand::id_type kCommandSetWindowBounds = 1; | |
| 65 static const SessionCommand::id_type kCommandSetTabIndexInWindow = 2; | |
| 66 // OBSOLETE Superseded kCommandTabClosed/kCommandWindowClosed commands. | |
| 67 // static const SessionCommand::id_type kCommandTabClosedObsolete = 3; | |
| 68 // static const SessionCommand::id_type kCommandWindowClosedObsolete = 4; | |
| 69 static const SessionCommand::id_type | |
| 70 kCommandTabNavigationPathPrunedFromBack = 5; | |
| 71 static const SessionCommand::id_type kCommandUpdateTabNavigation = 6; | |
| 72 static const SessionCommand::id_type kCommandSetSelectedNavigationIndex = 7; | |
| 73 static const SessionCommand::id_type kCommandSetSelectedTabInIndex = 8; | |
| 74 static const SessionCommand::id_type kCommandSetWindowType = 9; | |
| 75 // OBSOLETE Superseded by kCommandSetWindowBounds3. Except for data migration. | |
| 76 // static const SessionCommand::id_type kCommandSetWindowBounds2 = 10; | |
| 77 static const SessionCommand::id_type | |
| 78 kCommandTabNavigationPathPrunedFromFront = 11; | |
| 79 static const SessionCommand::id_type kCommandSetPinnedState = 12; | |
| 80 static const SessionCommand::id_type kCommandSetExtensionAppID = 13; | |
| 81 static const SessionCommand::id_type kCommandSetWindowBounds3 = 14; | |
| 82 static const SessionCommand::id_type kCommandSetWindowAppName = 15; | |
| 83 static const SessionCommand::id_type kCommandTabClosed = 16; | |
| 84 static const SessionCommand::id_type kCommandWindowClosed = 17; | |
| 85 static const SessionCommand::id_type kCommandSetTabUserAgentOverride = 18; | |
| 86 static const SessionCommand::id_type kCommandSessionStorageAssociated = 19; | |
| 87 static const SessionCommand::id_type kCommandSetActiveWindow = 20; | |
| 88 | |
| 89 // Every kWritesPerReset commands triggers recreating the file. | 61 // Every kWritesPerReset commands triggers recreating the file. |
| 90 static const int kWritesPerReset = 250; | 62 static const int kWritesPerReset = 250; |
| 91 | 63 |
| 92 namespace { | |
| 93 | |
| 94 // Various payload structures. | |
| 95 struct ClosedPayload { | |
| 96 SessionID::id_type id; | |
| 97 int64 close_time; | |
| 98 }; | |
| 99 | |
| 100 struct WindowBoundsPayload2 { | |
| 101 SessionID::id_type window_id; | |
| 102 int32 x; | |
| 103 int32 y; | |
| 104 int32 w; | |
| 105 int32 h; | |
| 106 bool is_maximized; | |
| 107 }; | |
| 108 | |
| 109 struct WindowBoundsPayload3 { | |
| 110 SessionID::id_type window_id; | |
| 111 int32 x; | |
| 112 int32 y; | |
| 113 int32 w; | |
| 114 int32 h; | |
| 115 int32 show_state; | |
| 116 }; | |
| 117 | |
| 118 typedef SessionID::id_type ActiveWindowPayload; | |
| 119 | |
| 120 struct IDAndIndexPayload { | |
| 121 SessionID::id_type id; | |
| 122 int32 index; | |
| 123 }; | |
| 124 | |
| 125 typedef IDAndIndexPayload TabIndexInWindowPayload; | |
| 126 | |
| 127 typedef IDAndIndexPayload TabNavigationPathPrunedFromBackPayload; | |
| 128 | |
| 129 typedef IDAndIndexPayload SelectedNavigationIndexPayload; | |
| 130 | |
| 131 typedef IDAndIndexPayload SelectedTabInIndexPayload; | |
| 132 | |
| 133 typedef IDAndIndexPayload WindowTypePayload; | |
| 134 | |
| 135 typedef IDAndIndexPayload TabNavigationPathPrunedFromFrontPayload; | |
| 136 | |
| 137 struct PinnedStatePayload { | |
| 138 SessionID::id_type tab_id; | |
| 139 bool pinned_state; | |
| 140 }; | |
| 141 | |
| 142 // Persisted versions of ui::WindowShowState that are written to disk and can | |
| 143 // never change. | |
| 144 enum PersistedWindowShowState { | |
| 145 // SHOW_STATE_DEFAULT (0) never persisted. | |
| 146 PERSISTED_SHOW_STATE_NORMAL = 1, | |
| 147 PERSISTED_SHOW_STATE_MINIMIZED = 2, | |
| 148 PERSISTED_SHOW_STATE_MAXIMIZED = 3, | |
| 149 // SHOW_STATE_INACTIVE (4) never persisted. | |
| 150 PERSISTED_SHOW_STATE_FULLSCREEN = 5, | |
| 151 PERSISTED_SHOW_STATE_DETACHED_DEPRECATED = 6, | |
| 152 PERSISTED_SHOW_STATE_END = 6 | |
| 153 }; | |
| 154 | |
| 155 // Assert to ensure PersistedWindowShowState is updated if ui::WindowShowState | |
| 156 // is changed. | |
| 157 COMPILE_ASSERT(ui::SHOW_STATE_END == | |
| 158 static_cast<ui::WindowShowState>(PERSISTED_SHOW_STATE_END), | |
| 159 persisted_show_state_mismatch); | |
| 160 | |
| 161 // Returns the show state to store to disk based |state|. | |
| 162 PersistedWindowShowState ShowStateToPersistedShowState( | |
| 163 ui::WindowShowState state) { | |
| 164 switch (state) { | |
| 165 case ui::SHOW_STATE_NORMAL: | |
| 166 return PERSISTED_SHOW_STATE_NORMAL; | |
| 167 case ui::SHOW_STATE_MINIMIZED: | |
| 168 return PERSISTED_SHOW_STATE_MINIMIZED; | |
| 169 case ui::SHOW_STATE_MAXIMIZED: | |
| 170 return PERSISTED_SHOW_STATE_MAXIMIZED; | |
| 171 case ui::SHOW_STATE_FULLSCREEN: | |
| 172 return PERSISTED_SHOW_STATE_FULLSCREEN; | |
| 173 | |
| 174 case ui::SHOW_STATE_DEFAULT: | |
| 175 case ui::SHOW_STATE_INACTIVE: | |
| 176 return PERSISTED_SHOW_STATE_NORMAL; | |
| 177 | |
| 178 case ui::SHOW_STATE_END: | |
| 179 break; | |
| 180 } | |
| 181 NOTREACHED(); | |
| 182 return PERSISTED_SHOW_STATE_NORMAL; | |
| 183 } | |
| 184 | |
| 185 // Lints show state values when read back from persited disk. | |
| 186 ui::WindowShowState PersistedShowStateToShowState(int state) { | |
| 187 switch (state) { | |
| 188 case PERSISTED_SHOW_STATE_NORMAL: | |
| 189 return ui::SHOW_STATE_NORMAL; | |
| 190 case PERSISTED_SHOW_STATE_MINIMIZED: | |
| 191 return ui::SHOW_STATE_MINIMIZED; | |
| 192 case PERSISTED_SHOW_STATE_MAXIMIZED: | |
| 193 return ui::SHOW_STATE_MAXIMIZED; | |
| 194 case PERSISTED_SHOW_STATE_FULLSCREEN: | |
| 195 return ui::SHOW_STATE_FULLSCREEN; | |
| 196 case PERSISTED_SHOW_STATE_DETACHED_DEPRECATED: | |
| 197 return ui::SHOW_STATE_NORMAL; | |
| 198 } | |
| 199 NOTREACHED(); | |
| 200 return ui::SHOW_STATE_NORMAL; | |
| 201 } | |
| 202 | |
| 203 } // namespace | |
| 204 | |
| 205 // SessionService ------------------------------------------------------------- | 64 // SessionService ------------------------------------------------------------- |
| 206 | 65 |
| 207 SessionService::SessionService(Profile* profile) | 66 SessionService::SessionService(Profile* profile) |
| 208 : BaseSessionService( | 67 : BaseSessionService( |
| 209 SESSION_RESTORE, | 68 SESSION_RESTORE, |
| 210 profile->GetPath(), | 69 profile->GetPath(), |
| 211 scoped_ptr<BaseSessionServiceDelegate>( | 70 scoped_ptr<BaseSessionServiceDelegate>( |
| 212 new BaseSessionServiceDelegateImpl(true))), | 71 new BaseSessionServiceDelegateImpl(true))), |
| 213 profile_(profile), | 72 profile_(profile), |
| 214 has_open_trackable_browsers_(false), | 73 has_open_trackable_browsers_(false), |
| (...skipping 30 matching lines...) Expand all Loading... |
| 245 // the SessionService is a KeyedService. | 104 // the SessionService is a KeyedService. |
| 246 BrowserList::RemoveObserver(this); | 105 BrowserList::RemoveObserver(this); |
| 247 Save(); | 106 Save(); |
| 248 } | 107 } |
| 249 | 108 |
| 250 bool SessionService::RestoreIfNecessary(const std::vector<GURL>& urls_to_open) { | 109 bool SessionService::RestoreIfNecessary(const std::vector<GURL>& urls_to_open) { |
| 251 return RestoreIfNecessary(urls_to_open, NULL); | 110 return RestoreIfNecessary(urls_to_open, NULL); |
| 252 } | 111 } |
| 253 | 112 |
| 254 void SessionService::ResetFromCurrentBrowsers() { | 113 void SessionService::ResetFromCurrentBrowsers() { |
| 255 ScheduleReset(); | 114 ScheduleResetCommands(); |
| 256 } | 115 } |
| 257 | 116 |
| 258 void SessionService::MoveCurrentSessionToLastSession() { | 117 void SessionService::MoveCurrentSessionToLastSession() { |
| 259 pending_tab_close_ids_.clear(); | 118 pending_tab_close_ids_.clear(); |
| 260 window_closing_ids_.clear(); | 119 window_closing_ids_.clear(); |
| 261 pending_window_close_ids_.clear(); | 120 pending_window_close_ids_.clear(); |
| 262 | 121 |
| 263 Save(); | 122 Save(); |
| 264 | 123 |
| 265 RunTaskOnBackendThread( | 124 RunTaskOnBackendThread( |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 // tab closed. | 195 // tab closed. |
| 337 pending_tab_close_ids_.insert(tab_id.id()); | 196 pending_tab_close_ids_.insert(tab_id.id()); |
| 338 has_open_trackable_browsers_ = false; | 197 has_open_trackable_browsers_ = false; |
| 339 } | 198 } |
| 340 } | 199 } |
| 341 | 200 |
| 342 void SessionService::WindowOpened(Browser* browser) { | 201 void SessionService::WindowOpened(Browser* browser) { |
| 343 if (!ShouldTrackBrowser(browser)) | 202 if (!ShouldTrackBrowser(browser)) |
| 344 return; | 203 return; |
| 345 | 204 |
| 346 AppType app_type = browser->is_app() ? TYPE_APP : TYPE_NORMAL; | 205 SessionServiceCommands::AppType app_type = |
| 206 browser->is_app() ? SessionServiceCommands::TYPE_APP : |
| 207 SessionServiceCommands::TYPE_NORMAL; |
| 347 RestoreIfNecessary(std::vector<GURL>(), browser); | 208 RestoreIfNecessary(std::vector<GURL>(), browser); |
| 348 SetWindowType(browser->session_id(), browser->type(), app_type); | 209 SetWindowType(browser->session_id(), browser->type(), app_type); |
| 349 SetWindowAppName(browser->session_id(), browser->app_name()); | 210 SetWindowAppName(browser->session_id(), browser->app_name()); |
| 350 } | 211 } |
| 351 | 212 |
| 352 void SessionService::WindowClosing(const SessionID& window_id) { | 213 void SessionService::WindowClosing(const SessionID& window_id) { |
| 353 if (!ShouldTrackChangesToWindow(window_id)) | 214 if (!ShouldTrackChangesToWindow(window_id)) |
| 354 return; | 215 return; |
| 355 | 216 |
| 356 // The window is about to close. If there are other tabbed browsers with the | 217 // The window is about to close. If there are other tabbed browsers with the |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 411 if (!has_open_trackable_browsers_) | 272 if (!has_open_trackable_browsers_) |
| 412 pending_window_close_ids_.insert(window_id.id()); | 273 pending_window_close_ids_.insert(window_id.id()); |
| 413 else | 274 else |
| 414 ScheduleCommand(CreateWindowClosedCommand(window_id.id())); | 275 ScheduleCommand(CreateWindowClosedCommand(window_id.id())); |
| 415 } | 276 } |
| 416 MaybeDeleteSessionOnlyData(); | 277 MaybeDeleteSessionOnlyData(); |
| 417 } | 278 } |
| 418 | 279 |
| 419 void SessionService::SetWindowType(const SessionID& window_id, | 280 void SessionService::SetWindowType(const SessionID& window_id, |
| 420 Browser::Type type, | 281 Browser::Type type, |
| 421 AppType app_type) { | 282 SessionServiceCommands::AppType app_type) { |
| 422 if (!should_track_changes_for_browser_type(type, app_type)) | 283 SessionWindow::WindowType window_type = WindowTypeForBrowserType(type); |
| 284 if (!ShouldRestoreWindowOfType(window_type, app_type)) |
| 423 return; | 285 return; |
| 424 | 286 |
| 425 windows_tracking_.insert(window_id.id()); | 287 windows_tracking_.insert(window_id.id()); |
| 426 | 288 |
| 427 // The user created a new tabbed browser with our profile. Commit any | 289 // The user created a new tabbed browser with our profile. Commit any |
| 428 // pending closes. | 290 // pending closes. |
| 429 CommitPendingCloses(); | 291 CommitPendingCloses(); |
| 430 | 292 |
| 431 has_open_trackable_browsers_ = true; | 293 has_open_trackable_browsers_ = true; |
| 432 move_on_new_browser_ = true; | 294 move_on_new_browser_ = true; |
| 433 | 295 |
| 434 ScheduleCommand( | 296 ScheduleCommand(CreateSetWindowTypeCommand(window_id, window_type)); |
| 435 CreateSetWindowTypeCommand(window_id, WindowTypeForBrowserType(type))); | |
| 436 } | 297 } |
| 437 | 298 |
| 438 void SessionService::SetWindowAppName( | 299 void SessionService::SetWindowAppName( |
| 439 const SessionID& window_id, | 300 const SessionID& window_id, |
| 440 const std::string& app_name) { | 301 const std::string& app_name) { |
| 441 if (!ShouldTrackChangesToWindow(window_id)) | 302 if (!ShouldTrackChangesToWindow(window_id)) |
| 442 return; | 303 return; |
| 443 | 304 |
| 444 ScheduleCommand(CreateSetTabExtensionAppIDCommand( | 305 ScheduleCommand(CreateSetWindowAppNameCommand(window_id, app_name)); |
| 445 kCommandSetWindowAppName, | |
| 446 window_id.id(), | |
| 447 app_name)); | |
| 448 } | 306 } |
| 449 | 307 |
| 450 void SessionService::TabNavigationPathPrunedFromBack(const SessionID& window_id, | 308 void SessionService::TabNavigationPathPrunedFromBack(const SessionID& window_id, |
| 451 const SessionID& tab_id, | 309 const SessionID& tab_id, |
| 452 int count) { | 310 int count) { |
| 453 if (!ShouldTrackChangesToWindow(window_id)) | 311 if (!ShouldTrackChangesToWindow(window_id)) |
| 454 return; | 312 return; |
| 455 | 313 |
| 456 TabNavigationPathPrunedFromBackPayload payload = { 0 }; | 314 ScheduleCommand(CreateTabNavigationPathPrunedFromBackCommand(tab_id, count)); |
| 457 payload.id = tab_id.id(); | |
| 458 payload.index = count; | |
| 459 SessionCommand* command = | |
| 460 new SessionCommand(kCommandTabNavigationPathPrunedFromBack, | |
| 461 sizeof(payload)); | |
| 462 memcpy(command->contents(), &payload, sizeof(payload)); | |
| 463 ScheduleCommand(command); | |
| 464 } | 315 } |
| 465 | 316 |
| 466 void SessionService::TabNavigationPathPrunedFromFront( | 317 void SessionService::TabNavigationPathPrunedFromFront( |
| 467 const SessionID& window_id, | 318 const SessionID& window_id, |
| 468 const SessionID& tab_id, | 319 const SessionID& tab_id, |
| 469 int count) { | 320 int count) { |
| 470 if (!ShouldTrackChangesToWindow(window_id)) | 321 if (!ShouldTrackChangesToWindow(window_id)) |
| 471 return; | 322 return; |
| 472 | 323 |
| 473 // Update the range of indices. | 324 // Update the range of indices. |
| 474 if (tab_to_available_range_.find(tab_id.id()) != | 325 if (tab_to_available_range_.find(tab_id.id()) != |
| 475 tab_to_available_range_.end()) { | 326 tab_to_available_range_.end()) { |
| 476 std::pair<int, int>& range = tab_to_available_range_[tab_id.id()]; | 327 std::pair<int, int>& range = tab_to_available_range_[tab_id.id()]; |
| 477 range.first = std::max(0, range.first - count); | 328 range.first = std::max(0, range.first - count); |
| 478 range.second = std::max(0, range.second - count); | 329 range.second = std::max(0, range.second - count); |
| 479 } | 330 } |
| 480 | 331 |
| 481 TabNavigationPathPrunedFromFrontPayload payload = { 0 }; | 332 ScheduleCommand(CreateTabNavigationPathPrunedFromFrontCommand(tab_id, count)); |
| 482 payload.id = tab_id.id(); | |
| 483 payload.index = count; | |
| 484 SessionCommand* command = | |
| 485 new SessionCommand(kCommandTabNavigationPathPrunedFromFront, | |
| 486 sizeof(payload)); | |
| 487 memcpy(command->contents(), &payload, sizeof(payload)); | |
| 488 ScheduleCommand(command); | |
| 489 } | 333 } |
| 490 | 334 |
| 491 void SessionService::UpdateTabNavigation( | 335 void SessionService::UpdateTabNavigation( |
| 492 const SessionID& window_id, | 336 const SessionID& window_id, |
| 493 const SessionID& tab_id, | 337 const SessionID& tab_id, |
| 494 const SerializedNavigationEntry& navigation) { | 338 const SerializedNavigationEntry& navigation) { |
| 495 if (!ShouldTrackEntry(navigation.virtual_url()) || | 339 if (!ShouldTrackEntry(navigation.virtual_url()) || |
| 496 !ShouldTrackChangesToWindow(window_id)) { | 340 !ShouldTrackChangesToWindow(window_id)) { |
| 497 return; | 341 return; |
| 498 } | 342 } |
| 499 | 343 |
| 500 if (tab_to_available_range_.find(tab_id.id()) != | 344 if (tab_to_available_range_.find(tab_id.id()) != |
| 501 tab_to_available_range_.end()) { | 345 tab_to_available_range_.end()) { |
| 502 std::pair<int, int>& range = tab_to_available_range_[tab_id.id()]; | 346 std::pair<int, int>& range = tab_to_available_range_[tab_id.id()]; |
| 503 range.first = std::min(navigation.index(), range.first); | 347 range.first = std::min(navigation.index(), range.first); |
| 504 range.second = std::max(navigation.index(), range.second); | 348 range.second = std::max(navigation.index(), range.second); |
| 505 } | 349 } |
| 506 ScheduleCommand(CreateUpdateTabNavigationCommand(kCommandUpdateTabNavigation, | 350 ScheduleCommand(CreateUpdateTabNavigationCommand(tab_id, navigation)); |
| 507 tab_id.id(), navigation)); | |
| 508 } | 351 } |
| 509 | 352 |
| 510 void SessionService::TabRestored(WebContents* tab, bool pinned) { | 353 void SessionService::TabRestored(WebContents* tab, bool pinned) { |
| 511 SessionTabHelper* session_tab_helper = SessionTabHelper::FromWebContents(tab); | 354 SessionTabHelper* session_tab_helper = SessionTabHelper::FromWebContents(tab); |
| 512 if (!ShouldTrackChangesToWindow(session_tab_helper->window_id())) | 355 if (!ShouldTrackChangesToWindow(session_tab_helper->window_id())) |
| 513 return; | 356 return; |
| 514 | 357 |
| 515 BuildCommandsForTab(session_tab_helper->window_id(), tab, -1, | 358 BuildCommandsForTab(session_tab_helper->window_id(), tab, -1, |
| 516 pinned, &pending_commands(), NULL); | 359 pinned, &pending_commands(), NULL); |
| 517 StartSaveTimer(); | 360 StartSaveTimer(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 534 } | 377 } |
| 535 } | 378 } |
| 536 ScheduleCommand(CreateSetSelectedNavigationIndexCommand(tab_id, index)); | 379 ScheduleCommand(CreateSetSelectedNavigationIndexCommand(tab_id, index)); |
| 537 } | 380 } |
| 538 | 381 |
| 539 void SessionService::SetSelectedTabInWindow(const SessionID& window_id, | 382 void SessionService::SetSelectedTabInWindow(const SessionID& window_id, |
| 540 int index) { | 383 int index) { |
| 541 if (!ShouldTrackChangesToWindow(window_id)) | 384 if (!ShouldTrackChangesToWindow(window_id)) |
| 542 return; | 385 return; |
| 543 | 386 |
| 544 ScheduleCommand(CreateSetSelectedTabInWindow(window_id, index)); | 387 ScheduleCommand(CreateSetSelectedTabInWindowCommand(window_id, index)); |
| 545 } | 388 } |
| 546 | 389 |
| 547 void SessionService::SetTabUserAgentOverride( | 390 void SessionService::SetTabUserAgentOverride( |
| 548 const SessionID& window_id, | 391 const SessionID& window_id, |
| 549 const SessionID& tab_id, | 392 const SessionID& tab_id, |
| 550 const std::string& user_agent_override) { | 393 const std::string& user_agent_override) { |
| 551 if (!ShouldTrackChangesToWindow(window_id)) | 394 if (!ShouldTrackChangesToWindow(window_id)) |
| 552 return; | 395 return; |
| 553 | 396 |
| 554 ScheduleCommand(CreateSetTabUserAgentOverrideCommand( | 397 ScheduleCommand(CreateSetTabUserAgentOverrideCommand(tab_id, |
| 555 kCommandSetTabUserAgentOverride, tab_id.id(), user_agent_override)); | 398 user_agent_override)); |
| 399 } |
| 400 |
| 401 void SessionService::SetTabExtensionAppID( |
| 402 const SessionID& window_id, |
| 403 const SessionID& tab_id, |
| 404 const std::string& extension_app_id) { |
| 405 if (!ShouldTrackChangesToWindow(window_id)) |
| 406 return; |
| 407 |
| 408 ScheduleCommand(CreateSetTabExtensionAppIDCommand(tab_id, extension_app_id)); |
| 409 } |
| 410 |
| 411 bool SessionService::ShouldRestoreWindowOfType( |
| 412 SessionWindow::WindowType window_type, |
| 413 SessionServiceCommands::AppType app_type) const { |
| 414 #if defined(OS_CHROMEOS) |
| 415 // Restore app popups for ChromeOS alone. |
| 416 if (window_type == SessionWindow::TYPE_POPUP && app_type == TYPE_APP) |
| 417 return true; |
| 418 #endif |
| 419 |
| 420 return window_type == SessionWindow::TYPE_TABBED; |
| 556 } | 421 } |
| 557 | 422 |
| 558 base::CancelableTaskTracker::TaskId SessionService::GetLastSession( | 423 base::CancelableTaskTracker::TaskId SessionService::GetLastSession( |
| 559 const SessionCallback& callback, | 424 const SessionCallback& callback, |
| 560 base::CancelableTaskTracker* tracker) { | 425 base::CancelableTaskTracker* tracker) { |
| 561 // OnGotSessionCommands maps the SessionCommands to browser state, then run | 426 // OnGotSessionCommands maps the SessionCommands to browser state, then run |
| 562 // the callback. | 427 // the callback. |
| 563 return ScheduleGetLastSessionCommands( | 428 return ScheduleGetLastSessionCommands( |
| 564 base::Bind(&SessionService::OnGotSessionCommands, | 429 base::Bind(&SessionService::OnGotSessionCommands, |
| 565 weak_factory_.GetWeakPtr(), callback), | 430 weak_factory_.GetWeakPtr(), callback), |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 745 default: | 610 default: |
| 746 NOTREACHED(); | 611 NOTREACHED(); |
| 747 } | 612 } |
| 748 } | 613 } |
| 749 | 614 |
| 750 void SessionService::OnBrowserSetLastActive(Browser* browser) { | 615 void SessionService::OnBrowserSetLastActive(Browser* browser) { |
| 751 if (ShouldTrackBrowser(browser)) | 616 if (ShouldTrackBrowser(browser)) |
| 752 ScheduleCommand(CreateSetActiveWindowCommand(browser->session_id())); | 617 ScheduleCommand(CreateSetActiveWindowCommand(browser->session_id())); |
| 753 } | 618 } |
| 754 | 619 |
| 755 void SessionService::SetTabExtensionAppID( | |
| 756 const SessionID& window_id, | |
| 757 const SessionID& tab_id, | |
| 758 const std::string& extension_app_id) { | |
| 759 if (!ShouldTrackChangesToWindow(window_id)) | |
| 760 return; | |
| 761 | |
| 762 ScheduleCommand(CreateSetTabExtensionAppIDCommand(kCommandSetExtensionAppID, | |
| 763 tab_id.id(), extension_app_id)); | |
| 764 } | |
| 765 | |
| 766 SessionCommand* SessionService::CreateSetSelectedTabInWindow( | |
| 767 const SessionID& window_id, | |
| 768 int index) { | |
| 769 SelectedTabInIndexPayload payload = { 0 }; | |
| 770 payload.id = window_id.id(); | |
| 771 payload.index = index; | |
| 772 SessionCommand* command = new SessionCommand(kCommandSetSelectedTabInIndex, | |
| 773 sizeof(payload)); | |
| 774 memcpy(command->contents(), &payload, sizeof(payload)); | |
| 775 return command; | |
| 776 } | |
| 777 | |
| 778 SessionCommand* SessionService::CreateSetTabWindowCommand( | |
| 779 const SessionID& window_id, | |
| 780 const SessionID& tab_id) { | |
| 781 SessionID::id_type payload[] = { window_id.id(), tab_id.id() }; | |
| 782 SessionCommand* command = | |
| 783 new SessionCommand(kCommandSetTabWindow, sizeof(payload)); | |
| 784 memcpy(command->contents(), payload, sizeof(payload)); | |
| 785 return command; | |
| 786 } | |
| 787 | |
| 788 SessionCommand* SessionService::CreateSetWindowBoundsCommand( | |
| 789 const SessionID& window_id, | |
| 790 const gfx::Rect& bounds, | |
| 791 ui::WindowShowState show_state) { | |
| 792 WindowBoundsPayload3 payload = { 0 }; | |
| 793 payload.window_id = window_id.id(); | |
| 794 payload.x = bounds.x(); | |
| 795 payload.y = bounds.y(); | |
| 796 payload.w = bounds.width(); | |
| 797 payload.h = bounds.height(); | |
| 798 payload.show_state = ShowStateToPersistedShowState(show_state); | |
| 799 SessionCommand* command = new SessionCommand(kCommandSetWindowBounds3, | |
| 800 sizeof(payload)); | |
| 801 memcpy(command->contents(), &payload, sizeof(payload)); | |
| 802 return command; | |
| 803 } | |
| 804 | |
| 805 SessionCommand* SessionService::CreateSetTabIndexInWindowCommand( | |
| 806 const SessionID& tab_id, | |
| 807 int new_index) { | |
| 808 TabIndexInWindowPayload payload = { 0 }; | |
| 809 payload.id = tab_id.id(); | |
| 810 payload.index = new_index; | |
| 811 SessionCommand* command = | |
| 812 new SessionCommand(kCommandSetTabIndexInWindow, sizeof(payload)); | |
| 813 memcpy(command->contents(), &payload, sizeof(payload)); | |
| 814 return command; | |
| 815 } | |
| 816 | |
| 817 SessionCommand* SessionService::CreateTabClosedCommand( | |
| 818 const SessionID::id_type tab_id) { | |
| 819 ClosedPayload payload; | |
| 820 // Because of what appears to be a compiler bug setting payload to {0} doesn't | |
| 821 // set the padding to 0, resulting in Purify reporting an UMR when we write | |
| 822 // the structure to disk. To avoid this we explicitly memset the struct. | |
| 823 memset(&payload, 0, sizeof(payload)); | |
| 824 payload.id = tab_id; | |
| 825 payload.close_time = Time::Now().ToInternalValue(); | |
| 826 SessionCommand* command = | |
| 827 new SessionCommand(kCommandTabClosed, sizeof(payload)); | |
| 828 memcpy(command->contents(), &payload, sizeof(payload)); | |
| 829 return command; | |
| 830 } | |
| 831 | |
| 832 SessionCommand* SessionService::CreateWindowClosedCommand( | |
| 833 const SessionID::id_type window_id) { | |
| 834 ClosedPayload payload; | |
| 835 // See comment in CreateTabClosedCommand as to why we do this. | |
| 836 memset(&payload, 0, sizeof(payload)); | |
| 837 payload.id = window_id; | |
| 838 payload.close_time = Time::Now().ToInternalValue(); | |
| 839 SessionCommand* command = | |
| 840 new SessionCommand(kCommandWindowClosed, sizeof(payload)); | |
| 841 memcpy(command->contents(), &payload, sizeof(payload)); | |
| 842 return command; | |
| 843 } | |
| 844 | |
| 845 SessionCommand* SessionService::CreateSetSelectedNavigationIndexCommand( | |
| 846 const SessionID& tab_id, | |
| 847 int index) { | |
| 848 SelectedNavigationIndexPayload payload = { 0 }; | |
| 849 payload.id = tab_id.id(); | |
| 850 payload.index = index; | |
| 851 SessionCommand* command = new SessionCommand( | |
| 852 kCommandSetSelectedNavigationIndex, sizeof(payload)); | |
| 853 memcpy(command->contents(), &payload, sizeof(payload)); | |
| 854 return command; | |
| 855 } | |
| 856 | |
| 857 SessionCommand* SessionService::CreateSetWindowTypeCommand( | |
| 858 const SessionID& window_id, | |
| 859 WindowType type) { | |
| 860 WindowTypePayload payload = { 0 }; | |
| 861 payload.id = window_id.id(); | |
| 862 payload.index = static_cast<int32>(type); | |
| 863 SessionCommand* command = new SessionCommand( | |
| 864 kCommandSetWindowType, sizeof(payload)); | |
| 865 memcpy(command->contents(), &payload, sizeof(payload)); | |
| 866 return command; | |
| 867 } | |
| 868 | |
| 869 SessionCommand* SessionService::CreatePinnedStateCommand( | |
| 870 const SessionID& tab_id, | |
| 871 bool is_pinned) { | |
| 872 PinnedStatePayload payload = { 0 }; | |
| 873 payload.tab_id = tab_id.id(); | |
| 874 payload.pinned_state = is_pinned; | |
| 875 SessionCommand* command = | |
| 876 new SessionCommand(kCommandSetPinnedState, sizeof(payload)); | |
| 877 memcpy(command->contents(), &payload, sizeof(payload)); | |
| 878 return command; | |
| 879 } | |
| 880 | |
| 881 SessionCommand* SessionService::CreateSessionStorageAssociatedCommand( | |
| 882 const SessionID& tab_id, | |
| 883 const std::string& session_storage_persistent_id) { | |
| 884 Pickle pickle; | |
| 885 pickle.WriteInt(tab_id.id()); | |
| 886 pickle.WriteString(session_storage_persistent_id); | |
| 887 return new SessionCommand(kCommandSessionStorageAssociated, pickle); | |
| 888 } | |
| 889 | |
| 890 SessionCommand* SessionService::CreateSetActiveWindowCommand( | |
| 891 const SessionID& window_id) { | |
| 892 ActiveWindowPayload payload = 0; | |
| 893 payload = window_id.id(); | |
| 894 SessionCommand* command = | |
| 895 new SessionCommand(kCommandSetActiveWindow, sizeof(payload)); | |
| 896 memcpy(command->contents(), &payload, sizeof(payload)); | |
| 897 return command; | |
| 898 } | |
| 899 | |
| 900 void SessionService::OnGotSessionCommands( | 620 void SessionService::OnGotSessionCommands( |
| 901 const SessionCallback& callback, | 621 const SessionCallback& callback, |
| 902 ScopedVector<SessionCommand> commands) { | 622 ScopedVector<SessionCommand> commands) { |
| 903 ScopedVector<SessionWindow> valid_windows; | 623 ScopedVector<SessionWindow> valid_windows; |
| 904 SessionID::id_type active_window_id = 0; | 624 SessionID::id_type active_window_id = 0; |
| 905 | 625 |
| 626 startup_metric_utils::ScopedSlowStartupUMA |
| 627 scoped_timer("Startup.SlowStartupSessionServiceCreateTabsAndWindows"); |
| 628 |
| 906 RestoreSessionFromCommands( | 629 RestoreSessionFromCommands( |
| 907 commands.get(), &valid_windows.get(), &active_window_id); | 630 commands.get(), &valid_windows.get(), &active_window_id); |
| 908 callback.Run(valid_windows.Pass(), active_window_id); | 631 callback.Run(valid_windows.Pass(), active_window_id); |
| 909 } | 632 } |
| 910 | 633 |
| 911 void SessionService::RestoreSessionFromCommands( | |
| 912 const std::vector<SessionCommand*>& commands, | |
| 913 std::vector<SessionWindow*>* valid_windows, | |
| 914 SessionID::id_type* active_window_id) { | |
| 915 std::map<int, SessionTab*> tabs; | |
| 916 std::map<int, SessionWindow*> windows; | |
| 917 | |
| 918 VLOG(1) << "RestoreSessionFromCommands " << commands.size(); | |
| 919 if (CreateTabsAndWindows(commands, &tabs, &windows, active_window_id)) { | |
| 920 AddTabsToWindows(&tabs, &windows); | |
| 921 SortTabsBasedOnVisualOrderAndPrune(&windows, valid_windows); | |
| 922 UpdateSelectedTabIndex(valid_windows); | |
| 923 } | |
| 924 STLDeleteValues(&tabs); | |
| 925 // Don't delete conents of windows, that is done by the caller as all | |
| 926 // valid windows are added to valid_windows. | |
| 927 } | |
| 928 | |
| 929 void SessionService::UpdateSelectedTabIndex( | |
| 930 std::vector<SessionWindow*>* windows) { | |
| 931 for (std::vector<SessionWindow*>::const_iterator i = windows->begin(); | |
| 932 i != windows->end(); ++i) { | |
| 933 // See note in SessionWindow as to why we do this. | |
| 934 int new_index = 0; | |
| 935 for (std::vector<SessionTab*>::const_iterator j = (*i)->tabs.begin(); | |
| 936 j != (*i)->tabs.end(); ++j) { | |
| 937 if ((*j)->tab_visual_index == (*i)->selected_tab_index) { | |
| 938 new_index = static_cast<int>(j - (*i)->tabs.begin()); | |
| 939 break; | |
| 940 } | |
| 941 } | |
| 942 (*i)->selected_tab_index = new_index; | |
| 943 } | |
| 944 } | |
| 945 | |
| 946 SessionWindow* SessionService::GetWindow( | |
| 947 SessionID::id_type window_id, | |
| 948 IdToSessionWindow* windows) { | |
| 949 std::map<int, SessionWindow*>::iterator i = windows->find(window_id); | |
| 950 if (i == windows->end()) { | |
| 951 SessionWindow* window = new SessionWindow(); | |
| 952 window->window_id.set_id(window_id); | |
| 953 (*windows)[window_id] = window; | |
| 954 return window; | |
| 955 } | |
| 956 return i->second; | |
| 957 } | |
| 958 | |
| 959 SessionTab* SessionService::GetTab( | |
| 960 SessionID::id_type tab_id, | |
| 961 IdToSessionTab* tabs) { | |
| 962 DCHECK(tabs); | |
| 963 std::map<int, SessionTab*>::iterator i = tabs->find(tab_id); | |
| 964 if (i == tabs->end()) { | |
| 965 SessionTab* tab = new SessionTab(); | |
| 966 tab->tab_id.set_id(tab_id); | |
| 967 (*tabs)[tab_id] = tab; | |
| 968 return tab; | |
| 969 } | |
| 970 return i->second; | |
| 971 } | |
| 972 | |
| 973 std::vector<SerializedNavigationEntry>::iterator | |
| 974 SessionService::FindClosestNavigationWithIndex( | |
| 975 std::vector<SerializedNavigationEntry>* navigations, | |
| 976 int index) { | |
| 977 DCHECK(navigations); | |
| 978 for (std::vector<SerializedNavigationEntry>::iterator | |
| 979 i = navigations->begin(); i != navigations->end(); ++i) { | |
| 980 if (i->index() >= index) | |
| 981 return i; | |
| 982 } | |
| 983 return navigations->end(); | |
| 984 } | |
| 985 | |
| 986 // Function used in sorting windows. Sorting is done based on window id. As | |
| 987 // window ids increment for each new window, this effectively sorts by creation | |
| 988 // time. | |
| 989 static bool WindowOrderSortFunction(const SessionWindow* w1, | |
| 990 const SessionWindow* w2) { | |
| 991 return w1->window_id.id() < w2->window_id.id(); | |
| 992 } | |
| 993 | |
| 994 // Compares the two tabs based on visual index. | |
| 995 static bool TabVisualIndexSortFunction(const SessionTab* t1, | |
| 996 const SessionTab* t2) { | |
| 997 const int delta = t1->tab_visual_index - t2->tab_visual_index; | |
| 998 return delta == 0 ? (t1->tab_id.id() < t2->tab_id.id()) : (delta < 0); | |
| 999 } | |
| 1000 | |
| 1001 void SessionService::SortTabsBasedOnVisualOrderAndPrune( | |
| 1002 std::map<int, SessionWindow*>* windows, | |
| 1003 std::vector<SessionWindow*>* valid_windows) { | |
| 1004 std::map<int, SessionWindow*>::iterator i = windows->begin(); | |
| 1005 while (i != windows->end()) { | |
| 1006 SessionWindow* window = i->second; | |
| 1007 AppType app_type = window->app_name.empty() ? TYPE_NORMAL : TYPE_APP; | |
| 1008 if (window->tabs.empty() || window->is_constrained || | |
| 1009 !should_track_changes_for_browser_type( | |
| 1010 static_cast<Browser::Type>(window->type), | |
| 1011 app_type)) { | |
| 1012 delete window; | |
| 1013 windows->erase(i++); | |
| 1014 } else { | |
| 1015 // Valid window; sort the tabs and add it to the list of valid windows. | |
| 1016 std::sort(window->tabs.begin(), window->tabs.end(), | |
| 1017 &TabVisualIndexSortFunction); | |
| 1018 // Otherwise, add the window such that older windows appear first. | |
| 1019 if (valid_windows->empty()) { | |
| 1020 valid_windows->push_back(window); | |
| 1021 } else { | |
| 1022 valid_windows->insert( | |
| 1023 std::upper_bound(valid_windows->begin(), valid_windows->end(), | |
| 1024 window, &WindowOrderSortFunction), | |
| 1025 window); | |
| 1026 } | |
| 1027 ++i; | |
| 1028 } | |
| 1029 } | |
| 1030 } | |
| 1031 | |
| 1032 void SessionService::AddTabsToWindows(std::map<int, SessionTab*>* tabs, | |
| 1033 std::map<int, SessionWindow*>* windows) { | |
| 1034 VLOG(1) << "AddTabsToWindws"; | |
| 1035 VLOG(1) << "Tabs " << tabs->size() << ", windows " << windows->size(); | |
| 1036 std::map<int, SessionTab*>::iterator i = tabs->begin(); | |
| 1037 while (i != tabs->end()) { | |
| 1038 SessionTab* tab = i->second; | |
| 1039 if (tab->window_id.id() && !tab->navigations.empty()) { | |
| 1040 SessionWindow* window = GetWindow(tab->window_id.id(), windows); | |
| 1041 window->tabs.push_back(tab); | |
| 1042 tabs->erase(i++); | |
| 1043 | |
| 1044 // See note in SessionTab as to why we do this. | |
| 1045 std::vector<SerializedNavigationEntry>::iterator j = | |
| 1046 FindClosestNavigationWithIndex(&(tab->navigations), | |
| 1047 tab->current_navigation_index); | |
| 1048 if (j == tab->navigations.end()) { | |
| 1049 tab->current_navigation_index = | |
| 1050 static_cast<int>(tab->navigations.size() - 1); | |
| 1051 } else { | |
| 1052 tab->current_navigation_index = | |
| 1053 static_cast<int>(j - tab->navigations.begin()); | |
| 1054 } | |
| 1055 } else { | |
| 1056 // Never got a set tab index in window, or tabs are empty, nothing | |
| 1057 // to do. | |
| 1058 ++i; | |
| 1059 } | |
| 1060 } | |
| 1061 } | |
| 1062 | |
| 1063 bool SessionService::CreateTabsAndWindows( | |
| 1064 const std::vector<SessionCommand*>& data, | |
| 1065 std::map<int, SessionTab*>* tabs, | |
| 1066 std::map<int, SessionWindow*>* windows, | |
| 1067 SessionID::id_type* active_window_id) { | |
| 1068 // If the file is corrupt (command with wrong size, or unknown command), we | |
| 1069 // still return true and attempt to restore what we we can. | |
| 1070 VLOG(1) << "CreateTabsAndWindows"; | |
| 1071 | |
| 1072 startup_metric_utils::ScopedSlowStartupUMA | |
| 1073 scoped_timer("Startup.SlowStartupSessionServiceCreateTabsAndWindows"); | |
| 1074 | |
| 1075 for (std::vector<SessionCommand*>::const_iterator i = data.begin(); | |
| 1076 i != data.end(); ++i) { | |
| 1077 const SessionCommand::id_type kCommandSetWindowBounds2 = 10; | |
| 1078 const SessionCommand* command = *i; | |
| 1079 | |
| 1080 VLOG(1) << "Read command " << (int) command->id(); | |
| 1081 switch (command->id()) { | |
| 1082 case kCommandSetTabWindow: { | |
| 1083 SessionID::id_type payload[2]; | |
| 1084 if (!command->GetPayload(payload, sizeof(payload))) { | |
| 1085 VLOG(1) << "Failed reading command " << command->id(); | |
| 1086 return true; | |
| 1087 } | |
| 1088 GetTab(payload[1], tabs)->window_id.set_id(payload[0]); | |
| 1089 break; | |
| 1090 } | |
| 1091 | |
| 1092 // This is here for forward migration only. New data is saved with | |
| 1093 // |kCommandSetWindowBounds3|. | |
| 1094 case kCommandSetWindowBounds2: { | |
| 1095 WindowBoundsPayload2 payload; | |
| 1096 if (!command->GetPayload(&payload, sizeof(payload))) { | |
| 1097 VLOG(1) << "Failed reading command " << command->id(); | |
| 1098 return true; | |
| 1099 } | |
| 1100 GetWindow(payload.window_id, windows)->bounds.SetRect(payload.x, | |
| 1101 payload.y, | |
| 1102 payload.w, | |
| 1103 payload.h); | |
| 1104 GetWindow(payload.window_id, windows)->show_state = | |
| 1105 payload.is_maximized ? | |
| 1106 ui::SHOW_STATE_MAXIMIZED : ui::SHOW_STATE_NORMAL; | |
| 1107 break; | |
| 1108 } | |
| 1109 | |
| 1110 case kCommandSetWindowBounds3: { | |
| 1111 WindowBoundsPayload3 payload; | |
| 1112 if (!command->GetPayload(&payload, sizeof(payload))) { | |
| 1113 VLOG(1) << "Failed reading command " << command->id(); | |
| 1114 return true; | |
| 1115 } | |
| 1116 GetWindow(payload.window_id, windows)->bounds.SetRect(payload.x, | |
| 1117 payload.y, | |
| 1118 payload.w, | |
| 1119 payload.h); | |
| 1120 GetWindow(payload.window_id, windows)->show_state = | |
| 1121 PersistedShowStateToShowState(payload.show_state); | |
| 1122 break; | |
| 1123 } | |
| 1124 | |
| 1125 case kCommandSetTabIndexInWindow: { | |
| 1126 TabIndexInWindowPayload payload; | |
| 1127 if (!command->GetPayload(&payload, sizeof(payload))) { | |
| 1128 VLOG(1) << "Failed reading command " << command->id(); | |
| 1129 return true; | |
| 1130 } | |
| 1131 GetTab(payload.id, tabs)->tab_visual_index = payload.index; | |
| 1132 break; | |
| 1133 } | |
| 1134 | |
| 1135 case kCommandTabClosed: | |
| 1136 case kCommandWindowClosed: { | |
| 1137 ClosedPayload payload; | |
| 1138 if (!command->GetPayload(&payload, sizeof(payload))) { | |
| 1139 VLOG(1) << "Failed reading command " << command->id(); | |
| 1140 return true; | |
| 1141 } | |
| 1142 if (command->id() == kCommandTabClosed) { | |
| 1143 delete GetTab(payload.id, tabs); | |
| 1144 tabs->erase(payload.id); | |
| 1145 } else { | |
| 1146 delete GetWindow(payload.id, windows); | |
| 1147 windows->erase(payload.id); | |
| 1148 } | |
| 1149 break; | |
| 1150 } | |
| 1151 | |
| 1152 case kCommandTabNavigationPathPrunedFromBack: { | |
| 1153 TabNavigationPathPrunedFromBackPayload payload; | |
| 1154 if (!command->GetPayload(&payload, sizeof(payload))) { | |
| 1155 VLOG(1) << "Failed reading command " << command->id(); | |
| 1156 return true; | |
| 1157 } | |
| 1158 SessionTab* tab = GetTab(payload.id, tabs); | |
| 1159 tab->navigations.erase( | |
| 1160 FindClosestNavigationWithIndex(&(tab->navigations), payload.index), | |
| 1161 tab->navigations.end()); | |
| 1162 break; | |
| 1163 } | |
| 1164 | |
| 1165 case kCommandTabNavigationPathPrunedFromFront: { | |
| 1166 TabNavigationPathPrunedFromFrontPayload payload; | |
| 1167 if (!command->GetPayload(&payload, sizeof(payload)) || | |
| 1168 payload.index <= 0) { | |
| 1169 VLOG(1) << "Failed reading command " << command->id(); | |
| 1170 return true; | |
| 1171 } | |
| 1172 SessionTab* tab = GetTab(payload.id, tabs); | |
| 1173 | |
| 1174 // Update the selected navigation index. | |
| 1175 tab->current_navigation_index = | |
| 1176 std::max(-1, tab->current_navigation_index - payload.index); | |
| 1177 | |
| 1178 // And update the index of existing navigations. | |
| 1179 for (std::vector<SerializedNavigationEntry>::iterator | |
| 1180 i = tab->navigations.begin(); | |
| 1181 i != tab->navigations.end();) { | |
| 1182 i->set_index(i->index() - payload.index); | |
| 1183 if (i->index() < 0) | |
| 1184 i = tab->navigations.erase(i); | |
| 1185 else | |
| 1186 ++i; | |
| 1187 } | |
| 1188 break; | |
| 1189 } | |
| 1190 | |
| 1191 case kCommandUpdateTabNavigation: { | |
| 1192 SerializedNavigationEntry navigation; | |
| 1193 SessionID::id_type tab_id; | |
| 1194 if (!RestoreUpdateTabNavigationCommand( | |
| 1195 *command, &navigation, &tab_id)) { | |
| 1196 VLOG(1) << "Failed reading command " << command->id(); | |
| 1197 return true; | |
| 1198 } | |
| 1199 SessionTab* tab = GetTab(tab_id, tabs); | |
| 1200 std::vector<SerializedNavigationEntry>::iterator i = | |
| 1201 FindClosestNavigationWithIndex(&(tab->navigations), | |
| 1202 navigation.index()); | |
| 1203 if (i != tab->navigations.end() && i->index() == navigation.index()) | |
| 1204 *i = navigation; | |
| 1205 else | |
| 1206 tab->navigations.insert(i, navigation); | |
| 1207 break; | |
| 1208 } | |
| 1209 | |
| 1210 case kCommandSetSelectedNavigationIndex: { | |
| 1211 SelectedNavigationIndexPayload payload; | |
| 1212 if (!command->GetPayload(&payload, sizeof(payload))) { | |
| 1213 VLOG(1) << "Failed reading command " << command->id(); | |
| 1214 return true; | |
| 1215 } | |
| 1216 GetTab(payload.id, tabs)->current_navigation_index = payload.index; | |
| 1217 break; | |
| 1218 } | |
| 1219 | |
| 1220 case kCommandSetSelectedTabInIndex: { | |
| 1221 SelectedTabInIndexPayload payload; | |
| 1222 if (!command->GetPayload(&payload, sizeof(payload))) { | |
| 1223 VLOG(1) << "Failed reading command " << command->id(); | |
| 1224 return true; | |
| 1225 } | |
| 1226 GetWindow(payload.id, windows)->selected_tab_index = payload.index; | |
| 1227 break; | |
| 1228 } | |
| 1229 | |
| 1230 case kCommandSetWindowType: { | |
| 1231 WindowTypePayload payload; | |
| 1232 if (!command->GetPayload(&payload, sizeof(payload))) { | |
| 1233 VLOG(1) << "Failed reading command " << command->id(); | |
| 1234 return true; | |
| 1235 } | |
| 1236 GetWindow(payload.id, windows)->is_constrained = false; | |
| 1237 GetWindow(payload.id, windows)->type = | |
| 1238 BrowserTypeForWindowType( | |
| 1239 static_cast<WindowType>(payload.index)); | |
| 1240 break; | |
| 1241 } | |
| 1242 | |
| 1243 case kCommandSetPinnedState: { | |
| 1244 PinnedStatePayload payload; | |
| 1245 if (!command->GetPayload(&payload, sizeof(payload))) { | |
| 1246 VLOG(1) << "Failed reading command " << command->id(); | |
| 1247 return true; | |
| 1248 } | |
| 1249 GetTab(payload.tab_id, tabs)->pinned = payload.pinned_state; | |
| 1250 break; | |
| 1251 } | |
| 1252 | |
| 1253 case kCommandSetWindowAppName: { | |
| 1254 SessionID::id_type window_id; | |
| 1255 std::string app_name; | |
| 1256 if (!RestoreSetWindowAppNameCommand(*command, &window_id, &app_name)) | |
| 1257 return true; | |
| 1258 | |
| 1259 GetWindow(window_id, windows)->app_name.swap(app_name); | |
| 1260 break; | |
| 1261 } | |
| 1262 | |
| 1263 case kCommandSetExtensionAppID: { | |
| 1264 SessionID::id_type tab_id; | |
| 1265 std::string extension_app_id; | |
| 1266 if (!RestoreSetTabExtensionAppIDCommand( | |
| 1267 *command, &tab_id, &extension_app_id)) { | |
| 1268 VLOG(1) << "Failed reading command " << command->id(); | |
| 1269 return true; | |
| 1270 } | |
| 1271 | |
| 1272 GetTab(tab_id, tabs)->extension_app_id.swap(extension_app_id); | |
| 1273 break; | |
| 1274 } | |
| 1275 | |
| 1276 case kCommandSetTabUserAgentOverride: { | |
| 1277 SessionID::id_type tab_id; | |
| 1278 std::string user_agent_override; | |
| 1279 if (!RestoreSetTabUserAgentOverrideCommand( | |
| 1280 *command, &tab_id, &user_agent_override)) { | |
| 1281 return true; | |
| 1282 } | |
| 1283 | |
| 1284 GetTab(tab_id, tabs)->user_agent_override.swap(user_agent_override); | |
| 1285 break; | |
| 1286 } | |
| 1287 | |
| 1288 case kCommandSessionStorageAssociated: { | |
| 1289 scoped_ptr<Pickle> command_pickle(command->PayloadAsPickle()); | |
| 1290 SessionID::id_type command_tab_id; | |
| 1291 std::string session_storage_persistent_id; | |
| 1292 PickleIterator iter(*command_pickle.get()); | |
| 1293 if (!command_pickle->ReadInt(&iter, &command_tab_id) || | |
| 1294 !command_pickle->ReadString(&iter, &session_storage_persistent_id)) | |
| 1295 return true; | |
| 1296 // Associate the session storage back. | |
| 1297 GetTab(command_tab_id, tabs)->session_storage_persistent_id = | |
| 1298 session_storage_persistent_id; | |
| 1299 break; | |
| 1300 } | |
| 1301 | |
| 1302 case kCommandSetActiveWindow: { | |
| 1303 ActiveWindowPayload payload; | |
| 1304 if (!command->GetPayload(&payload, sizeof(payload))) { | |
| 1305 VLOG(1) << "Failed reading command " << command->id(); | |
| 1306 return true; | |
| 1307 } | |
| 1308 *active_window_id = payload; | |
| 1309 break; | |
| 1310 } | |
| 1311 | |
| 1312 default: | |
| 1313 VLOG(1) << "Failed reading an unknown command " << command->id(); | |
| 1314 return true; | |
| 1315 } | |
| 1316 } | |
| 1317 return true; | |
| 1318 } | |
| 1319 | |
| 1320 void SessionService::BuildCommandsForTab(const SessionID& window_id, | 634 void SessionService::BuildCommandsForTab(const SessionID& window_id, |
| 1321 WebContents* tab, | 635 WebContents* tab, |
| 1322 int index_in_window, | 636 int index_in_window, |
| 1323 bool is_pinned, | 637 bool is_pinned, |
| 1324 std::vector<SessionCommand*>* commands, | 638 std::vector<SessionCommand*>* commands, |
| 1325 IdToRange* tab_to_available_range) { | 639 IdToRange* tab_to_available_range) { |
| 1326 DCHECK(tab && commands && window_id.id()); | 640 DCHECK(tab && commands && window_id.id()); |
| 1327 SessionTabHelper* session_tab_helper = SessionTabHelper::FromWebContents(tab); | 641 SessionTabHelper* session_tab_helper = SessionTabHelper::FromWebContents(tab); |
| 1328 const SessionID& session_id(session_tab_helper->session_id()); | 642 const SessionID& session_id(session_tab_helper->session_id()); |
| 1329 commands->push_back(CreateSetTabWindowCommand(window_id, session_id)); | 643 commands->push_back(CreateSetTabWindowCommand(window_id, session_id)); |
| 1330 | 644 |
| 1331 const int current_index = tab->GetController().GetCurrentEntryIndex(); | 645 const int current_index = tab->GetController().GetCurrentEntryIndex(); |
| 1332 const int min_index = std::max(0, | 646 const int min_index = std::max(0, |
| 1333 current_index - max_persist_navigation_count); | 647 current_index - max_persist_navigation_count); |
| 1334 const int max_index = | 648 const int max_index = |
| 1335 std::min(current_index + max_persist_navigation_count, | 649 std::min(current_index + max_persist_navigation_count, |
| 1336 tab->GetController().GetEntryCount()); | 650 tab->GetController().GetEntryCount()); |
| 1337 const int pending_index = tab->GetController().GetPendingEntryIndex(); | 651 const int pending_index = tab->GetController().GetPendingEntryIndex(); |
| 1338 if (tab_to_available_range) { | 652 if (tab_to_available_range) { |
| 1339 (*tab_to_available_range)[session_id.id()] = | 653 (*tab_to_available_range)[session_id.id()] = |
| 1340 std::pair<int, int>(min_index, max_index); | 654 std::pair<int, int>(min_index, max_index); |
| 1341 } | 655 } |
| 1342 | 656 |
| 1343 if (is_pinned) { | 657 if (is_pinned) |
| 1344 commands->push_back(CreatePinnedStateCommand(session_id, true)); | 658 commands->push_back(CreatePinnedStateCommand(session_id, true)); |
| 1345 } | |
| 1346 | 659 |
| 1347 extensions::TabHelper* extensions_tab_helper = | 660 extensions::TabHelper* extensions_tab_helper = |
| 1348 extensions::TabHelper::FromWebContents(tab); | 661 extensions::TabHelper::FromWebContents(tab); |
| 1349 if (extensions_tab_helper->extension_app()) { | 662 if (extensions_tab_helper->extension_app()) { |
| 1350 commands->push_back( | 663 commands->push_back(CreateSetTabExtensionAppIDCommand( |
| 1351 CreateSetTabExtensionAppIDCommand( | 664 session_id, |
| 1352 kCommandSetExtensionAppID, session_id.id(), | 665 extensions_tab_helper->extension_app()->id())); |
| 1353 extensions_tab_helper->extension_app()->id())); | |
| 1354 } | 666 } |
| 1355 | 667 |
| 1356 const std::string& ua_override = tab->GetUserAgentOverride(); | 668 const std::string& ua_override = tab->GetUserAgentOverride(); |
| 1357 if (!ua_override.empty()) { | 669 if (!ua_override.empty()) { |
| 1358 commands->push_back( | 670 commands->push_back(CreateSetTabUserAgentOverrideCommand(session_id, |
| 1359 CreateSetTabUserAgentOverrideCommand( | 671 ua_override)); |
| 1360 kCommandSetTabUserAgentOverride, session_id.id(), ua_override)); | |
| 1361 } | 672 } |
| 1362 | 673 |
| 1363 for (int i = min_index; i < max_index; ++i) { | 674 for (int i = min_index; i < max_index; ++i) { |
| 1364 const NavigationEntry* entry = (i == pending_index) ? | 675 const NavigationEntry* entry = (i == pending_index) ? |
| 1365 tab->GetController().GetPendingEntry() : | 676 tab->GetController().GetPendingEntry() : |
| 1366 tab->GetController().GetEntryAtIndex(i); | 677 tab->GetController().GetEntryAtIndex(i); |
| 1367 DCHECK(entry); | 678 DCHECK(entry); |
| 1368 if (ShouldTrackEntry(entry->GetVirtualURL())) { | 679 if (ShouldTrackEntry(entry->GetVirtualURL())) { |
| 1369 const SerializedNavigationEntry navigation = | 680 const SerializedNavigationEntry navigation = |
| 1370 ContentSerializedNavigationBuilder::FromNavigationEntry(i, *entry); | 681 ContentSerializedNavigationBuilder::FromNavigationEntry(i, *entry); |
| 1371 commands->push_back( | 682 commands->push_back( |
| 1372 CreateUpdateTabNavigationCommand( | 683 CreateUpdateTabNavigationCommand(session_id, navigation)); |
| 1373 kCommandUpdateTabNavigation, session_id.id(), navigation)); | |
| 1374 } | 684 } |
| 1375 } | 685 } |
| 1376 commands->push_back( | 686 commands->push_back( |
| 1377 CreateSetSelectedNavigationIndexCommand(session_id, current_index)); | 687 CreateSetSelectedNavigationIndexCommand(session_id, current_index)); |
| 1378 | 688 |
| 1379 if (index_in_window != -1) { | 689 if (index_in_window != -1) { |
| 1380 commands->push_back( | 690 commands->push_back( |
| 1381 CreateSetTabIndexInWindowCommand(session_id, index_in_window)); | 691 CreateSetTabIndexInWindowCommand(session_id, index_in_window)); |
| 1382 } | 692 } |
| 1383 | 693 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1396 std::set<SessionID::id_type>* windows_to_track) { | 706 std::set<SessionID::id_type>* windows_to_track) { |
| 1397 DCHECK(browser && commands); | 707 DCHECK(browser && commands); |
| 1398 DCHECK(browser->session_id().id()); | 708 DCHECK(browser->session_id().id()); |
| 1399 | 709 |
| 1400 commands->push_back( | 710 commands->push_back( |
| 1401 CreateSetWindowBoundsCommand(browser->session_id(), | 711 CreateSetWindowBoundsCommand(browser->session_id(), |
| 1402 browser->window()->GetRestoredBounds(), | 712 browser->window()->GetRestoredBounds(), |
| 1403 browser->window()->GetRestoredState())); | 713 browser->window()->GetRestoredState())); |
| 1404 | 714 |
| 1405 commands->push_back(CreateSetWindowTypeCommand( | 715 commands->push_back(CreateSetWindowTypeCommand( |
| 1406 browser->session_id(), WindowTypeForBrowserType(browser->type()))); | 716 browser->session_id(), |
| 717 WindowTypeForBrowserType(browser->type()))); |
| 1407 | 718 |
| 1408 if (!browser->app_name().empty()) { | 719 if (!browser->app_name().empty()) { |
| 1409 commands->push_back(CreateSetWindowAppNameCommand( | 720 commands->push_back(CreateSetWindowAppNameCommand(browser->session_id(), |
| 1410 kCommandSetWindowAppName, | 721 browser->app_name())); |
| 1411 browser->session_id().id(), | |
| 1412 browser->app_name())); | |
| 1413 } | 722 } |
| 1414 | 723 |
| 1415 windows_to_track->insert(browser->session_id().id()); | 724 windows_to_track->insert(browser->session_id().id()); |
| 1416 TabStripModel* tab_strip = browser->tab_strip_model(); | 725 TabStripModel* tab_strip = browser->tab_strip_model(); |
| 1417 for (int i = 0; i < tab_strip->count(); ++i) { | 726 for (int i = 0; i < tab_strip->count(); ++i) { |
| 1418 WebContents* tab = tab_strip->GetWebContentsAt(i); | 727 WebContents* tab = tab_strip->GetWebContentsAt(i); |
| 1419 DCHECK(tab); | 728 DCHECK(tab); |
| 1420 BuildCommandsForTab(browser->session_id(), tab, i, | 729 BuildCommandsForTab(browser->session_id(), tab, i, |
| 1421 tab_strip->IsTabPinned(i), | 730 tab_strip->IsTabPinned(i), |
| 1422 commands, tab_to_available_range); | 731 commands, tab_to_available_range); |
| 1423 } | 732 } |
| 1424 | 733 |
| 1425 commands->push_back( | 734 commands->push_back(CreateSetSelectedTabInWindowCommand( |
| 1426 CreateSetSelectedTabInWindow(browser->session_id(), | 735 browser->session_id(), |
| 1427 browser->tab_strip_model()->active_index())); | 736 browser->tab_strip_model()->active_index())); |
| 1428 } | 737 } |
| 1429 | 738 |
| 1430 void SessionService::BuildCommandsFromBrowsers( | 739 void SessionService::BuildCommandsFromBrowsers( |
| 1431 std::vector<SessionCommand*>* commands, | 740 std::vector<SessionCommand*>* commands, |
| 1432 IdToRange* tab_to_available_range, | 741 IdToRange* tab_to_available_range, |
| 1433 std::set<SessionID::id_type>* windows_to_track) { | 742 std::set<SessionID::id_type>* windows_to_track) { |
| 1434 DCHECK(commands); | 743 DCHECK(commands); |
| 1435 for (chrome::BrowserIterator it; !it.done(); it.Next()) { | 744 for (chrome::BrowserIterator it; !it.done(); it.Next()) { |
| 1436 Browser* browser = *it; | 745 Browser* browser = *it; |
| 1437 // Make sure the browser has tabs and a window. Browser's destructor | 746 // Make sure the browser has tabs and a window. Browser's destructor |
| 1438 // removes itself from the BrowserList. When a browser is closed the | 747 // removes itself from the BrowserList. When a browser is closed the |
| 1439 // destructor is not necessarily run immediately. This means it's possible | 748 // destructor is not necessarily run immediately. This means it's possible |
| 1440 // for us to get a handle to a browser that is about to be removed. If | 749 // for us to get a handle to a browser that is about to be removed. If |
| 1441 // the tab count is 0 or the window is NULL, the browser is about to be | 750 // the tab count is 0 or the window is NULL, the browser is about to be |
| 1442 // deleted, so we ignore it. | 751 // deleted, so we ignore it. |
| 1443 if (ShouldTrackBrowser(browser) && browser->tab_strip_model()->count() && | 752 if (ShouldTrackBrowser(browser) && browser->tab_strip_model()->count() && |
| 1444 browser->window()) { | 753 browser->window()) { |
| 1445 BuildCommandsForBrowser(browser, commands, tab_to_available_range, | 754 BuildCommandsForBrowser(browser, commands, tab_to_available_range, |
| 1446 windows_to_track); | 755 windows_to_track); |
| 1447 } | 756 } |
| 1448 } | 757 } |
| 1449 } | 758 } |
| 1450 | 759 |
| 1451 void SessionService::ScheduleReset() { | 760 void SessionService::ScheduleResetCommands() { |
| 1452 set_pending_reset(true); | 761 set_pending_reset(true); |
| 1453 STLDeleteElements(&pending_commands()); | 762 STLDeleteElements(&pending_commands()); |
| 1454 tab_to_available_range_.clear(); | 763 tab_to_available_range_.clear(); |
| 1455 windows_tracking_.clear(); | 764 windows_tracking_.clear(); |
| 1456 BuildCommandsFromBrowsers(&pending_commands(), &tab_to_available_range_, | 765 BuildCommandsFromBrowsers(&pending_commands(), &tab_to_available_range_, |
| 1457 &windows_tracking_); | 766 &windows_tracking_); |
| 1458 if (!windows_tracking_.empty()) { | 767 if (!windows_tracking_.empty()) { |
| 1459 // We're lazily created on startup and won't get an initial batch of | 768 // We're lazily created on startup and won't get an initial batch of |
| 1460 // SetWindowType messages. Set these here to make sure our state is correct. | 769 // SetWindowType messages. Set these here to make sure our state is correct. |
| 1461 has_open_trackable_browsers_ = true; | 770 has_open_trackable_browsers_ = true; |
| 1462 move_on_new_browser_ = true; | 771 move_on_new_browser_ = true; |
| 1463 } | 772 } |
| 1464 StartSaveTimer(); | 773 StartSaveTimer(); |
| 1465 } | 774 } |
| 1466 | 775 |
| 1467 bool SessionService::ReplacePendingCommand(SessionCommand* command) { | |
| 1468 // We optimize page navigations, which can happen quite frequently and | |
| 1469 // are expensive. And activation is like Highlander, there can only be one! | |
| 1470 if (command->id() != kCommandUpdateTabNavigation && | |
| 1471 command->id() != kCommandSetActiveWindow) { | |
| 1472 return false; | |
| 1473 } | |
| 1474 for (std::vector<SessionCommand*>::reverse_iterator i = | |
| 1475 pending_commands().rbegin(); i != pending_commands().rend(); ++i) { | |
| 1476 SessionCommand* existing_command = *i; | |
| 1477 if (command->id() == kCommandUpdateTabNavigation && | |
| 1478 existing_command->id() == kCommandUpdateTabNavigation) { | |
| 1479 scoped_ptr<Pickle> command_pickle(command->PayloadAsPickle()); | |
| 1480 PickleIterator iterator(*command_pickle); | |
| 1481 SessionID::id_type command_tab_id; | |
| 1482 int command_nav_index; | |
| 1483 if (!command_pickle->ReadInt(&iterator, &command_tab_id) || | |
| 1484 !command_pickle->ReadInt(&iterator, &command_nav_index)) { | |
| 1485 return false; | |
| 1486 } | |
| 1487 SessionID::id_type existing_tab_id; | |
| 1488 int existing_nav_index; | |
| 1489 { | |
| 1490 // Creating a pickle like this means the Pickle references the data from | |
| 1491 // the command. Make sure we delete the pickle before the command, else | |
| 1492 // the pickle references deleted memory. | |
| 1493 scoped_ptr<Pickle> existing_pickle(existing_command->PayloadAsPickle()); | |
| 1494 iterator = PickleIterator(*existing_pickle); | |
| 1495 if (!existing_pickle->ReadInt(&iterator, &existing_tab_id) || | |
| 1496 !existing_pickle->ReadInt(&iterator, &existing_nav_index)) { | |
| 1497 return false; | |
| 1498 } | |
| 1499 } | |
| 1500 if (existing_tab_id == command_tab_id && | |
| 1501 existing_nav_index == command_nav_index) { | |
| 1502 // existing_command is an update for the same tab/index pair. Replace | |
| 1503 // it with the new one. We need to add to the end of the list just in | |
| 1504 // case there is a prune command after the update command. | |
| 1505 delete existing_command; | |
| 1506 pending_commands().erase(i.base() - 1); | |
| 1507 pending_commands().push_back(command); | |
| 1508 return true; | |
| 1509 } | |
| 1510 return false; | |
| 1511 } | |
| 1512 if (command->id() == kCommandSetActiveWindow && | |
| 1513 existing_command->id() == kCommandSetActiveWindow) { | |
| 1514 *i = command; | |
| 1515 delete existing_command; | |
| 1516 return true; | |
| 1517 } | |
| 1518 } | |
| 1519 return false; | |
| 1520 } | |
| 1521 | |
| 1522 void SessionService::ScheduleCommand(SessionCommand* command) { | 776 void SessionService::ScheduleCommand(SessionCommand* command) { |
| 1523 DCHECK(command); | 777 DCHECK(command); |
| 1524 if (ReplacePendingCommand(command)) | 778 if (ReplacePendingCommand(command, pending_commands())) |
| 1525 return; | 779 return; |
| 1526 BaseSessionService::ScheduleCommand(command); | 780 BaseSessionService::ScheduleCommand(command); |
| 1527 // Don't schedule a reset on tab closed/window closed. Otherwise we may | 781 // Don't schedule a reset on tab closed/window closed. Otherwise we may |
| 1528 // lose tabs/windows we want to restore from if we exit right after this. | 782 // lose tabs/windows we want to restore from if we exit right after this. |
| 1529 if (!pending_reset() && pending_window_close_ids_.empty() && | 783 if (!pending_reset() && pending_window_close_ids_.empty() && |
| 1530 commands_since_reset() >= kWritesPerReset && | 784 commands_since_reset() >= kWritesPerReset && !IsClosingCommand(command)) { |
| 1531 (command->id() != kCommandTabClosed && | 785 ScheduleResetCommands(); |
| 1532 command->id() != kCommandWindowClosed)) { | |
| 1533 ScheduleReset(); | |
| 1534 } | 786 } |
| 1535 } | 787 } |
| 1536 | 788 |
| 1537 void SessionService::CommitPendingCloses() { | 789 void SessionService::CommitPendingCloses() { |
| 1538 for (PendingTabCloseIDs::iterator i = pending_tab_close_ids_.begin(); | 790 for (PendingTabCloseIDs::iterator i = pending_tab_close_ids_.begin(); |
| 1539 i != pending_tab_close_ids_.end(); ++i) { | 791 i != pending_tab_close_ids_.end(); ++i) { |
| 1540 ScheduleCommand(CreateTabClosedCommand(*i)); | 792 ScheduleCommand(CreateTabClosedCommand(*i)); |
| 1541 } | 793 } |
| 1542 pending_tab_close_ids_.clear(); | 794 pending_tab_close_ids_.clear(); |
| 1543 | 795 |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1598 bool SessionService::ShouldTrackBrowser(Browser* browser) const { | 850 bool SessionService::ShouldTrackBrowser(Browser* browser) const { |
| 1599 if (browser->profile() != profile()) | 851 if (browser->profile() != profile()) |
| 1600 return false; | 852 return false; |
| 1601 // Never track app popup windows that do not have a trusted source (i.e. | 853 // Never track app popup windows that do not have a trusted source (i.e. |
| 1602 // popup windows spawned by an app). If this logic changes, be sure to also | 854 // popup windows spawned by an app). If this logic changes, be sure to also |
| 1603 // change SessionRestoreImpl::CreateRestoredBrowser(). | 855 // change SessionRestoreImpl::CreateRestoredBrowser(). |
| 1604 if (browser->is_app() && browser->is_type_popup() && | 856 if (browser->is_app() && browser->is_type_popup() && |
| 1605 !browser->is_trusted_source()) { | 857 !browser->is_trusted_source()) { |
| 1606 return false; | 858 return false; |
| 1607 } | 859 } |
| 1608 AppType app_type = browser->is_app() ? TYPE_APP : TYPE_NORMAL; | 860 SessionServiceCommands::AppType app_type = |
| 1609 return should_track_changes_for_browser_type(browser->type(), app_type); | 861 browser->is_app() ? SessionServiceCommands::TYPE_APP : |
| 862 SessionServiceCommands::TYPE_NORMAL; |
| 863 return ShouldRestoreWindowOfType(WindowTypeForBrowserType(browser->type()), |
| 864 app_type); |
| 1610 } | 865 } |
| 1611 | 866 |
| 1612 bool SessionService::should_track_changes_for_browser_type(Browser::Type type, | 867 SessionWindow::WindowType SessionService::WindowTypeForBrowserType( |
| 1613 AppType app_type) { | |
| 1614 #if defined(OS_CHROMEOS) | |
| 1615 // Restore app popups for chromeos alone. | |
| 1616 if (type == Browser::TYPE_POPUP && app_type == TYPE_APP) | |
| 1617 return true; | |
| 1618 #endif | |
| 1619 | |
| 1620 return type == Browser::TYPE_TABBED; | |
| 1621 } | |
| 1622 | |
| 1623 SessionService::WindowType SessionService::WindowTypeForBrowserType( | |
| 1624 Browser::Type type) { | 868 Browser::Type type) { |
| 1625 switch (type) { | 869 switch (type) { |
| 1626 case Browser::TYPE_POPUP: | 870 case Browser::TYPE_POPUP: |
| 1627 return TYPE_POPUP; | 871 return SessionWindow::TYPE_POPUP; |
| 1628 case Browser::TYPE_TABBED: | 872 case Browser::TYPE_TABBED: |
| 1629 return TYPE_TABBED; | 873 return SessionWindow::TYPE_TABBED; |
| 1630 default: | 874 default: |
| 1631 DCHECK(false); | 875 DCHECK(false); |
| 1632 return TYPE_TABBED; | 876 return SessionWindow::TYPE_TABBED; |
| 1633 } | 877 } |
| 1634 } | 878 } |
| 1635 | 879 |
| 1636 Browser::Type SessionService::BrowserTypeForWindowType(WindowType type) { | 880 Browser::Type SessionService::BrowserTypeForWindowType( |
| 881 SessionWindow::WindowType type) { |
| 1637 switch (type) { | 882 switch (type) { |
| 1638 case TYPE_POPUP: | 883 case SessionWindow::TYPE_POPUP: |
| 1639 return Browser::TYPE_POPUP; | 884 return Browser::TYPE_POPUP; |
| 1640 case TYPE_TABBED: | 885 case SessionWindow::TYPE_TABBED: |
| 1641 default: | 886 default: |
| 1642 return Browser::TYPE_TABBED; | 887 return Browser::TYPE_TABBED; |
| 1643 } | 888 } |
| 1644 } | 889 } |
| 1645 | 890 |
| 1646 void SessionService::RecordSessionUpdateHistogramData(int type, | 891 void SessionService::RecordSessionUpdateHistogramData(int type, |
| 1647 base::TimeTicks* last_updated_time) { | 892 base::TimeTicks* last_updated_time) { |
| 1648 if (!last_updated_time->is_null()) { | 893 if (!last_updated_time->is_null()) { |
| 1649 base::TimeDelta delta = base::TimeTicks::Now() - *last_updated_time; | 894 base::TimeDelta delta = base::TimeTicks::Now() - *last_updated_time; |
| 1650 // We're interested in frequent updates periods longer than | 895 // We're interested in frequent updates periods longer than |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1834 return; | 1079 return; |
| 1835 } | 1080 } |
| 1836 | 1081 |
| 1837 // Check for any open windows for the current profile that we aren't tracking. | 1082 // Check for any open windows for the current profile that we aren't tracking. |
| 1838 for (chrome::BrowserIterator it; !it.done(); it.Next()) { | 1083 for (chrome::BrowserIterator it; !it.done(); it.Next()) { |
| 1839 if ((*it)->profile() == profile()) | 1084 if ((*it)->profile() == profile()) |
| 1840 return; | 1085 return; |
| 1841 } | 1086 } |
| 1842 DeleteSessionOnlyData(profile()); | 1087 DeleteSessionOnlyData(profile()); |
| 1843 } | 1088 } |
| OLD | NEW |