Home | History | Annotate | Download | only in imageburner
      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