1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_POLICY_APP_PACK_UPDATER_H_
#define CHROME_BROWSER_POLICY_APP_PACK_UPDATER_H_
#include <map>
#include <set>
#include <string>
#include "base/basictypes.h"
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/file_path.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/sequenced_worker_pool.h"
#include "chrome/browser/extensions/updater/extension_downloader_delegate.h"
#include "chrome/browser/policy/cloud_policy_subsystem.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "net/base/network_change_notifier.h"
class GURL;
namespace extensions {
class CrxInstaller;
class ExtensionDownloader;
class ExternalLoader;
}
namespace net {
class URLRequestContextGetter;
}
namespace tracked_objects {
class Location;
}
namespace policy {
class AppPackExternalLoader;
class BrowserPolicyConnector;
// The AppPackUpdater manages a set of extensions that are configured via a
// device policy to be locally cached and installed into the Demo user account
// at login time.
class AppPackUpdater : public CloudPolicySubsystem::Observer,
public content::NotificationObserver,
public net::NetworkChangeNotifier::IPAddressObserver,
public extensions::ExtensionDownloaderDelegate {
public:
// Callback to listen for updates to the screensaver extension's path.
typedef base::Callback<void(const FilePath&)> ScreenSaverUpdateCallback;
// Keys for the entries in the AppPack dictionary policy.
static const char kExtensionId[];
static const char kUpdateUrl[];
// The |request_context| is used for the update checks.
AppPackUpdater(net::URLRequestContextGetter* request_context,
BrowserPolicyConnector* connector);
virtual ~AppPackUpdater();
// Creates an extensions::ExternalLoader that will load the crx files
// downloaded by the AppPackUpdater. This can be called at most once, and the
// caller owns the returned value.
extensions::ExternalLoader* CreateExternalLoader();
// |callback| will be invoked whenever the screen saver extension's path
// changes. It will be invoked "soon" after this call if a valid path already
// exists. Subsequent calls will override the previous |callback|. A null
// |callback| can be used to remove a previous callback.
void SetScreenSaverUpdateCallback(const ScreenSaverUpdateCallback& callback);
private:
struct AppPackEntry {
std::string update_url;
bool update_checked;
};
struct CacheEntry {
std::string path;
std::string cached_version;
};
// Maps an extension ID to its update URL and update information.
typedef std::map<std::string, AppPackEntry> PolicyEntryMap;
// Maps an extension ID to a CacheEntry.
typedef std::map<std::string, CacheEntry> CacheEntryMap;
void Init();
// CloudPolicySubsystem::Observer:
virtual void OnPolicyStateChanged(
CloudPolicySubsystem::PolicySubsystemState state,
CloudPolicySubsystem::ErrorDetails error_details) OVERRIDE;
// content::NotificationObserver:
virtual void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE;
// net::NetworkChangeNotifier::IPAddressObserver:
virtual void OnIPAddressChanged() OVERRIDE;
// Loads the current policy and schedules a cache update.
void LoadPolicy();
// Starts a cache update check immediately.
void CheckCacheNow();
// Performs a cache update check on the blocking pool. |app_pack_updater| is
// used to reply in the UI thread. |valid_ids| contains the list of IDs that
// are currently configured by policy; anything else is invalid, and should
// be removed from the cache. |valid_ids| is owned by the posted task.
static void BlockingCheckCache(base::WeakPtr<AppPackUpdater> app_pack_updater,
const std::set<std::string>* valid_ids);
// Helper for BlockingCheckCache().
static void BlockingCheckCacheInternal(
const std::set<std::string>* valid_ids,
CacheEntryMap* entries);
// Invoked when the cache has been updated. |cache_entries| contains all the
// currently valid crx files in the cache, and is owned by the posted task.
void OnCacheUpdated(CacheEntryMap* cache_entries);
// Notifies the |extension_loader_| that the cache has been updated, providing
// it with an updated list of app-pack extensions.
void UpdateExtensionLoader();
// Schedules downloads of all the extensions that are currently configured
// by the policy but missing in the cache.
void DownloadMissingExtensions();
// Implementation of ExtensionDownloaderDelegate:
virtual void OnExtensionDownloadFailed(
const std::string& id,
Error error,
const PingResult& ping_result) OVERRIDE;
virtual void OnExtensionDownloadFinished(
const std::string& id,
const FilePath& path,
const GURL& download_url,
const std::string& version,
const PingResult& ping_result) OVERRIDE;
virtual void OnBlacklistDownloadFinished(
const std::string& data,
const std::string& package_hash,
const std::string& version,
const PingResult& ping_result) OVERRIDE;
virtual bool IsExtensionPending(const std::string& id) OVERRIDE;
virtual bool GetExtensionExistingVersion(const std::string& id,
std::string* version) OVERRIDE;
// Invoked to install the downloaded crx file at |path| in the AppPack cache.
static void BlockingInstallCacheEntry(
base::WeakPtr<AppPackUpdater> app_pack_updater,
const std::string& id,
const FilePath& path,
const std::string& version);
// Invoked on the UI thread when a new AppPack entry has been installed in
// the AppPack cache.
void OnCacheEntryInstalled(const std::string& id,
const std::string& path,
const std::string& version);
// Handles failure to install CRX files. The file is deleted if it came from
// the cache.
void OnCrxInstallFailed(extensions::CrxInstaller* installer);
// Helper to post blocking IO tasks to the blocking pool.
void PostBlockingTask(const tracked_objects::Location& from_here,
const base::Closure& task);
// Sets |screen_saver_path_| and invokes |screen_saver_update_callback_| if
// appropriate.
void SetScreenSaverPath(const FilePath& path);
// Marks extension |id| in |app_pack_extensions_| as having already been
// checked for updates, if it exists.
void SetUpdateChecked(const std::string& id);
base::WeakPtrFactory<AppPackUpdater> weak_ptr_factory_;
// Observes updates to the |device_cloud_policy_subsystem_|, to detect
// device enrollment.
scoped_ptr<CloudPolicySubsystem::ObserverRegistrar> policy_registrar_;
// Observes failures to install CRX files.
content::NotificationRegistrar notification_registrar_;
// Unique sequence token so that tasks posted by the AppPackUpdater are
// executed sequentially in the blocking pool.
base::SequencedWorkerPool::SequenceToken worker_pool_token_;
// This is the list of extensions currently configured by the policy.
PolicyEntryMap app_pack_extensions_;
// This contains extensions that are both currently configured by the policy
// and that have a valid crx in the cache.
CacheEntryMap cached_extensions_;
// The extension ID and path of the CRX file of the screen saver extension,
// if it is configured by the policy. Otherwise these fields are empty.
std::string screen_saver_id_;
FilePath screen_saver_path_;
// Callback to invoke whenever the screen saver's extension path changes.
// Can be null.
ScreenSaverUpdateCallback screen_saver_update_callback_;
// The extension loader wires the AppPackUpdater to the extensions system, and
// makes it install the currently cached extensions.
bool created_extension_loader_;
base::WeakPtr<AppPackExternalLoader> extension_loader_;
// Used to download the extensions configured via policy, and to check for
// updates.
scoped_ptr<extensions::ExtensionDownloader> downloader_;
// Request context used by the |downloader_|.
net::URLRequestContextGetter* request_context_;
DISALLOW_COPY_AND_ASSIGN(AppPackUpdater);
};
} // namespace policy
#endif // CHROME_BROWSER_POLICY_APP_PACK_UPDATER_H_
|