• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
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"
11 
12 namespace extensions {
13 namespace image_writer {
14 
15 using chromeos::disks::DiskMountManager;
16 using chromeos::ImageBurnerClient;
17 using content::BrowserThread;
18 
19 namespace {
20 
ClearImageBurner()21 void ClearImageBurner() {
22   if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
23     BrowserThread::PostTask(BrowserThread::UI,
24                             FROM_HERE,
25                             base::Bind(&ClearImageBurner));
26     return;
27   }
28 
29   chromeos::DBusThreadManager::Get()->
30       GetImageBurnerClient()->
31       ResetEventHandlers();
32 }
33 
34 }  // namespace
35 
Write(const base::Closure & continuation)36 void Operation::Write(const base::Closure& continuation) {
37   DCHECK_CURRENTLY_ON(BrowserThread::FILE);
38   SetStage(image_writer_api::STAGE_WRITE);
39 
40   // Note this has to be run on the FILE thread to avoid concurrent access.
41   AddCleanUpFunction(base::Bind(&ClearImageBurner));
42 
43   BrowserThread::PostTask(
44       BrowserThread::UI,
45       FROM_HERE,
46       base::Bind(&Operation::UnmountVolumes, this, continuation));
47 }
48 
VerifyWrite(const base::Closure & continuation)49 void Operation::VerifyWrite(const base::Closure& continuation) {
50   DCHECK_CURRENTLY_ON(BrowserThread::FILE);
51 
52   // No verification is available in Chrome OS currently.
53   continuation.Run();
54 }
55 
UnmountVolumes(const base::Closure & continuation)56 void Operation::UnmountVolumes(const base::Closure& continuation) {
57   DCHECK_CURRENTLY_ON(BrowserThread::UI);
58   DiskMountManager::GetInstance()->UnmountDeviceRecursively(
59       device_path_.value(),
60       base::Bind(&Operation::UnmountVolumesCallback, this, continuation));
61 }
62 
UnmountVolumesCallback(const base::Closure & continuation,bool success)63 void Operation::UnmountVolumesCallback(const base::Closure& continuation,
64                                        bool success) {
65   DCHECK_CURRENTLY_ON(BrowserThread::UI);
66 
67   if (!success) {
68     LOG(ERROR) << "Volume unmounting failed.";
69     Error(error::kUnmountVolumesError);
70     return;
71   }
72 
73   const DiskMountManager::DiskMap& disks =
74       DiskMountManager::GetInstance()->disks();
75   DiskMountManager::DiskMap::const_iterator iter =
76       disks.find(device_path_.value());
77 
78   if (iter == disks.end()) {
79     LOG(ERROR) << "Disk not found in disk list after unmounting volumes.";
80     Error(error::kUnmountVolumesError);
81     return;
82   }
83 
84   StartWriteOnUIThread(iter->second->file_path(), continuation);
85 }
86 
StartWriteOnUIThread(const std::string & target_path,const base::Closure & continuation)87 void Operation::StartWriteOnUIThread(const std::string& target_path,
88                                      const base::Closure& continuation) {
89   DCHECK_CURRENTLY_ON(BrowserThread::UI);
90 
91   // TODO(haven): Image Burner cannot handle multiple burns. crbug.com/373575
92   ImageBurnerClient* burner =
93       chromeos::DBusThreadManager::Get()->GetImageBurnerClient();
94 
95   burner->SetEventHandlers(
96       base::Bind(&Operation::OnBurnFinished, this, continuation),
97       base::Bind(&Operation::OnBurnProgress, this));
98 
99   burner->BurnImage(image_path_.value(),
100                     target_path,
101                     base::Bind(&Operation::OnBurnError, this));
102 }
103 
OnBurnFinished(const base::Closure & continuation,const std::string & target_path,bool success,const std::string & error)104 void Operation::OnBurnFinished(const base::Closure& continuation,
105                                const std::string& target_path,
106                                bool success,
107                                const std::string& error) {
108   if (success) {
109     SetProgress(kProgressComplete);
110     BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, continuation);
111   } else {
112     DLOG(ERROR) << "Error encountered while burning: " << error;
113     Error(error::kChromeOSImageBurnerError);
114   }
115 }
116 
OnBurnProgress(const std::string & target_path,int64 num_bytes_burnt,int64 total_size)117 void Operation::OnBurnProgress(const std::string& target_path,
118                                int64 num_bytes_burnt,
119                                int64 total_size) {
120   int progress = kProgressComplete * num_bytes_burnt / total_size;
121   SetProgress(progress);
122 }
123 
OnBurnError()124 void Operation::OnBurnError() {
125   Error(error::kChromeOSImageBurnerError);
126 }
127 
128 }  // namespace image_writer
129 }  // namespace extensions
130