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
|
// Copyright 2013 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_EXTENSIONS_API_IMAGE_WRITER_PRIVATE_OPERATION_H_
#define CHROME_BROWSER_EXTENSIONS_API_IMAGE_WRITER_PRIVATE_OPERATION_H_
#include "base/callback.h"
#include "base/md5.h"
#include "base/memory/ref_counted_memory.h"
#include "base/memory/weak_ptr.h"
#include "base/task/cancelable_task_tracker.h"
#include "base/timer/timer.h"
#include "chrome/browser/extensions/api/image_writer_private/image_writer_utils.h"
#include "chrome/common/extensions/api/image_writer_private.h"
#include "third_party/zlib/google/zip_reader.h"
namespace image_writer_api = extensions::api::image_writer_private;
namespace base {
class FilePath;
} // namespace base
namespace extensions {
namespace image_writer {
const int kProgressComplete = 100;
class OperationManager;
// Encapsulates an operation being run on behalf of the
// OperationManager. Construction of the operation does not start
// anything. The operation's Start method should be called to start it, and
// then the Cancel method will stop it. The operation will call back to the
// OperationManager periodically or on any significant event.
//
// Each stage of the operation is generally divided into three phases: Start,
// Run, Complete. Start and Complete run on the UI thread and are responsible
// for advancing to the next stage and other UI interaction. The Run phase does
// the work on the FILE thread and calls SendProgress or Error as appropriate.
class Operation : public base::RefCountedThreadSafe<Operation> {
public:
typedef base::Callback<void(bool, const std::string&)> StartWriteCallback;
typedef base::Callback<void(bool, const std::string&)> CancelWriteCallback;
typedef std::string ExtensionId;
Operation(base::WeakPtr<OperationManager> manager,
const ExtensionId& extension_id,
const std::string& storage_unit_id);
// Starts the operation.
virtual void Start() = 0;
// Cancel the operation. This must be called to clean up internal state and
// cause the the operation to actually stop. It will not be destroyed until
// all callbacks have completed.
void Cancel();
// Aborts the operation, cancelling it and generating an error.
void Abort();
// Informational getters.
int GetProgress();
image_writer_api::Stage GetStage();
protected:
virtual ~Operation();
// Generates an error.
// |error_message| is used to create an OnWriteError event which is
// sent to the extension
virtual void Error(const std::string& error_message);
// Set |progress_| and send an event. Progress should be in the interval
// [0,100]
void SetProgress(int progress);
// Change to a new |stage_| and set |progress_| to zero. Triggers a progress
// event.
void SetStage(image_writer_api::Stage stage);
// Can be queried to safely determine if the operation has been cancelled.
bool IsCancelled();
// Adds a callback that will be called during clean-up, whether the operation
// is aborted, encounters and error, or finishes successfully. These
// functions will be run on the FILE thread.
void AddCleanUpFunction(base::Closure);
void UnzipStart(scoped_ptr<base::FilePath> zip_file);
void WriteStart();
void VerifyWriteStart();
void Finish();
// If |file_size| is non-zero, only |file_size| bytes will be read from file,
// otherwise the entire file will be read.
// |progress_scale| is a percentage to which the progress will be scale, e.g.
// a scale of 50 means it will increment from 0 to 50 over the course of the
// sum. |progress_offset| is an percentage that will be added to the progress
// of the MD5 sum before updating |progress_| but after scaling.
void GetMD5SumOfFile(
scoped_ptr<base::FilePath> file,
int64 file_size,
int progress_offset,
int progress_scale,
const base::Callback<void(scoped_ptr<std::string>)>& callback);
base::WeakPtr<OperationManager> manager_;
const ExtensionId extension_id_;
base::FilePath image_path_;
const std::string storage_unit_id_;
// Whether or not to run the final verification step.
bool verify_write_;
private:
friend class base::RefCountedThreadSafe<Operation>;
// TODO(haven): Clean up these switches. http://crbug.com/292956
#if defined(OS_LINUX) && !defined(CHROMEOS)
void WriteRun();
void WriteChunk(scoped_ptr<image_writer_utils::ImageReader> reader,
scoped_ptr<image_writer_utils::ImageWriter> writer,
int64 bytes_written);
bool WriteCleanUp(scoped_ptr<image_writer_utils::ImageReader> reader,
scoped_ptr<image_writer_utils::ImageWriter> writer);
void WriteComplete();
void VerifyWriteStage2(scoped_ptr<std::string> image_hash);
void VerifyWriteCompare(scoped_ptr<std::string> image_hash,
scoped_ptr<std::string> device_hash);
#endif
#if defined(OS_CHROMEOS)
void StartWriteOnUIThread();
void OnBurnFinished(const std::string& target_path,
bool success,
const std::string& error);
void OnBurnProgress(const std::string& target_path,
int64 num_bytes_burnt,
int64 total_size);
void OnBurnError();
#endif
// Incrementally calculates the MD5 sum of a file.
void MD5Chunk(scoped_ptr<image_writer_utils::ImageReader> reader,
int64 bytes_processed,
int64 bytes_total,
int progress_offset,
int progress_scale,
const base::Callback<void(scoped_ptr<std::string>)>& callback);
// Callbacks for zip::ZipReader.
void OnUnzipSuccess();
void OnUnzipFailure();
void OnUnzipProgress(int64 total_bytes, int64 progress_bytes);
// Runs all cleanup functions.
void CleanUp();
// |stage_| and |progress_| are owned by the FILE thread, use |SetStage| and
// |SetProgress| to update. Progress should be in the interval [0,100]
image_writer_api::Stage stage_;
int progress_;
// MD5 contexts don't play well with smart pointers. Just going to allocate
// memory here. This requires that we only do one MD5 sum at a time.
base::MD5Context md5_context_;
// Zip reader for unzip operations.
zip::ZipReader zip_reader_;
// CleanUp operations that must be run. All these functions are run on the
// FILE thread.
std::vector<base::Closure> cleanup_functions_;
};
} // namespace image_writer
} // namespace extensions
#endif // CHROME_BROWSER_EXTENSIONS_API_IMAGE_WRITER_PRIVATE_OPERATION_H_
|