Home | History | Annotate | Download | only in storage_monitor
      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/storage_monitor/storage_monitor.h"
      6 
      7 #include "base/stl_util.h"
      8 #include "base/strings/utf_string_conversions.h"
      9 #include "chrome/browser/browser_process.h"
     10 #include "chrome/browser/storage_monitor/removable_storage_observer.h"
     11 #include "chrome/browser/storage_monitor/transient_device_ids.h"
     12 
     13 namespace chrome {
     14 
     15 StorageMonitor::Receiver::~Receiver() {
     16 }
     17 
     18 class StorageMonitor::ReceiverImpl : public StorageMonitor::Receiver {
     19  public:
     20   explicit ReceiverImpl(StorageMonitor* notifications)
     21       : notifications_(notifications) {}
     22 
     23   virtual ~ReceiverImpl() {}
     24 
     25   virtual void ProcessAttach(const StorageInfo& info) OVERRIDE;
     26 
     27   virtual void ProcessDetach(const std::string& id) OVERRIDE;
     28 
     29   virtual void MarkInitialized() OVERRIDE;
     30 
     31  private:
     32   StorageMonitor* notifications_;
     33 };
     34 
     35 void StorageMonitor::ReceiverImpl::ProcessAttach(const StorageInfo& info) {
     36   notifications_->ProcessAttach(info);
     37 }
     38 
     39 void StorageMonitor::ReceiverImpl::ProcessDetach(const std::string& id) {
     40   notifications_->ProcessDetach(id);
     41 }
     42 
     43 void StorageMonitor::ReceiverImpl::MarkInitialized() {
     44   notifications_->MarkInitialized();
     45 }
     46 
     47 StorageMonitor* StorageMonitor::GetInstance() {
     48   if (g_browser_process)
     49     return g_browser_process->storage_monitor();
     50 
     51   return NULL;
     52 }
     53 
     54 std::vector<StorageInfo> StorageMonitor::GetAllAvailableStorages() const {
     55   std::vector<StorageInfo> results;
     56 
     57   base::AutoLock lock(storage_lock_);
     58   for (StorageMap::const_iterator it = storage_map_.begin();
     59        it != storage_map_.end();
     60        ++it) {
     61     results.push_back(it->second);
     62   }
     63   return results;
     64 }
     65 
     66 void StorageMonitor::EnsureInitialized(base::Closure callback) {
     67   DCHECK(thread_checker_.CalledOnValidThread());
     68   if (initialized_) {
     69     if (!callback.is_null())
     70       callback.Run();
     71     return;
     72   }
     73 
     74   if (!callback.is_null()) {
     75     on_initialize_callbacks_.push_back(callback);
     76   }
     77 
     78   if (initializing_)
     79     return;
     80 
     81   initializing_ = true;
     82   Init();
     83 }
     84 
     85 bool StorageMonitor::IsInitialized() {
     86   return initialized_;
     87 }
     88 
     89 void StorageMonitor::AddObserver(RemovableStorageObserver* obs) {
     90   observer_list_->AddObserver(obs);
     91 }
     92 
     93 void StorageMonitor::RemoveObserver(
     94     RemovableStorageObserver* obs) {
     95   observer_list_->RemoveObserver(obs);
     96 }
     97 
     98 std::string StorageMonitor::GetTransientIdForDeviceId(
     99     const std::string& device_id) {
    100   return transient_device_ids_->GetTransientIdForDeviceId(device_id);
    101 }
    102 
    103 std::string StorageMonitor::GetDeviceIdForTransientId(
    104     const std::string& transient_id) const {
    105   return transient_device_ids_->DeviceIdFromTransientId(transient_id);
    106 }
    107 
    108 void StorageMonitor::EjectDevice(
    109     const std::string& device_id,
    110     base::Callback<void(EjectStatus)> callback) {
    111   // Platform-specific implementations will override this method to
    112   // perform actual device ejection.
    113   callback.Run(EJECT_FAILURE);
    114 }
    115 
    116 StorageMonitor::StorageMonitor()
    117     : observer_list_(new ObserverListThreadSafe<RemovableStorageObserver>()),
    118       initializing_(false),
    119       initialized_(false),
    120       transient_device_ids_(new TransientDeviceIds) {
    121   receiver_.reset(new ReceiverImpl(this));
    122 }
    123 
    124 StorageMonitor::~StorageMonitor() {
    125 }
    126 
    127 StorageMonitor::Receiver* StorageMonitor::receiver() const {
    128   return receiver_.get();
    129 }
    130 
    131 void StorageMonitor::MarkInitialized() {
    132   initialized_ = true;
    133   for (std::vector<base::Closure>::iterator iter =
    134            on_initialize_callbacks_.begin();
    135        iter != on_initialize_callbacks_.end(); ++iter) {
    136     iter->Run();
    137   }
    138   on_initialize_callbacks_.clear();
    139 }
    140 
    141 void StorageMonitor::ProcessAttach(const StorageInfo& info) {
    142   {
    143     base::AutoLock lock(storage_lock_);
    144     if (ContainsKey(storage_map_, info.device_id())) {
    145       // This can happen if our unique id scheme fails. Ignore the incoming
    146       // non-unique attachment.
    147       return;
    148     }
    149     storage_map_.insert(std::make_pair(info.device_id(), info));
    150   }
    151 
    152   DVLOG(1) << "StorageAttached with name " << UTF16ToUTF8(info.name())
    153            << " and id " << info.device_id();
    154   if (StorageInfo::IsRemovableDevice(info.device_id())) {
    155     observer_list_->Notify(
    156         &RemovableStorageObserver::OnRemovableStorageAttached, info);
    157   }
    158 }
    159 
    160 void StorageMonitor::ProcessDetach(const std::string& id) {
    161   StorageInfo info;
    162   {
    163     base::AutoLock lock(storage_lock_);
    164     StorageMap::iterator it = storage_map_.find(id);
    165     if (it == storage_map_.end())
    166       return;
    167     info = it->second;
    168     storage_map_.erase(it);
    169   }
    170 
    171   DVLOG(1) << "StorageDetached for id " << id;
    172   if (StorageInfo::IsRemovableDevice(info.device_id())) {
    173     observer_list_->Notify(
    174         &RemovableStorageObserver::OnRemovableStorageDetached, info);
    175   }
    176 }
    177 
    178 }  // namespace chrome
    179