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