| 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 |