OLD | NEW |
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 "chrome/browser/ui/toolbar/recent_tabs_sub_menu_model.h" | 5 #include "chrome/browser/ui/toolbar/recent_tabs_sub_menu_model.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
9 #include "base/prefs/scoped_user_pref_update.h" | 9 #include "base/prefs/scoped_user_pref_update.h" |
10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
11 #include "base/strings/utf_string_conversions.h" | 11 #include "base/strings/utf_string_conversions.h" |
12 #include "chrome/app/chrome_command_ids.h" | 12 #include "chrome/app/chrome_command_ids.h" |
13 #include "chrome/browser/favicon/favicon_service_factory.h" | 13 #include "chrome/browser/favicon/favicon_service_factory.h" |
14 #include "chrome/browser/profiles/profile.h" | 14 #include "chrome/browser/profiles/profile.h" |
15 #include "chrome/browser/search/search.h" | 15 #include "chrome/browser/search/search.h" |
16 #include "chrome/browser/sessions/session_restore.h" | 16 #include "chrome/browser/sessions/session_restore.h" |
17 #include "chrome/browser/sessions/tab_restore_service.h" | 17 #include "chrome/browser/sessions/tab_restore_service.h" |
18 #include "chrome/browser/sessions/tab_restore_service_delegate.h" | 18 #include "chrome/browser/sessions/tab_restore_service_delegate.h" |
19 #include "chrome/browser/sessions/tab_restore_service_factory.h" | 19 #include "chrome/browser/sessions/tab_restore_service_factory.h" |
20 #include "chrome/browser/sync/glue/session_model_associator.h" | |
21 #include "chrome/browser/sync/glue/synced_session.h" | 20 #include "chrome/browser/sync/glue/synced_session.h" |
| 21 #include "chrome/browser/sync/open_tabs_ui_delegate.h" |
22 #include "chrome/browser/sync/profile_sync_service.h" | 22 #include "chrome/browser/sync/profile_sync_service.h" |
23 #include "chrome/browser/sync/profile_sync_service_factory.h" | 23 #include "chrome/browser/sync/profile_sync_service_factory.h" |
24 #include "chrome/browser/ui/browser.h" | 24 #include "chrome/browser/ui/browser.h" |
25 #include "chrome/browser/ui/browser_commands.h" | 25 #include "chrome/browser/ui/browser_commands.h" |
26 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 26 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
27 #include "chrome/browser/ui/toolbar/wrench_menu_model.h" | 27 #include "chrome/browser/ui/toolbar/wrench_menu_model.h" |
28 #include "chrome/common/favicon/favicon_types.h" | 28 #include "chrome/common/favicon/favicon_types.h" |
29 #include "chrome/common/pref_names.h" | 29 #include "chrome/common/pref_names.h" |
30 #include "grit/browser_resources.h" | 30 #include "grit/browser_resources.h" |
31 #include "grit/generated_resources.h" | 31 #include "grit/generated_resources.h" |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
160 string16 title; | 160 string16 title; |
161 GURL url; | 161 GURL url; |
162 }; | 162 }; |
163 | 163 |
164 const int RecentTabsSubMenuModel::kRecentlyClosedHeaderCommandId = 1120; | 164 const int RecentTabsSubMenuModel::kRecentlyClosedHeaderCommandId = 1120; |
165 const int RecentTabsSubMenuModel::kDisabledRecentlyClosedHeaderCommandId = 1121; | 165 const int RecentTabsSubMenuModel::kDisabledRecentlyClosedHeaderCommandId = 1121; |
166 | 166 |
167 RecentTabsSubMenuModel::RecentTabsSubMenuModel( | 167 RecentTabsSubMenuModel::RecentTabsSubMenuModel( |
168 ui::AcceleratorProvider* accelerator_provider, | 168 ui::AcceleratorProvider* accelerator_provider, |
169 Browser* browser, | 169 Browser* browser, |
170 browser_sync::SessionModelAssociator* associator) | 170 browser_sync::OpenTabsUIDelegate* delegate) |
171 : ui::SimpleMenuModel(this), | 171 : ui::SimpleMenuModel(this), |
172 browser_(browser), | 172 browser_(browser), |
173 associator_(associator), | 173 open_tabs_(delegate), |
174 last_local_model_index_(-1), | 174 last_local_model_index_(-1), |
175 default_favicon_(ResourceBundle::GetSharedInstance(). | 175 default_favicon_(ResourceBundle::GetSharedInstance(). |
176 GetNativeImageNamed(IDR_DEFAULT_FAVICON)), | 176 GetNativeImageNamed(IDR_DEFAULT_FAVICON)), |
177 weak_ptr_factory_(this) { | 177 weak_ptr_factory_(this) { |
178 // Invoke asynchronous call to load tabs from local last session, which does | 178 // Invoke asynchronous call to load tabs from local last session, which does |
179 // nothing if the tabs have already been loaded or they shouldn't be loaded. | 179 // nothing if the tabs have already been loaded or they shouldn't be loaded. |
180 // TabRestoreServiceChanged() will be called after the tabs are loaded. | 180 // TabRestoreServiceChanged() will be called after the tabs are loaded. |
181 TabRestoreService* service = | 181 TabRestoreService* service = |
182 TabRestoreServiceFactory::GetForProfile(browser_->profile()); | 182 TabRestoreServiceFactory::GetForProfile(browser_->profile()); |
183 if (service) { | 183 if (service) { |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
278 DCHECK(item.tab_id > -1 && item.url.is_valid()); | 278 DCHECK(item.tab_id > -1 && item.url.is_valid()); |
279 | 279 |
280 if (item.session_tag.empty()) { // Restore tab of local session. | 280 if (item.session_tag.empty()) { // Restore tab of local session. |
281 if (service && delegate) { | 281 if (service && delegate) { |
282 UMA_HISTOGRAM_ENUMERATION("WrenchMenu.RecentTabsSubMenu", | 282 UMA_HISTOGRAM_ENUMERATION("WrenchMenu.RecentTabsSubMenu", |
283 LOCAL_SESSION_TAB, LIMIT_RECENT_TAB_ACTION); | 283 LOCAL_SESSION_TAB, LIMIT_RECENT_TAB_ACTION); |
284 service->RestoreEntryById(delegate, item.tab_id, | 284 service->RestoreEntryById(delegate, item.tab_id, |
285 browser_->host_desktop_type(), disposition); | 285 browser_->host_desktop_type(), disposition); |
286 } | 286 } |
287 } else { // Restore tab of session from other devices. | 287 } else { // Restore tab of session from other devices. |
288 browser_sync::SessionModelAssociator* associator = GetModelAssociator(); | 288 browser_sync::OpenTabsUIDelegate* open_tabs = GetOpenTabsUIDelegate(); |
289 if (!associator) | 289 if (!open_tabs) |
290 return; | 290 return; |
291 const SessionTab* tab; | 291 const SessionTab* tab; |
292 if (!associator->GetForeignTab(item.session_tag, item.tab_id, &tab)) | 292 if (!open_tabs->GetForeignTab(item.session_tag, item.tab_id, &tab)) |
293 return; | 293 return; |
294 if (tab->navigations.empty()) | 294 if (tab->navigations.empty()) |
295 return; | 295 return; |
296 UMA_HISTOGRAM_ENUMERATION("WrenchMenu.RecentTabsSubMenu", | 296 UMA_HISTOGRAM_ENUMERATION("WrenchMenu.RecentTabsSubMenu", |
297 OTHER_DEVICE_TAB, LIMIT_RECENT_TAB_ACTION); | 297 OTHER_DEVICE_TAB, LIMIT_RECENT_TAB_ACTION); |
298 SessionRestore::RestoreForeignSessionTab( | 298 SessionRestore::RestoreForeignSessionTab( |
299 browser_->tab_strip_model()->GetActiveWebContents(), | 299 browser_->tab_strip_model()->GetActiveWebContents(), |
300 *tab, disposition); | 300 *tab, disposition); |
301 } | 301 } |
302 } else { | 302 } else { |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
415 } | 415 } |
416 | 416 |
417 DCHECK_GE(last_local_model_index_, 0); | 417 DCHECK_GE(last_local_model_index_, 0); |
418 } | 418 } |
419 | 419 |
420 void RecentTabsSubMenuModel::BuildTabsFromOtherDevices() { | 420 void RecentTabsSubMenuModel::BuildTabsFromOtherDevices() { |
421 // All other devices' items (device headers or tabs) use AddItem*() to append | 421 // All other devices' items (device headers or tabs) use AddItem*() to append |
422 // a menu item, because they are always only built once (i.e. invoked from | 422 // a menu item, because they are always only built once (i.e. invoked from |
423 // Constructor()) and don't change after that. | 423 // Constructor()) and don't change after that. |
424 | 424 |
425 browser_sync::SessionModelAssociator* associator = GetModelAssociator(); | 425 browser_sync::OpenTabsUIDelegate* open_tabs = GetOpenTabsUIDelegate(); |
426 std::vector<const browser_sync::SyncedSession*> sessions; | 426 std::vector<const browser_sync::SyncedSession*> sessions; |
427 if (!associator || !associator->GetAllForeignSessions(&sessions)) { | 427 if (!open_tabs || !open_tabs->GetAllForeignSessions(&sessions)) { |
428 AddSeparator(ui::NORMAL_SEPARATOR); | 428 AddSeparator(ui::NORMAL_SEPARATOR); |
429 AddItemWithStringId(IDC_RECENT_TABS_NO_DEVICE_TABS, | 429 AddItemWithStringId(IDC_RECENT_TABS_NO_DEVICE_TABS, |
430 IDS_RECENT_TABS_NO_DEVICE_TABS); | 430 IDS_RECENT_TABS_NO_DEVICE_TABS); |
431 return; | 431 return; |
432 } | 432 } |
433 | 433 |
434 // Sort sessions from most recent to least recent. | 434 // Sort sessions from most recent to least recent. |
435 std::sort(sessions.begin(), sessions.end(), SortSessionsByRecency); | 435 std::sort(sessions.begin(), sessions.end(), SortSessionsByRecency); |
436 | 436 |
437 const size_t kMaxSessionsToShow = 3; | 437 const size_t kMaxSessionsToShow = 3; |
438 size_t num_sessions_added = 0; | 438 size_t num_sessions_added = 0; |
439 for (size_t i = 0; | 439 for (size_t i = 0; |
440 i < sessions.size() && num_sessions_added < kMaxSessionsToShow; ++i) { | 440 i < sessions.size() && num_sessions_added < kMaxSessionsToShow; ++i) { |
441 const browser_sync::SyncedSession* session = sessions[i]; | 441 const browser_sync::SyncedSession* session = sessions[i]; |
442 const std::string& session_tag = session->session_tag; | 442 const std::string& session_tag = session->session_tag; |
443 | 443 |
444 // Get windows of session. | 444 // Get windows of session. |
445 std::vector<const SessionWindow*> windows; | 445 std::vector<const SessionWindow*> windows; |
446 if (!associator->GetForeignSession(session_tag, &windows) || | 446 if (!open_tabs->GetForeignSession(session_tag, &windows) || |
447 windows.empty()) { | 447 windows.empty()) { |
448 continue; | 448 continue; |
449 } | 449 } |
450 | 450 |
451 // Collect tabs from all windows of session, pruning those that are not | 451 // Collect tabs from all windows of session, pruning those that are not |
452 // syncable or are NewTabPage, then sort them from most recent to least | 452 // syncable or are NewTabPage, then sort them from most recent to least |
453 // recent, independent of which window the tabs were from. | 453 // recent, independent of which window the tabs were from. |
454 std::vector<const SessionTab*> tabs_in_session; | 454 std::vector<const SessionTab*> tabs_in_session; |
455 for (size_t j = 0; j < windows.size(); ++j) { | 455 for (size_t j = 0; j < windows.size(); ++j) { |
456 const SessionWindow* window = windows[j]; | 456 const SessionWindow* window = windows[j]; |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
581 void RecentTabsSubMenuModel::AddTabFavicon(int command_id, const GURL& url) { | 581 void RecentTabsSubMenuModel::AddTabFavicon(int command_id, const GURL& url) { |
582 bool is_local_tab = command_id < kFirstOtherDevicesTabCommandId; | 582 bool is_local_tab = command_id < kFirstOtherDevicesTabCommandId; |
583 int index_in_menu = GetIndexOfCommandId(command_id); | 583 int index_in_menu = GetIndexOfCommandId(command_id); |
584 | 584 |
585 if (!is_local_tab) { | 585 if (!is_local_tab) { |
586 // If tab has synced favicon, use it. | 586 // If tab has synced favicon, use it. |
587 // Note that currently, other devices' tabs only have favicons if | 587 // Note that currently, other devices' tabs only have favicons if |
588 // --sync-tab-favicons switch is on; according to zea@, this flag is now | 588 // --sync-tab-favicons switch is on; according to zea@, this flag is now |
589 // automatically enabled for iOS and android, and they're looking into | 589 // automatically enabled for iOS and android, and they're looking into |
590 // enabling it for other platforms. | 590 // enabling it for other platforms. |
591 browser_sync::SessionModelAssociator* associator = GetModelAssociator(); | 591 browser_sync::OpenTabsUIDelegate* open_tabs = GetOpenTabsUIDelegate(); |
592 scoped_refptr<base::RefCountedMemory> favicon_png; | 592 scoped_refptr<base::RefCountedMemory> favicon_png; |
593 if (associator && | 593 if (open_tabs && |
594 associator->GetSyncedFaviconForPageURL(url.spec(), &favicon_png)) { | 594 open_tabs->GetSyncedFaviconForPageURL(url.spec(), &favicon_png)) { |
595 gfx::Image image = gfx::Image::CreateFrom1xPNGBytes(favicon_png->front(), | 595 gfx::Image image = gfx::Image::CreateFrom1xPNGBytes(favicon_png->front(), |
596 favicon_png->size()); | 596 favicon_png->size()); |
597 SetIcon(index_in_menu, image); | 597 SetIcon(index_in_menu, image); |
598 return; | 598 return; |
599 } | 599 } |
600 } | 600 } |
601 | 601 |
602 // Otherwise, start to fetch the favicon from local history asynchronously. | 602 // Otherwise, start to fetch the favicon from local history asynchronously. |
603 // Set default icon first. | 603 // Set default icon first. |
604 SetIcon(index_in_menu, default_favicon_); | 604 SetIcon(index_in_menu, default_favicon_); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
653 // local tabs. | 653 // local tabs. |
654 local_tab_cancelable_task_tracker_.TryCancelAll(); | 654 local_tab_cancelable_task_tracker_.TryCancelAll(); |
655 | 655 |
656 // Remove all local tab navigation items. | 656 // Remove all local tab navigation items. |
657 local_tab_navigation_items_.clear(); | 657 local_tab_navigation_items_.clear(); |
658 | 658 |
659 // Remove all local window items. | 659 // Remove all local window items. |
660 local_window_items_.clear(); | 660 local_window_items_.clear(); |
661 } | 661 } |
662 | 662 |
663 browser_sync::SessionModelAssociator* | 663 browser_sync::OpenTabsUIDelegate* |
664 RecentTabsSubMenuModel::GetModelAssociator() { | 664 RecentTabsSubMenuModel::GetOpenTabsUIDelegate() { |
665 if (!associator_) { | 665 if (!open_tabs_) { |
666 ProfileSyncService* service = ProfileSyncServiceFactory::GetInstance()-> | 666 ProfileSyncService* service = ProfileSyncServiceFactory::GetInstance()-> |
667 GetForProfile(browser_->profile()); | 667 GetForProfile(browser_->profile()); |
668 // Only return the associator if it exists and it is done syncing sessions. | 668 // Only return the delegate if it exists and it is done syncing sessions. |
669 if (service && service->ShouldPushChanges()) | 669 if (service && service->ShouldPushChanges()) |
670 associator_ = service->GetSessionModelAssociator(); | 670 open_tabs_ = service->GetOpenTabsUIDelegate(); |
671 } | 671 } |
672 return associator_; | 672 return open_tabs_; |
673 } | 673 } |
674 | 674 |
675 void RecentTabsSubMenuModel::TabRestoreServiceChanged( | 675 void RecentTabsSubMenuModel::TabRestoreServiceChanged( |
676 TabRestoreService* service) { | 676 TabRestoreService* service) { |
677 ClearLocalEntries(); | 677 ClearLocalEntries(); |
678 | 678 |
679 BuildLocalEntries(); | 679 BuildLocalEntries(); |
680 | 680 |
681 ui::MenuModelDelegate* menu_model_delegate = GetMenuModelDelegate(); | 681 ui::MenuModelDelegate* menu_model_delegate = GetMenuModelDelegate(); |
682 if (menu_model_delegate) | 682 if (menu_model_delegate) |
683 menu_model_delegate->OnMenuStructureChanged(); | 683 menu_model_delegate->OnMenuStructureChanged(); |
684 } | 684 } |
685 | 685 |
686 void RecentTabsSubMenuModel::TabRestoreServiceDestroyed( | 686 void RecentTabsSubMenuModel::TabRestoreServiceDestroyed( |
687 TabRestoreService* service) { | 687 TabRestoreService* service) { |
688 TabRestoreServiceChanged(service); | 688 TabRestoreServiceChanged(service); |
689 } | 689 } |
OLD | NEW |