Home | History | Annotate | Download | only in app_list
      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