summaryrefslogtreecommitdiffstats
path: root/chrome/browser/policy/app_pack_updater.h
blob: 142ec9aee05a3a4c0bce7636bf7e64a3a3312672 (plain)
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
// 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 "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.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 EnterpriseInstallAttributes;

// 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 content::NotificationObserver,
                       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,
                 EnterpriseInstallAttributes* install_attributes);
  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);

  // If a user of one of the AppPack's extensions detects that the extension
  // is damaged then this method can be used to remove it from the cache and
  // retry to download it after a restart.
  void OnDamagedFileDetected(const FilePath& path);

 private:
  struct CacheEntry {
    std::string path;
    std::string cached_version;
  };

  // Maps an extension ID to its update URL.
  typedef std::map<std::string, std::string> PolicyEntryMap;

  // Maps an extension ID to a CacheEntry.
  typedef std::map<std::string, CacheEntry> CacheEntryMap;

  void Init();

  // content::NotificationObserver:
  virtual void Observe(int type,
                       const content::NotificationSource& source,
                       const content::NotificationDetails& details) 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,
      const std::set<int>& request_ids) OVERRIDE;

  virtual void OnExtensionDownloadFinished(
      const std::string& id,
      const FilePath& path,
      const GURL& download_url,
      const std::string& version,
      const PingResult& ping_result,
      const std::set<int>& request_ids) OVERRIDE;

  virtual void OnBlacklistDownloadFinished(
      const std::string& data,
      const std::string& package_hash,
      const std::string& version,
      const PingResult& ping_result,
      const std::set<int>& request_ids) 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);

  base::WeakPtrFactory<AppPackUpdater> weak_ptr_factory_;

  // 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_;

  // Whether the updater has initialized. This is only done if the device is in
  // kiosk mode and the app pack policy is present.
  bool initialized_;

  // 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_;

  // For checking the device mode.
  EnterpriseInstallAttributes* install_attributes_;

  DISALLOW_COPY_AND_ASSIGN(AppPackUpdater);
};

}  // namespace policy

#endif  // CHROME_BROWSER_POLICY_APP_PACK_UPDATER_H_