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