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