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 <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/metrics/histogram_macros.h" | 10 #include "base/metrics/histogram_macros.h" |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
78 // The maximum number of local recently closed entries (tab or window) to be | 78 // The maximum number of local recently closed entries (tab or window) to be |
79 // shown in the menu. | 79 // shown in the menu. |
80 const int kMaxLocalEntries = 8; | 80 const int kMaxLocalEntries = 8; |
81 | 81 |
82 // Index of the separator that follows the history menu item. Used as a | 82 // Index of the separator that follows the history menu item. Used as a |
83 // reference position for inserting local entries. | 83 // reference position for inserting local entries. |
84 const int kHistorySeparatorIndex = 1; | 84 const int kHistorySeparatorIndex = 1; |
85 | 85 |
86 // Comparator function for use with std::sort that will sort sessions by | 86 // Comparator function for use with std::sort that will sort sessions by |
87 // descending modified_time (i.e., most recent first). | 87 // descending modified_time (i.e., most recent first). |
88 bool SortSessionsByRecency(const sync_driver::SyncedSession* s1, | 88 bool SortSessionsByRecency(const sync_sessions::SyncedSession* s1, |
89 const sync_driver::SyncedSession* s2) { | 89 const sync_sessions::SyncedSession* s2) { |
90 return s1->modified_time > s2->modified_time; | 90 return s1->modified_time > s2->modified_time; |
91 } | 91 } |
92 | 92 |
93 // Returns true if the command id identifies a tab menu item. | 93 // Returns true if the command id identifies a tab menu item. |
94 bool IsTabModelCommandId(int command_id) { | 94 bool IsTabModelCommandId(int command_id) { |
95 return ((command_id >= kFirstLocalTabCommandId && | 95 return ((command_id >= kFirstLocalTabCommandId && |
96 command_id < kFirstLocalWindowCommandId) || | 96 command_id < kFirstLocalWindowCommandId) || |
97 (command_id >= kFirstOtherDevicesTabCommandId && | 97 (command_id >= kFirstOtherDevicesTabCommandId && |
98 command_id < kMinDeviceNameCommandId)); | 98 command_id < kMinDeviceNameCommandId)); |
99 } | 99 } |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
173 base::string16 title; | 173 base::string16 title; |
174 GURL url; | 174 GURL url; |
175 }; | 175 }; |
176 | 176 |
177 const int RecentTabsSubMenuModel::kRecentlyClosedHeaderCommandId = 1120; | 177 const int RecentTabsSubMenuModel::kRecentlyClosedHeaderCommandId = 1120; |
178 const int RecentTabsSubMenuModel::kDisabledRecentlyClosedHeaderCommandId = 1121; | 178 const int RecentTabsSubMenuModel::kDisabledRecentlyClosedHeaderCommandId = 1121; |
179 | 179 |
180 RecentTabsSubMenuModel::RecentTabsSubMenuModel( | 180 RecentTabsSubMenuModel::RecentTabsSubMenuModel( |
181 ui::AcceleratorProvider* accelerator_provider, | 181 ui::AcceleratorProvider* accelerator_provider, |
182 Browser* browser, | 182 Browser* browser, |
183 sync_driver::OpenTabsUIDelegate* open_tabs_delegate) | 183 sync_sessions::OpenTabsUIDelegate* open_tabs_delegate) |
184 : ui::SimpleMenuModel(this), | 184 : ui::SimpleMenuModel(this), |
185 browser_(browser), | 185 browser_(browser), |
186 open_tabs_delegate_(open_tabs_delegate), | 186 open_tabs_delegate_(open_tabs_delegate), |
187 last_local_model_index_(kHistorySeparatorIndex), | 187 last_local_model_index_(kHistorySeparatorIndex), |
188 default_favicon_(ui::ResourceBundle::GetSharedInstance(). | 188 default_favicon_( |
189 GetNativeImageNamed(IDR_DEFAULT_FAVICON)), | 189 ui::ResourceBundle::GetSharedInstance().GetNativeImageNamed( |
| 190 IDR_DEFAULT_FAVICON)), |
190 weak_ptr_factory_(this) { | 191 weak_ptr_factory_(this) { |
191 // Invoke asynchronous call to load tabs from local last session, which does | 192 // Invoke asynchronous call to load tabs from local last session, which does |
192 // nothing if the tabs have already been loaded or they shouldn't be loaded. | 193 // nothing if the tabs have already been loaded or they shouldn't be loaded. |
193 // TabRestoreServiceChanged() will be called after the tabs are loaded. | 194 // TabRestoreServiceChanged() will be called after the tabs are loaded. |
194 sessions::TabRestoreService* service = | 195 sessions::TabRestoreService* service = |
195 TabRestoreServiceFactory::GetForProfile(browser_->profile()); | 196 TabRestoreServiceFactory::GetForProfile(browser_->profile()); |
196 if (service) { | 197 if (service) { |
197 service->LoadTabsFromLastSession(); | 198 service->LoadTabsFromLastSession(); |
198 | 199 |
199 // TODO(sail): enable this when mac implements the dynamic menu, together with | 200 // TODO(sail): enable this when mac implements the dynamic menu, together with |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
310 | 311 |
311 if (item.session_tag.empty()) { // Restore tab of local session. | 312 if (item.session_tag.empty()) { // Restore tab of local session. |
312 if (service && context) { | 313 if (service && context) { |
313 content::RecordAction( | 314 content::RecordAction( |
314 base::UserMetricsAction("WrenchMenu_OpenRecentTabFromLocal")); | 315 base::UserMetricsAction("WrenchMenu_OpenRecentTabFromLocal")); |
315 UMA_HISTOGRAM_ENUMERATION("WrenchMenu.RecentTabsSubMenu", | 316 UMA_HISTOGRAM_ENUMERATION("WrenchMenu.RecentTabsSubMenu", |
316 LOCAL_SESSION_TAB, LIMIT_RECENT_TAB_ACTION); | 317 LOCAL_SESSION_TAB, LIMIT_RECENT_TAB_ACTION); |
317 service->RestoreEntryById(context, item.tab_id, disposition); | 318 service->RestoreEntryById(context, item.tab_id, disposition); |
318 } | 319 } |
319 } else { // Restore tab of session from other devices. | 320 } else { // Restore tab of session from other devices. |
320 sync_driver::OpenTabsUIDelegate* open_tabs = GetOpenTabsUIDelegate(); | 321 sync_sessions::OpenTabsUIDelegate* open_tabs = GetOpenTabsUIDelegate(); |
321 if (!open_tabs) | 322 if (!open_tabs) |
322 return; | 323 return; |
323 const sessions::SessionTab* tab; | 324 const sessions::SessionTab* tab; |
324 if (!open_tabs->GetForeignTab(item.session_tag, item.tab_id, &tab)) | 325 if (!open_tabs->GetForeignTab(item.session_tag, item.tab_id, &tab)) |
325 return; | 326 return; |
326 if (tab->navigations.empty()) | 327 if (tab->navigations.empty()) |
327 return; | 328 return; |
328 content::RecordAction( | 329 content::RecordAction( |
329 base::UserMetricsAction("WrenchMenu_OpenRecentTabFromDevice")); | 330 base::UserMetricsAction("WrenchMenu_OpenRecentTabFromDevice")); |
330 UMA_HISTOGRAM_ENUMERATION("WrenchMenu.RecentTabsSubMenu", | 331 UMA_HISTOGRAM_ENUMERATION("WrenchMenu.RecentTabsSubMenu", |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
469 } | 470 } |
470 } | 471 } |
471 DCHECK_GE(last_local_model_index_, 0); | 472 DCHECK_GE(last_local_model_index_, 0); |
472 } | 473 } |
473 | 474 |
474 void RecentTabsSubMenuModel::BuildTabsFromOtherDevices() { | 475 void RecentTabsSubMenuModel::BuildTabsFromOtherDevices() { |
475 // All other devices' items (device headers or tabs) use AddItem*() to append | 476 // All other devices' items (device headers or tabs) use AddItem*() to append |
476 // a menu item, because they are always only built once (i.e. invoked from | 477 // a menu item, because they are always only built once (i.e. invoked from |
477 // Constructor()) and don't change after that. | 478 // Constructor()) and don't change after that. |
478 | 479 |
479 sync_driver::OpenTabsUIDelegate* open_tabs = GetOpenTabsUIDelegate(); | 480 sync_sessions::OpenTabsUIDelegate* open_tabs = GetOpenTabsUIDelegate(); |
480 std::vector<const sync_driver::SyncedSession*> sessions; | 481 std::vector<const sync_sessions::SyncedSession*> sessions; |
481 if (!open_tabs || !open_tabs->GetAllForeignSessions(&sessions)) { | 482 if (!open_tabs || !open_tabs->GetAllForeignSessions(&sessions)) { |
482 AddSeparator(ui::NORMAL_SEPARATOR); | 483 AddSeparator(ui::NORMAL_SEPARATOR); |
483 AddItemWithStringId(IDC_RECENT_TABS_NO_DEVICE_TABS, | 484 AddItemWithStringId(IDC_RECENT_TABS_NO_DEVICE_TABS, |
484 IDS_RECENT_TABS_NO_DEVICE_TABS); | 485 IDS_RECENT_TABS_NO_DEVICE_TABS); |
485 return; | 486 return; |
486 } | 487 } |
487 | 488 |
488 // Sort sessions from most recent to least recent. | 489 // Sort sessions from most recent to least recent. |
489 std::sort(sessions.begin(), sessions.end(), SortSessionsByRecency); | 490 std::sort(sessions.begin(), sessions.end(), SortSessionsByRecency); |
490 | 491 |
491 const size_t kMaxSessionsToShow = 3; | 492 const size_t kMaxSessionsToShow = 3; |
492 size_t num_sessions_added = 0; | 493 size_t num_sessions_added = 0; |
493 for (size_t i = 0; | 494 for (size_t i = 0; |
494 i < sessions.size() && num_sessions_added < kMaxSessionsToShow; ++i) { | 495 i < sessions.size() && num_sessions_added < kMaxSessionsToShow; ++i) { |
495 const sync_driver::SyncedSession* session = sessions[i]; | 496 const sync_sessions::SyncedSession* session = sessions[i]; |
496 const std::string& session_tag = session->session_tag; | 497 const std::string& session_tag = session->session_tag; |
497 | 498 |
498 // Collect tabs from all windows of the session, ordered by recency. | 499 // Collect tabs from all windows of the session, ordered by recency. |
499 std::vector<const sessions::SessionTab*> tabs_in_session; | 500 std::vector<const sessions::SessionTab*> tabs_in_session; |
500 if (!open_tabs->GetForeignSessionTabs(session_tag, &tabs_in_session) || | 501 if (!open_tabs->GetForeignSessionTabs(session_tag, &tabs_in_session) || |
501 tabs_in_session.empty()) | 502 tabs_in_session.empty()) |
502 continue; | 503 continue; |
503 | 504 |
504 // Add the header for the device session. | 505 // Add the header for the device session. |
505 DCHECK(!session->session_name.empty()); | 506 DCHECK(!session->session_name.empty()); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
571 // There may be no tab title, in which case, use the url as tab title. | 572 // There may be no tab title, in which case, use the url as tab title. |
572 AddItem(command_id, | 573 AddItem(command_id, |
573 current_navigation.title().empty() ? | 574 current_navigation.title().empty() ? |
574 base::UTF8ToUTF16(item.url.spec()) : current_navigation.title()); | 575 base::UTF8ToUTF16(item.url.spec()) : current_navigation.title()); |
575 AddTabFavicon(command_id, item.url); | 576 AddTabFavicon(command_id, item.url); |
576 other_devices_tab_navigation_items_.push_back(item); | 577 other_devices_tab_navigation_items_.push_back(item); |
577 } | 578 } |
578 | 579 |
579 void RecentTabsSubMenuModel::AddDeviceFavicon( | 580 void RecentTabsSubMenuModel::AddDeviceFavicon( |
580 int index_in_menu, | 581 int index_in_menu, |
581 sync_driver::SyncedSession::DeviceType device_type) { | 582 sync_sessions::SyncedSession::DeviceType device_type) { |
582 #if defined(OS_MACOSX) | 583 #if defined(OS_MACOSX) |
583 int favicon_id = -1; | 584 int favicon_id = -1; |
584 switch (device_type) { | 585 switch (device_type) { |
585 case sync_driver::SyncedSession::TYPE_PHONE: | 586 case sync_sessions::SyncedSession::TYPE_PHONE: |
586 favicon_id = IDR_PHONE_FAVICON; | 587 favicon_id = IDR_PHONE_FAVICON; |
587 break; | 588 break; |
588 | 589 |
589 case sync_driver::SyncedSession::TYPE_TABLET: | 590 case sync_sessions::SyncedSession::TYPE_TABLET: |
590 favicon_id = IDR_TABLET_FAVICON; | 591 favicon_id = IDR_TABLET_FAVICON; |
591 break; | 592 break; |
592 | 593 |
593 case sync_driver::SyncedSession::TYPE_CHROMEOS: | 594 case sync_sessions::SyncedSession::TYPE_CHROMEOS: |
594 case sync_driver::SyncedSession::TYPE_WIN: | 595 case sync_sessions::SyncedSession::TYPE_WIN: |
595 case sync_driver::SyncedSession::TYPE_MACOSX: | 596 case sync_sessions::SyncedSession::TYPE_MACOSX: |
596 case sync_driver::SyncedSession::TYPE_LINUX: | 597 case sync_sessions::SyncedSession::TYPE_LINUX: |
597 case sync_driver::SyncedSession::TYPE_OTHER: | 598 case sync_sessions::SyncedSession::TYPE_OTHER: |
598 case sync_driver::SyncedSession::TYPE_UNSET: | 599 case sync_sessions::SyncedSession::TYPE_UNSET: |
599 favicon_id = IDR_LAPTOP_FAVICON; | 600 favicon_id = IDR_LAPTOP_FAVICON; |
600 break; | 601 break; |
601 } | 602 } |
602 | 603 |
603 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 604 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
604 SetIcon(index_in_menu, rb.GetNativeImageNamed(favicon_id)); | 605 SetIcon(index_in_menu, rb.GetNativeImageNamed(favicon_id)); |
605 #else | 606 #else |
606 gfx::VectorIconId favicon_id = gfx::VectorIconId::VECTOR_ICON_NONE; | 607 gfx::VectorIconId favicon_id = gfx::VectorIconId::VECTOR_ICON_NONE; |
607 switch (device_type) { | 608 switch (device_type) { |
608 case sync_driver::SyncedSession::TYPE_PHONE: | 609 case sync_sessions::SyncedSession::TYPE_PHONE: |
609 favicon_id = gfx::VectorIconId::SMARTPHONE; | 610 favicon_id = gfx::VectorIconId::SMARTPHONE; |
610 break; | 611 break; |
611 | 612 |
612 case sync_driver::SyncedSession::TYPE_TABLET: | 613 case sync_sessions::SyncedSession::TYPE_TABLET: |
613 favicon_id = gfx::VectorIconId::TABLET; | 614 favicon_id = gfx::VectorIconId::TABLET; |
614 break; | 615 break; |
615 | 616 |
616 case sync_driver::SyncedSession::TYPE_CHROMEOS: | 617 case sync_sessions::SyncedSession::TYPE_CHROMEOS: |
617 case sync_driver::SyncedSession::TYPE_WIN: | 618 case sync_sessions::SyncedSession::TYPE_WIN: |
618 case sync_driver::SyncedSession::TYPE_MACOSX: | 619 case sync_sessions::SyncedSession::TYPE_MACOSX: |
619 case sync_driver::SyncedSession::TYPE_LINUX: | 620 case sync_sessions::SyncedSession::TYPE_LINUX: |
620 case sync_driver::SyncedSession::TYPE_OTHER: | 621 case sync_sessions::SyncedSession::TYPE_OTHER: |
621 case sync_driver::SyncedSession::TYPE_UNSET: | 622 case sync_sessions::SyncedSession::TYPE_UNSET: |
622 favicon_id = gfx::VectorIconId::LAPTOP; | 623 favicon_id = gfx::VectorIconId::LAPTOP; |
623 break; | 624 break; |
624 } | 625 } |
625 | 626 |
626 SetIcon(index_in_menu, CreateFavicon(favicon_id)); | 627 SetIcon(index_in_menu, CreateFavicon(favicon_id)); |
627 #endif | 628 #endif |
628 } | 629 } |
629 | 630 |
630 void RecentTabsSubMenuModel::AddTabFavicon(int command_id, const GURL& url) { | 631 void RecentTabsSubMenuModel::AddTabFavicon(int command_id, const GURL& url) { |
631 bool is_local_tab = command_id < kFirstOtherDevicesTabCommandId; | 632 bool is_local_tab = command_id < kFirstOtherDevicesTabCommandId; |
632 int index_in_menu = GetIndexOfCommandId(command_id); | 633 int index_in_menu = GetIndexOfCommandId(command_id); |
633 | 634 |
634 if (!is_local_tab) { | 635 if (!is_local_tab) { |
635 // If tab has synced favicon, use it. | 636 // If tab has synced favicon, use it. |
636 // Note that currently, other devices' tabs only have favicons if | 637 // Note that currently, other devices' tabs only have favicons if |
637 // --sync-tab-favicons switch is on; according to zea@, this flag is now | 638 // --sync-tab-favicons switch is on; according to zea@, this flag is now |
638 // automatically enabled for iOS and android, and they're looking into | 639 // automatically enabled for iOS and android, and they're looking into |
639 // enabling it for other platforms. | 640 // enabling it for other platforms. |
640 sync_driver::OpenTabsUIDelegate* open_tabs = GetOpenTabsUIDelegate(); | 641 sync_sessions::OpenTabsUIDelegate* open_tabs = GetOpenTabsUIDelegate(); |
641 scoped_refptr<base::RefCountedMemory> favicon_png; | 642 scoped_refptr<base::RefCountedMemory> favicon_png; |
642 if (open_tabs && | 643 if (open_tabs && |
643 open_tabs->GetSyncedFaviconForPageURL(url.spec(), &favicon_png)) { | 644 open_tabs->GetSyncedFaviconForPageURL(url.spec(), &favicon_png)) { |
644 gfx::Image image = gfx::Image::CreateFrom1xPNGBytes(favicon_png); | 645 gfx::Image image = gfx::Image::CreateFrom1xPNGBytes(favicon_png); |
645 SetIcon(index_in_menu, image); | 646 SetIcon(index_in_menu, image); |
646 return; | 647 return; |
647 } | 648 } |
648 } | 649 } |
649 | 650 |
650 // Otherwise, start to fetch the favicon from local history asynchronously. | 651 // Otherwise, start to fetch the favicon from local history asynchronously. |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
700 // all local tabs. | 701 // all local tabs. |
701 local_tab_cancelable_task_tracker_.TryCancelAll(); | 702 local_tab_cancelable_task_tracker_.TryCancelAll(); |
702 | 703 |
703 // Remove all local tab navigation items. | 704 // Remove all local tab navigation items. |
704 local_tab_navigation_items_.clear(); | 705 local_tab_navigation_items_.clear(); |
705 | 706 |
706 // Remove all local window items. | 707 // Remove all local window items. |
707 local_window_items_.clear(); | 708 local_window_items_.clear(); |
708 } | 709 } |
709 | 710 |
710 sync_driver::OpenTabsUIDelegate* | 711 sync_sessions::OpenTabsUIDelegate* |
711 RecentTabsSubMenuModel::GetOpenTabsUIDelegate() { | 712 RecentTabsSubMenuModel::GetOpenTabsUIDelegate() { |
712 if (!open_tabs_delegate_) { | 713 if (!open_tabs_delegate_) { |
713 ProfileSyncService* service = ProfileSyncServiceFactory::GetInstance()-> | 714 ProfileSyncService* service = ProfileSyncServiceFactory::GetInstance()-> |
714 GetForProfile(browser_->profile()); | 715 GetForProfile(browser_->profile()); |
715 // Only return the delegate if it exists and it is done syncing sessions. | 716 // Only return the delegate if it exists and it is done syncing sessions. |
716 if (service && service->IsSyncActive()) | 717 if (service && service->IsSyncActive()) |
717 open_tabs_delegate_ = service->GetOpenTabsUIDelegate(); | 718 open_tabs_delegate_ = service->GetOpenTabsUIDelegate(); |
718 } | 719 } |
719 return open_tabs_delegate_; | 720 return open_tabs_delegate_; |
720 } | 721 } |
721 | 722 |
722 void RecentTabsSubMenuModel::TabRestoreServiceChanged( | 723 void RecentTabsSubMenuModel::TabRestoreServiceChanged( |
723 sessions::TabRestoreService* service) { | 724 sessions::TabRestoreService* service) { |
724 ClearLocalEntries(); | 725 ClearLocalEntries(); |
725 | 726 |
726 BuildLocalEntries(); | 727 BuildLocalEntries(); |
727 | 728 |
728 ui::MenuModelDelegate* menu_model_delegate = GetMenuModelDelegate(); | 729 ui::MenuModelDelegate* menu_model_delegate = GetMenuModelDelegate(); |
729 if (menu_model_delegate) | 730 if (menu_model_delegate) |
730 menu_model_delegate->OnMenuStructureChanged(); | 731 menu_model_delegate->OnMenuStructureChanged(); |
731 } | 732 } |
732 | 733 |
733 void RecentTabsSubMenuModel::TabRestoreServiceDestroyed( | 734 void RecentTabsSubMenuModel::TabRestoreServiceDestroyed( |
734 sessions::TabRestoreService* service) { | 735 sessions::TabRestoreService* service) { |
735 TabRestoreServiceChanged(service); | 736 TabRestoreServiceChanged(service); |
736 } | 737 } |
OLD | NEW |