| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/chromeos/imageburner/burn_controller.h" |
| |
| #include "base/bind.h" |
| #include "base/files/file_path.h" |
| #include "base/memory/weak_ptr.h" |
| #include "chrome/browser/chromeos/imageburner/burn_manager.h" |
| #include "chromeos/network/network_state_handler.h" |
| #include "grit/generated_resources.h" |
| #include "url/gurl.h" |
| |
| namespace chromeos { |
| namespace imageburner { |
| |
| namespace { |
| |
| // 3.9GB. It is less than 4GB because true device size ussually varies a little. |
| const uint64 kMinDeviceSize = static_cast<uint64>(3.9 * 1000 * 1000 * 1000); |
| |
| class BurnControllerImpl |
| : public BurnController, |
| public StateMachine::Observer, |
| public BurnManager::Observer { |
| public: |
| explicit BurnControllerImpl(BurnController::Delegate* delegate) |
| : burn_manager_(NULL), |
| state_machine_(NULL), |
| working_(false), |
| delegate_(delegate) { |
| burn_manager_ = BurnManager::GetInstance(); |
| burn_manager_->AddObserver(this); |
| state_machine_ = burn_manager_->state_machine(); |
| state_machine_->AddObserver(this); |
| } |
| |
| virtual ~BurnControllerImpl() { |
| state_machine_->RemoveObserver(this); |
| burn_manager_->RemoveObserver(this); |
| } |
| |
| // BurnManager::Observer override. |
| virtual void OnDeviceAdded( |
| const disks::DiskMountManager::Disk& disk) OVERRIDE { |
| delegate_->OnDeviceAdded(disk); |
| } |
| |
| // BurnManager::Observer override. |
| virtual void OnDeviceRemoved( |
| const disks::DiskMountManager::Disk& disk) OVERRIDE { |
| delegate_->OnDeviceRemoved(disk); |
| } |
| |
| // BurnManager::Observer override. |
| virtual void OnNetworkDetected() OVERRIDE { |
| delegate_->OnNetworkDetected(); |
| } |
| |
| // BurnManager::Observer override. |
| virtual void OnSuccess() OVERRIDE { |
| delegate_->OnSuccess(); |
| // TODO(hidehiko): Remove |working_| flag. |
| working_ = false; |
| } |
| |
| // BurnManager::Observer override. |
| virtual void OnProgressWithRemainingTime( |
| ProgressType progress_type, |
| int64 received_bytes, |
| int64 total_bytes, |
| const base::TimeDelta& estimated_remaining_time) OVERRIDE { |
| delegate_->OnProgressWithRemainingTime( |
| progress_type, received_bytes, total_bytes, estimated_remaining_time); |
| } |
| |
| // BurnManager::Observer override. |
| virtual void OnProgress(ProgressType progress_type, |
| int64 received_bytes, |
| int64 total_bytes) OVERRIDE { |
| delegate_->OnProgress(progress_type, received_bytes, total_bytes); |
| } |
| |
| // StateMachine::Observer interface. |
| virtual void OnBurnStateChanged(StateMachine::State state) OVERRIDE { |
| if (state != StateMachine::INITIAL && !working_) { |
| // User has started burn process, so let's start observing. |
| StartBurnImage(base::FilePath(), base::FilePath()); |
| } |
| } |
| |
| virtual void OnError(int error_message_id) OVERRIDE { |
| delegate_->OnFail(error_message_id); |
| working_ = false; |
| } |
| |
| // BurnController override. |
| virtual void Init() OVERRIDE { |
| if (state_machine_->state() == StateMachine::BURNING) { |
| // There is nothing else left to do but observe burn progress. |
| burn_manager_->DoBurn(); |
| } else if (state_machine_->state() != StateMachine::INITIAL) { |
| // User has started burn process, so let's start observing. |
| StartBurnImage(base::FilePath(), base::FilePath()); |
| } |
| } |
| |
| // BurnController override. |
| virtual std::vector<disks::DiskMountManager::Disk> GetBurnableDevices() |
| OVERRIDE { |
| // Now this is just a proxy to the BurnManager. |
| // TODO(hidehiko): Remove this method. |
| return burn_manager_->GetBurnableDevices(); |
| } |
| |
| // BurnController override. |
| virtual void CancelBurnImage() OVERRIDE { |
| burn_manager_->Cancel(); |
| } |
| |
| // BurnController override. |
| // May be called with empty values if there is a handler that has started |
| // burning, and thus set the target paths. |
| virtual void StartBurnImage(const base::FilePath& target_device_path, |
| const base::FilePath& target_file_path) OVERRIDE { |
| if (!target_device_path.empty() && !target_file_path.empty() && |
| state_machine_->new_burn_posible()) { |
| if (!NetworkHandler::Get()->network_state_handler()->DefaultNetwork()) { |
| delegate_->OnNoNetwork(); |
| return; |
| } |
| burn_manager_->set_target_device_path(target_device_path); |
| burn_manager_->set_target_file_path(target_file_path); |
| uint64 device_size = GetDeviceSize( |
| burn_manager_->target_device_path().value()); |
| if (device_size < kMinDeviceSize) { |
| delegate_->OnDeviceTooSmall(device_size); |
| return; |
| } |
| } |
| if (working_) |
| return; |
| working_ = true; |
| // Send progress signal now so ui doesn't hang in intial state until we get |
| // config file |
| delegate_->OnProgress(DOWNLOADING, 0, 0); |
| if (burn_manager_->GetImageDir().empty()) { |
| burn_manager_->CreateImageDir(); |
| } else { |
| burn_manager_->FetchConfigFile(); |
| } |
| } |
| |
| private: |
| int64 GetDeviceSize(const std::string& device_path) { |
| disks::DiskMountManager* disk_mount_manager = |
| disks::DiskMountManager::GetInstance(); |
| const disks::DiskMountManager::Disk* disk = |
| disk_mount_manager->FindDiskBySourcePath(device_path); |
| return disk ? disk->total_size_in_bytes() : 0; |
| } |
| |
| BurnManager* burn_manager_; |
| StateMachine* state_machine_; |
| bool working_; |
| BurnController::Delegate* delegate_; |
| |
| DISALLOW_COPY_AND_ASSIGN(BurnControllerImpl); |
| }; |
| |
| } // namespace |
| |
| // static |
| BurnController* BurnController::CreateBurnController( |
| content::WebContents* web_contents, |
| Delegate* delegate) { |
| return new BurnControllerImpl(delegate); |
| } |
| |
| } // namespace imageburner |
| } // namespace chromeos |