Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / app_list / recommended_apps.cc
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, 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