Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(98)

Side by Side Diff: chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc

Issue 10829268: chromeos: Sync animation. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: for sky's comments in #3 Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698