15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/storage_monitor/media_storage_util.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h" 101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h" 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/storage_monitor/removable_device_constants.h" 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/storage_monitor/storage_monitor.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace storage_monitor { 22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// MediaDeviceNotification.DeviceInfo histogram values. 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum DeviceInfoHistogramBuckets { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MASS_STORAGE_DEVICE_NAME_AND_UUID_AVAILABLE, 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MASS_STORAGE_DEVICE_UUID_MISSING, 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MASS_STORAGE_DEVICE_NAME_MISSING, 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MASS_STORAGE_DEVICE_NAME_AND_UUID_MISSING, 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MTP_STORAGE_DEVICE_NAME_AND_UUID_AVAILABLE, 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MTP_STORAGE_DEVICE_UUID_MISSING, 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MTP_STORAGE_DEVICE_NAME_MISSING, 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MTP_STORAGE_DEVICE_NAME_AND_UUID_MISSING, 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEVICE_INFO_BUCKET_BOUNDARY 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if !defined(OS_WIN) 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kRootPath[] = "/"; 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef std::vector<StorageInfo> StorageInfoList; 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath::StringType FindRemovableStorageLocationById( 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& device_id) { 467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) StorageInfoList devices = 477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) StorageMonitor::GetInstance()->GetAllAvailableStorages(); 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (StorageInfoList::const_iterator it = devices.begin(); 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != devices.end(); ++it) { 507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (it->device_id() == device_id 517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) && StorageInfo::IsRemovableDevice(device_id)) 5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return it->location(); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::FilePath::StringType(); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FilterAttachedDevicesOnFileThread(MediaStorageUtil::DeviceIdSet* devices) { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MediaStorageUtil::DeviceIdSet missing_devices; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (MediaStorageUtil::DeviceIdSet::const_iterator it = devices->begin(); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != devices->end(); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++it) { 6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) StorageInfo::Type type; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string unique_id; 6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!StorageInfo::CrackDeviceId(*it, &type, &unique_id)) { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) missing_devices.insert(*it); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (type == StorageInfo::FIXED_MASS_STORAGE || 7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) type == StorageInfo::ITUNES || 734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) type == StorageInfo::IPHOTO || 7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) type == StorageInfo::PICASA) { 757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!base::PathExists(base::FilePath::FromUTF8Unsafe(unique_id))) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) missing_devices.insert(*it); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!MediaStorageUtil::IsRemovableStorageAttached(*it)) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) missing_devices.insert(*it); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (MediaStorageUtil::DeviceIdSet::const_iterator it = 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) missing_devices.begin(); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != missing_devices.end(); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++it) { 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) devices->erase(*it); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MediaStorageUtil::HasDcim(const base::FilePath& mount_point) { 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath::StringType dcim_dir(kDCIMDirectoryName); 997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!base::DirectoryExists(mount_point.Append(dcim_dir))) { 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Check for lowercase 'dcim' as well. 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath dcim_path_lower( 1026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) mount_point.Append(base::StringToLowerASCII(dcim_dir))); 1037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!base::DirectoryExists(dcim_path_lower)) 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool MediaStorageUtil::CanCreateFileSystem(const std::string& device_id, 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& path) { 11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) StorageInfo::Type type; 11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!StorageInfo::CrackDeviceId(device_id, &type, NULL)) 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (type == StorageInfo::MAC_IMAGE_CAPTURE) 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 119effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return !path.empty() && path.IsAbsolute() && !path.ReferencesParent(); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MediaStorageUtil::FilterAttachedDevices(DeviceIdSet* devices, 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& done) { 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (BrowserThread::CurrentlyOn(BrowserThread::FILE)) { 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FilterAttachedDevicesOnFileThread(devices); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done.Run(); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTaskAndReply(BrowserThread::FILE, 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&FilterAttachedDevicesOnFileThread, 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) devices), 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// TODO(kmadhusu) Write unit tests for GetDeviceInfoFromPath(). 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool MediaStorageUtil::GetDeviceInfoFromPath(const base::FilePath& path, 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StorageInfo* device_info, 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath* relative_path) { 14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(device_info); 14290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(relative_path); 14390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!path.IsAbsolute()) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StorageInfo info; 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StorageMonitor* monitor = StorageMonitor::GetInstance(); 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool found_device = monitor->GetStorageInfoForPath(path, &info); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (found_device && StorageInfo::IsRemovableDevice(info.device_id())) { 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath sub_folder_path; 15390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::FilePath device_path(info.location()); 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (path != device_path) { 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool success = device_path.AppendRelativePath(path, &sub_folder_path); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(success); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 15990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *device_info = info; 16090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *relative_path = sub_folder_path; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // On Posix systems, there's one root so any absolute path could be valid. 16590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // TODO(gbillock): Delete this stanza? Posix systems should have the root 16690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // volume information. If not, we should move the below into the 16790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // right GetStorageInfoForPath implementations. 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_POSIX) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!found_device) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Handle non-removable devices. Note: this is just overwriting 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // good values from StorageMonitor. 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(gbillock): Make sure return values from that class are definitive, 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // and don't do this here. 17790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) info.set_device_id( 17890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) StorageInfo::MakeDeviceId(StorageInfo::FIXED_MASS_STORAGE, 17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) path.AsUTF8Unsafe())); 18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *device_info = info; 18190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *relative_path = base::FilePath(); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath MediaStorageUtil::FindDevicePathById( 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& device_id) { 18890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) StorageInfo::Type type; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string unique_id; 19090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!StorageInfo::CrackDeviceId(device_id, &type, &unique_id)) 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::FilePath(); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (type == StorageInfo::FIXED_MASS_STORAGE || 19490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) type == StorageInfo::ITUNES || 1954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) type == StorageInfo::IPHOTO || 19690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) type == StorageInfo::PICASA) { 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For this type, the unique_id is the path. 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::FilePath::FromUTF8Unsafe(unique_id); 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // For ImageCapture, the synthetic filesystem will be rooted at a fake 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // top-level directory which is the device_id. 20390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (type == StorageInfo::MAC_IMAGE_CAPTURE) { 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if !defined(OS_WIN) 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::FilePath(kRootPath + device_id); 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(type == StorageInfo::MTP_OR_PTP || 21090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) type == StorageInfo::REMOVABLE_MASS_STORAGE_WITH_DCIM || 21190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) type == StorageInfo::REMOVABLE_MASS_STORAGE_NO_DCIM); 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::FilePath(FindRemovableStorageLocationById(device_id)); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 216a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void MediaStorageUtil::RecordDeviceInfoHistogram( 217a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool mass_storage, 218a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::string& device_uuid, 219a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& device_label) { 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int event_number = 0; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!mass_storage) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_number = 4; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 224b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (device_label.empty()) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_number += 2; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (device_uuid.empty()) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_number += 1; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum DeviceInfoHistogramBuckets event = 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<enum DeviceInfoHistogramBuckets>(event_number); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event >= DEVICE_INFO_BUCKET_BOUNDARY) { 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("MediaDeviceNotifications.DeviceInfo", event, 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEVICE_INFO_BUCKET_BOUNDARY); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 239eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool MediaStorageUtil::IsRemovableStorageAttached(const std::string& id) { 240eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch StorageInfoList devices = 241eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch StorageMonitor::GetInstance()->GetAllAvailableStorages(); 242eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (StorageInfoList::const_iterator it = devices.begin(); 243eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch it != devices.end(); ++it) { 244eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (StorageInfo::IsRemovableDevice(id) && it->device_id() == id) 245eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return true; 246eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 247eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return false; 248eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 249a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 250a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace storage_monitor 251