Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/ash/launcher/chrome_launcher_controller.h" | 5 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "ash/ash_switches.h" | 9 #include "ash/ash_switches.h" |
| 10 #include "ash/desktop_background/desktop_background_controller.h" | 10 #include "ash/desktop_background/desktop_background_controller.h" |
| (...skipping 902 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 913 void ChromeLauncherController::ToggleShelfAutoHideBehavior( | 913 void ChromeLauncherController::ToggleShelfAutoHideBehavior( |
| 914 aura::Window* root_window) { | 914 aura::Window* root_window) { |
| 915 ash::ShelfAutoHideBehavior behavior = GetShelfAutoHideBehavior(root_window) == | 915 ash::ShelfAutoHideBehavior behavior = GetShelfAutoHideBehavior(root_window) == |
| 916 ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS ? | 916 ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS ? |
| 917 ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER : | 917 ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER : |
| 918 ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS; | 918 ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS; |
| 919 SetShelfAutoHideBehaviorPrefs(behavior, root_window); | 919 SetShelfAutoHideBehaviorPrefs(behavior, root_window); |
| 920 return; | 920 return; |
| 921 } | 921 } |
| 922 | 922 |
| 923 void ChromeLauncherController::RemoveTabFromRunningApp( | |
| 924 WebContents* tab, | |
| 925 const std::string& app_id) { | |
| 926 web_contents_to_app_id_.erase(tab); | |
| 927 // BrowserShortcutLauncherItemController::UpdateBrowserItemState() will update | |
| 928 // the state when no application is associated with the tab. | |
| 929 if (app_id.empty()) | |
| 930 return; | |
| 931 | |
| 932 AppIDToWebContentsListMap::iterator i_app_id = | |
| 933 app_id_to_web_contents_list_.find(app_id); | |
| 934 if (i_app_id != app_id_to_web_contents_list_.end()) { | |
| 935 WebContentsList* tab_list = &i_app_id->second; | |
| 936 tab_list->remove(tab); | |
| 937 ash::ShelfItemStatus status = ash::STATUS_RUNNING; | |
| 938 if (tab_list->empty()) { | |
| 939 app_id_to_web_contents_list_.erase(i_app_id); | |
| 940 status = ash::STATUS_CLOSED; | |
| 941 } | |
| 942 ash::ShelfID id = GetShelfIDForAppID(app_id); | |
| 943 if (id) | |
| 944 SetItemStatus(id, status); | |
| 945 } | |
| 946 } | |
| 947 | |
| 948 void ChromeLauncherController::UpdateAppState(content::WebContents* contents, | 923 void ChromeLauncherController::UpdateAppState(content::WebContents* contents, |
| 949 AppState app_state) { | 924 AppState app_state) { |
| 950 std::string app_id = app_tab_helper_->GetAppID(contents); | 925 std::string app_id = app_tab_helper_->GetAppID(contents); |
| 951 | 926 |
| 952 // Check if the gMail app is loaded and it matches the given content. | 927 // Check if the gMail app is loaded and it matches the given content. |
| 953 // This special treatment is needed to address crbug.com/234268. | 928 // This special treatment is needed to address crbug.com/234268. |
| 954 if (app_id.empty() && ContentCanBeHandledByGmailApp(contents)) | 929 if (app_id.empty() && ContentCanBeHandledByGmailApp(contents)) |
| 955 app_id = kGmailAppId; | 930 app_id = kGmailAppId; |
| 956 | 931 |
| 957 // Check the old |app_id| for a tab. If the contents has changed we need to | 932 // Check the old |app_id| for a tab. If the contents has changed we need to |
| 958 // remove it from the previous app. | 933 // remove it from the previous app. |
| 959 if (web_contents_to_app_id_.find(contents) != web_contents_to_app_id_.end()) { | 934 if (web_contents_to_app_id_.find(contents) != web_contents_to_app_id_.end()) { |
| 960 std::string last_app_id = web_contents_to_app_id_[contents]; | 935 std::string last_app_id = web_contents_to_app_id_[contents]; |
| 961 if (last_app_id != app_id) | 936 if (last_app_id != app_id) { |
| 962 RemoveTabFromRunningApp(contents, last_app_id); | 937 ash::ShelfID id = GetShelfIDForAppID(last_app_id); |
| 938 if (id) { | |
| 939 // We remove the content before checking existence with GetAppState. | |
|
sky
2014/03/26 21:59:35
Again, document why. This comment just documents c
Mr4D (OOO till 08-26)
2014/03/27 14:50:54
I do not see it this way. It says that it removes
| |
| 940 web_contents_to_app_id_.erase(contents); | |
| 941 SetItemStatus(id, GetAppState(last_app_id)); | |
| 942 } | |
| 943 } | |
| 963 } | 944 } |
| 964 | 945 |
| 965 web_contents_to_app_id_[contents] = app_id; | 946 web_contents_to_app_id_[contents] = app_id; |
|
sky
2014/03/26 21:59:35
Seems silly to have a remove 2 lines later. How ab
Mr4D (OOO till 08-26)
2014/03/27 14:50:54
Done.
| |
| 966 | 947 |
| 967 if (app_state == APP_STATE_REMOVED) { | 948 if (app_state == APP_STATE_REMOVED) |
| 968 // The tab has gone away. | 949 web_contents_to_app_id_.erase(contents); |
| 969 RemoveTabFromRunningApp(contents, app_id); | |
| 970 } else if (!app_id.empty()) { | |
| 971 WebContentsList& tab_list(app_id_to_web_contents_list_[app_id]); | |
| 972 WebContentsList::const_iterator i_tab = | |
| 973 std::find(tab_list.begin(), tab_list.end(), contents); | |
| 974 | 950 |
| 975 if (i_tab == tab_list.end()) | 951 ash::ShelfID id = GetShelfIDForAppID(app_id); |
| 976 tab_list.push_back(contents); | 952 if (id) |
| 977 | 953 SetItemStatus(id, GetAppState(app_id)); |
| 978 if (app_state == APP_STATE_INACTIVE || app_state == APP_STATE_ACTIVE) { | |
| 979 if (i_tab != tab_list.begin()) { | |
| 980 // Going to running state, but wasn't the front tab, indicating that a | |
| 981 // new tab has already become active. | |
| 982 return; | |
| 983 } | |
| 984 } | |
| 985 | |
| 986 if (app_state == APP_STATE_ACTIVE || app_state == APP_STATE_WINDOW_ACTIVE) { | |
| 987 tab_list.remove(contents); | |
| 988 tab_list.push_front(contents); | |
| 989 } | |
| 990 | |
| 991 ash::ShelfID id = GetShelfIDForAppID(app_id); | |
| 992 if (id) { | |
| 993 // If the window is active, mark the app as active. | |
| 994 SetItemStatus(id, app_state == APP_STATE_WINDOW_ACTIVE ? | |
| 995 ash::STATUS_ACTIVE : ash::STATUS_RUNNING); | |
| 996 } | |
| 997 } | |
| 998 } | 954 } |
| 999 | 955 |
| 1000 ash::ShelfID ChromeLauncherController::GetShelfIDForWebContents( | 956 ash::ShelfID ChromeLauncherController::GetShelfIDForWebContents( |
| 1001 content::WebContents* contents) { | 957 content::WebContents* contents) { |
| 1002 DCHECK(contents); | 958 DCHECK(contents); |
| 1003 | 959 |
| 1004 std::string app_id = app_tab_helper_->GetAppID(contents); | 960 std::string app_id = app_tab_helper_->GetAppID(contents); |
| 1005 | 961 |
| 1006 if (app_id.empty() && ContentCanBeHandledByGmailApp(contents)) | 962 if (app_id.empty() && ContentCanBeHandledByGmailApp(contents)) |
| 1007 app_id = kGmailAppId; | 963 app_id = kGmailAppId; |
| (...skipping 704 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1712 alignment = ash::SHELF_ALIGNMENT_TOP; | 1668 alignment = ash::SHELF_ALIGNMENT_TOP; |
| 1713 ash::Shell::GetInstance()->SetShelfAlignment(alignment, *iter); | 1669 ash::Shell::GetInstance()->SetShelfAlignment(alignment, *iter); |
| 1714 } | 1670 } |
| 1715 } | 1671 } |
| 1716 | 1672 |
| 1717 void ChromeLauncherController::SetShelfBehaviorsFromPrefs() { | 1673 void ChromeLauncherController::SetShelfBehaviorsFromPrefs() { |
| 1718 SetShelfAutoHideBehaviorFromPrefs(); | 1674 SetShelfAutoHideBehaviorFromPrefs(); |
| 1719 SetShelfAlignmentFromPrefs(); | 1675 SetShelfAlignmentFromPrefs(); |
| 1720 } | 1676 } |
| 1721 | 1677 |
| 1722 WebContents* ChromeLauncherController::GetLastActiveWebContents( | 1678 ash::ShelfItemStatus ChromeLauncherController::GetAppState( |
| 1723 const std::string& app_id) { | 1679 const::std::string& app_id) { |
| 1724 AppIDToWebContentsListMap::iterator i = | 1680 ash::ShelfItemStatus status = ash::STATUS_CLOSED; |
| 1725 app_id_to_web_contents_list_.find(app_id); | 1681 WebContentsToAppIDMap::iterator it = web_contents_to_app_id_.begin(); |
|
sky
2014/03/26 21:59:35
nit: for loop?
Mr4D (OOO till 08-26)
2014/03/27 14:50:54
Done.
| |
| 1726 if (i == app_id_to_web_contents_list_.end()) | 1682 while (it != web_contents_to_app_id_.end()) { |
| 1727 return NULL; | 1683 if (it->second == app_id) { |
| 1728 | 1684 Browser* browser = chrome::FindBrowserWithWebContents(it->first); |
| 1729 // There are many crash records (crbug.com/341250) which indicate that the | 1685 DCHECK(browser); |
|
sky
2014/03/26 21:59:35
Are you sure this DCHECK is valid here? Seems to m
Mr4D (OOO till 08-26)
2014/03/27 14:50:54
This DCHECK was added to identify an ilegal state
| |
| 1730 // app_id_to_web_contents_list_ contains deleted content entries - so there | 1686 if (browser->window()->IsActive()) { |
| 1731 // must be a way that the content does not get properly updated. To fix | 1687 return browser->tab_strip_model()->GetActiveWebContents() == it->first ? |
| 1732 // M33 and M34 we filter out the invalid items here, but this should be | 1688 ash::STATUS_ACTIVE : ash::STATUS_RUNNING; |
| 1733 // addressed by a later patch correctly. Looking at the code however, the | 1689 } else { |
| 1734 // real culprit is possibly BrowserStatusMonitor::UpdateAppItemState which | 1690 status = ash::STATUS_RUNNING; |
| 1735 // does not call "UpdateAppState(.., APP_STATE_REMOVED)" because due to a | 1691 } |
| 1736 // Browser::SwapTabContent operation it isn't able to get the browser. I | 1692 } |
| 1737 // think that the real patch is to call anyway when APP_STATE_REMOVED is | 1693 ++it; |
| 1738 // requested, but for a backport that seems risky. | |
| 1739 WebContentsList* list = &i->second; | |
| 1740 while (!list->empty()) { | |
| 1741 WebContents* contents = *list->begin(); | |
| 1742 if (chrome::FindBrowserWithWebContents(contents)) | |
| 1743 return contents; | |
| 1744 list->erase(list->begin()); | |
| 1745 // This might not be necessary, but since we do not know why the lists | |
| 1746 // diverged we also erase it since it cannot be correct either. | |
| 1747 web_contents_to_app_id_.erase(contents); | |
| 1748 } | 1694 } |
| 1749 app_id_to_web_contents_list_.erase(app_id); | 1695 return status; |
| 1750 return NULL; | |
| 1751 } | 1696 } |
| 1752 | 1697 |
| 1753 ash::ShelfID ChromeLauncherController::InsertAppLauncherItem( | 1698 ash::ShelfID ChromeLauncherController::InsertAppLauncherItem( |
| 1754 LauncherItemController* controller, | 1699 LauncherItemController* controller, |
| 1755 const std::string& app_id, | 1700 const std::string& app_id, |
| 1756 ash::ShelfItemStatus status, | 1701 ash::ShelfItemStatus status, |
| 1757 int index, | 1702 int index, |
| 1758 ash::ShelfItemType shelf_item_type) { | 1703 ash::ShelfItemType shelf_item_type) { |
| 1759 ash::ShelfID id = model_->next_id(); | 1704 ash::ShelfID id = model_->next_id(); |
| 1760 CHECK(!HasItemController(id)); | 1705 CHECK(!HasItemController(id)); |
| 1761 CHECK(controller); | 1706 CHECK(controller); |
| 1762 id_to_item_controller_map_[id] = controller; | 1707 id_to_item_controller_map_[id] = controller; |
| 1763 controller->set_shelf_id(id); | 1708 controller->set_shelf_id(id); |
| 1764 | 1709 |
| 1765 ash::ShelfItem item; | 1710 ash::ShelfItem item; |
| 1766 item.type = shelf_item_type; | 1711 item.type = shelf_item_type; |
| 1767 item.image = extensions::IconsInfo::GetDefaultAppIcon(); | 1712 item.image = extensions::IconsInfo::GetDefaultAppIcon(); |
| 1768 | 1713 |
| 1769 WebContents* active_tab = GetLastActiveWebContents(app_id); | 1714 ash::ShelfItemStatus new_state = GetAppState(app_id); |
| 1770 if (active_tab) { | 1715 if (new_state != ash::STATUS_CLOSED) |
| 1771 Browser* browser = chrome::FindBrowserWithWebContents(active_tab); | 1716 status = new_state; |
| 1772 DCHECK(browser); | 1717 |
| 1773 if (browser->window()->IsActive()) | |
| 1774 status = ash::STATUS_ACTIVE; | |
| 1775 else | |
| 1776 status = ash::STATUS_RUNNING; | |
| 1777 } | |
| 1778 item.status = status; | 1718 item.status = status; |
| 1779 | 1719 |
| 1780 model_->AddAt(index, item); | 1720 model_->AddAt(index, item); |
| 1781 | 1721 |
| 1782 app_icon_loader_->FetchImage(app_id); | 1722 app_icon_loader_->FetchImage(app_id); |
| 1783 | 1723 |
| 1784 SetShelfItemDelegate(id, controller); | 1724 SetShelfItemDelegate(id, controller); |
| 1785 | 1725 |
| 1786 return id; | 1726 return id; |
| 1787 } | 1727 } |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2058 } | 1998 } |
| 2059 | 1999 |
| 2060 void ChromeLauncherController::ReleaseProfile() { | 2000 void ChromeLauncherController::ReleaseProfile() { |
| 2061 if (app_sync_ui_state_) | 2001 if (app_sync_ui_state_) |
| 2062 app_sync_ui_state_->RemoveObserver(this); | 2002 app_sync_ui_state_->RemoveObserver(this); |
| 2063 | 2003 |
| 2064 PrefServiceSyncable::FromProfile(profile_)->RemoveObserver(this); | 2004 PrefServiceSyncable::FromProfile(profile_)->RemoveObserver(this); |
| 2065 | 2005 |
| 2066 pref_change_registrar_.RemoveAll(); | 2006 pref_change_registrar_.RemoveAll(); |
| 2067 } | 2007 } |
| OLD | NEW |