Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / extensions / api / image_writer_private / operation.h
blobf4e025d5bde3d962064b072c7fbe46d6a9bb9d05
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.
5 #ifndef CHROME_BROWSER_EXTENSIONS_API_IMAGE_WRITER_PRIVATE_OPERATION_H_
6 #define CHROME_BROWSER_EXTENSIONS_API_IMAGE_WRITER_PRIVATE_OPERATION_H_
8 #include "base/callback.h"
9 #include "base/files/file.h"
10 #include "base/files/scoped_temp_dir.h"
11 #include "base/md5.h"
12 #include "base/memory/ref_counted_memory.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/task/cancelable_task_tracker.h"
15 #include "chrome/browser/extensions/api/image_writer_private/image_writer_utility_client.h"
16 #include "chrome/common/extensions/api/image_writer_private.h"
17 #include "third_party/zlib/google/zip_reader.h"
19 namespace image_writer_api = extensions::api::image_writer_private;
21 namespace base {
22 class FilePath;
23 } // namespace base
25 namespace extensions {
26 namespace image_writer {
28 const int kProgressComplete = 100;
30 class OperationManager;
32 // Encapsulates an operation being run on behalf of the
33 // OperationManager. Construction of the operation does not start
34 // anything. The operation's Start method should be called to start it, and
35 // then the Cancel method will stop it. The operation will call back to the
36 // OperationManager periodically or on any significant event.
38 // Each stage of the operation is generally divided into three phases: Start,
39 // Run, Complete. Start and Complete run on the UI thread and are responsible
40 // for advancing to the next stage and other UI interaction. The Run phase does
41 // the work on the FILE thread and calls SendProgress or Error as appropriate.
43 // TODO(haven): This class is current refcounted because it is owned by the
44 // OperationManager on the UI thread but needs to do work on the FILE thread.
45 // There is probably a better way to organize this so that it can be represented
46 // by a WeakPtr, but those are not thread-safe. Additionally, if destruction is
47 // done on the UI thread then that causes problems if any of the fields were
48 // allocated/accessed on the FILE thread. http://crbug.com/344713
49 class Operation : public base::RefCountedThreadSafe<Operation> {
50 public:
51 typedef base::Callback<void(bool, const std::string&)> StartWriteCallback;
52 typedef base::Callback<void(bool, const std::string&)> CancelWriteCallback;
53 typedef std::string ExtensionId;
55 Operation(base::WeakPtr<OperationManager> manager,
56 const ExtensionId& extension_id,
57 const std::string& device_path);
59 // Starts the operation.
60 void Start();
62 // Cancel the operation. This must be called to clean up internal state and
63 // cause the the operation to actually stop. It will not be destroyed until
64 // all callbacks have completed.
65 void Cancel();
67 // Aborts the operation, cancelling it and generating an error.
68 void Abort();
70 // Informational getters.
71 int GetProgress();
72 image_writer_api::Stage GetStage();
74 #if !defined(OS_CHROMEOS)
75 // Set an ImageWriterClient to use. Should be called only when testing. This
76 // does not set up automatic shutdown of the client and it must be shutdown
77 // manually.
78 static void SetUtilityClientForTesting(
79 scoped_refptr<ImageWriterUtilityClient> client);
80 #endif
82 protected:
83 virtual ~Operation();
85 // This function should be overriden by subclasses to set up the work of the
86 // operation. It will be called from Start().
87 virtual void StartImpl() = 0;
89 // Unzips the current file if it ends in ".zip". The current_file will be set
90 // to the unzipped file.
91 void Unzip(const base::Closure& continuation);
93 // Writes the current file to device_path.
94 void Write(const base::Closure& continuation);
96 // Verifies that the current file and device_path contents match.
97 void VerifyWrite(const base::Closure& continuation);
99 // Completes the operation.
100 void Finish();
102 // Generates an error.
103 // |error_message| is used to create an OnWriteError event which is
104 // sent to the extension
105 virtual void Error(const std::string& error_message);
107 // Set |progress_| and send an event. Progress should be in the interval
108 // [0,100]
109 void SetProgress(int progress);
110 // Change to a new |stage_| and set |progress_| to zero. Triggers a progress
111 // event.
112 void SetStage(image_writer_api::Stage stage);
114 // Can be queried to safely determine if the operation has been cancelled.
115 bool IsCancelled();
117 // Adds a callback that will be called during clean-up, whether the operation
118 // is aborted, encounters and error, or finishes successfully. These
119 // functions will be run on the FILE thread.
120 void AddCleanUpFunction(const base::Closure& callback);
122 // Completes the current operation (progress set to 100) and runs the
123 // continuation.
124 void CompleteAndContinue(const base::Closure& continuation);
126 // If |file_size| is non-zero, only |file_size| bytes will be read from file,
127 // otherwise the entire file will be read.
128 // |progress_scale| is a percentage to which the progress will be scale, e.g.
129 // a scale of 50 means it will increment from 0 to 50 over the course of the
130 // sum. |progress_offset| is an percentage that will be added to the progress
131 // of the MD5 sum before updating |progress_| but after scaling.
132 void GetMD5SumOfFile(
133 const base::FilePath& file,
134 int64 file_size,
135 int progress_offset,
136 int progress_scale,
137 const base::Callback<void(const std::string&)>& callback);
139 base::WeakPtr<OperationManager> manager_;
140 const ExtensionId extension_id_;
142 base::FilePath image_path_;
143 base::FilePath device_path_;
145 // Temporary directory to store files as we go.
146 base::ScopedTempDir temp_dir_;
148 private:
149 friend class base::RefCountedThreadSafe<Operation>;
151 #if !defined(OS_CHROMEOS)
152 // Ensures the client is started. This may be called many times but will only
153 // instantiate one client which should exist for the lifetime of the
154 // Operation.
155 void StartUtilityClient();
157 // Stops the client. This must be called to ensure the utility process can
158 // shutdown.
159 void StopUtilityClient();
161 // Reports progress from the client, transforming from bytes to percentage.
162 virtual void WriteImageProgress(int64 total_bytes, int64 curr_bytes);
164 scoped_refptr<ImageWriterUtilityClient> image_writer_client_;
165 #endif
167 #if defined(OS_CHROMEOS)
168 // Unmounts all volumes on |device_path_|.
169 void UnmountVolumes(const base::Closure& continuation);
170 // Starts the write after unmounting.
171 void UnmountVolumesCallback(const base::Closure& continuation, bool success);
172 // Starts the ImageBurner write. Note that target_path is the file path of
173 // the device where device_path has been a system device path.
174 void StartWriteOnUIThread(const std::string& target_path,
175 const base::Closure& continuation);
176 void OnBurnFinished(const base::Closure& continuation,
177 const std::string& target_path,
178 bool success,
179 const std::string& error);
180 void OnBurnProgress(const std::string& target_path,
181 int64 num_bytes_burnt,
182 int64 total_size);
183 void OnBurnError();
184 #endif
186 // Incrementally calculates the MD5 sum of a file.
187 void MD5Chunk(base::File file,
188 int64 bytes_processed,
189 int64 bytes_total,
190 int progress_offset,
191 int progress_scale,
192 const base::Callback<void(const std::string&)>& callback);
194 // Callbacks for zip::ZipReader.
195 void OnUnzipFailure();
196 void OnUnzipProgress(int64 total_bytes, int64 progress_bytes);
198 // Runs all cleanup functions.
199 void CleanUp();
201 // |stage_| and |progress_| are owned by the FILE thread, use |SetStage| and
202 // |SetProgress| to update. Progress should be in the interval [0,100]
203 image_writer_api::Stage stage_;
204 int progress_;
206 // MD5 contexts don't play well with smart pointers. Just going to allocate
207 // memory here. This requires that we only do one MD5 sum at a time.
208 base::MD5Context md5_context_;
210 // Zip reader for unzip operations.
211 zip::ZipReader zip_reader_;
213 // CleanUp operations that must be run. All these functions are run on the
214 // FILE thread.
215 std::vector<base::Closure> cleanup_functions_;
218 } // namespace image_writer
219 } // namespace extensions
221 #endif // CHROME_BROWSER_EXTENSIONS_API_IMAGE_WRITER_PRIVATE_OPERATION_H_