Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/system_monitor/media_transfer_protocol_device_observer_ chromeos.h" | 5 #include "chrome/browser/system_monitor/media_transfer_protocol_device_observer_ chromeos.h" |
| 6 | 6 |
| 7 #include "base/file_path.h" | |
| 7 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
| 8 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
| 9 #include "base/string_number_conversions.h" | 10 #include "base/string_number_conversions.h" |
| 10 #include "base/string_split.h" | 11 #include "base/string_split.h" |
| 11 #include "base/stringprintf.h" | 12 #include "base/stringprintf.h" |
| 12 #include "base/system_monitor/system_monitor.h" | |
| 13 #include "base/utf_string_conversions.h" | 13 #include "base/utf_string_conversions.h" |
| 14 #include "chrome/browser/chromeos/mtp/media_transfer_protocol_manager.h" | 14 #include "chrome/browser/chromeos/mtp/media_transfer_protocol_manager.h" |
| 15 #include "chrome/browser/system_monitor/removable_device_constants.h" | 15 #include "chrome/browser/system_monitor/removable_device_constants.h" |
| 16 #include "chrome/browser/system_monitor/media_storage_util.h" | 16 #include "chrome/browser/system_monitor/media_storage_util.h" |
| 17 #include "chromeos/dbus/mtp_storage_info.pb.h" | 17 #include "chromeos/dbus/mtp_storage_info.pb.h" |
| 18 | 18 |
| 19 namespace chromeos { | 19 namespace chromeos { |
| 20 namespace mtp { | 20 namespace mtp { |
| 21 | 21 |
| 22 using chrome::MediaStorageUtil; | 22 using chrome::MediaStorageUtil; |
| 23 | 23 |
| 24 namespace { | 24 namespace { |
| 25 | 25 |
| 26 static MediaTransferProtocolDeviceObserverCros* g_mtp_device_observer = NULL; | |
| 27 | |
| 26 // Device root path constant. | 28 // Device root path constant. |
| 27 const char kRootPath[] = "/"; | 29 const char kRootPath[] = "/"; |
| 28 | 30 |
| 31 // Constructs and returns the location of the device using the |storage_name|. | |
| 32 std::string GetDeviceLocationFromStorageName(const std::string& storage_name) { | |
| 33 // Construct a dummy device path using the storage name. This is only used | |
| 34 // for registering device media file system. | |
| 35 // E.g.: /usb:2,2:12345 | |
| 36 DCHECK(!storage_name.empty()); | |
| 37 return kRootPath + storage_name; | |
| 38 } | |
| 39 | |
| 29 // Returns the storage identifier of the device from the given |storage_name|. | 40 // Returns the storage identifier of the device from the given |storage_name|. |
| 30 // E.g. If the |storage_name| is "usb:2,2:65537", the storage identifier is | 41 // E.g. If the |storage_name| is "usb:2,2:65537", the storage identifier is |
| 31 // "65537". | 42 // "65537". |
| 32 std::string GetStorageIdFromStorageName(const std::string& storage_name) { | 43 std::string GetStorageIdFromStorageName(const std::string& storage_name) { |
| 33 std::vector<std::string> name_parts; | 44 std::vector<std::string> name_parts; |
| 34 base::SplitString(storage_name, ':', &name_parts); | 45 base::SplitString(storage_name, ':', &name_parts); |
| 35 return name_parts.size() == 3 ? name_parts[2] : std::string(); | 46 return name_parts.size() == 3 ? name_parts[2] : std::string(); |
| 36 } | 47 } |
| 37 | 48 |
| 38 // Returns a unique device id from the given |storage_info|. | 49 // Returns a unique device id from the given |storage_info|. |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 91 | 102 |
| 92 if (!storage_info) | 103 if (!storage_info) |
| 93 return; | 104 return; |
| 94 | 105 |
| 95 if (id) | 106 if (id) |
| 96 *id = GetDeviceIdFromStorageInfo(*storage_info); | 107 *id = GetDeviceIdFromStorageInfo(*storage_info); |
| 97 | 108 |
| 98 if (label) | 109 if (label) |
| 99 *label = GetDeviceLabelFromStorageInfo(*storage_info); | 110 *label = GetDeviceLabelFromStorageInfo(*storage_info); |
| 100 | 111 |
| 101 // Construct a dummy device path using the storage name. This is only used | 112 |
| 102 // for registering device media file system. | |
| 103 // E.g.: /usb:2,2:12345 | |
| 104 if (location) | 113 if (location) |
| 105 *location = kRootPath + storage_name; | 114 *location = GetDeviceLocationFromStorageName(storage_name); |
| 106 } | 115 } |
| 107 | 116 |
| 108 } // namespace | 117 } // namespace |
| 109 | 118 |
| 110 MediaTransferProtocolDeviceObserverCros:: | 119 MediaTransferProtocolDeviceObserverCros:: |
| 111 MediaTransferProtocolDeviceObserverCros() | 120 MediaTransferProtocolDeviceObserverCros() |
| 112 : get_storage_info_func_(&GetStorageInfo) { | 121 : get_storage_info_func_(&GetStorageInfo) { |
| 122 DCHECK(!g_mtp_device_observer); | |
| 123 g_mtp_device_observer = this; | |
| 124 | |
| 113 MediaTransferProtocolManager* mtp_manager = | 125 MediaTransferProtocolManager* mtp_manager = |
| 114 MediaTransferProtocolManager::GetInstance(); | 126 MediaTransferProtocolManager::GetInstance(); |
| 115 if (mtp_manager) | 127 if (mtp_manager) |
| 116 mtp_manager->AddObserver(this); | 128 mtp_manager->AddObserver(this); |
| 117 EnumerateStorages(); | 129 EnumerateStorages(); |
| 118 } | 130 } |
| 119 | 131 |
| 120 // This constructor is only used by unit tests. | 132 // This constructor is only used by unit tests. |
| 121 MediaTransferProtocolDeviceObserverCros:: | 133 MediaTransferProtocolDeviceObserverCros:: |
| 122 MediaTransferProtocolDeviceObserverCros( | 134 MediaTransferProtocolDeviceObserverCros( |
| 123 GetStorageInfoFunc get_storage_info_func) | 135 GetStorageInfoFunc get_storage_info_func) |
| 124 : get_storage_info_func_(get_storage_info_func) { | 136 : get_storage_info_func_(get_storage_info_func) { |
| 125 // In unit tests, we don't have a media transfer protocol manager. | 137 // In unit tests, we don't have a media transfer protocol manager. |
| 126 DCHECK(!MediaTransferProtocolManager::GetInstance()); | 138 DCHECK(!MediaTransferProtocolManager::GetInstance()); |
| 139 | |
| 140 // In unit tests, we don't call | |
| 141 // MediaTransferProtocolDeviceObserverCros::GetInstance(). so it is safe to | |
| 142 // keep this NULL; | |
| 143 DCHECK(!g_mtp_device_observer); | |
|
Lei Zhang
2012/09/16 00:17:05
this is weird, why not just set |g_mtp_device_obse
kmadhusu
2012/09/16 22:35:42
Done.
| |
| 127 } | 144 } |
| 128 | 145 |
| 129 MediaTransferProtocolDeviceObserverCros:: | 146 MediaTransferProtocolDeviceObserverCros:: |
| 130 ~MediaTransferProtocolDeviceObserverCros() { | 147 ~MediaTransferProtocolDeviceObserverCros() { |
| 148 if (g_mtp_device_observer) { | |
| 149 DCHECK_EQ(this, g_mtp_device_observer); | |
| 150 g_mtp_device_observer = NULL; | |
| 151 } | |
| 152 | |
| 131 MediaTransferProtocolManager* mtp_manager = | 153 MediaTransferProtocolManager* mtp_manager = |
| 132 MediaTransferProtocolManager::GetInstance(); | 154 MediaTransferProtocolManager::GetInstance(); |
| 133 if (mtp_manager) | 155 if (mtp_manager) |
| 134 mtp_manager->RemoveObserver(this); | 156 mtp_manager->RemoveObserver(this); |
| 135 } | 157 } |
| 136 | 158 |
| 159 // static | |
| 160 MediaTransferProtocolDeviceObserverCros* | |
| 161 MediaTransferProtocolDeviceObserverCros::GetInstance() { | |
| 162 DCHECK(g_mtp_device_observer != NULL); | |
| 163 return g_mtp_device_observer; | |
| 164 } | |
| 165 | |
| 166 MediaTransferProtocolDeviceObserverCros::StorageInfo::StorageInfo() { | |
| 167 } | |
| 168 | |
| 169 bool MediaTransferProtocolDeviceObserverCros::GetStorageInfoForPath( | |
| 170 const FilePath& path, | |
| 171 base::SystemMonitor::RemovableStorageInfo* storage_info) const { | |
| 172 if (!path.IsAbsolute()) | |
| 173 return false; | |
| 174 | |
| 175 FilePath current = path; | |
| 176 while (!ContainsKey(storage_map_, current.value()) && | |
|
vandebo (ex-Chrome)
2012/09/16 00:31:44
Why do this? Isn't the path for a mtp device a fi
kmadhusu
2012/09/16 22:35:42
Fixed. The first component of the path is always t
| |
| 177 current != current.DirName()) { | |
| 178 current = current.DirName(); | |
| 179 } | |
| 180 | |
| 181 StorageLocationToInfoMap::const_iterator info_it = | |
| 182 storage_map_.find(current.value()); | |
| 183 if (info_it == storage_map_.end()) | |
| 184 return false; | |
| 185 | |
| 186 if (storage_info) { | |
| 187 storage_info->device_id = info_it->second.id; | |
| 188 storage_info->name = info_it->second.name; | |
| 189 storage_info->location = info_it->second.location; | |
| 190 } | |
| 191 return true; | |
| 192 } | |
| 193 | |
| 137 // MediaTransferProtocolManager::Observer override. | 194 // MediaTransferProtocolManager::Observer override. |
| 138 void MediaTransferProtocolDeviceObserverCros::StorageChanged( | 195 void MediaTransferProtocolDeviceObserverCros::StorageChanged( |
| 139 bool is_attached, | 196 bool is_attached, |
| 140 const std::string& storage_name) { | 197 const std::string& storage_name) { |
| 141 DCHECK(!storage_name.empty()); | 198 DCHECK(!storage_name.empty()); |
| 142 | 199 |
| 143 base::SystemMonitor* system_monitor = base::SystemMonitor::Get(); | 200 base::SystemMonitor* system_monitor = base::SystemMonitor::Get(); |
| 144 DCHECK(system_monitor); | 201 DCHECK(system_monitor); |
| 145 | 202 |
| 146 // New storage is attached. | 203 // New storage is attached. |
| 147 if (is_attached) { | 204 if (is_attached) { |
| 148 std::string device_id; | 205 std::string device_id; |
| 149 string16 device_name; | 206 string16 device_name; |
| 150 std::string location; | 207 std::string location; |
| 151 get_storage_info_func_(storage_name, &device_id, &device_name, &location); | 208 get_storage_info_func_(storage_name, &device_id, &device_name, &location); |
| 152 | 209 |
| 153 // Keep track of device id and device name to see how often we receive | 210 // Keep track of device id and device name to see how often we receive |
| 154 // empty values. | 211 // empty values. |
| 155 UMA_HISTOGRAM_BOOLEAN("MediaDeviceNotification.MTPDeviceUUIDAvailable", | 212 UMA_HISTOGRAM_BOOLEAN("MediaDeviceNotification.MTPDeviceUUIDAvailable", |
| 156 !device_id.empty()); | 213 !device_id.empty()); |
| 157 UMA_HISTOGRAM_BOOLEAN("MediaDeviceNotification.MTPDeviceNameAvailable", | 214 UMA_HISTOGRAM_BOOLEAN("MediaDeviceNotification.MTPDeviceNameAvailable", |
| 158 !device_name.empty()); | 215 !device_name.empty()); |
| 159 | 216 |
| 160 if (device_id.empty() || device_name.empty()) | 217 if (device_id.empty() || device_name.empty()) |
| 161 return; | 218 return; |
| 162 | 219 |
| 163 DCHECK(!ContainsKey(storage_map_, storage_name)); | 220 DCHECK(!ContainsKey(storage_map_, location)); |
| 164 storage_map_[storage_name] = device_id; | 221 |
| 222 StorageInfo storage_info; | |
| 223 storage_info.id = device_id; | |
| 224 storage_info.location = location; | |
| 225 storage_info.name = device_name; | |
| 226 storage_map_[location] = storage_info; | |
| 165 system_monitor->ProcessRemovableStorageAttached(device_id, device_name, | 227 system_monitor->ProcessRemovableStorageAttached(device_id, device_name, |
| 166 location); | 228 location); |
| 167 } else { | 229 } else { |
| 168 // Existing storage is detached. | 230 // Existing storage is detached. |
| 169 StorageNameToIdMap::iterator it = storage_map_.find(storage_name); | 231 std::string location; |
| 232 StorageLocationToInfoMap::iterator it = | |
| 233 storage_map_.find(GetDeviceLocationFromStorageName(storage_name)); | |
| 170 if (it == storage_map_.end()) | 234 if (it == storage_map_.end()) |
| 171 return; | 235 return; |
| 172 system_monitor->ProcessRemovableStorageDetached(it->second); | 236 system_monitor->ProcessRemovableStorageDetached(it->second.id); |
| 173 storage_map_.erase(it); | 237 storage_map_.erase(it); |
| 174 } | 238 } |
| 175 } | 239 } |
| 176 | 240 |
| 177 void MediaTransferProtocolDeviceObserverCros::EnumerateStorages() { | 241 void MediaTransferProtocolDeviceObserverCros::EnumerateStorages() { |
| 178 typedef std::vector<std::string> StorageList; | 242 typedef std::vector<std::string> StorageList; |
| 179 MediaTransferProtocolManager* mtp_manager = | 243 MediaTransferProtocolManager* mtp_manager = |
| 180 MediaTransferProtocolManager::GetInstance(); | 244 MediaTransferProtocolManager::GetInstance(); |
| 181 DCHECK(mtp_manager); | 245 DCHECK(mtp_manager); |
| 182 StorageList storages = mtp_manager->GetStorages(); | 246 StorageList storages = mtp_manager->GetStorages(); |
| 183 for (StorageList::const_iterator storage_iter = storages.begin(); | 247 for (StorageList::const_iterator storage_iter = storages.begin(); |
| 184 storage_iter != storages.end(); ++storage_iter) { | 248 storage_iter != storages.end(); ++storage_iter) { |
| 185 StorageChanged(true, *storage_iter); | 249 StorageChanged(true, *storage_iter); |
| 186 } | 250 } |
| 187 } | 251 } |
| 188 | 252 |
| 189 } // namespace mtp | 253 } // namespace mtp |
| 190 } // namespace chromeos | 254 } // namespace chromeos |
| OLD | NEW |