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/extensions/install_tracker.h"
6
7 #include "base/bind.h"
8 #include "chrome/browser/chrome_notification_types.h"
9 #include "chrome/browser/extensions/install_tracker_factory.h"
10 #include "content/public/browser/notification_service.h"
11 #include "extensions/browser/extension_prefs.h"
12 #include "extensions/browser/extension_registry.h"
13 #include "extensions/browser/pref_names.h"
14
15 namespace extensions {
16
InstallTracker(content::BrowserContext * browser_context,extensions::ExtensionPrefs * prefs)17 InstallTracker::InstallTracker(content::BrowserContext* browser_context,
18 extensions::ExtensionPrefs* prefs)
19 : extension_registry_observer_(this) {
20 registrar_.Add(this,
21 extensions::NOTIFICATION_EXTENSION_UPDATE_DISABLED,
22 content::Source<content::BrowserContext>(browser_context));
23 registrar_.Add(this,
24 chrome::NOTIFICATION_APP_INSTALLED_TO_APPLIST,
25 content::Source<content::BrowserContext>(browser_context));
26 extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context));
27
28 // Prefs may be null in tests.
29 if (prefs) {
30 AppSorting* sorting = prefs->app_sorting();
31 registrar_.Add(this,
32 chrome::NOTIFICATION_APP_LAUNCHER_REORDERED,
33 content::Source<AppSorting>(sorting));
34 pref_change_registrar_.Init(prefs->pref_service());
35 pref_change_registrar_.Add(
36 pref_names::kExtensions,
37 base::Bind(&InstallTracker::OnAppsReordered, base::Unretained(this)));
38 }
39 }
40
~InstallTracker()41 InstallTracker::~InstallTracker() {
42 }
43
44 // static
Get(content::BrowserContext * context)45 InstallTracker* InstallTracker::Get(content::BrowserContext* context) {
46 return InstallTrackerFactory::GetForBrowserContext(context);
47 }
48
AddObserver(InstallObserver * observer)49 void InstallTracker::AddObserver(InstallObserver* observer) {
50 observers_.AddObserver(observer);
51 }
52
RemoveObserver(InstallObserver * observer)53 void InstallTracker::RemoveObserver(InstallObserver* observer) {
54 observers_.RemoveObserver(observer);
55 }
56
GetActiveInstall(const std::string & extension_id) const57 const ActiveInstallData* InstallTracker::GetActiveInstall(
58 const std::string& extension_id) const {
59 ActiveInstallsMap::const_iterator install_data =
60 active_installs_.find(extension_id);
61 if (install_data == active_installs_.end())
62 return NULL;
63 else
64 return &(install_data->second);
65 }
66
AddActiveInstall(const ActiveInstallData & install_data)67 void InstallTracker::AddActiveInstall(const ActiveInstallData& install_data) {
68 DCHECK(!install_data.extension_id.empty());
69 DCHECK(active_installs_.find(install_data.extension_id) ==
70 active_installs_.end());
71 active_installs_.insert(
72 std::make_pair(install_data.extension_id, install_data));
73 }
74
RemoveActiveInstall(const std::string & extension_id)75 void InstallTracker::RemoveActiveInstall(const std::string& extension_id) {
76 active_installs_.erase(extension_id);
77 }
78
OnBeginExtensionInstall(const InstallObserver::ExtensionInstallParams & params)79 void InstallTracker::OnBeginExtensionInstall(
80 const InstallObserver::ExtensionInstallParams& params) {
81 ActiveInstallsMap::iterator install_data =
82 active_installs_.find(params.extension_id);
83 if (install_data == active_installs_.end()) {
84 ActiveInstallData install_data(params.extension_id);
85 install_data.is_ephemeral = params.is_ephemeral;
86 active_installs_.insert(std::make_pair(params.extension_id, install_data));
87 }
88
89 FOR_EACH_OBSERVER(InstallObserver, observers_,
90 OnBeginExtensionInstall(params));
91 }
92
OnBeginExtensionDownload(const std::string & extension_id)93 void InstallTracker::OnBeginExtensionDownload(const std::string& extension_id) {
94 FOR_EACH_OBSERVER(
95 InstallObserver, observers_, OnBeginExtensionDownload(extension_id));
96 }
97
OnDownloadProgress(const std::string & extension_id,int percent_downloaded)98 void InstallTracker::OnDownloadProgress(const std::string& extension_id,
99 int percent_downloaded) {
100 ActiveInstallsMap::iterator install_data =
101 active_installs_.find(extension_id);
102 if (install_data != active_installs_.end()) {
103 install_data->second.percent_downloaded = percent_downloaded;
104 } else {
105 NOTREACHED();
106 }
107
108 FOR_EACH_OBSERVER(InstallObserver, observers_,
109 OnDownloadProgress(extension_id, percent_downloaded));
110 }
111
OnBeginCrxInstall(const std::string & extension_id)112 void InstallTracker::OnBeginCrxInstall(const std::string& extension_id) {
113 FOR_EACH_OBSERVER(
114 InstallObserver, observers_, OnBeginCrxInstall(extension_id));
115 }
116
OnFinishCrxInstall(const std::string & extension_id,bool success)117 void InstallTracker::OnFinishCrxInstall(const std::string& extension_id,
118 bool success) {
119 FOR_EACH_OBSERVER(
120 InstallObserver, observers_, OnFinishCrxInstall(extension_id, success));
121 }
122
OnInstallFailure(const std::string & extension_id)123 void InstallTracker::OnInstallFailure(
124 const std::string& extension_id) {
125 RemoveActiveInstall(extension_id);
126 FOR_EACH_OBSERVER(InstallObserver, observers_,
127 OnInstallFailure(extension_id));
128 }
129
Shutdown()130 void InstallTracker::Shutdown() {
131 FOR_EACH_OBSERVER(InstallObserver, observers_, OnShutdown());
132 }
133
Observe(int type,const content::NotificationSource & source,const content::NotificationDetails & details)134 void InstallTracker::Observe(int type,
135 const content::NotificationSource& source,
136 const content::NotificationDetails& details) {
137 switch (type) {
138 case extensions::NOTIFICATION_EXTENSION_UPDATE_DISABLED: {
139 const Extension* extension =
140 content::Details<const Extension>(details).ptr();
141 FOR_EACH_OBSERVER(
142 InstallObserver, observers_, OnDisabledExtensionUpdated(extension));
143 break;
144 }
145 case chrome::NOTIFICATION_APP_LAUNCHER_REORDERED: {
146 FOR_EACH_OBSERVER(InstallObserver, observers_, OnAppsReordered());
147 break;
148 }
149 case chrome::NOTIFICATION_APP_INSTALLED_TO_APPLIST: {
150 const std::string& extension_id(
151 *content::Details<const std::string>(details).ptr());
152 FOR_EACH_OBSERVER(InstallObserver, observers_,
153 OnAppInstalledToAppList(extension_id));
154 break;
155 }
156 default:
157 NOTREACHED();
158 }
159 }
160
OnExtensionInstalled(content::BrowserContext * browser_context,const Extension * extension,bool is_update)161 void InstallTracker::OnExtensionInstalled(
162 content::BrowserContext* browser_context,
163 const Extension* extension,
164 bool is_update) {
165 RemoveActiveInstall(extension->id());
166 }
167
OnAppsReordered()168 void InstallTracker::OnAppsReordered() {
169 FOR_EACH_OBSERVER(InstallObserver, observers_, OnAppsReordered());
170 }
171
172 } // namespace extensions
173