OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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/ash/launcher/chrome_launcher_controller.h" | 5 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "ash/launcher/launcher_model.h" | 10 #include "ash/launcher/launcher_model.h" |
11 #include "ash/launcher/launcher_types.h" | 11 #include "ash/launcher/launcher_types.h" |
12 #include "ash/shell.h" | 12 #include "ash/shell.h" |
13 #include "ash/wm/window_util.h" | 13 #include "ash/wm/window_util.h" |
14 #include "base/command_line.h" | 14 #include "base/command_line.h" |
15 #include "base/utf_string_conversions.h" | 15 #include "base/utf_string_conversions.h" |
16 #include "base/values.h" | 16 #include "base/values.h" |
17 #include "chrome/browser/defaults.h" | 17 #include "chrome/browser/defaults.h" |
18 #include "chrome/browser/extensions/extension_service.h" | 18 #include "chrome/browser/extensions/extension_service.h" |
19 #include "chrome/browser/extensions/pending_extension_manager.h" | |
19 #include "chrome/browser/prefs/incognito_mode_prefs.h" | 20 #include "chrome/browser/prefs/incognito_mode_prefs.h" |
20 #include "chrome/browser/prefs/pref_service.h" | 21 #include "chrome/browser/prefs/pref_service.h" |
21 #include "chrome/browser/prefs/scoped_user_pref_update.h" | 22 #include "chrome/browser/prefs/scoped_user_pref_update.h" |
22 #include "chrome/browser/profiles/profile.h" | 23 #include "chrome/browser/profiles/profile.h" |
23 #include "chrome/browser/profiles/profile_manager.h" | 24 #include "chrome/browser/profiles/profile_manager.h" |
25 #include "chrome/browser/sync/profile_sync_service.h" | |
26 #include "chrome/browser/sync/profile_sync_service_factory.h" | |
24 #include "chrome/browser/ui/ash/chrome_launcher_prefs.h" | 27 #include "chrome/browser/ui/ash/chrome_launcher_prefs.h" |
25 #include "chrome/browser/ui/ash/extension_utils.h" | 28 #include "chrome/browser/ui/ash/extension_utils.h" |
26 #include "chrome/browser/ui/ash/launcher/browser_launcher_item_controller.h" | 29 #include "chrome/browser/ui/ash/launcher/browser_launcher_item_controller.h" |
27 #include "chrome/browser/ui/ash/launcher/launcher_app_icon_loader.h" | 30 #include "chrome/browser/ui/ash/launcher/launcher_app_icon_loader.h" |
28 #include "chrome/browser/ui/ash/launcher/launcher_app_tab_helper.h" | 31 #include "chrome/browser/ui/ash/launcher/launcher_app_tab_helper.h" |
29 #include "chrome/browser/ui/ash/launcher/launcher_context_menu.h" | 32 #include "chrome/browser/ui/ash/launcher/launcher_context_menu.h" |
30 #include "chrome/browser/ui/browser.h" | 33 #include "chrome/browser/ui/browser.h" |
31 #include "chrome/browser/ui/browser_commands.h" | 34 #include "chrome/browser/ui/browser_commands.h" |
32 #include "chrome/browser/ui/browser_finder.h" | 35 #include "chrome/browser/ui/browser_finder.h" |
33 #include "chrome/browser/ui/browser_window.h" | 36 #include "chrome/browser/ui/browser_window.h" |
34 #include "chrome/browser/ui/extensions/shell_window.h" | 37 #include "chrome/browser/ui/extensions/shell_window.h" |
35 #include "chrome/browser/ui/tab_contents/tab_contents.h" | 38 #include "chrome/browser/ui/tab_contents/tab_contents.h" |
36 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 39 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
37 #include "chrome/browser/web_applications/web_app.h" | 40 #include "chrome/browser/web_applications/web_app.h" |
38 #include "chrome/common/chrome_notification_types.h" | 41 #include "chrome/common/chrome_notification_types.h" |
39 #include "chrome/common/chrome_switches.h" | 42 #include "chrome/common/chrome_switches.h" |
40 #include "chrome/common/extensions/extension.h" | 43 #include "chrome/common/extensions/extension.h" |
41 #include "chrome/common/extensions/extension_resource.h" | 44 #include "chrome/common/extensions/extension_resource.h" |
42 #include "chrome/common/pref_names.h" | 45 #include "chrome/common/pref_names.h" |
43 #include "content/public/browser/notification_service.h" | 46 #include "content/public/browser/notification_service.h" |
44 #include "content/public/browser/web_contents.h" | 47 #include "content/public/browser/web_contents.h" |
45 #include "grit/theme_resources.h" | 48 #include "grit/theme_resources.h" |
46 #include "ui/aura/client/activation_client.h" | 49 #include "ui/aura/client/activation_client.h" |
47 #include "ui/aura/window.h" | 50 #include "ui/aura/window.h" |
48 #include "ui/views/widget/widget.h" | 51 #include "ui/views/widget/widget.h" |
49 | 52 |
50 using extensions::Extension; | 53 using extensions::Extension; |
51 | 54 |
55 namespace { | |
56 | |
57 const int kMaxLoadingPlaceholders = 4; | |
58 | |
59 // Max loading animation time in milliseconds. | |
60 const int kMaxLoadingTimeMs = 60 * 1000; | |
61 | |
62 } // namespace | |
63 | |
52 // ChromeLauncherController::Item ---------------------------------------------- | 64 // ChromeLauncherController::Item ---------------------------------------------- |
53 | 65 |
54 ChromeLauncherController::Item::Item() | 66 ChromeLauncherController::Item::Item() |
55 : item_type(TYPE_TABBED_BROWSER), | 67 : item_type(TYPE_TABBED_BROWSER), |
56 controller(NULL) { | 68 controller(NULL) { |
57 } | 69 } |
58 | 70 |
59 ChromeLauncherController::Item::~Item() { | 71 ChromeLauncherController::Item::~Item() { |
60 } | 72 } |
61 | 73 |
62 // ChromeLauncherController ---------------------------------------------------- | 74 // ChromeLauncherController ---------------------------------------------------- |
63 | 75 |
64 // static | 76 // static |
65 ChromeLauncherController* ChromeLauncherController::instance_ = NULL; | 77 ChromeLauncherController* ChromeLauncherController::instance_ = NULL; |
66 | 78 |
67 ChromeLauncherController::ChromeLauncherController(Profile* profile, | 79 ChromeLauncherController::ChromeLauncherController(Profile* profile, |
68 ash::LauncherModel* model) | 80 ash::LauncherModel* model) |
69 : model_(model), | 81 : model_(model), |
70 profile_(profile), | 82 profile_(profile), |
71 activation_client_(NULL) { | 83 activation_client_(NULL), |
84 observed_sync_service_(NULL) { | |
72 if (!profile_) { | 85 if (!profile_) { |
73 // Use the original profile as on chromeos we may get a temporary off the | 86 // Use the original profile as on chromeos we may get a temporary off the |
74 // record profile. | 87 // record profile. |
75 profile_ = ProfileManager::GetDefaultProfile()->GetOriginalProfile(); | 88 profile_ = ProfileManager::GetDefaultProfile()->GetOriginalProfile(); |
76 } | 89 } |
77 instance_ = this; | 90 instance_ = this; |
78 model_->AddObserver(this); | 91 model_->AddObserver(this); |
79 ShellWindowRegistry::Get(profile_)->AddObserver(this); | 92 ShellWindowRegistry::Get(profile_)->AddObserver(this); |
80 app_tab_helper_.reset(new LauncherAppTabHelper(profile_)); | 93 app_tab_helper_.reset(new LauncherAppTabHelper(profile_)); |
81 app_icon_loader_.reset(new LauncherAppIconLoader(profile_, this)); | 94 app_icon_loader_.reset(new LauncherAppIconLoader(profile_, this)); |
82 | 95 |
83 notification_registrar_.Add(this, | 96 notification_registrar_.Add(this, |
84 chrome::NOTIFICATION_EXTENSION_LOADED, | 97 chrome::NOTIFICATION_EXTENSION_LOADED, |
85 content::Source<Profile>(profile_)); | 98 content::Source<Profile>(profile_)); |
86 notification_registrar_.Add(this, | 99 notification_registrar_.Add(this, |
87 chrome::NOTIFICATION_EXTENSION_UNLOADED, | 100 chrome::NOTIFICATION_EXTENSION_UNLOADED, |
88 content::Source<Profile>(profile_)); | 101 content::Source<Profile>(profile_)); |
89 pref_change_registrar_.Init(profile_->GetPrefs()); | 102 pref_change_registrar_.Init(profile_->GetPrefs()); |
90 pref_change_registrar_.Add(prefs::kPinnedLauncherApps, this); | 103 pref_change_registrar_.Add(prefs::kPinnedLauncherApps, this); |
91 pref_change_registrar_.Add(prefs::kShelfAlignment, this); | 104 pref_change_registrar_.Add(prefs::kShelfAlignment, this); |
92 pref_change_registrar_.Add(prefs::kShelfAutoHideBehavior, this); | 105 pref_change_registrar_.Add(prefs::kShelfAutoHideBehavior, this); |
106 | |
107 if (!IsLoggedInAsGuest()) { | |
108 observed_sync_service_ = | |
109 ProfileSyncServiceFactory::GetForProfile(profile_); | |
110 if (observed_sync_service_) { | |
111 observed_sync_service_->AddObserver(this); | |
112 StartLoadingUI(); | |
113 } | |
114 } | |
93 } | 115 } |
94 | 116 |
95 ChromeLauncherController::~ChromeLauncherController() { | 117 ChromeLauncherController::~ChromeLauncherController() { |
96 ShellWindowRegistry::Get(profile_)->RemoveObserver(this); | 118 ShellWindowRegistry::Get(profile_)->RemoveObserver(this); |
97 model_->RemoveObserver(this); | 119 model_->RemoveObserver(this); |
98 for (IDToItemMap::iterator i = id_to_item_map_.begin(); | 120 for (IDToItemMap::iterator i = id_to_item_map_.begin(); |
99 i != id_to_item_map_.end(); ++i) { | 121 i != id_to_item_map_.end(); ++i) { |
100 model_->RemoveItemAt(model_->ItemIndexByID(i->first)); | 122 model_->RemoveItemAt(model_->ItemIndexByID(i->first)); |
101 } | 123 } |
102 if (instance_ == this) | 124 if (instance_ == this) |
103 instance_ = NULL; | 125 instance_ = NULL; |
104 if (activation_client_) | 126 if (activation_client_) |
105 activation_client_->RemoveObserver(this); | 127 activation_client_->RemoveObserver(this); |
106 | 128 |
107 for (WindowToIDMap::iterator i = window_to_id_map_.begin(); | 129 for (WindowToIDMap::iterator i = window_to_id_map_.begin(); |
108 i != window_to_id_map_.end(); ++i) { | 130 i != window_to_id_map_.end(); ++i) { |
109 i->first->RemoveObserver(this); | 131 i->first->RemoveObserver(this); |
110 } | 132 } |
111 | 133 |
112 if (ash::Shell::HasInstance()) | 134 if (ash::Shell::HasInstance()) |
113 ash::Shell::GetInstance()->RemoveShellObserver(this); | 135 ash::Shell::GetInstance()->RemoveShellObserver(this); |
136 | |
137 if (observed_sync_service_) | |
138 observed_sync_service_->RemoveObserver(this); | |
114 } | 139 } |
115 | 140 |
116 void ChromeLauncherController::Init() { | 141 void ChromeLauncherController::Init() { |
117 // TODO(xiyuan): Remove migration code and kUseDefaultPinnedApp after M20. | 142 // TODO(xiyuan): Remove migration code and kUseDefaultPinnedApp after M20. |
118 // Migration cases: | 143 // Migration cases: |
119 // - Users that unpin all apps: | 144 // - Users that unpin all apps: |
120 // - have default pinned apps | 145 // - have default pinned apps |
121 // - kUseDefaultPinnedApps set to false | 146 // - kUseDefaultPinnedApps set to false |
122 // Migrate them by setting an empty list for kPinnedLauncherApps. | 147 // Migrate them by setting an empty list for kPinnedLauncherApps. |
123 // | 148 // |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
256 void ChromeLauncherController::Open(ash::LauncherID id, int event_flags) { | 281 void ChromeLauncherController::Open(ash::LauncherID id, int event_flags) { |
257 if (id_to_item_map_.find(id) == id_to_item_map_.end()) | 282 if (id_to_item_map_.find(id) == id_to_item_map_.end()) |
258 return; // In case invoked from menu and item closed while menu up. | 283 return; // In case invoked from menu and item closed while menu up. |
259 | 284 |
260 BrowserLauncherItemController* controller = id_to_item_map_[id].controller; | 285 BrowserLauncherItemController* controller = id_to_item_map_[id].controller; |
261 if (controller) { | 286 if (controller) { |
262 controller->window()->Show(); | 287 controller->window()->Show(); |
263 ash::wm::ActivateWindow(controller->window()); | 288 ash::wm::ActivateWindow(controller->window()); |
264 } else { | 289 } else { |
265 DCHECK_EQ(TYPE_APP, id_to_item_map_[id].item_type); | 290 DCHECK_EQ(TYPE_APP, id_to_item_map_[id].item_type); |
266 | |
267 // Do nothing for pending app shortcut. | |
268 if (GetItemStatus(id) == ash::STATUS_IS_PENDING) | |
269 return; | |
270 | |
271 OpenAppID(id_to_item_map_[id].app_id, event_flags); | 291 OpenAppID(id_to_item_map_[id].app_id, event_flags); |
272 } | 292 } |
273 } | 293 } |
274 | 294 |
275 void ChromeLauncherController::OpenAppID( | 295 void ChromeLauncherController::OpenAppID( |
276 const std::string& app_id, | 296 const std::string& app_id, |
277 int event_flags) { | 297 int event_flags) { |
278 ash::LauncherID launcher_id = GetLauncherIDForAppID(app_id); | 298 ash::LauncherID launcher_id = GetLauncherIDForAppID(app_id); |
279 // Check if this item has any windows in the activation list. | 299 // Check if this item has any windows in the activation list. |
280 for (WindowList::const_iterator i = platform_app_windows_.begin(); | 300 for (WindowList::const_iterator i = platform_app_windows_.begin(); |
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
613 } | 633 } |
614 } | 634 } |
615 | 635 |
616 void ChromeLauncherController::Observe( | 636 void ChromeLauncherController::Observe( |
617 int type, | 637 int type, |
618 const content::NotificationSource& source, | 638 const content::NotificationSource& source, |
619 const content::NotificationDetails& details) { | 639 const content::NotificationDetails& details) { |
620 switch (type) { | 640 switch (type) { |
621 case chrome::NOTIFICATION_EXTENSION_LOADED: { | 641 case chrome::NOTIFICATION_EXTENSION_LOADED: { |
622 UpdateAppLaunchersFromPref(); | 642 UpdateAppLaunchersFromPref(); |
643 CheckAppSync(); | |
623 break; | 644 break; |
624 } | 645 } |
625 case chrome::NOTIFICATION_EXTENSION_UNLOADED: { | 646 case chrome::NOTIFICATION_EXTENSION_UNLOADED: { |
626 const content::Details<extensions::UnloadedExtensionInfo> unload_info( | 647 const content::Details<extensions::UnloadedExtensionInfo> unload_info( |
627 details); | 648 details); |
628 const Extension* extension = unload_info->extension; | 649 const Extension* extension = unload_info->extension; |
629 if (IsAppPinned(extension->id())) { | 650 if (IsAppPinned(extension->id())) |
630 if (unload_info->reason == extension_misc::UNLOAD_REASON_UPDATE) | 651 DoUnpinAppsWithID(extension->id()); |
631 MarkAppPending(extension->id()); | |
632 else | |
633 DoUnpinAppsWithID(extension->id()); | |
634 } | |
635 break; | 652 break; |
636 } | 653 } |
637 case chrome::NOTIFICATION_PREF_CHANGED: { | 654 case chrome::NOTIFICATION_PREF_CHANGED: { |
638 const std::string& pref_name( | 655 const std::string& pref_name( |
639 *content::Details<std::string>(details).ptr()); | 656 *content::Details<std::string>(details).ptr()); |
640 if (pref_name == prefs::kPinnedLauncherApps) | 657 if (pref_name == prefs::kPinnedLauncherApps) |
641 UpdateAppLaunchersFromPref(); | 658 UpdateAppLaunchersFromPref(); |
642 else if (pref_name == prefs::kShelfAlignment) | 659 else if (pref_name == prefs::kShelfAlignment) |
643 SetShelfAlignmentFromPrefs(); | 660 SetShelfAlignmentFromPrefs(); |
644 else if (pref_name == prefs::kShelfAutoHideBehavior) | 661 else if (pref_name == prefs::kShelfAutoHideBehavior) |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
736 case ash::SHELF_ALIGNMENT_LEFT: | 753 case ash::SHELF_ALIGNMENT_LEFT: |
737 pref_value = ash::kShelfAlignmentLeft; | 754 pref_value = ash::kShelfAlignmentLeft; |
738 break; | 755 break; |
739 case ash::SHELF_ALIGNMENT_RIGHT: | 756 case ash::SHELF_ALIGNMENT_RIGHT: |
740 pref_value = ash::kShelfAlignmentRight; | 757 pref_value = ash::kShelfAlignmentRight; |
741 break; | 758 break; |
742 } | 759 } |
743 profile_->GetPrefs()->SetString(prefs::kShelfAlignment, pref_value); | 760 profile_->GetPrefs()->SetString(prefs::kShelfAlignment, pref_value); |
744 } | 761 } |
745 | 762 |
763 void ChromeLauncherController::OnStateChanged() { | |
764 DCHECK(observed_sync_service_); | |
765 CheckAppSync(); | |
766 } | |
767 | |
746 void ChromeLauncherController::PersistPinnedState() { | 768 void ChromeLauncherController::PersistPinnedState() { |
747 // It is a coding error to call PersistPinnedState() if the pinned apps are | 769 // It is a coding error to call PersistPinnedState() if the pinned apps are |
748 // not user-editable. The code should check earlier and not perform any | 770 // not user-editable. The code should check earlier and not perform any |
749 // modification actions that trigger persisting the state. | 771 // modification actions that trigger persisting the state. |
750 if (!CanPin()) { | 772 if (!CanPin()) { |
751 NOTREACHED() << "Can't pin but pinned state being updated"; | 773 NOTREACHED() << "Can't pin but pinned state being updated"; |
752 return; | 774 return; |
753 } | 775 } |
754 | 776 |
755 // Set kUseDefaultPinnedApps to false and use pinned apps list from prefs | 777 // Set kUseDefaultPinnedApps to false and use pinned apps list from prefs |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
792 } | 814 } |
793 | 815 |
794 ash::LauncherItemStatus ChromeLauncherController::GetItemStatus( | 816 ash::LauncherItemStatus ChromeLauncherController::GetItemStatus( |
795 ash::LauncherID id) const { | 817 ash::LauncherID id) const { |
796 int index = model_->ItemIndexByID(id); | 818 int index = model_->ItemIndexByID(id); |
797 DCHECK_GE(index, 0); | 819 DCHECK_GE(index, 0); |
798 const ash::LauncherItem& item = model_->items()[index]; | 820 const ash::LauncherItem& item = model_->items()[index]; |
799 return item.status; | 821 return item.status; |
800 } | 822 } |
801 | 823 |
802 void ChromeLauncherController::MarkAppPending(const std::string& app_id) { | |
803 for (IDToItemMap::const_iterator i = id_to_item_map_.begin(); | |
804 i != id_to_item_map_.end(); ++i) { | |
805 if (i->second.item_type == TYPE_APP && i->second.app_id == app_id) { | |
806 if (GetItemStatus(i->first) == ash::STATUS_CLOSED) | |
807 SetItemStatus(i->first, ash::STATUS_IS_PENDING); | |
808 | |
809 break; | |
810 } | |
811 } | |
812 } | |
813 | |
814 void ChromeLauncherController::DoPinAppWithID(const std::string& app_id) { | 824 void ChromeLauncherController::DoPinAppWithID(const std::string& app_id) { |
815 // If there is an item, do nothing and return. | 825 // If there is an item, do nothing and return. |
816 if (IsAppPinned(app_id)) | 826 if (IsAppPinned(app_id)) |
817 return; | 827 return; |
818 | 828 |
819 // Otherwise, create an item for it. | 829 // Otherwise, create an item for it. |
820 CreateAppLauncherItem(NULL, app_id, ash::STATUS_CLOSED); | 830 CreateAppLauncherItem(NULL, app_id, ash::STATUS_CLOSED); |
821 if (CanPin()) | 831 if (CanPin()) |
822 PersistPinnedState(); | 832 PersistPinnedState(); |
823 } | 833 } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
861 // delete all app launcher entries in between. | 871 // delete all app launcher entries in between. |
862 if (IsAppPinned(*pref_app_id)) { | 872 if (IsAppPinned(*pref_app_id)) { |
863 for (; index < model_->item_count(); ++index) { | 873 for (; index < model_->item_count(); ++index) { |
864 const ash::LauncherItem& item(model_->items()[index]); | 874 const ash::LauncherItem& item(model_->items()[index]); |
865 if (item.type != ash::TYPE_APP_SHORTCUT) | 875 if (item.type != ash::TYPE_APP_SHORTCUT) |
866 continue; | 876 continue; |
867 | 877 |
868 IDToItemMap::const_iterator entry(id_to_item_map_.find(item.id)); | 878 IDToItemMap::const_iterator entry(id_to_item_map_.find(item.id)); |
869 if (entry != id_to_item_map_.end() && | 879 if (entry != id_to_item_map_.end() && |
870 entry->second.app_id == *pref_app_id) { | 880 entry->second.app_id == *pref_app_id) { |
871 // Current item will be kept. Reset its pending state and ensure | |
872 // its icon is loaded since it has to be valid to be in |pinned_apps|. | |
873 if (item.status == ash::STATUS_IS_PENDING) { | |
874 SetItemStatus(item.id, ash::STATUS_CLOSED); | |
875 app_icon_loader_->FetchImage(*pref_app_id); | |
876 } | |
877 | |
878 ++pref_app_id; | 881 ++pref_app_id; |
879 break; | 882 break; |
880 } else { | 883 } else { |
881 LauncherItemClosed(item.id); | 884 LauncherItemClosed(item.id); |
882 --index; | 885 --index; |
883 } | 886 } |
884 } | 887 } |
885 // If the item wasn't found, that means id_to_item_map_ is out of sync. | 888 // If the item wasn't found, that means id_to_item_map_ is out of sync. |
886 DCHECK(index < model_->item_count()); | 889 DCHECK(index < model_->item_count()); |
887 } else { | 890 } else { |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
964 } else if (controller->type() == | 967 } else if (controller->type() == |
965 BrowserLauncherItemController::TYPE_APP_PANEL || | 968 BrowserLauncherItemController::TYPE_APP_PANEL || |
966 controller->type() == | 969 controller->type() == |
967 BrowserLauncherItemController::TYPE_EXTENSION_PANEL) { | 970 BrowserLauncherItemController::TYPE_EXTENSION_PANEL) { |
968 item.type = ash::TYPE_APP_PANEL; | 971 item.type = ash::TYPE_APP_PANEL; |
969 } else { | 972 } else { |
970 item.type = ash::TYPE_TABBED; | 973 item.type = ash::TYPE_TABBED; |
971 } | 974 } |
972 item.is_incognito = false; | 975 item.is_incognito = false; |
973 item.image = Extension::GetDefaultIcon(true); | 976 item.image = Extension::GetDefaultIcon(true); |
974 if (item.type == ash::TYPE_APP_SHORTCUT && | 977 |
975 !app_tab_helper_->IsValidID(app_id)) { | 978 TabContents* active_tab = GetLastActiveTabContents(app_id); |
976 item.status = ash::STATUS_IS_PENDING; | 979 if (active_tab) { |
977 } else { | 980 Browser* browser = browser::FindBrowserWithWebContents( |
978 TabContents* active_tab = GetLastActiveTabContents(app_id); | 981 active_tab->web_contents()); |
979 if (active_tab) { | 982 DCHECK(browser); |
980 Browser* browser = browser::FindBrowserWithWebContents( | 983 if (browser->window()->IsActive()) |
981 active_tab->web_contents()); | 984 status = ash::STATUS_ACTIVE; |
982 DCHECK(browser); | 985 else |
983 if (browser->window()->IsActive()) | 986 status = ash::STATUS_RUNNING; |
984 status = ash::STATUS_ACTIVE; | |
985 else | |
986 status = ash::STATUS_RUNNING; | |
987 } | |
988 item.status = status; | |
989 } | 987 } |
988 item.status = status; | |
989 | |
990 // Removes an app placeholder for added app shortcut. This needs to be done | |
991 // before adding the shortcut to avoid unnecessary sliding animations. | |
992 if (item.type == ash::TYPE_APP_SHORTCUT && !app_placeholders_.empty()) { | |
993 ash::LauncherID id = app_placeholders_.front(); | |
994 app_placeholders_.pop_front(); | |
995 model_->RemoveItemAt(model_->ItemIndexByID(id)); | |
996 } | |
997 | |
990 model_->AddAt(index, item); | 998 model_->AddAt(index, item); |
991 | 999 |
992 if (!controller || controller->type() != | 1000 if (!controller || controller->type() != |
993 BrowserLauncherItemController::TYPE_EXTENSION_PANEL) { | 1001 BrowserLauncherItemController::TYPE_EXTENSION_PANEL) { |
994 if (item.status != ash::STATUS_IS_PENDING) | 1002 app_icon_loader_->FetchImage(app_id); |
995 app_icon_loader_->FetchImage(app_id); | |
996 } | 1003 } |
1004 | |
997 return id; | 1005 return id; |
998 } | 1006 } |
1007 | |
1008 void ChromeLauncherController::CheckAppSync() { | |
1009 if (!observed_sync_service_) | |
1010 return; | |
1011 | |
1012 const bool synced = observed_sync_service_->ShouldPushChanges(); | |
1013 const bool has_pending_extension = profile_->GetExtensionService()-> | |
1014 pending_extension_manager()->HasPendingExtensionFromSync(); | |
1015 | |
1016 if (synced && !has_pending_extension) | |
1017 StopLoadingUI(); | |
1018 } | |
1019 | |
1020 void ChromeLauncherController::StartLoadingUI() { | |
1021 DCHECK(!loading_timer_.IsRunning()); | |
1022 loading_timer_.Start( | |
1023 FROM_HERE, | |
1024 base::TimeDelta::FromMilliseconds(kMaxLoadingTimeMs), | |
1025 this, &ChromeLauncherController::StopLoadingUI); | |
1026 | |
1027 for (int i = 0; i < kMaxLoadingPlaceholders; ++i) { | |
sky
2012/08/15 20:52:36
Do we unconditionally add kMaxLoadingPlaceholders
xiyuan
2012/08/15 21:36:03
I am doing this because StartLoadingUI is called b
| |
1028 ash::LauncherID id = model_->next_id(); | |
1029 app_placeholders_.push_back(id); | |
1030 | |
1031 ash::LauncherItem item; | |
1032 item.type = ash::TYPE_APP_PLACEHOLDER; | |
1033 item.is_incognito = false; | |
1034 model_->Add(item); | |
1035 } | |
1036 } | |
1037 | |
1038 void ChromeLauncherController::StopLoadingUI() { | |
1039 loading_timer_.Stop(); | |
1040 observed_sync_service_->RemoveObserver(this); | |
1041 observed_sync_service_ = NULL; | |
1042 | |
1043 while (!app_placeholders_.empty()) { | |
1044 ash::LauncherID id = app_placeholders_.front(); | |
1045 app_placeholders_.pop_front(); | |
1046 | |
1047 model_->RemoveItemAt(model_->ItemIndexByID(id)); | |
1048 } | |
1049 } | |
OLD | NEW |