Revert 187767 "Add a unified observer to replace NetworkManagerO..."
[chromium-blink-merge.git] / chrome / browser / chromeos / imageburner / burn_manager.h
blobba67dc6f8f44d3cc320dc1a1f37d3716312091df
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.
5 #ifndef CHROME_BROWSER_CHROMEOS_IMAGEBURNER_BURN_MANAGER_H_
6 #define CHROME_BROWSER_CHROMEOS_IMAGEBURNER_BURN_MANAGER_H_
8 #include <list>
9 #include <map>
10 #include <set>
11 #include <string>
12 #include <vector>
14 #include "base/files/file_path.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/observer_list.h"
17 #include "base/time.h"
18 #include "chrome/browser/chromeos/cros/burn_library.h"
19 #include "chrome/browser/chromeos/cros/network_library.h"
20 #include "chrome/browser/chromeos/imageburner/burn_device_handler.h"
21 #include "chromeos/disks/disk_mount_manager.h"
22 #include "googleurl/src/gurl.h"
23 #include "net/url_request/url_fetcher_delegate.h"
25 namespace net {
26 class URLFetcher;
27 } // namespace net
29 namespace chromeos {
30 namespace imageburner {
32 // Config file properties.
33 extern const char kName[];
34 extern const char kHwid[];
35 extern const char kFileName[];
36 extern const char kUrl[];
38 // Config file is divided into blocks. Each block is associated with one image
39 // and containes information about that image in form of key-value pairs, one
40 // pair per line. Each block starts with name property.
41 // Also, Each image can be associated with multiple hardware classes, so we
42 // treat hwid property separately.
43 // Config file example:
44 // name=image1
45 // version=version1
46 // hwid=hwid1
47 // hwid=hwid2
49 // name=name2
50 // version=version2
51 // hwid=hwid3
52 class ConfigFile {
53 public:
54 ConfigFile();
56 explicit ConfigFile(const std::string& file_content);
58 ~ConfigFile();
60 // Builds config file data structure.
61 void reset(const std::string& file_content);
63 void clear();
65 bool empty() const { return config_struct_.empty(); }
67 size_t size() const { return config_struct_.size(); }
69 // Returns property_name property of image for hardware class hwid.
70 const std::string& GetProperty(const std::string& property_name,
71 const std::string& hwid) const;
73 private:
74 void DeleteLastBlockIfHasNoHwid();
75 void ProcessLine(const std::vector<std::string>& line);
77 typedef std::map<std::string, std::string> PropertyMap;
78 typedef std::set<std::string> HwidsSet;
80 // Struct that contains config file block info. We separate hwid from other
81 // properties for two reasons:
82 // * there are multiple hwids defined for each block.
83 // * we will retieve properties by hwid.
84 struct ConfigFileBlock {
85 ConfigFileBlock();
86 ~ConfigFileBlock();
88 PropertyMap properties;
89 HwidsSet hwids;
92 // At the moment we have only two entries in the config file, so we can live
93 // with linear search. Should consider changing data structure if number of
94 // entries gets bigger.
95 // Also, there is only one entry for each hwid, if that changes we should
96 // return vector of strings.
97 typedef std::list<ConfigFileBlock> BlockList;
98 BlockList config_struct_;
101 class StateMachine {
102 public:
103 enum State {
104 INITIAL,
105 DOWNLOADING,
106 BURNING,
109 State state() { return state_; }
111 class Observer {
112 public:
113 virtual void OnBurnStateChanged(State new_state) = 0;
114 virtual void OnError(int error_message_id) = 0;
117 StateMachine();
118 ~StateMachine();
120 bool download_started() const { return download_started_; }
121 void OnDownloadStarted() {
122 download_started_ = true;
123 state_ = DOWNLOADING;
124 OnStateChanged();
127 bool download_finished() const { return download_finished_; }
128 void OnDownloadFinished() { download_finished_ = true; }
130 void OnBurnStarted() {
131 state_ = BURNING;
132 OnStateChanged();
135 bool new_burn_posible() const { return state_ == INITIAL; }
137 void OnSuccess();
138 void OnError(int error_message_id);
140 void OnStateChanged() {
141 FOR_EACH_OBSERVER(Observer, observers_, OnBurnStateChanged(state_));
144 void AddObserver(Observer* observer) {
145 observers_.AddObserver(observer);
148 void RemoveObserver(Observer* observer) {
149 observers_.RemoveObserver(observer);
152 private:
153 bool download_started_;
154 bool download_finished_;
156 State state_;
158 ObserverList<Observer> observers_;
160 DISALLOW_COPY_AND_ASSIGN(StateMachine);
163 // This is a system-wide singleton class to manage burning the recovery media.
164 // Here is how the burning image procedure works:
165 // 0) Choose the device the image to be burned (manually via web-ui).
166 // 1) Create ImageDir, which is a working directory for the procedure.
167 // 2) Download the config file.
168 // 2-1) Fetch the config file from the server.
169 // 2-2) Parse the config file content, and extract url and name of the image
170 // file.
171 // 3) Fetch the image file.
172 // 4) Burn the image to the device.
173 // 4-1) Unzip the fetched image file.
174 // 4-2) Unmount the device from file system.
175 // 4-3) Copy the unzipped file to the device directly.
176 // Currently, this only provides some methods to start/cancel background tasks,
177 // and some accessors to obtain the current status. Other functions are
178 // distributed among BurnController and BurnLibrary.
179 // TODO(hidehiko): Simplify the relationship among this class, BurnLibrary,
180 // BurnController and helper classes defined above.
181 class BurnManager : public net::URLFetcherDelegate,
182 public BurnLibrary::Observer,
183 public NetworkLibrary::NetworkManagerObserver {
184 public:
186 // Interface for classes that need to observe events for the burning image
187 // tasks.
188 class Observer {
189 public:
190 // Triggered when a burnable device is added.
191 virtual void OnDeviceAdded(const disks::DiskMountManager::Disk& disk) = 0;
193 // Triggered when a burnable device is removed.
194 virtual void OnDeviceRemoved(const disks::DiskMountManager::Disk& disk) = 0;
196 // Triggered when a network is detected.
197 virtual void OnNetworkDetected() = 0;
199 // Triggered when the creating a ImageDir is done.
200 // The status of the creating the directory is passed to |success|.
201 virtual void OnImageDirCreated(bool success) = 0;
203 // Triggered when the fetching of the config file is done.
204 // The result status of the fetch is passed to |success|.
205 virtual void OnConfigFileFetched(bool success) = 0;
207 // Triggered during the image file downloading periodically.
208 // |estimated_remaining_time| is the remaining duration to download the
209 // remaining content estimated based on the elapsed time.
210 virtual void OnImageFileFetchDownloadProgressUpdated(
211 int64 received_bytes,
212 int64 total_bytes,
213 const base::TimeDelta& estimated_remaining_time) = 0;
215 // Triggered when the fetching of the image file is done.
216 // The result status is passed to |success|.
217 virtual void OnImageFileFetched(bool success) = 0;
219 // Triggered during the burning the image to the device.
220 // See also BurnLibrary's comment for more details.
221 virtual void OnBurnProgressUpdated(BurnEvent event,
222 const ImageBurnStatus& status) = 0;
225 // Creates the global BurnManager instance.
226 static void Initialize();
228 // Destroys the global BurnManager instance if it exists.
229 static void Shutdown();
231 // Returns the global BurnManager instance.
232 // Initialize() should already have been called.
233 static BurnManager* GetInstance();
235 // Add an observer.
236 void AddObserver(Observer* observer);
238 // Remove an observer.
239 void RemoveObserver(Observer* observer);
241 // Returns devices on which we can burn recovery image.
242 std::vector<disks::DiskMountManager::Disk> GetBurnableDevices();
244 // Returns true if some network is connected.
245 bool IsNetworkConnected() const;
247 // Cancels a currently running task of burning recovery image.
248 // Note: currently we only support Cancel method, which may look asymmetry
249 // because there is no method to start the task. It is just because that
250 // we are on the way of refactoring.
251 // TODO(hidehiko): Introduce Start method, which actually starts a whole
252 // image burning task, including config/image file fetching and unzipping.
253 void Cancel();
255 // Error is usually detected by all existing Burn handlers, but only first
256 // one that calls this method should actually process it.
257 // The |message_id| is the id for human readable error message, although
258 // here is not the place to handle UI.
259 // TODO(hidehiko): Replace it with semantical enum value.
260 // Note: currently, due to some implementation reasons, the errors can be
261 // observed in outside classes, and this method is public to be accessed from
262 // them.
263 // TODO(hidehiko): Refactor the structure.
264 void OnError(int message_id);
266 // Creates URL image should be fetched from.
267 // Must be called from UI thread.
268 void FetchConfigFile();
270 // Fetch a zipped recovery image.
271 void FetchImage();
273 // Burns the image of |zip_image_file_path_| and |image_file_name|
274 // to |target_device_path_| and |target_file_path_|.
275 // TODO(hidehiko): The name "Burn" sounds confusing because there are two
276 // meaning here.
277 // 1) In wider sense, Burn means a whole process, including config/image
278 // file fetching, or file unzipping.
279 // 2) In narrower sense, Burn means just write the image onto a device.
280 // To avoid such a confusion, rename the method.
281 void DoBurn();
283 // Cancels the image burning.
284 // TODO(hidehiko): Rename this method along with the renaming of DoBurn.
285 void CancelBurnImage();
287 // Cancel fetching image.
288 void CancelImageFetch();
290 // URLFetcherDelegate overrides:
291 virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
292 virtual void OnURLFetchDownloadProgress(const net::URLFetcher* source,
293 int64 current,
294 int64 total) OVERRIDE;
296 // BurnLibrary::Observer orverrides.
297 virtual void BurnProgressUpdated(BurnLibrary* object,
298 BurnEvent event,
299 const ImageBurnStatus& status) OVERRIDE;
301 // NetworkLibrary::NetworkManagerObserver interface.
302 virtual void OnNetworkManagerChanged(NetworkLibrary* obj) OVERRIDE;
304 // Creates directory image will be downloaded to.
305 // Must be called from FILE thread.
306 void CreateImageDir();
308 // Returns directory image should be dopwnloaded to.
309 // The directory has to be previously created.
310 const base::FilePath& GetImageDir();
312 const base::FilePath& target_device_path() { return target_device_path_; }
313 void set_target_device_path(const base::FilePath& path) {
314 target_device_path_ = path;
317 const base::FilePath& target_file_path() { return target_file_path_; }
318 void set_target_file_path(const base::FilePath& path) {
319 target_file_path_ = path;
322 void ResetTargetPaths() {
323 target_device_path_.clear();
324 target_file_path_.clear();
327 StateMachine* state_machine() const { return state_machine_.get(); }
329 private:
330 BurnManager();
331 virtual ~BurnManager();
333 void OnImageDirCreated(bool success);
334 void ConfigFileFetched(bool fetched, const std::string& content);
336 void NotifyDeviceAdded(const disks::DiskMountManager::Disk& disk);
337 void NotifyDeviceRemoved(const disks::DiskMountManager::Disk& disk);
339 BurnDeviceHandler device_handler_;
341 base::FilePath image_dir_;
342 base::FilePath zip_image_file_path_;
343 base::FilePath target_device_path_;
344 base::FilePath target_file_path_;
346 GURL config_file_url_;
347 bool config_file_fetched_;
348 std::string image_file_name_;
349 GURL image_download_url_;
351 scoped_ptr<StateMachine> state_machine_;
353 scoped_ptr<net::URLFetcher> config_fetcher_;
354 scoped_ptr<net::URLFetcher> image_fetcher_;
356 base::TimeTicks tick_image_download_start_;
357 int64 bytes_image_download_progress_last_reported_;
359 ObserverList<Observer> observers_;
361 // Note: This should remain the last member so it'll be destroyed and
362 // invalidate its weak pointers before any other members are destroyed.
363 base::WeakPtrFactory<BurnManager> weak_ptr_factory_;
365 DISALLOW_COPY_AND_ASSIGN(BurnManager);
368 } // namespace imageburner
370 } // namespace chromeos
372 #endif // CHROME_BROWSER_CHROMEOS_IMAGEBURNER_BURN_MANAGER_H_