blob: 615d0630c3106bdda7b91a00d486f3b7ad33910a [file] [log] [blame]
// 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