burn_library.cc revision ddb351dbec246cf1fab5ec20d2d5520909041de1
1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Use of this source code is governed by a BSD-style license that can be 3bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// found in the LICENSE file. 4bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 5bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/chromeos/cros/burn_library.h" 6bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 7bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include <cstring> 8ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/linked_ptr.h" 9bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/chromeos/cros/cros_library.h" 10dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h" 11bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 12bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsennamespace chromeos { 13bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 1472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenclass BurnLibraryImpl : public BurnLibrary, 1572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen public base::SupportsWeakPtr<BurnLibraryImpl> { 1672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen public: 1772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 1872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen BurnLibraryImpl(); 1972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual ~BurnLibraryImpl(); 2072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 2172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // BurnLibrary implementation. 2272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual void AddObserver(Observer* observer); 2372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual void RemoveObserver(Observer* observer); 2472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual bool DoBurn(const FilePath& from_path, const FilePath& to_path); 2572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 2672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen bool BurnImage(const FilePath& from_path, const FilePath& to_path); 2772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen void UpdateBurnStatus(const ImageBurnStatus& status, BurnEventType evt); 2872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 2972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen private: 3072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen void Init(); 3172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen static void BurnStatusChangedHandler(void* object, 3272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const BurnStatus& status, 3372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen BurnEventType evt); 3472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 3572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen private: 3672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ObserverList<BurnLibrary::Observer> observers_; 3772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen BurnStatusConnection burn_status_connection_; 3872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 3972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Holds a path that is currently being burnt to. 4072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::string target_path_; 4172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 4272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DISALLOW_COPY_AND_ASSIGN(BurnLibraryImpl); 4372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}; 4472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 4572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenclass BurnLibraryTaskProxy 4672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen : public base::RefCountedThreadSafe<BurnLibraryTaskProxy> { 4772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen public: 4872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen explicit BurnLibraryTaskProxy(const base::WeakPtr<BurnLibraryImpl>& library); 4972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 5072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen void BurnImage(const FilePath& from_path, const FilePath& to_path); 5172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 5272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen void UpdateBurnStatus(ImageBurnStatus* status, BurnEventType evt); 5372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 5472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen private: 5572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::WeakPtr<BurnLibraryImpl> library_; 5672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 5772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen friend class base::RefCountedThreadSafe<BurnLibraryTaskProxy>; 5872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 5972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DISALLOW_COPY_AND_ASSIGN(BurnLibraryTaskProxy); 6072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}; 6172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 62bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian MonsenBurnLibraryImpl::BurnLibraryImpl() { 63bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (CrosLibrary::Get()->EnsureLoaded()) { 64bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen Init(); 65bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } else { 66bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen LOG(ERROR) << "Cros Library has not been loaded"; 67bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 68bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 69bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 70bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian MonsenBurnLibraryImpl::~BurnLibraryImpl() { 71bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (burn_status_connection_) { 72bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen DisconnectBurnStatus(burn_status_connection_); 73bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 74bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 75bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 76bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid BurnLibraryImpl::AddObserver(Observer* observer) { 77bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen observers_.AddObserver(observer); 78bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 79bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 80bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid BurnLibraryImpl::RemoveObserver(Observer* observer) { 81bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen observers_.RemoveObserver(observer); 82bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 83bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 84bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenbool BurnLibraryImpl::DoBurn(const FilePath& from_path, 85bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen const FilePath& to_path) { 86bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen BurnLibraryTaskProxy* task = new BurnLibraryTaskProxy(AsWeakPtr()); 87bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen task->AddRef(); 88bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen task->BurnImage(from_path, to_path); 89731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 90bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen NewRunnableMethod(task, &BurnLibraryTaskProxy::BurnImage, 91bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen from_path, to_path)); 92bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return true; 93bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 94bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 95bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenbool BurnLibraryImpl::BurnImage(const FilePath& from_path, 96bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen const FilePath& to_path) { 97bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // Make sure we run on file thread. 98731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 99bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 100bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // Check if there is a target path already being burnt to. 101bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (target_path_ == "") { 102bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen target_path_ = to_path.value(); 103bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } else { 104bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return false; 105bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 106bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 107bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen StartBurn(from_path.value().c_str(), to_path.value().c_str(), 108bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen burn_status_connection_); 109bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return true; 110bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 111bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 112bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid BurnLibraryImpl::BurnStatusChangedHandler(void* object, 113bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen const BurnStatus& status, 114bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen BurnEventType evt) { 115bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen BurnLibraryImpl* burn = static_cast<BurnLibraryImpl*>(object); 116bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 117bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // Copy burn status because it will be freed after returning from this method. 118bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen ImageBurnStatus* status_copy = new ImageBurnStatus(status); 119bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 120bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen BurnLibraryTaskProxy* task = new BurnLibraryTaskProxy(burn->AsWeakPtr()); 121bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen task->AddRef(); 122731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 123bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen NewRunnableMethod(task, &BurnLibraryTaskProxy::UpdateBurnStatus, 124bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen status_copy, evt)); 125bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 126bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 127bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid BurnLibraryImpl::Init() { 128bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen burn_status_connection_ = MonitorBurnStatus(&BurnStatusChangedHandler, this); 129bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 130bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 131bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid BurnLibraryImpl::UpdateBurnStatus(const ImageBurnStatus& status, 132bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen BurnEventType evt) { 133bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // Make sure we run on UI thread. 134731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 135bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 136bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // If burn is finished, remove target paths from paths being burnt to. 137bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // This has to be done in thread-safe way, hence using task proxy class. 138bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if ((evt == BURN_CANCELED || evt == BURN_COMPLETE) && 139bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen target_path_ == status.target_path) 140bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen target_path_ = ""; 141bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 142bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen FOR_EACH_OBSERVER(Observer, observers_, ProgressUpdated(this, evt, status)); 143bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 144bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 145bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian MonsenBurnLibraryTaskProxy::BurnLibraryTaskProxy( 146bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen const base::WeakPtr<BurnLibraryImpl>& library) 147bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen : library_(library) { 148bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 149bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 150bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid BurnLibraryTaskProxy::BurnImage(const FilePath& from_path, 151bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen const FilePath& to_path) { 152bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen library_->BurnImage(from_path, to_path); 153bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 154bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 155bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid BurnLibraryTaskProxy::UpdateBurnStatus(ImageBurnStatus* status, 156bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen BurnEventType evt) { 157bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen library_->UpdateBurnStatus(*status, evt); 158bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen delete status; 159bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 160bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 161bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 162bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenclass BurnLibraryStubImpl : public BurnLibrary { 163bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen public: 164bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen BurnLibraryStubImpl() {} 165bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen virtual ~BurnLibraryStubImpl() {} 166bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 167bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // BurnLibrary overrides. 168bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen virtual void AddObserver(Observer* observer) {} 169bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen virtual void RemoveObserver(Observer* observer) {} 170bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen virtual bool DoBurn(const FilePath& from_path, const FilePath& to_path) { 171bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return false; 172bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 173bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 174bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen DISALLOW_COPY_AND_ASSIGN(BurnLibraryStubImpl); 175bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}; 176bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 177bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// static 178bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian MonsenBurnLibrary* BurnLibrary::GetImpl(bool stub) { 179bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (stub) 180bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return new BurnLibraryStubImpl(); 181bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen else 182bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return new BurnLibraryImpl(); 183bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 184bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 185bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} // namespace chromeos 186bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 187bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Allows InvokeLater without adding refcounting. This class is a Singleton and 188bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// won't be deleted until it's last InvokeLater is run. 189bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian MonsenDISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::BurnLibraryImpl); 190bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 191