1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/browser/ui/app_list/recommended_apps.h" 6 7 #include <algorithm> 8 #include <vector> 9 10 #include "base/bind.h" 11 #include "chrome/browser/extensions/extension_ui_util.h" 12 #include "chrome/browser/profiles/profile.h" 13 #include "chrome/browser/ui/app_list/recommended_apps_observer.h" 14 #include "chrome/common/pref_names.h" 15 #include "extensions/browser/extension_prefs.h" 16 #include "extensions/browser/extension_registry.h" 17 #include "extensions/browser/pref_names.h" 18 #include "extensions/common/extension.h" 19 #include "extensions/common/extension_set.h" 20 21 namespace app_list { 22 23 namespace { 24 25 struct AppSortInfo { 26 AppSortInfo() : app(NULL) {} 27 AppSortInfo(const extensions::Extension* app, 28 const base::Time& last_launch_time) 29 : app(app), last_launch_time(last_launch_time) {} 30 31 const extensions::Extension* app; 32 base::Time last_launch_time; 33 }; 34 35 bool AppLaunchedMoreRecent(const AppSortInfo& app1, const AppSortInfo& app2) { 36 return app1.last_launch_time > app2.last_launch_time; 37 } 38 39 } // namespace 40 41 RecommendedApps::RecommendedApps(Profile* profile) 42 : profile_(profile), extension_registry_observer_(this) { 43 extensions::ExtensionPrefs* prefs = extensions::ExtensionPrefs::Get(profile_); 44 pref_change_registrar_.Init(prefs->pref_service()); 45 pref_change_registrar_.Add(extensions::pref_names::kExtensions, 46 base::Bind(&RecommendedApps::Update, 47 base::Unretained(this))); 48 extension_registry_observer_.Add(extensions::ExtensionRegistry::Get(profile)); 49 Update(); 50 } 51 52 RecommendedApps::~RecommendedApps() { 53 } 54 55 void RecommendedApps::AddObserver(RecommendedAppsObserver* observer) { 56 observers_.AddObserver(observer); 57 } 58 59 void RecommendedApps::RemoveObserver(RecommendedAppsObserver* observer) { 60 observers_.RemoveObserver(observer); 61 } 62 63 void RecommendedApps::Update() { 64 extensions::ExtensionPrefs* prefs = extensions::ExtensionPrefs::Get(profile_); 65 66 std::vector<AppSortInfo> sorted_apps; 67 const extensions::ExtensionSet& extensions = 68 extensions::ExtensionRegistry::Get(profile_)->enabled_extensions(); 69 for (extensions::ExtensionSet::const_iterator app = extensions.begin(); 70 app != extensions.end(); 71 ++app) { 72 if (!extensions::ui_util::ShouldDisplayInAppLauncher(app->get(), profile_)) 73 continue; 74 75 sorted_apps.push_back( 76 AppSortInfo(app->get(), prefs->GetLastLaunchTime((*app)->id()))); 77 } 78 79 std::sort(sorted_apps.begin(), sorted_apps.end(), &AppLaunchedMoreRecent); 80 81 const size_t kMaxRecommendedApps = 4; 82 sorted_apps.resize(std::min(kMaxRecommendedApps, sorted_apps.size())); 83 84 Apps new_recommends; 85 for (size_t i = 0; i < sorted_apps.size(); ++i) 86 new_recommends.push_back(sorted_apps[i].app); 87 88 const bool changed = apps_.size() != new_recommends.size() || 89 !std::equal(apps_.begin(), apps_.end(), new_recommends.begin()); 90 if (changed) { 91 apps_.swap(new_recommends); 92 FOR_EACH_OBSERVER( 93 RecommendedAppsObserver, observers_, OnRecommendedAppsChanged()); 94 } 95 } 96 97 void RecommendedApps::OnExtensionWillBeInstalled( 98 content::BrowserContext* browser_context, 99 const extensions::Extension* extension, 100 bool is_update, 101 bool from_ephemeral, 102 const std::string& old_name) { 103 Update(); 104 } 105 106 void RecommendedApps::OnExtensionLoaded( 107 content::BrowserContext* browser_context, 108 const extensions::Extension* extension) { 109 Update(); 110 } 111 112 void RecommendedApps::OnExtensionUnloaded( 113 content::BrowserContext* browser_context, 114 const extensions::Extension* extension, 115 extensions::UnloadedExtensionInfo::Reason reason) { 116 Update(); 117 } 118 119 void RecommendedApps::OnExtensionUninstalled( 120 content::BrowserContext* browser_context, 121 const extensions::Extension* extension, 122 extensions::UninstallReason reason) { 123 Update(); 124 } 125 126 } // namespace app_list 127