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 ~Receiver()13StorageMonitor::Receiver::~Receiver() { 14 } 15 16 class StorageMonitor::ReceiverImpl : public StorageMonitor::Receiver { 17 public: ReceiverImpl(StorageMonitor * notifications)18 explicit ReceiverImpl(StorageMonitor* notifications) 19 : notifications_(notifications) {} 20 ~ReceiverImpl()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 ProcessAttach(const StorageInfo & info)33void StorageMonitor::ReceiverImpl::ProcessAttach(const StorageInfo& info) { 34 notifications_->ProcessAttach(info); 35 } 36 ProcessDetach(const std::string & id)37void StorageMonitor::ReceiverImpl::ProcessDetach(const std::string& id) { 38 notifications_->ProcessDetach(id); 39 } 40 MarkInitialized()41void StorageMonitor::ReceiverImpl::MarkInitialized() { 42 notifications_->MarkInitialized(); 43 } 44 GetInstance()45StorageMonitor* StorageMonitor::GetInstance() { 46 if (g_browser_process) 47 return g_browser_process->storage_monitor(); 48 49 return NULL; 50 } 51 GetAllAvailableStorages() const52std::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 EnsureInitialized(base::Closure callback)64void 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 IsInitialized() const83bool StorageMonitor::IsInitialized() const { 84 return initialized_; 85 } 86 AddObserver(RemovableStorageObserver * obs)87void StorageMonitor::AddObserver(RemovableStorageObserver* obs) { 88 observer_list_->AddObserver(obs); 89 } 90 RemoveObserver(RemovableStorageObserver * obs)91void StorageMonitor::RemoveObserver( 92 RemovableStorageObserver* obs) { 93 observer_list_->RemoveObserver(obs); 94 } 95 GetTransientIdForDeviceId(const std::string & device_id)96std::string StorageMonitor::GetTransientIdForDeviceId( 97 const std::string& device_id) { 98 return transient_device_ids_->GetTransientIdForDeviceId(device_id); 99 } 100 GetDeviceIdForTransientId(const std::string & transient_id) const101std::string StorageMonitor::GetDeviceIdForTransientId( 102 const std::string& transient_id) const { 103 return transient_device_ids_->DeviceIdFromTransientId(transient_id); 104 } 105 EjectDevice(const std::string & device_id,base::Callback<void (EjectStatus)> callback)106void 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 StorageMonitor()114StorageMonitor::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 ~StorageMonitor()122StorageMonitor::~StorageMonitor() { 123 } 124 receiver() const125StorageMonitor::Receiver* StorageMonitor::receiver() const { 126 return receiver_.get(); 127 } 128 MarkInitialized()129void 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 ProcessAttach(const StorageInfo & info)139void 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 ProcessDetach(const std::string & id)158void 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