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 #include "chrome/browser/extensions/api/image_writer_private/error_messages.h"
6 #include "chrome/browser/extensions/api/image_writer_private/operation.h"
7 #include "chromeos/dbus/dbus_thread_manager.h"
8 #include "chromeos/dbus/image_burner_client.h"
9 #include "chromeos/disks/disk_mount_manager.h"
10 #include "content/public/browser/browser_thread.h"
12 namespace extensions
{
13 namespace image_writer
{
15 using chromeos::disks::DiskMountManager
;
16 using chromeos::ImageBurnerClient
;
17 using content::BrowserThread
;
21 void ClearImageBurner() {
22 if (!BrowserThread::CurrentlyOn(BrowserThread::UI
)) {
23 BrowserThread::PostTask(BrowserThread::UI
,
25 base::Bind(&ClearImageBurner
));
29 chromeos::DBusThreadManager::Get()->
30 GetImageBurnerClient()->
36 void Operation::Write(const base::Closure
& continuation
) {
37 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
38 SetStage(image_writer_api::STAGE_WRITE
);
40 // Note this has to be run on the FILE thread to avoid concurrent access.
41 AddCleanUpFunction(base::Bind(&ClearImageBurner
));
43 BrowserThread::PostTask(
46 base::Bind(&Operation::UnmountVolumes
, this, continuation
));
49 void Operation::VerifyWrite(const base::Closure
& continuation
) {
50 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
52 // No verification is available in Chrome OS currently.
56 void Operation::UnmountVolumes(const base::Closure
& continuation
) {
57 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
58 DiskMountManager::GetInstance()->UnmountDeviceRecursively(
60 base::Bind(&Operation::UnmountVolumesCallback
, this, continuation
));
63 void Operation::UnmountVolumesCallback(const base::Closure
& continuation
,
65 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
68 LOG(ERROR
) << "Volume unmounting failed.";
69 Error(error::kUnmountVolumesError
);
73 const DiskMountManager::DiskMap
& disks
=
74 DiskMountManager::GetInstance()->disks();
75 DiskMountManager::DiskMap::const_iterator iter
=
76 disks
.find(device_path_
.value());
78 if (iter
== disks
.end()) {
79 LOG(ERROR
) << "Disk not found in disk list after unmounting volumes.";
80 Error(error::kUnmountVolumesError
);
84 StartWriteOnUIThread(iter
->second
->file_path(), continuation
);
87 void Operation::StartWriteOnUIThread(const std::string
& target_path
,
88 const base::Closure
& continuation
) {
89 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
91 // TODO(haven): Image Burner cannot handle multiple burns. crbug.com/373575
92 ImageBurnerClient
* burner
=
93 chromeos::DBusThreadManager::Get()->GetImageBurnerClient();
95 burner
->SetEventHandlers(
96 base::Bind(&Operation::OnBurnFinished
, this, continuation
),
97 base::Bind(&Operation::OnBurnProgress
, this));
99 burner
->BurnImage(image_path_
.value(),
101 base::Bind(&Operation::OnBurnError
, this));
104 void Operation::OnBurnFinished(const base::Closure
& continuation
,
105 const std::string
& target_path
,
107 const std::string
& error
) {
109 SetProgress(kProgressComplete
);
110 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE
, continuation
);
112 DLOG(ERROR
) << "Error encountered while burning: " << error
;
113 Error(error::kChromeOSImageBurnerError
);
117 void Operation::OnBurnProgress(const std::string
& target_path
,
118 int64 num_bytes_burnt
,
120 int progress
= kProgressComplete
* num_bytes_burnt
/ total_size
;
121 SetProgress(progress
);
124 void Operation::OnBurnError() {
125 Error(error::kChromeOSImageBurnerError
);
128 } // namespace image_writer
129 } // namespace extensions