Upstream version 6.35.121.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/install_tracker.h"
12 #include "chrome/browser/extensions/install_tracker_factory.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/ui/app_list/recommended_apps_observer.h"
15 #include "chrome/common/pref_names.h"
16 #include "extensions/browser/extension_prefs.h"
17 #include "extensions/browser/extension_registry.h"
18 #include "extensions/browser/pref_names.h"
19 #include "extensions/common/extension.h"
20 #include "extensions/common/extension_set.h"
21
22 namespace app_list {
23
24 namespace {
25
26 struct AppSortInfo {
27   AppSortInfo() : app(NULL) {}
28   AppSortInfo(const extensions::Extension* app,
29               const base::Time& last_launch_time)
30       : app(app), last_launch_time(last_launch_time) {}
31
32   const extensions::Extension* app;
33   base::Time last_launch_time;
34 };
35
36 bool AppLaunchedMoreRecent(const AppSortInfo& app1, const AppSortInfo& app2) {
37   return app1.last_launch_time > app2.last_launch_time;
38 }
39
40 }  // namespace
41
42 RecommendedApps::RecommendedApps(Profile* profile) : profile_(profile) {
43   extensions::InstallTrackerFactory::GetForProfile(profile_)->AddObserver(this);
44
45   extensions::ExtensionPrefs* prefs = extensions::ExtensionPrefs::Get(profile_);
46   pref_change_registrar_.Init(prefs->pref_service());
47   pref_change_registrar_.Add(extensions::pref_names::kExtensions,
48                              base::Bind(&RecommendedApps::Update,
49                                         base::Unretained(this)));
50
51   Update();
52 }
53
54 RecommendedApps::~RecommendedApps() {
55   extensions::InstallTrackerFactory::GetForProfile(profile_)
56       ->RemoveObserver(this);
57 }
58
59 void RecommendedApps::AddObserver(RecommendedAppsObserver* observer) {
60   observers_.AddObserver(observer);
61 }
62
63 void RecommendedApps::RemoveObserver(RecommendedAppsObserver* observer) {
64   observers_.RemoveObserver(observer);
65 }
66
67 void RecommendedApps::Update() {
68   extensions::ExtensionPrefs* prefs = extensions::ExtensionPrefs::Get(profile_);
69
70   std::vector<AppSortInfo> sorted_apps;
71   const extensions::ExtensionSet& extensions =
72       extensions::ExtensionRegistry::Get(profile_)->enabled_extensions();
73   for (extensions::ExtensionSet::const_iterator app = extensions.begin();
74        app != extensions.end();
75        ++app) {
76     if (!(*app)->ShouldDisplayInAppLauncher())
77       continue;
78
79     sorted_apps.push_back(
80         AppSortInfo(app->get(), prefs->GetLastLaunchTime((*app)->id())));
81   }
82
83   std::sort(sorted_apps.begin(), sorted_apps.end(), &AppLaunchedMoreRecent);
84
85   const size_t kMaxRecommendedApps = 4;
86   sorted_apps.resize(std::min(kMaxRecommendedApps, sorted_apps.size()));
87
88   Apps new_recommends;
89   for (size_t i = 0; i < sorted_apps.size(); ++i)
90     new_recommends.push_back(sorted_apps[i].app);
91
92   const bool changed = apps_.size() != new_recommends.size() ||
93       !std::equal(apps_.begin(), apps_.end(), new_recommends.begin());
94   if (changed) {
95     apps_.swap(new_recommends);
96     FOR_EACH_OBSERVER(
97         RecommendedAppsObserver, observers_, OnRecommendedAppsChanged());
98   }
99 }
100
101 void RecommendedApps::OnExtensionInstalled(
102     const extensions::Extension* extension) {
103   Update();
104 }
105
106 void RecommendedApps::OnExtensionLoaded(
107     const extensions::Extension* extension) {
108   Update();
109 }
110
111 void RecommendedApps::OnExtensionUnloaded(
112     const extensions::Extension* extension) {
113   Update();
114 }
115
116 void RecommendedApps::OnExtensionUninstalled(
117     const extensions::Extension* extension) {
118   Update();
119 }
120
121 }  // namespace app_list