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.
4
5 #include "chrome/browser/chromeos/imageburner/burn_controller.h"
6
7 #include "base/bind.h"
8 #include "base/files/file_path.h"
9 #include "base/memory/weak_ptr.h"
10 #include "chrome/browser/chromeos/imageburner/burn_manager.h"
11 #include "chromeos/network/network_state_handler.h"
12 #include "url/gurl.h"
13
14 namespace chromeos {
15 namespace imageburner {
16
17 namespace {
18
19 // 3.9GB. It is less than 4GB because true device size ussually varies a little.
20 const uint64 kMinDeviceSize = static_cast<uint64>(3.9 * 1000 * 1000 * 1000);
21
22 class BurnControllerImpl
23 : public BurnController,
24 public StateMachine::Observer,
25 public BurnManager::Observer {
26 public:
BurnControllerImpl(BurnController::Delegate * delegate)27 explicit BurnControllerImpl(BurnController::Delegate* delegate)
28 : burn_manager_(NULL),
29 state_machine_(NULL),
30 working_(false),
31 delegate_(delegate) {
32 burn_manager_ = BurnManager::GetInstance();
33 burn_manager_->AddObserver(this);
34 state_machine_ = burn_manager_->state_machine();
35 state_machine_->AddObserver(this);
36 }
37
~BurnControllerImpl()38 virtual ~BurnControllerImpl() {
39 state_machine_->RemoveObserver(this);
40 burn_manager_->RemoveObserver(this);
41 }
42
43 // BurnManager::Observer override.
OnDeviceAdded(const disks::DiskMountManager::Disk & disk)44 virtual void OnDeviceAdded(
45 const disks::DiskMountManager::Disk& disk) OVERRIDE {
46 delegate_->OnDeviceAdded(disk);
47 }
48
49 // BurnManager::Observer override.
OnDeviceRemoved(const disks::DiskMountManager::Disk & disk)50 virtual void OnDeviceRemoved(
51 const disks::DiskMountManager::Disk& disk) OVERRIDE {
52 delegate_->OnDeviceRemoved(disk);
53 }
54
55 // BurnManager::Observer override.
OnNetworkDetected()56 virtual void OnNetworkDetected() OVERRIDE {
57 delegate_->OnNetworkDetected();
58 }
59
60 // BurnManager::Observer override.
OnSuccess()61 virtual void OnSuccess() OVERRIDE {
62 delegate_->OnSuccess();
63 // TODO(hidehiko): Remove |working_| flag.
64 working_ = false;
65 }
66
67 // BurnManager::Observer override.
OnProgressWithRemainingTime(ProgressType progress_type,int64 received_bytes,int64 total_bytes,const base::TimeDelta & estimated_remaining_time)68 virtual void OnProgressWithRemainingTime(
69 ProgressType progress_type,
70 int64 received_bytes,
71 int64 total_bytes,
72 const base::TimeDelta& estimated_remaining_time) OVERRIDE {
73 delegate_->OnProgressWithRemainingTime(
74 progress_type, received_bytes, total_bytes, estimated_remaining_time);
75 }
76
77 // BurnManager::Observer override.
OnProgress(ProgressType progress_type,int64 received_bytes,int64 total_bytes)78 virtual void OnProgress(ProgressType progress_type,
79 int64 received_bytes,
80 int64 total_bytes) OVERRIDE {
81 delegate_->OnProgress(progress_type, received_bytes, total_bytes);
82 }
83
84 // StateMachine::Observer interface.
OnBurnStateChanged(StateMachine::State state)85 virtual void OnBurnStateChanged(StateMachine::State state) OVERRIDE {
86 if (state != StateMachine::INITIAL && !working_) {
87 // User has started burn process, so let's start observing.
88 StartBurnImage(base::FilePath(), base::FilePath());
89 }
90 }
91
OnError(int error_message_id)92 virtual void OnError(int error_message_id) OVERRIDE {
93 delegate_->OnFail(error_message_id);
94 working_ = false;
95 }
96
97 // BurnController override.
Init()98 virtual void Init() OVERRIDE {
99 if (state_machine_->state() == StateMachine::BURNING) {
100 // There is nothing else left to do but observe burn progress.
101 burn_manager_->DoBurn();
102 } else if (state_machine_->state() != StateMachine::INITIAL) {
103 // User has started burn process, so let's start observing.
104 StartBurnImage(base::FilePath(), base::FilePath());
105 }
106 }
107
108 // BurnController override.
GetBurnableDevices()109 virtual std::vector<disks::DiskMountManager::Disk> GetBurnableDevices()
110 OVERRIDE {
111 // Now this is just a proxy to the BurnManager.
112 // TODO(hidehiko): Remove this method.
113 return burn_manager_->GetBurnableDevices();
114 }
115
116 // BurnController override.
CancelBurnImage()117 virtual void CancelBurnImage() OVERRIDE {
118 burn_manager_->Cancel();
119 }
120
121 // BurnController override.
122 // May be called with empty values if there is a handler that has started
123 // burning, and thus set the target paths.
StartBurnImage(const base::FilePath & target_device_path,const base::FilePath & target_file_path)124 virtual void StartBurnImage(const base::FilePath& target_device_path,
125 const base::FilePath& target_file_path) OVERRIDE {
126 if (!target_device_path.empty() && !target_file_path.empty() &&
127 state_machine_->new_burn_posible()) {
128 if (!NetworkHandler::Get()->network_state_handler()->DefaultNetwork()) {
129 delegate_->OnNoNetwork();
130 return;
131 }
132 burn_manager_->set_target_device_path(target_device_path);
133 burn_manager_->set_target_file_path(target_file_path);
134 uint64 device_size = GetDeviceSize(
135 burn_manager_->target_device_path().value());
136 if (device_size < kMinDeviceSize) {
137 delegate_->OnDeviceTooSmall(device_size);
138 return;
139 }
140 }
141 if (working_)
142 return;
143 working_ = true;
144 // Send progress signal now so ui doesn't hang in intial state until we get
145 // config file
146 delegate_->OnProgress(DOWNLOADING, 0, 0);
147 if (burn_manager_->GetImageDir().empty()) {
148 burn_manager_->CreateImageDir();
149 } else {
150 burn_manager_->FetchConfigFile();
151 }
152 }
153
154 private:
GetDeviceSize(const std::string & device_path)155 int64 GetDeviceSize(const std::string& device_path) {
156 disks::DiskMountManager* disk_mount_manager =
157 disks::DiskMountManager::GetInstance();
158 const disks::DiskMountManager::Disk* disk =
159 disk_mount_manager->FindDiskBySourcePath(device_path);
160 return disk ? disk->total_size_in_bytes() : 0;
161 }
162
163 BurnManager* burn_manager_;
164 StateMachine* state_machine_;
165 bool working_;
166 BurnController::Delegate* delegate_;
167
168 DISALLOW_COPY_AND_ASSIGN(BurnControllerImpl);
169 };
170
171 } // namespace
172
173 // static
CreateBurnController(content::WebContents * web_contents,Delegate * delegate)174 BurnController* BurnController::CreateBurnController(
175 content::WebContents* web_contents,
176 Delegate* delegate) {
177 return new BurnControllerImpl(delegate);
178 }
179
180 } // namespace imageburner
181 } // namespace chromeos
182