Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(147)

Side by Side Diff: components/sessions/core/tab_restore_service_helper.cc

Issue 2868983003: Ensure History > Recent Tabs restore preserves window disposition. (Closed)
Patch Set: Remove NOTREACHED(). Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 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 "components/sessions/core/tab_restore_service_helper.h" 5 #include "components/sessions/core/tab_restore_service_helper.h"
6 6
7 #include <inttypes.h> 7 #include <inttypes.h>
8 #include <stddef.h> 8 #include <stddef.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 void TabRestoreServiceHelper::RemoveObserver( 75 void TabRestoreServiceHelper::RemoveObserver(
76 TabRestoreServiceObserver* observer) { 76 TabRestoreServiceObserver* observer) {
77 observer_list_.RemoveObserver(observer); 77 observer_list_.RemoveObserver(observer);
78 } 78 }
79 79
80 void TabRestoreServiceHelper::CreateHistoricalTab(LiveTab* live_tab, 80 void TabRestoreServiceHelper::CreateHistoricalTab(LiveTab* live_tab,
81 int index) { 81 int index) {
82 if (restoring_) 82 if (restoring_)
83 return; 83 return;
84 84
85 // If an entire window is being closed than all of the tabs have already
86 // been persisted via "BrowserClosing". Ignore the subsequent tab closing
87 // notifications.
85 LiveTabContext* context = client_->FindLiveTabContextForTab(live_tab); 88 LiveTabContext* context = client_->FindLiveTabContextForTab(live_tab);
86 if (closing_contexts_.find(context) != closing_contexts_.end()) 89 if (closing_contexts_.find(context) != closing_contexts_.end())
87 return; 90 return;
88 91
89 auto local_tab = base::MakeUnique<Tab>(); 92 auto local_tab = base::MakeUnique<Tab>();
90 PopulateTab(local_tab.get(), index, context, live_tab); 93 PopulateTab(local_tab.get(), index, context, live_tab);
91 if (local_tab->navigations.empty()) 94 if (local_tab->navigations.empty())
92 return; 95 return;
93 96
94 AddEntry(std::move(local_tab), true, true); 97 AddEntry(std::move(local_tab), true, true);
95 } 98 }
96 99
97 void TabRestoreServiceHelper::BrowserClosing(LiveTabContext* context) { 100 void TabRestoreServiceHelper::BrowserClosing(LiveTabContext* context) {
98 closing_contexts_.insert(context); 101 closing_contexts_.insert(context);
99 102
100 auto window = base::MakeUnique<Window>(); 103 auto window = base::MakeUnique<Window>();
101 window->selected_tab_index = context->GetSelectedIndex(); 104 window->selected_tab_index = context->GetSelectedIndex();
102 window->timestamp = TimeNow(); 105 window->timestamp = TimeNow();
103 window->app_name = context->GetAppName(); 106 window->app_name = context->GetAppName();
107 window->bounds = context->GetRestoredBounds();
108 window->show_state = context->GetRestoredState();
109 window->workspace = context->GetWorkspace();
104 110
105 for (int tab_index = 0; tab_index < context->GetTabCount(); ++tab_index) { 111 for (int tab_index = 0; tab_index < context->GetTabCount(); ++tab_index) {
106 auto tab = base::MakeUnique<Tab>(); 112 auto tab = base::MakeUnique<Tab>();
107 PopulateTab(tab.get(), tab_index, context, 113 PopulateTab(tab.get(), tab_index, context,
108 context->GetLiveTabAt(tab_index)); 114 context->GetLiveTabAt(tab_index));
109 if (!tab->navigations.empty()) { 115 if (!tab->navigations.empty()) {
110 tab->browser_id = context->GetSessionID().id(); 116 tab->browser_id = context->GetSessionID().id();
111 window->tabs.push_back(std::move(tab)); 117 window->tabs.push_back(std::move(tab));
112 } 118 }
113 } 119 }
120
114 if (window->tabs.size() == 1 && window->app_name.empty()) { 121 if (window->tabs.size() == 1 && window->app_name.empty()) {
115 // Short-circuit creating a Window if only 1 tab was present. This fixes 122 // Short-circuit creating a Window if only 1 tab was present. This fixes
116 // http://crbug.com/56744. 123 // http://crbug.com/56744.
117 AddEntry(std::move(window->tabs[0]), true, true); 124 AddEntry(std::move(window->tabs[0]), true, true);
118 } else if (!window->tabs.empty()) { 125 } else if (!window->tabs.empty()) {
119 window->selected_tab_index = std::min( 126 window->selected_tab_index = std::min(
120 static_cast<int>(window->tabs.size() - 1), window->selected_tab_index); 127 static_cast<int>(window->tabs.size() - 1), window->selected_tab_index);
121 AddEntry(std::move(window), true, true); 128 AddEntry(std::move(window), true, true);
122 } 129 }
123 } 130 }
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 break; 199 break;
193 } 200 }
194 case TabRestoreService::WINDOW: { 201 case TabRestoreService::WINDOW: {
195 LiveTabContext* current_context = context; 202 LiveTabContext* current_context = context;
196 auto& window = static_cast<Window&>(entry); 203 auto& window = static_cast<Window&>(entry);
197 204
198 // When restoring a window, either the entire window can be restored, or a 205 // When restoring a window, either the entire window can be restored, or a
199 // single tab within it. If the entry's ID matches the one to restore, 206 // single tab within it. If the entry's ID matches the one to restore,
200 // then the entire window will be restored. 207 // then the entire window will be restored.
201 if (!restoring_tab_in_window) { 208 if (!restoring_tab_in_window) {
202 context = client_->CreateLiveTabContext(window.app_name); 209 context =
210 client_->CreateLiveTabContext(window.app_name, window.bounds,
211 window.show_state, window.workspace);
203 for (size_t tab_i = 0; tab_i < window.tabs.size(); ++tab_i) { 212 for (size_t tab_i = 0; tab_i < window.tabs.size(); ++tab_i) {
204 const Tab& tab = *window.tabs[tab_i]; 213 const Tab& tab = *window.tabs[tab_i];
205 LiveTab* restored_tab = context->AddRestoredTab( 214 LiveTab* restored_tab = context->AddRestoredTab(
206 tab.navigations, context->GetTabCount(), 215 tab.navigations, context->GetTabCount(),
207 tab.current_navigation_index, tab.extension_app_id, 216 tab.current_navigation_index, tab.extension_app_id,
208 static_cast<int>(tab_i) == window.selected_tab_index, tab.pinned, 217 static_cast<int>(tab_i) == window.selected_tab_index, tab.pinned,
209 tab.from_last_session, tab.platform_data.get(), 218 tab.from_last_session, tab.platform_data.get(),
210 tab.user_agent_override); 219 tab.user_agent_override);
211 if (restored_tab) { 220 if (restored_tab) {
212 client_->OnTabRestored( 221 client_->OnTabRestored(
213 tab.navigations.at(tab.current_navigation_index).virtual_url()); 222 tab.navigations.at(tab.current_navigation_index).virtual_url());
214 live_tabs.push_back(restored_tab); 223 live_tabs.push_back(restored_tab);
215 } 224 }
216 } 225 }
217 // All the window's tabs had the same former browser_id. 226 // All the window's tabs had the same former browser_id.
218 if (auto browser_id = window.tabs[0]->browser_id) { 227 if (auto browser_id = window.tabs[0]->browser_id) {
219 UpdateTabBrowserIDs(browser_id, context->GetSessionID().id()); 228 UpdateTabBrowserIDs(browser_id, context->GetSessionID().id());
220 } 229 }
221 } else { 230 } else {
222 // Restore a single tab from the window. Find the tab that matches the 231 // Restore a single tab from the window. Find the tab that matches the
223 // ID 232 // ID in the window and restore it.
224 // in the window and restore it.
225 for (auto tab_i = window.tabs.begin(); tab_i != window.tabs.end(); 233 for (auto tab_i = window.tabs.begin(); tab_i != window.tabs.end();
226 ++tab_i) { 234 ++tab_i) {
227 SessionID::id_type restored_tab_browser_id; 235 SessionID::id_type restored_tab_browser_id;
228 { 236 {
229 const Tab& tab = **tab_i; 237 const Tab& tab = **tab_i;
230 if (tab.id != id) 238 if (tab.id != id)
231 continue; 239 continue;
232 240
233 restored_tab_browser_id = tab.browser_id; 241 restored_tab_browser_id = tab.browser_id;
234 LiveTab* restored_tab = nullptr; 242 LiveTab* restored_tab = nullptr;
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
438 const Tab& tab, 446 const Tab& tab,
439 LiveTabContext* context, 447 LiveTabContext* context,
440 WindowOpenDisposition disposition, 448 WindowOpenDisposition disposition,
441 LiveTab** live_tab) { 449 LiveTab** live_tab) {
442 LiveTab* restored_tab; 450 LiveTab* restored_tab;
443 if (disposition == WindowOpenDisposition::CURRENT_TAB && context) { 451 if (disposition == WindowOpenDisposition::CURRENT_TAB && context) {
444 restored_tab = context->ReplaceRestoredTab( 452 restored_tab = context->ReplaceRestoredTab(
445 tab.navigations, tab.current_navigation_index, tab.from_last_session, 453 tab.navigations, tab.current_navigation_index, tab.from_last_session,
446 tab.extension_app_id, tab.platform_data.get(), tab.user_agent_override); 454 tab.extension_app_id, tab.platform_data.get(), tab.user_agent_override);
447 } else { 455 } else {
448 // We only respsect the tab's original browser if there's no disposition. 456 // We only respect the tab's original browser if there's no disposition.
449 if (disposition == WindowOpenDisposition::UNKNOWN && tab.browser_id) { 457 if (disposition == WindowOpenDisposition::UNKNOWN && tab.browser_id) {
450 context = client_->FindLiveTabContextWithID(tab.browser_id); 458 context = client_->FindLiveTabContextWithID(tab.browser_id);
451 } 459 }
452 460
453 int tab_index = -1; 461 int tab_index = -1;
454 462
455 // |context| will be NULL in cases where one isn't already available (eg, 463 // |context| will be NULL in cases where one isn't already available (eg,
456 // when invoked on Mac OS X with no windows open). In this case, create a 464 // when invoked on Mac OS X with no windows open). In this case, create a
457 // new browser into which we restore the tabs. 465 // new browser into which we restore the tabs.
458 if (context && disposition != WindowOpenDisposition::NEW_WINDOW) { 466 if (context && disposition != WindowOpenDisposition::NEW_WINDOW) {
459 tab_index = tab.tabstrip_index; 467 tab_index = tab.tabstrip_index;
460 } else { 468 } else {
461 context = client_->CreateLiveTabContext(std::string()); 469 context = client_->CreateLiveTabContext(
470 std::string(), gfx::Rect(), ui::SHOW_STATE_NORMAL, std::string());
462 if (tab.browser_id) 471 if (tab.browser_id)
463 UpdateTabBrowserIDs(tab.browser_id, context->GetSessionID().id()); 472 UpdateTabBrowserIDs(tab.browser_id, context->GetSessionID().id());
464 } 473 }
465 474
466 // Place the tab at the end if the tab index is no longer valid or 475 // Place the tab at the end if the tab index is no longer valid or
467 // we were passed a specific disposition. 476 // we were passed a specific disposition.
468 if (tab_index < 0 || tab_index > context->GetTabCount() || 477 if (tab_index < 0 || tab_index > context->GetTabCount() ||
469 disposition != WindowOpenDisposition::UNKNOWN) { 478 disposition != WindowOpenDisposition::UNKNOWN) {
470 tab_index = context->GetTabCount(); 479 tab_index = context->GetTabCount();
471 } 480 }
(...skipping 13 matching lines...) Expand all
485 return context; 494 return context;
486 } 495 }
487 496
488 bool TabRestoreServiceHelper::ValidateTab(const Tab& tab) { 497 bool TabRestoreServiceHelper::ValidateTab(const Tab& tab) {
489 return !tab.navigations.empty() && 498 return !tab.navigations.empty() &&
490 static_cast<size_t>(tab.current_navigation_index) < 499 static_cast<size_t>(tab.current_navigation_index) <
491 tab.navigations.size(); 500 tab.navigations.size();
492 } 501 }
493 502
494 bool TabRestoreServiceHelper::ValidateWindow(const Window& window) { 503 bool TabRestoreServiceHelper::ValidateWindow(const Window& window) {
495 if (static_cast<size_t>(window.selected_tab_index) >= window.tabs.size()) { 504 if (static_cast<size_t>(window.selected_tab_index) >= window.tabs.size())
496 return false; 505 return false;
497 }
498 506
499 for (const auto& tab : window.tabs) { 507 for (const auto& tab : window.tabs) {
500 if (!ValidateTab(*tab)) { 508 if (!ValidateTab(*tab))
501 return false; 509 return false;
502 }
503 } 510 }
504 511
505 return true; 512 return true;
506 } 513 }
507 514
508 bool TabRestoreServiceHelper::IsTabInteresting(const Tab& tab) { 515 bool TabRestoreServiceHelper::IsTabInteresting(const Tab& tab) {
509 if (tab.navigations.empty()) 516 if (tab.navigations.empty())
510 return false; 517 return false;
511 518
512 if (tab.navigations.size() > 1) 519 if (tab.navigations.size() > 1)
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
549 tab.browser_id = new_id; 556 tab.browser_id = new_id;
550 } 557 }
551 } 558 }
552 } 559 }
553 560
554 base::Time TabRestoreServiceHelper::TimeNow() const { 561 base::Time TabRestoreServiceHelper::TimeNow() const {
555 return time_factory_ ? time_factory_->TimeNow() : base::Time::Now(); 562 return time_factory_ ? time_factory_->TimeNow() : base::Time::Now();
556 } 563 }
557 564
558 } // namespace sessions 565 } // namespace sessions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698