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