Revert 168224 - Update V8 to version 3.15.4.
[chromium-blink-merge.git] / chrome / browser / chromeos / imageburner / burn_controller.cc
blobcef84d983ff2dc8a1e596a58aee0f0303c460650
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 #include "chrome/browser/chromeos/imageburner/burn_controller.h"
7 #include "base/bind.h"
8 #include "base/file_path.h"
9 #include "base/memory/weak_ptr.h"
10 #include "chrome/browser/chromeos/cros/burn_library.h"
11 #include "chrome/browser/chromeos/cros/cros_library.h"
12 #include "chrome/browser/chromeos/cros/network_library.h"
13 #include "chrome/browser/chromeos/imageburner/burn_manager.h"
14 #include "grit/generated_resources.h"
15 #include "googleurl/src/gurl.h"
17 namespace chromeos {
18 namespace imageburner {
20 namespace {
22 const char kImageZipFileName[] = "chromeos_image.bin.zip";
24 // 3.9GB. It is less than 4GB because true device size ussually varies a little.
25 const uint64 kMinDeviceSize = static_cast<uint64>(3.9 * 1000 * 1000 * 1000);
27 // Returns true when |disk| is a device on which we can burn recovery image.
28 bool IsBurnableDevice(const disks::DiskMountManager::Disk& disk) {
29 return disk.is_parent() && !disk.on_boot_device() && disk.has_media() &&
30 (disk.device_type() == DEVICE_TYPE_USB ||
31 disk.device_type() == DEVICE_TYPE_SD);
34 class BurnControllerImpl
35 : public BurnController,
36 public disks::DiskMountManager::Observer,
37 public BurnLibrary::Observer,
38 public NetworkLibrary::NetworkManagerObserver,
39 public StateMachine::Observer,
40 public BurnManager::Delegate,
41 public BurnManager::Observer {
42 public:
43 explicit BurnControllerImpl(BurnController::Delegate* delegate)
44 : burn_manager_(NULL),
45 state_machine_(NULL),
46 observing_burn_lib_(false),
47 working_(false),
48 delegate_(delegate) {
49 disks::DiskMountManager::GetInstance()->AddObserver(this);
50 CrosLibrary::Get()->GetNetworkLibrary()->AddNetworkManagerObserver(this);
51 burn_manager_ = BurnManager::GetInstance();
52 burn_manager_->AddObserver(this);
53 state_machine_ = burn_manager_->state_machine();
54 state_machine_->AddObserver(this);
57 virtual ~BurnControllerImpl() {
58 CrosLibrary::Get()->GetBurnLibrary()->RemoveObserver(this);
59 if (state_machine_)
60 state_machine_->RemoveObserver(this);
61 burn_manager_->RemoveObserver(this);
62 CrosLibrary::Get()->GetNetworkLibrary()->RemoveNetworkManagerObserver(this);
63 disks::DiskMountManager::GetInstance()->RemoveObserver(this);
66 // disks::DiskMountManager::Observer interface.
67 virtual void OnDiskEvent(disks::DiskMountManager::DiskEvent event,
68 const disks::DiskMountManager::Disk* disk) OVERRIDE {
69 if (!IsBurnableDevice(*disk))
70 return;
71 if (event == disks::DiskMountManager::DISK_ADDED) {
72 delegate_->OnDeviceAdded(*disk);
73 } else if (event == disks::DiskMountManager::DISK_REMOVED) {
74 delegate_->OnDeviceRemoved(*disk);
75 if (burn_manager_->target_device_path().value() == disk->device_path())
76 ProcessError(IDS_IMAGEBURN_DEVICE_NOT_FOUND_ERROR);
80 virtual void OnDeviceEvent(disks::DiskMountManager::DeviceEvent event,
81 const std::string& device_path) OVERRIDE {
84 virtual void OnMountEvent(
85 disks::DiskMountManager::MountEvent event,
86 MountError error_code,
87 const disks::DiskMountManager::MountPointInfo& mount_info) OVERRIDE {
90 virtual void OnFormatEvent(
91 disks::DiskMountManager::FormatEvent event,
92 FormatError error_code,
93 const std::string& device_path) OVERRIDE {
96 // BurnLibrary::Observer interface.
97 virtual void BurnProgressUpdated(BurnLibrary* object,
98 BurnEvent evt,
99 const ImageBurnStatus& status) OVERRIDE {
100 switch (evt) {
101 case(BURN_SUCCESS):
102 FinalizeBurn();
103 break;
104 case(BURN_FAIL):
105 ProcessError(IDS_IMAGEBURN_BURN_ERROR);
106 break;
107 case(BURN_UPDATE):
108 delegate_->OnProgress(BURNING, status.amount_burnt, status.total_size);
109 break;
110 case(UNZIP_STARTED):
111 delegate_->OnProgress(UNZIPPING, 0, 0);
112 break;
113 case(UNZIP_FAIL):
114 ProcessError(IDS_IMAGEBURN_EXTRACTING_ERROR);
115 break;
116 case(UNZIP_COMPLETE):
117 // We ignore this.
118 break;
119 default:
120 NOTREACHED();
121 break;
125 // NetworkLibrary::NetworkManagerObserver interface.
126 virtual void OnNetworkManagerChanged(NetworkLibrary* obj) OVERRIDE {
127 if (state_machine_->state() == StateMachine::INITIAL && CheckNetwork())
128 delegate_->OnNetworkDetected();
130 if (state_machine_->state() == StateMachine::DOWNLOADING &&
131 !CheckNetwork())
132 ProcessError(IDS_IMAGEBURN_NETWORK_ERROR);
135 // BurnManager::Observer override.
136 virtual void OnDownloadUpdated(
137 int64 received_bytes,
138 int64 total_bytes,
139 const base::TimeDelta& time_remaining) OVERRIDE {
140 if (state_machine_->state() == StateMachine::DOWNLOADING) {
141 delegate_->OnProgressWithRemainingTime(DOWNLOADING,
142 received_bytes,
143 total_bytes,
144 time_remaining);
148 // BurnManager::Observer override.
149 virtual void OnDownloadCancelled() OVERRIDE {
150 DownloadCompleted(false);
153 // BurnManager::Observer override.
154 virtual void OnDownloadCompleted() OVERRIDE {
155 DownloadCompleted(true);
158 // StateMachine::Observer interface.
159 virtual void OnBurnStateChanged(StateMachine::State state) OVERRIDE {
160 if (state == StateMachine::CANCELLED) {
161 ProcessError(IDS_IMAGEBURN_USER_ERROR);
162 } else if (state != StateMachine::INITIAL && !working_) {
163 // User has started burn process, so let's start observing.
164 StartBurnImage(FilePath(), FilePath());
168 virtual void OnError(int error_message_id) OVERRIDE {
169 delegate_->OnFail(error_message_id);
170 working_ = false;
173 // Part of BurnManager::Delegate interface.
174 virtual void OnImageDirCreated(bool success) OVERRIDE {
175 if (success) {
176 zip_image_file_path_ =
177 burn_manager_->GetImageDir().Append(kImageZipFileName);
178 burn_manager_->FetchConfigFile(this);
179 } else {
180 DownloadCompleted(success);
184 // Part of BurnManager::Delegate interface.
185 virtual void OnConfigFileFetched(bool success,
186 const std::string& image_file_name,
187 const GURL& image_download_url) OVERRIDE {
188 if (!success) {
189 DownloadCompleted(false);
190 return;
192 image_file_name_ = image_file_name;
194 if (state_machine_->download_finished()) {
195 BurnImage();
196 return;
199 if (!state_machine_->download_started()) {
200 burn_manager_->FetchImage(image_download_url, zip_image_file_path_);
201 state_machine_->OnDownloadStarted();
205 // BurnController override.
206 virtual void Init() OVERRIDE {
207 if (state_machine_->state() == StateMachine::BURNING) {
208 // There is nothing else left to do but observe burn progress.
209 BurnImage();
210 } else if (state_machine_->state() != StateMachine::INITIAL) {
211 // User has started burn process, so let's start observing.
212 StartBurnImage(FilePath(), FilePath());
216 // BurnController override.
217 virtual std::vector<disks::DiskMountManager::Disk> GetBurnableDevices()
218 OVERRIDE {
219 const disks::DiskMountManager::DiskMap& disks =
220 disks::DiskMountManager::GetInstance()->disks();
221 std::vector<disks::DiskMountManager::Disk> result;
222 for (disks::DiskMountManager::DiskMap::const_iterator iter = disks.begin();
223 iter != disks.end();
224 ++iter) {
225 const disks::DiskMountManager::Disk& disk = *iter->second;
226 if (IsBurnableDevice(disk))
227 result.push_back(disk);
229 return result;
232 // BurnController override.
233 virtual void CancelBurnImage() OVERRIDE {
234 state_machine_->OnCancelation();
237 // BurnController override.
238 // May be called with empty values if there is a handler that has started
239 // burning, and thus set the target paths.
240 virtual void StartBurnImage(const FilePath& target_device_path,
241 const FilePath& target_file_path) OVERRIDE {
242 if (!target_device_path.empty() && !target_file_path.empty() &&
243 state_machine_->new_burn_posible()) {
244 if (!CheckNetwork()) {
245 delegate_->OnNoNetwork();
246 return;
248 burn_manager_->set_target_device_path(target_device_path);
249 burn_manager_->set_target_file_path(target_file_path);
250 uint64 device_size = GetDeviceSize(
251 burn_manager_->target_device_path().value());
252 if (device_size < kMinDeviceSize) {
253 delegate_->OnDeviceTooSmall(device_size);
254 return;
257 if (working_)
258 return;
259 working_ = true;
260 // Send progress signal now so ui doesn't hang in intial state until we get
261 // config file
262 delegate_->OnProgress(DOWNLOADING, 0, 0);
263 if (burn_manager_->GetImageDir().empty()) {
264 burn_manager_->CreateImageDir(this);
265 } else {
266 OnImageDirCreated(true);
270 private:
271 void DownloadCompleted(bool success) {
272 if (success) {
273 state_machine_->OnDownloadFinished();
274 BurnImage();
275 } else {
276 ProcessError(IDS_IMAGEBURN_DOWNLOAD_ERROR);
280 void BurnImage() {
281 if (!observing_burn_lib_) {
282 CrosLibrary::Get()->GetBurnLibrary()->AddObserver(this);
283 observing_burn_lib_ = true;
285 if (state_machine_->state() == StateMachine::BURNING)
286 return;
287 state_machine_->OnBurnStarted();
289 CrosLibrary::Get()->GetBurnLibrary()->DoBurn(
290 zip_image_file_path_,
291 image_file_name_, burn_manager_->target_file_path(),
292 burn_manager_->target_device_path());
295 void FinalizeBurn() {
296 state_machine_->OnSuccess();
297 burn_manager_->ResetTargetPaths();
298 CrosLibrary::Get()->GetBurnLibrary()->RemoveObserver(this);
299 observing_burn_lib_ = false;
300 delegate_->OnSuccess();
301 working_ = false;
304 // Error is ussually detected by all existing Burn handlers, but only first
305 // one that calls ProcessError should actually process it.
306 void ProcessError(int message_id) {
307 // If we are in intial state, error has already been dispached.
308 if (state_machine_->state() == StateMachine::INITIAL) {
309 // We don't need burn library since we are not the ones doing the cleanup.
310 if (observing_burn_lib_) {
311 CrosLibrary::Get()->GetBurnLibrary()->RemoveObserver(this);
312 observing_burn_lib_ = false;
314 return;
317 // Remember burner state, since it will be reset after OnError call.
318 StateMachine::State state = state_machine_->state();
320 // Dispach error. All hadlers' OnError event will be called before returning
321 // from this. This includes us, too.
322 state_machine_->OnError(message_id);
324 // Do cleanup.
325 if (state == StateMachine::DOWNLOADING) {
326 burn_manager_->CancelImageFetch();
327 } else if (state == StateMachine::BURNING) {
328 DCHECK(observing_burn_lib_);
329 // Burn library doesn't send cancelled signal upon CancelBurnImage
330 // invokation.
331 CrosLibrary::Get()->GetBurnLibrary()->CancelBurnImage();
332 CrosLibrary::Get()->GetBurnLibrary()->RemoveObserver(this);
333 observing_burn_lib_ = false;
335 burn_manager_->ResetTargetPaths();
338 int64 GetDeviceSize(const std::string& device_path) {
339 disks::DiskMountManager* disk_mount_manager =
340 disks::DiskMountManager::GetInstance();
341 const disks::DiskMountManager::Disk* disk =
342 disk_mount_manager->FindDiskBySourcePath(device_path);
343 return disk ? disk->total_size_in_bytes() : 0;
346 bool CheckNetwork() {
347 return CrosLibrary::Get()->GetNetworkLibrary()->Connected();
350 FilePath zip_image_file_path_;
351 std::string image_file_name_;
352 BurnManager* burn_manager_;
353 StateMachine* state_machine_;
354 bool observing_burn_lib_;
355 bool working_;
356 BurnController::Delegate* delegate_;
358 DISALLOW_COPY_AND_ASSIGN(BurnControllerImpl);
361 } // namespace
363 // static
364 BurnController* BurnController::CreateBurnController(
365 content::WebContents* web_contents,
366 Delegate* delegate) {
367 return new BurnControllerImpl(delegate);
370 } // namespace imageburner
371 } // namespace chromeos