| 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 // chrome::MediaStorageUtil implementation. | 5 // chrome::MediaStorageUtil implementation. |
| 6 | 6 |
| 7 #include "chrome/browser/system_monitor/media_storage_util.h" | 7 #include "chrome/browser/system_monitor/media_storage_util.h" |
| 8 | 8 |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 #include "chrome/browser/system_monitor/removable_device_notifications_window_wi
n.h" | 27 #include "chrome/browser/system_monitor/removable_device_notifications_window_wi
n.h" |
| 28 #endif | 28 #endif |
| 29 | 29 |
| 30 #if defined(OS_LINUX) // Implies OS_CHROMEOS | 30 #if defined(OS_LINUX) // Implies OS_CHROMEOS |
| 31 #include "chrome/browser/system_monitor/media_transfer_protocol_device_observer_
linux.h" | 31 #include "chrome/browser/system_monitor/media_transfer_protocol_device_observer_
linux.h" |
| 32 #endif | 32 #endif |
| 33 | 33 |
| 34 using base::SystemMonitor; | 34 using base::SystemMonitor; |
| 35 using content::BrowserThread; | 35 using content::BrowserThread; |
| 36 | 36 |
| 37 const char kRootPath[] = "/"; |
| 38 |
| 37 namespace chrome { | 39 namespace chrome { |
| 38 | 40 |
| 39 namespace { | 41 namespace { |
| 40 | 42 |
| 41 typedef std::vector<SystemMonitor::RemovableStorageInfo> RemovableStorageInfo; | |
| 42 | |
| 43 // MediaDeviceNotification.DeviceInfo histogram values. | 43 // MediaDeviceNotification.DeviceInfo histogram values. |
| 44 enum DeviceInfoHistogramBuckets { | 44 enum DeviceInfoHistogramBuckets { |
| 45 MASS_STORAGE_DEVICE_NAME_AND_UUID_AVAILABLE, | 45 MASS_STORAGE_DEVICE_NAME_AND_UUID_AVAILABLE, |
| 46 MASS_STORAGE_DEVICE_UUID_MISSING, | 46 MASS_STORAGE_DEVICE_UUID_MISSING, |
| 47 MASS_STORAGE_DEVICE_NAME_MISSING, | 47 MASS_STORAGE_DEVICE_NAME_MISSING, |
| 48 MASS_STORAGE_DEVICE_NAME_AND_UUID_MISSING, | 48 MASS_STORAGE_DEVICE_NAME_AND_UUID_MISSING, |
| 49 MTP_STORAGE_DEVICE_NAME_AND_UUID_AVAILABLE, | 49 MTP_STORAGE_DEVICE_NAME_AND_UUID_AVAILABLE, |
| 50 MTP_STORAGE_DEVICE_UUID_MISSING, | 50 MTP_STORAGE_DEVICE_UUID_MISSING, |
| 51 MTP_STORAGE_DEVICE_NAME_MISSING, | 51 MTP_STORAGE_DEVICE_NAME_MISSING, |
| 52 MTP_STORAGE_DEVICE_NAME_AND_UUID_MISSING, | 52 MTP_STORAGE_DEVICE_NAME_AND_UUID_MISSING, |
| 53 DEVICE_INFO_BUCKET_BOUNDARY | 53 DEVICE_INFO_BUCKET_BOUNDARY |
| 54 }; | 54 }; |
| 55 | 55 |
| 56 // Prefix constants for different device id spaces. | 56 // Prefix constants for different device id spaces. |
| 57 const char kRemovableMassStorageWithDCIMPrefix[] = "dcim:"; | 57 const char kRemovableMassStorageWithDCIMPrefix[] = "dcim:"; |
| 58 const char kRemovableMassStorageNoDCIMPrefix[] = "nodcim:"; | 58 const char kRemovableMassStorageNoDCIMPrefix[] = "nodcim:"; |
| 59 const char kFixedMassStoragePrefix[] = "path:"; | 59 const char kFixedMassStoragePrefix[] = "path:"; |
| 60 const char kMtpPtpPrefix[] = "mtp:"; | 60 const char kMtpPtpPrefix[] = "mtp:"; |
| 61 const char kMacImageCapture[] = "ic:"; |
| 61 | 62 |
| 62 static bool (*g_test_get_device_info_from_path_function)( // NOLINT | 63 static bool (*g_test_get_device_info_from_path_function)( // NOLINT |
| 63 const FilePath& path, std::string* device_id, string16* device_name, | 64 const FilePath& path, std::string* device_id, string16* device_name, |
| 64 FilePath* relative_path) = NULL; | 65 FilePath* relative_path) = NULL; |
| 65 | 66 |
| 66 void ValidatePathOnFileThread( | 67 void ValidatePathOnFileThread( |
| 67 const FilePath& path, const MediaStorageUtil::BoolCallback& callback) { | 68 const FilePath& path, const MediaStorageUtil::BoolCallback& callback) { |
| 68 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 69 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 69 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 70 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 70 base::Bind(callback, file_util::PathExists(path))); | 71 base::Bind(callback, file_util::PathExists(path))); |
| 71 } | 72 } |
| 72 | 73 |
| 74 bool IsRemovableStorageAttached(const std::string& id) { |
| 75 std::vector<SystemMonitor::RemovableStorageInfo> media_devices = |
| 76 SystemMonitor::Get()->GetAttachedRemovableStorage(); |
| 77 for (std::vector<SystemMonitor::RemovableStorageInfo>::const_iterator it = |
| 78 media_devices.begin(); |
| 79 it != media_devices.end(); |
| 80 ++it) { |
| 81 if (it->device_id == id) |
| 82 return true; |
| 83 } |
| 84 return false; |
| 85 } |
| 86 |
| 73 FilePath::StringType FindRemovableStorageLocationById( | 87 FilePath::StringType FindRemovableStorageLocationById( |
| 74 const std::string& device_id) { | 88 const std::string& device_id) { |
| 75 RemovableStorageInfo media_devices = | 89 std::vector<SystemMonitor::RemovableStorageInfo> media_devices = |
| 76 SystemMonitor::Get()->GetAttachedRemovableStorage(); | 90 SystemMonitor::Get()->GetAttachedRemovableStorage(); |
| 77 for (RemovableStorageInfo::const_iterator it = media_devices.begin(); | 91 for (std::vector<SystemMonitor::RemovableStorageInfo>::const_iterator it = |
| 92 media_devices.begin(); |
| 78 it != media_devices.end(); | 93 it != media_devices.end(); |
| 79 ++it) { | 94 ++it) { |
| 80 if (it->device_id == device_id) | 95 if (it->device_id == device_id) |
| 81 return it->location; | 96 return it->location; |
| 82 } | 97 } |
| 83 return FilePath::StringType(); | 98 return FilePath::StringType(); |
| 84 } | 99 } |
| 85 | 100 |
| 86 void FilterAttachedDevicesOnFileThread(MediaStorageUtil::DeviceIdSet* devices) { | 101 void FilterAttachedDevicesOnFileThread(MediaStorageUtil::DeviceIdSet* devices) { |
| 87 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 102 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 88 MediaStorageUtil::DeviceIdSet missing_devices; | 103 MediaStorageUtil::DeviceIdSet missing_devices; |
| 89 | 104 |
| 90 for (MediaStorageUtil::DeviceIdSet::const_iterator it = devices->begin(); | 105 for (MediaStorageUtil::DeviceIdSet::const_iterator it = devices->begin(); |
| 91 it != devices->end(); | 106 it != devices->end(); |
| 92 ++it) { | 107 ++it) { |
| 93 MediaStorageUtil::Type type; | 108 MediaStorageUtil::Type type; |
| 94 std::string unique_id; | 109 std::string unique_id; |
| 95 if (!MediaStorageUtil::CrackDeviceId(*it, &type, &unique_id)) { | 110 if (!MediaStorageUtil::CrackDeviceId(*it, &type, &unique_id)) { |
| 96 missing_devices.insert(*it); | 111 missing_devices.insert(*it); |
| 97 continue; | 112 continue; |
| 98 } | 113 } |
| 99 | 114 |
| 100 if (type == MediaStorageUtil::FIXED_MASS_STORAGE) { | 115 if (type == MediaStorageUtil::FIXED_MASS_STORAGE) { |
| 101 if (!file_util::PathExists(FilePath::FromUTF8Unsafe(unique_id))) | 116 if (!file_util::PathExists(FilePath::FromUTF8Unsafe(unique_id))) |
| 102 missing_devices.insert(*it); | 117 missing_devices.insert(*it); |
| 103 continue; | 118 continue; |
| 104 } | 119 } |
| 105 | 120 |
| 106 DCHECK(type == MediaStorageUtil::MTP_OR_PTP || | 121 if (!IsRemovableStorageAttached(*it)) |
| 107 type == MediaStorageUtil::REMOVABLE_MASS_STORAGE_WITH_DCIM || | |
| 108 type == MediaStorageUtil::REMOVABLE_MASS_STORAGE_NO_DCIM); | |
| 109 if (FindRemovableStorageLocationById(*it).empty()) | |
| 110 missing_devices.insert(*it); | 122 missing_devices.insert(*it); |
| 111 } | 123 } |
| 112 | 124 |
| 113 for (MediaStorageUtil::DeviceIdSet::const_iterator it = | 125 for (MediaStorageUtil::DeviceIdSet::const_iterator it = |
| 114 missing_devices.begin(); | 126 missing_devices.begin(); |
| 115 it != missing_devices.end(); | 127 it != missing_devices.end(); |
| 116 ++it) { | 128 ++it) { |
| 117 devices->erase(*it); | 129 devices->erase(*it); |
| 118 } | 130 } |
| 119 } | 131 } |
| 120 | 132 |
| 121 } // namespace | 133 } // namespace |
| 122 | 134 |
| 123 // static | 135 // static |
| 124 std::string MediaStorageUtil::MakeDeviceId(Type type, | 136 std::string MediaStorageUtil::MakeDeviceId(Type type, |
| 125 const std::string& unique_id) { | 137 const std::string& unique_id) { |
| 126 DCHECK(!unique_id.empty()); | 138 DCHECK(!unique_id.empty()); |
| 127 switch (type) { | 139 switch (type) { |
| 128 case REMOVABLE_MASS_STORAGE_WITH_DCIM: | 140 case REMOVABLE_MASS_STORAGE_WITH_DCIM: |
| 129 return std::string(kRemovableMassStorageWithDCIMPrefix) + unique_id; | 141 return std::string(kRemovableMassStorageWithDCIMPrefix) + unique_id; |
| 130 case REMOVABLE_MASS_STORAGE_NO_DCIM: | 142 case REMOVABLE_MASS_STORAGE_NO_DCIM: |
| 131 return std::string(kRemovableMassStorageNoDCIMPrefix) + unique_id; | 143 return std::string(kRemovableMassStorageNoDCIMPrefix) + unique_id; |
| 132 case FIXED_MASS_STORAGE: | 144 case FIXED_MASS_STORAGE: |
| 133 return std::string(kFixedMassStoragePrefix) + unique_id; | 145 return std::string(kFixedMassStoragePrefix) + unique_id; |
| 134 case MTP_OR_PTP: | 146 case MTP_OR_PTP: |
| 135 return std::string(kMtpPtpPrefix) + unique_id; | 147 return std::string(kMtpPtpPrefix) + unique_id; |
| 148 case MAC_IMAGE_CAPTURE: |
| 149 return std::string(kMacImageCapture) + unique_id; |
| 136 } | 150 } |
| 137 NOTREACHED(); | 151 NOTREACHED(); |
| 138 return std::string(); | 152 return std::string(); |
| 139 } | 153 } |
| 140 | 154 |
| 141 // static | 155 // static |
| 142 bool MediaStorageUtil::CrackDeviceId(const std::string& device_id, | 156 bool MediaStorageUtil::CrackDeviceId(const std::string& device_id, |
| 143 Type* type, std::string* unique_id) { | 157 Type* type, std::string* unique_id) { |
| 144 size_t prefix_length = device_id.find_first_of(':'); | 158 size_t prefix_length = device_id.find_first_of(':'); |
| 145 std::string prefix = prefix_length != std::string::npos ? | 159 std::string prefix = prefix_length != std::string::npos ? |
| 146 device_id.substr(0, prefix_length + 1) : ""; | 160 device_id.substr(0, prefix_length + 1) : ""; |
| 147 | 161 |
| 148 Type found_type; | 162 Type found_type; |
| 149 if (prefix == kRemovableMassStorageWithDCIMPrefix) { | 163 if (prefix == kRemovableMassStorageWithDCIMPrefix) { |
| 150 found_type = REMOVABLE_MASS_STORAGE_WITH_DCIM; | 164 found_type = REMOVABLE_MASS_STORAGE_WITH_DCIM; |
| 151 } else if (prefix == kRemovableMassStorageNoDCIMPrefix) { | 165 } else if (prefix == kRemovableMassStorageNoDCIMPrefix) { |
| 152 found_type = REMOVABLE_MASS_STORAGE_NO_DCIM; | 166 found_type = REMOVABLE_MASS_STORAGE_NO_DCIM; |
| 153 } else if (prefix == kFixedMassStoragePrefix) { | 167 } else if (prefix == kFixedMassStoragePrefix) { |
| 154 found_type = FIXED_MASS_STORAGE; | 168 found_type = FIXED_MASS_STORAGE; |
| 155 } else if (prefix == kMtpPtpPrefix) { | 169 } else if (prefix == kMtpPtpPrefix) { |
| 156 found_type = MTP_OR_PTP; | 170 found_type = MTP_OR_PTP; |
| 171 } else if (prefix == kMacImageCapture) { |
| 172 found_type = MAC_IMAGE_CAPTURE; |
| 157 } else { | 173 } else { |
| 158 NOTREACHED(); | 174 NOTREACHED(); |
| 159 return false; | 175 return false; |
| 160 } | 176 } |
| 161 if (type) | 177 if (type) |
| 162 *type = found_type; | 178 *type = found_type; |
| 163 | 179 |
| 164 if (unique_id) | 180 if (unique_id) |
| 165 *unique_id = device_id.substr(prefix_length + 1); | 181 *unique_id = device_id.substr(prefix_length + 1); |
| 166 return true; | 182 return true; |
| 167 } | 183 } |
| 168 | 184 |
| 169 // static | 185 // static |
| 170 bool MediaStorageUtil::IsMediaDevice(const std::string& device_id) { | 186 bool MediaStorageUtil::IsMediaDevice(const std::string& device_id) { |
| 171 Type type; | 187 Type type; |
| 172 return CrackDeviceId(device_id, &type, NULL) && | 188 return CrackDeviceId(device_id, &type, NULL) && |
| 173 (type == REMOVABLE_MASS_STORAGE_WITH_DCIM || type == MTP_OR_PTP); | 189 (type == REMOVABLE_MASS_STORAGE_WITH_DCIM || type == MTP_OR_PTP || |
| 190 type == MAC_IMAGE_CAPTURE); |
| 174 } | 191 } |
| 175 | 192 |
| 176 // static | 193 // static |
| 177 bool MediaStorageUtil::IsRemovableDevice(const std::string& device_id) { | 194 bool MediaStorageUtil::IsRemovableDevice(const std::string& device_id) { |
| 178 Type type; | 195 Type type; |
| 179 return CrackDeviceId(device_id, &type, NULL) && type != FIXED_MASS_STORAGE; | 196 return CrackDeviceId(device_id, &type, NULL) && type != FIXED_MASS_STORAGE; |
| 180 } | 197 } |
| 181 | 198 |
| 182 // static | 199 // static |
| 183 bool MediaStorageUtil::IsMassStorageDevice(const std::string& device_id) { | 200 bool MediaStorageUtil::IsMassStorageDevice(const std::string& device_id) { |
| 184 Type type; | 201 Type type; |
| 185 return CrackDeviceId(device_id, &type, NULL) && type != MTP_OR_PTP; | 202 return CrackDeviceId(device_id, &type, NULL) && |
| 203 (type == REMOVABLE_MASS_STORAGE_WITH_DCIM || |
| 204 type == REMOVABLE_MASS_STORAGE_NO_DCIM || |
| 205 type == FIXED_MASS_STORAGE); |
| 186 } | 206 } |
| 187 | 207 |
| 188 // static | 208 // static |
| 209 bool MediaStorageUtil::CanCreateFileSystem(const std::string& device_id, |
| 210 const FilePath& path) { |
| 211 Type type; |
| 212 if (!CrackDeviceId(device_id, &type, NULL)) |
| 213 return false; |
| 214 |
| 215 if (type == MAC_IMAGE_CAPTURE) |
| 216 return true; |
| 217 |
| 218 return path.IsAbsolute() && !path.ReferencesParent(); |
| 219 } |
| 220 |
| 221 // static |
| 189 void MediaStorageUtil::IsDeviceAttached(const std::string& device_id, | 222 void MediaStorageUtil::IsDeviceAttached(const std::string& device_id, |
| 190 const BoolCallback& callback) { | 223 const BoolCallback& callback) { |
| 191 Type type; | 224 Type type; |
| 192 std::string unique_id; | 225 std::string unique_id; |
| 193 if (!CrackDeviceId(device_id, &type, &unique_id)) { | 226 if (!CrackDeviceId(device_id, &type, &unique_id)) { |
| 194 callback.Run(false); | 227 callback.Run(false); |
| 195 return; | 228 return; |
| 196 } | 229 } |
| 197 | 230 |
| 198 if (type == FIXED_MASS_STORAGE) { | 231 if (type == FIXED_MASS_STORAGE) { |
| 199 // For this type, the unique_id is the path. | 232 // For this type, the unique_id is the path. |
| 200 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | 233 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
| 201 base::Bind(&ValidatePathOnFileThread, | 234 base::Bind(&ValidatePathOnFileThread, |
| 202 FilePath::FromUTF8Unsafe(unique_id), | 235 FilePath::FromUTF8Unsafe(unique_id), |
| 203 callback)); | 236 callback)); |
| 204 } else { | 237 } else { |
| 205 DCHECK(type == MTP_OR_PTP || | 238 DCHECK(type == MTP_OR_PTP || |
| 206 type == REMOVABLE_MASS_STORAGE_WITH_DCIM || | 239 type == REMOVABLE_MASS_STORAGE_WITH_DCIM || |
| 207 type == REMOVABLE_MASS_STORAGE_NO_DCIM); | 240 type == REMOVABLE_MASS_STORAGE_NO_DCIM); |
| 208 // We should be able to find removable storage in SystemMonitor. | 241 // We should be able to find removable storage in SystemMonitor. |
| 209 callback.Run(!FindRemovableStorageLocationById(device_id).empty()); | 242 callback.Run(IsRemovableStorageAttached(device_id)); |
| 210 } | 243 } |
| 211 } | 244 } |
| 212 | 245 |
| 213 // static | 246 // static |
| 214 void MediaStorageUtil::FilterAttachedDevices(DeviceIdSet* devices, | 247 void MediaStorageUtil::FilterAttachedDevices(DeviceIdSet* devices, |
| 215 const base::Closure& done) { | 248 const base::Closure& done) { |
| 216 if (BrowserThread::CurrentlyOn(BrowserThread::FILE)) { | 249 if (BrowserThread::CurrentlyOn(BrowserThread::FILE)) { |
| 217 FilterAttachedDevicesOnFileThread(devices); | 250 FilterAttachedDevicesOnFileThread(devices); |
| 218 done.Run(); | 251 done.Run(); |
| 219 return; | 252 return; |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 303 Type type; | 336 Type type; |
| 304 std::string unique_id; | 337 std::string unique_id; |
| 305 if (!CrackDeviceId(device_id, &type, &unique_id)) | 338 if (!CrackDeviceId(device_id, &type, &unique_id)) |
| 306 return FilePath(); | 339 return FilePath(); |
| 307 | 340 |
| 308 if (type == FIXED_MASS_STORAGE) { | 341 if (type == FIXED_MASS_STORAGE) { |
| 309 // For this type, the unique_id is the path. | 342 // For this type, the unique_id is the path. |
| 310 return FilePath::FromUTF8Unsafe(unique_id); | 343 return FilePath::FromUTF8Unsafe(unique_id); |
| 311 } | 344 } |
| 312 | 345 |
| 346 // This should return "/" because when the prefs returns an absolute path, |
| 347 // it just smacks it on the end of whatever this method returns. |
| 348 // For ImageCapture, we're not using the path as a path anyway, so return |
| 349 // something to make the fake path arithmetic work out. |
| 350 if (type == MAC_IMAGE_CAPTURE) { |
| 351 return FilePath(kRootPath + device_id); |
| 352 } |
| 353 |
| 313 DCHECK(type == MTP_OR_PTP || | 354 DCHECK(type == MTP_OR_PTP || |
| 314 type == REMOVABLE_MASS_STORAGE_WITH_DCIM || | 355 type == REMOVABLE_MASS_STORAGE_WITH_DCIM || |
| 315 type == REMOVABLE_MASS_STORAGE_NO_DCIM); | 356 type == REMOVABLE_MASS_STORAGE_NO_DCIM); |
| 316 return FilePath(FindRemovableStorageLocationById(device_id)); | 357 return FilePath(FindRemovableStorageLocationById(device_id)); |
| 317 } | 358 } |
| 318 | 359 |
| 319 // static | 360 // static |
| 320 void MediaStorageUtil::RecordDeviceInfoHistogram(bool mass_storage, | 361 void MediaStorageUtil::RecordDeviceInfoHistogram(bool mass_storage, |
| 321 const std::string& device_uuid, | 362 const std::string& device_uuid, |
| 322 const string16& device_name) { | 363 const string16& device_name) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 341 | 382 |
| 342 // static | 383 // static |
| 343 void MediaStorageUtil::SetGetDeviceInfoFromPathFunctionForTesting( | 384 void MediaStorageUtil::SetGetDeviceInfoFromPathFunctionForTesting( |
| 344 GetDeviceInfoFromPathFunction function) { | 385 GetDeviceInfoFromPathFunction function) { |
| 345 g_test_get_device_info_from_path_function = function; | 386 g_test_get_device_info_from_path_function = function; |
| 346 } | 387 } |
| 347 | 388 |
| 348 MediaStorageUtil::MediaStorageUtil() {} | 389 MediaStorageUtil::MediaStorageUtil() {} |
| 349 | 390 |
| 350 } // namespace chrome | 391 } // namespace chrome |
| OLD | NEW |