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: 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 39 virtual ~BurnControllerImpl() { 40 state_machine_->RemoveObserver(this); 41 burn_manager_->RemoveObserver(this); 42 } 43 44 // BurnManager::Observer override. 45 virtual void OnDeviceAdded( 46 const disks::DiskMountManager::Disk& disk) OVERRIDE { 47 delegate_->OnDeviceAdded(disk); 48 } 49 50 // BurnManager::Observer override. 51 virtual void OnDeviceRemoved( 52 const disks::DiskMountManager::Disk& disk) OVERRIDE { 53 delegate_->OnDeviceRemoved(disk); 54 } 55 56 // BurnManager::Observer override. 57 virtual void OnNetworkDetected() OVERRIDE { 58 delegate_->OnNetworkDetected(); 59 } 60 61 // BurnManager::Observer override. 62 virtual void OnSuccess() OVERRIDE { 63 delegate_->OnSuccess(); 64 // TODO(hidehiko): Remove |working_| flag. 65 working_ = false; 66 } 67 68 // BurnManager::Observer override. 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. 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. 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 93 virtual void OnError(int error_message_id) OVERRIDE { 94 delegate_->OnFail(error_message_id); 95 working_ = false; 96 } 97 98 // BurnController override. 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. 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. 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. 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: 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 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