| 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/launcher_app_icon_loader.h" | 29 #include "chrome/browser/ui/ash/launcher/launcher_app_icon_loader.h" |
| 27 #include "chrome/browser/ui/ash/launcher/launcher_app_tab_helper.h" | 30 #include "chrome/browser/ui/ash/launcher/launcher_app_tab_helper.h" |
| 28 #include "chrome/browser/ui/ash/launcher/launcher_context_menu.h" | 31 #include "chrome/browser/ui/ash/launcher/launcher_context_menu.h" |
| 29 #include "chrome/browser/ui/ash/launcher/launcher_item_controller.h" | 32 #include "chrome/browser/ui/ash/launcher/launcher_item_controller.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 // Max loading animation time in milliseconds. |
| 58 const int kMaxLoadingTimeMs = 60 * 1000; |
| 59 |
| 60 } // namespace |
| 61 |
| 52 // ChromeLauncherController::Item ---------------------------------------------- | 62 // ChromeLauncherController::Item ---------------------------------------------- |
| 53 | 63 |
| 54 ChromeLauncherController::Item::Item() | 64 ChromeLauncherController::Item::Item() |
| 55 : item_type(TYPE_TABBED_BROWSER), | 65 : item_type(TYPE_TABBED_BROWSER), |
| 56 controller(NULL) { | 66 controller(NULL) { |
| 57 } | 67 } |
| 58 | 68 |
| 59 ChromeLauncherController::Item::~Item() { | 69 ChromeLauncherController::Item::~Item() { |
| 60 } | 70 } |
| 61 | 71 |
| 62 // ChromeLauncherController ---------------------------------------------------- | 72 // ChromeLauncherController ---------------------------------------------------- |
| 63 | 73 |
| 64 // static | 74 // static |
| 65 ChromeLauncherController* ChromeLauncherController::instance_ = NULL; | 75 ChromeLauncherController* ChromeLauncherController::instance_ = NULL; |
| 66 | 76 |
| 67 ChromeLauncherController::ChromeLauncherController(Profile* profile, | 77 ChromeLauncherController::ChromeLauncherController(Profile* profile, |
| 68 ash::LauncherModel* model) | 78 ash::LauncherModel* model) |
| 69 : model_(model), | 79 : model_(model), |
| 70 profile_(profile), | 80 profile_(profile), |
| 71 activation_client_(NULL) { | 81 activation_client_(NULL), |
| 82 observed_sync_service_(NULL) { |
| 72 if (!profile_) { | 83 if (!profile_) { |
| 73 // Use the original profile as on chromeos we may get a temporary off the | 84 // Use the original profile as on chromeos we may get a temporary off the |
| 74 // record profile. | 85 // record profile. |
| 75 profile_ = ProfileManager::GetDefaultProfile()->GetOriginalProfile(); | 86 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 } |
| 76 } | 95 } |
| 96 |
| 77 instance_ = this; | 97 instance_ = this; |
| 78 model_->AddObserver(this); | 98 model_->AddObserver(this); |
| 79 extensions::ShellWindowRegistry::Get(profile_)->AddObserver(this); | 99 extensions::ShellWindowRegistry::Get(profile_)->AddObserver(this); |
| 80 app_tab_helper_.reset(new LauncherAppTabHelper(profile_)); | 100 app_tab_helper_.reset(new LauncherAppTabHelper(profile_)); |
| 81 app_icon_loader_.reset(new LauncherAppIconLoader(profile_, this)); | 101 app_icon_loader_.reset(new LauncherAppIconLoader(profile_, this)); |
| 82 | 102 |
| 83 notification_registrar_.Add(this, | 103 notification_registrar_.Add(this, |
| 84 chrome::NOTIFICATION_EXTENSION_LOADED, | 104 chrome::NOTIFICATION_EXTENSION_LOADED, |
| 85 content::Source<Profile>(profile_)); | 105 content::Source<Profile>(profile_)); |
| 86 notification_registrar_.Add(this, | 106 notification_registrar_.Add(this, |
| (...skipping 17 matching lines...) Expand all Loading... |
| 104 if (activation_client_) | 124 if (activation_client_) |
| 105 activation_client_->RemoveObserver(this); | 125 activation_client_->RemoveObserver(this); |
| 106 | 126 |
| 107 for (WindowToIDMap::iterator i = window_to_id_map_.begin(); | 127 for (WindowToIDMap::iterator i = window_to_id_map_.begin(); |
| 108 i != window_to_id_map_.end(); ++i) { | 128 i != window_to_id_map_.end(); ++i) { |
| 109 i->first->RemoveObserver(this); | 129 i->first->RemoveObserver(this); |
| 110 } | 130 } |
| 111 | 131 |
| 112 if (ash::Shell::HasInstance()) | 132 if (ash::Shell::HasInstance()) |
| 113 ash::Shell::GetInstance()->RemoveShellObserver(this); | 133 ash::Shell::GetInstance()->RemoveShellObserver(this); |
| 134 |
| 135 if (observed_sync_service_) |
| 136 observed_sync_service_->RemoveObserver(this); |
| 114 } | 137 } |
| 115 | 138 |
| 116 void ChromeLauncherController::Init() { | 139 void ChromeLauncherController::Init() { |
| 117 // TODO(xiyuan): Remove migration code and kUseDefaultPinnedApp after M20. | 140 // TODO(xiyuan): Remove migration code and kUseDefaultPinnedApp after M20. |
| 118 // Migration cases: | 141 // Migration cases: |
| 119 // - Users that unpin all apps: | 142 // - Users that unpin all apps: |
| 120 // - have default pinned apps | 143 // - have default pinned apps |
| 121 // - kUseDefaultPinnedApps set to false | 144 // - kUseDefaultPinnedApps set to false |
| 122 // Migrate them by setting an empty list for kPinnedLauncherApps. | 145 // Migrate them by setting an empty list for kPinnedLauncherApps. |
| 123 // | 146 // |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 | 278 |
| 256 void ChromeLauncherController::Open(ash::LauncherID id, int event_flags) { | 279 void ChromeLauncherController::Open(ash::LauncherID id, int event_flags) { |
| 257 if (id_to_item_map_.find(id) == id_to_item_map_.end()) | 280 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. | 281 return; // In case invoked from menu and item closed while menu up. |
| 259 | 282 |
| 260 LauncherItemController* controller = id_to_item_map_[id].controller; | 283 LauncherItemController* controller = id_to_item_map_[id].controller; |
| 261 if (controller) { | 284 if (controller) { |
| 262 controller->Open(); | 285 controller->Open(); |
| 263 } else { | 286 } else { |
| 264 DCHECK_EQ(TYPE_APP, id_to_item_map_[id].item_type); | 287 DCHECK_EQ(TYPE_APP, id_to_item_map_[id].item_type); |
| 265 | |
| 266 // Do nothing for pending app shortcut. | |
| 267 if (GetItemStatus(id) == ash::STATUS_IS_PENDING) | |
| 268 return; | |
| 269 | |
| 270 OpenAppID(id_to_item_map_[id].app_id, event_flags); | 288 OpenAppID(id_to_item_map_[id].app_id, event_flags); |
| 271 } | 289 } |
| 272 } | 290 } |
| 273 | 291 |
| 274 void ChromeLauncherController::OpenAppID( | 292 void ChromeLauncherController::OpenAppID( |
| 275 const std::string& app_id, | 293 const std::string& app_id, |
| 276 int event_flags) { | 294 int event_flags) { |
| 277 ash::LauncherID launcher_id = GetLauncherIDForAppID(app_id); | 295 ash::LauncherID launcher_id = GetLauncherIDForAppID(app_id); |
| 278 // Check if this item has any windows in the activation list. | 296 // Check if this item has any windows in the activation list. |
| 279 for (WindowList::const_iterator i = platform_app_windows_.begin(); | 297 for (WindowList::const_iterator i = platform_app_windows_.begin(); |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 587 int index, | 605 int index, |
| 588 const ash::LauncherItem& old_item) { | 606 const ash::LauncherItem& old_item) { |
| 589 if (model_->items()[index].status == ash::STATUS_ACTIVE && | 607 if (model_->items()[index].status == ash::STATUS_ACTIVE && |
| 590 old_item.status == ash::STATUS_RUNNING) { | 608 old_item.status == ash::STATUS_RUNNING) { |
| 591 ash::LauncherID id = model_->items()[index].id; | 609 ash::LauncherID id = model_->items()[index].id; |
| 592 if (id_to_item_map_[id].controller) | 610 if (id_to_item_map_[id].controller) |
| 593 id_to_item_map_[id].controller->Open(); | 611 id_to_item_map_[id].controller->Open(); |
| 594 } | 612 } |
| 595 } | 613 } |
| 596 | 614 |
| 615 void ChromeLauncherController::LauncherStatusChanged() { |
| 616 } |
| 617 |
| 597 void ChromeLauncherController::Observe( | 618 void ChromeLauncherController::Observe( |
| 598 int type, | 619 int type, |
| 599 const content::NotificationSource& source, | 620 const content::NotificationSource& source, |
| 600 const content::NotificationDetails& details) { | 621 const content::NotificationDetails& details) { |
| 601 switch (type) { | 622 switch (type) { |
| 602 case chrome::NOTIFICATION_EXTENSION_LOADED: { | 623 case chrome::NOTIFICATION_EXTENSION_LOADED: { |
| 603 UpdateAppLaunchersFromPref(); | 624 UpdateAppLaunchersFromPref(); |
| 625 CheckAppSync(); |
| 604 break; | 626 break; |
| 605 } | 627 } |
| 606 case chrome::NOTIFICATION_EXTENSION_UNLOADED: { | 628 case chrome::NOTIFICATION_EXTENSION_UNLOADED: { |
| 607 const content::Details<extensions::UnloadedExtensionInfo> unload_info( | 629 const content::Details<extensions::UnloadedExtensionInfo> unload_info( |
| 608 details); | 630 details); |
| 609 const Extension* extension = unload_info->extension; | 631 const Extension* extension = unload_info->extension; |
| 610 if (IsAppPinned(extension->id())) { | 632 if (IsAppPinned(extension->id())) |
| 611 if (unload_info->reason == extension_misc::UNLOAD_REASON_UPDATE) | 633 DoUnpinAppsWithID(extension->id()); |
| 612 MarkAppPending(extension->id()); | |
| 613 else | |
| 614 DoUnpinAppsWithID(extension->id()); | |
| 615 } | |
| 616 break; | 634 break; |
| 617 } | 635 } |
| 618 case chrome::NOTIFICATION_PREF_CHANGED: { | 636 case chrome::NOTIFICATION_PREF_CHANGED: { |
| 619 const std::string& pref_name( | 637 const std::string& pref_name( |
| 620 *content::Details<std::string>(details).ptr()); | 638 *content::Details<std::string>(details).ptr()); |
| 621 if (pref_name == prefs::kPinnedLauncherApps) | 639 if (pref_name == prefs::kPinnedLauncherApps) |
| 622 UpdateAppLaunchersFromPref(); | 640 UpdateAppLaunchersFromPref(); |
| 623 else if (pref_name == prefs::kShelfAlignment) | 641 else if (pref_name == prefs::kShelfAlignment) |
| 624 SetShelfAlignmentFromPrefs(); | 642 SetShelfAlignmentFromPrefs(); |
| 625 else if (pref_name == prefs::kShelfAutoHideBehavior) | 643 else if (pref_name == prefs::kShelfAutoHideBehavior) |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 718 case ash::SHELF_ALIGNMENT_LEFT: | 736 case ash::SHELF_ALIGNMENT_LEFT: |
| 719 pref_value = ash::kShelfAlignmentLeft; | 737 pref_value = ash::kShelfAlignmentLeft; |
| 720 break; | 738 break; |
| 721 case ash::SHELF_ALIGNMENT_RIGHT: | 739 case ash::SHELF_ALIGNMENT_RIGHT: |
| 722 pref_value = ash::kShelfAlignmentRight; | 740 pref_value = ash::kShelfAlignmentRight; |
| 723 break; | 741 break; |
| 724 } | 742 } |
| 725 profile_->GetPrefs()->SetString(prefs::kShelfAlignment, pref_value); | 743 profile_->GetPrefs()->SetString(prefs::kShelfAlignment, pref_value); |
| 726 } | 744 } |
| 727 | 745 |
| 746 void ChromeLauncherController::OnStateChanged() { |
| 747 DCHECK(observed_sync_service_); |
| 748 CheckAppSync(); |
| 749 } |
| 750 |
| 728 void ChromeLauncherController::PersistPinnedState() { | 751 void ChromeLauncherController::PersistPinnedState() { |
| 729 // It is a coding error to call PersistPinnedState() if the pinned apps are | 752 // It is a coding error to call PersistPinnedState() if the pinned apps are |
| 730 // not user-editable. The code should check earlier and not perform any | 753 // not user-editable. The code should check earlier and not perform any |
| 731 // modification actions that trigger persisting the state. | 754 // modification actions that trigger persisting the state. |
| 732 if (!CanPin()) { | 755 if (!CanPin()) { |
| 733 NOTREACHED() << "Can't pin but pinned state being updated"; | 756 NOTREACHED() << "Can't pin but pinned state being updated"; |
| 734 return; | 757 return; |
| 735 } | 758 } |
| 736 | 759 |
| 737 // Set kUseDefaultPinnedApps to false and use pinned apps list from prefs | 760 // Set kUseDefaultPinnedApps to false and use pinned apps list from prefs |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 774 } | 797 } |
| 775 | 798 |
| 776 ash::LauncherItemStatus ChromeLauncherController::GetItemStatus( | 799 ash::LauncherItemStatus ChromeLauncherController::GetItemStatus( |
| 777 ash::LauncherID id) const { | 800 ash::LauncherID id) const { |
| 778 int index = model_->ItemIndexByID(id); | 801 int index = model_->ItemIndexByID(id); |
| 779 DCHECK_GE(index, 0); | 802 DCHECK_GE(index, 0); |
| 780 const ash::LauncherItem& item = model_->items()[index]; | 803 const ash::LauncherItem& item = model_->items()[index]; |
| 781 return item.status; | 804 return item.status; |
| 782 } | 805 } |
| 783 | 806 |
| 784 void ChromeLauncherController::MarkAppPending(const std::string& app_id) { | |
| 785 for (IDToItemMap::const_iterator i = id_to_item_map_.begin(); | |
| 786 i != id_to_item_map_.end(); ++i) { | |
| 787 if (i->second.item_type == TYPE_APP && i->second.app_id == app_id) { | |
| 788 if (GetItemStatus(i->first) == ash::STATUS_CLOSED) | |
| 789 SetItemStatus(i->first, ash::STATUS_IS_PENDING); | |
| 790 | |
| 791 break; | |
| 792 } | |
| 793 } | |
| 794 } | |
| 795 | |
| 796 void ChromeLauncherController::DoPinAppWithID(const std::string& app_id) { | 807 void ChromeLauncherController::DoPinAppWithID(const std::string& app_id) { |
| 797 // If there is an item, do nothing and return. | 808 // If there is an item, do nothing and return. |
| 798 if (IsAppPinned(app_id)) | 809 if (IsAppPinned(app_id)) |
| 799 return; | 810 return; |
| 800 | 811 |
| 801 // Otherwise, create an item for it. | 812 // Otherwise, create an item for it. |
| 802 CreateAppLauncherItem(NULL, app_id, ash::STATUS_CLOSED); | 813 CreateAppLauncherItem(NULL, app_id, ash::STATUS_CLOSED); |
| 803 if (CanPin()) | 814 if (CanPin()) |
| 804 PersistPinnedState(); | 815 PersistPinnedState(); |
| 805 } | 816 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 843 // delete all app launcher entries in between. | 854 // delete all app launcher entries in between. |
| 844 if (IsAppPinned(*pref_app_id)) { | 855 if (IsAppPinned(*pref_app_id)) { |
| 845 for (; index < model_->item_count(); ++index) { | 856 for (; index < model_->item_count(); ++index) { |
| 846 const ash::LauncherItem& item(model_->items()[index]); | 857 const ash::LauncherItem& item(model_->items()[index]); |
| 847 if (item.type != ash::TYPE_APP_SHORTCUT) | 858 if (item.type != ash::TYPE_APP_SHORTCUT) |
| 848 continue; | 859 continue; |
| 849 | 860 |
| 850 IDToItemMap::const_iterator entry(id_to_item_map_.find(item.id)); | 861 IDToItemMap::const_iterator entry(id_to_item_map_.find(item.id)); |
| 851 if (entry != id_to_item_map_.end() && | 862 if (entry != id_to_item_map_.end() && |
| 852 entry->second.app_id == *pref_app_id) { | 863 entry->second.app_id == *pref_app_id) { |
| 853 // Current item will be kept. Reset its pending state and ensure | |
| 854 // its icon is loaded since it has to be valid to be in |pinned_apps|. | |
| 855 if (item.status == ash::STATUS_IS_PENDING) { | |
| 856 SetItemStatus(item.id, ash::STATUS_CLOSED); | |
| 857 app_icon_loader_->FetchImage(*pref_app_id); | |
| 858 } | |
| 859 | |
| 860 ++pref_app_id; | 864 ++pref_app_id; |
| 861 break; | 865 break; |
| 862 } else { | 866 } else { |
| 863 LauncherItemClosed(item.id); | 867 LauncherItemClosed(item.id); |
| 864 --index; | 868 --index; |
| 865 } | 869 } |
| 866 } | 870 } |
| 867 // If the item wasn't found, that means id_to_item_map_ is out of sync. | 871 // If the item wasn't found, that means id_to_item_map_ is out of sync. |
| 868 DCHECK(index < model_->item_count()); | 872 DCHECK(index < model_->item_count()); |
| 869 } else { | 873 } else { |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 945 item.type = ash::TYPE_PLATFORM_APP; | 949 item.type = ash::TYPE_PLATFORM_APP; |
| 946 } else if (controller->type() == LauncherItemController::TYPE_APP_PANEL || | 950 } else if (controller->type() == LauncherItemController::TYPE_APP_PANEL || |
| 947 controller->type() == | 951 controller->type() == |
| 948 LauncherItemController::TYPE_EXTENSION_PANEL) { | 952 LauncherItemController::TYPE_EXTENSION_PANEL) { |
| 949 item.type = ash::TYPE_APP_PANEL; | 953 item.type = ash::TYPE_APP_PANEL; |
| 950 } else { | 954 } else { |
| 951 item.type = ash::TYPE_TABBED; | 955 item.type = ash::TYPE_TABBED; |
| 952 } | 956 } |
| 953 item.is_incognito = false; | 957 item.is_incognito = false; |
| 954 item.image = Extension::GetDefaultIcon(true); | 958 item.image = Extension::GetDefaultIcon(true); |
| 955 if (item.type == ash::TYPE_APP_SHORTCUT && | 959 |
| 956 !app_tab_helper_->IsValidID(app_id)) { | 960 TabContents* active_tab = GetLastActiveTabContents(app_id); |
| 957 item.status = ash::STATUS_IS_PENDING; | 961 if (active_tab) { |
| 958 } else { | 962 Browser* browser = browser::FindBrowserWithWebContents( |
| 959 TabContents* active_tab = GetLastActiveTabContents(app_id); | 963 active_tab->web_contents()); |
| 960 if (active_tab) { | 964 DCHECK(browser); |
| 961 Browser* browser = browser::FindBrowserWithWebContents( | 965 if (browser->window()->IsActive()) |
| 962 active_tab->web_contents()); | 966 status = ash::STATUS_ACTIVE; |
| 963 DCHECK(browser); | 967 else |
| 964 if (browser->window()->IsActive()) | 968 status = ash::STATUS_RUNNING; |
| 965 status = ash::STATUS_ACTIVE; | |
| 966 else | |
| 967 status = ash::STATUS_RUNNING; | |
| 968 } | |
| 969 item.status = status; | |
| 970 } | 969 } |
| 970 item.status = status; |
| 971 |
| 971 model_->AddAt(index, item); | 972 model_->AddAt(index, item); |
| 972 | 973 |
| 973 if (!controller || | 974 if (!controller || |
| 974 controller->type() != LauncherItemController::TYPE_EXTENSION_PANEL) { | 975 controller->type() != LauncherItemController::TYPE_EXTENSION_PANEL) { |
| 975 if (item.status != ash::STATUS_IS_PENDING) | 976 app_icon_loader_->FetchImage(app_id); |
| 976 app_icon_loader_->FetchImage(app_id); | |
| 977 } | 977 } |
| 978 return id; | 978 return id; |
| 979 } | 979 } |
| 980 |
| 981 void ChromeLauncherController::CheckAppSync() { |
| 982 if (!observed_sync_service_ || |
| 983 !observed_sync_service_->HasSyncSetupCompleted()) { |
| 984 return; |
| 985 } |
| 986 |
| 987 const bool synced = observed_sync_service_->ShouldPushChanges(); |
| 988 const bool has_pending_extension = profile_->GetExtensionService()-> |
| 989 pending_extension_manager()->HasPendingExtensionFromSync(); |
| 990 |
| 991 if (synced && !has_pending_extension) |
| 992 StopLoadingAnimation(); |
| 993 else |
| 994 StartLoadingAnimation(); |
| 995 } |
| 996 |
| 997 void ChromeLauncherController::StartLoadingAnimation() { |
| 998 DCHECK(observed_sync_service_); |
| 999 if (model_->status() == ash::LauncherModel::STATUS_LOADING) |
| 1000 return; |
| 1001 |
| 1002 loading_timer_.Start( |
| 1003 FROM_HERE, |
| 1004 base::TimeDelta::FromMilliseconds(kMaxLoadingTimeMs), |
| 1005 this, &ChromeLauncherController::StopLoadingAnimation); |
| 1006 model_->SetStatus(ash::LauncherModel::STATUS_LOADING); |
| 1007 } |
| 1008 |
| 1009 void ChromeLauncherController::StopLoadingAnimation() { |
| 1010 DCHECK(observed_sync_service_); |
| 1011 |
| 1012 model_->SetStatus(ash::LauncherModel::STATUS_NORMAL); |
| 1013 loading_timer_.Stop(); |
| 1014 observed_sync_service_->RemoveObserver(this); |
| 1015 observed_sync_service_ = NULL; |
| 1016 } |
| OLD | NEW |