// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "components/metrics/drive_metrics_provider.h" #include #include #include #include #include #include #include #include "base/files/file_path.h" #include "base/mac/foundation_util.h" #include "base/mac/mac_util.h" #include "base/mac/scoped_cftyperef.h" #include "base/mac/scoped_ioobject.h" namespace metrics { // static bool DriveMetricsProvider::HasSeekPenalty(const base::FilePath& path, bool* has_seek_penalty) { struct stat path_stat; if (stat(path.value().c_str(), &path_stat) < 0) return false; const char* dev_name = devname(path_stat.st_dev, S_IFBLK); if (!dev_name) return false; std::string bsd_name("/dev/"); bsd_name.append(dev_name); base::ScopedCFTypeRef session( DASessionCreate(kCFAllocatorDefault)); if (!session) return false; base::ScopedCFTypeRef disk( DADiskCreateFromBSDName(kCFAllocatorDefault, session, bsd_name.c_str())); if (!disk) return false; base::mac::ScopedIOObject io_media(DADiskCopyIOMedia(disk)); base::ScopedCFTypeRef characteristics( static_cast(IORegistryEntrySearchCFProperty( io_media, kIOServicePlane, CFSTR(kIOPropertyDeviceCharacteristicsKey), kCFAllocatorDefault, kIORegistryIterateRecursively | kIORegistryIterateParents))); if (!characteristics) return false; CFStringRef type_ref = base::mac::GetValueFromDictionary( characteristics, CFSTR(kIOPropertyMediumTypeKey)); if (!type_ref) return false; NSString* type = base::mac::CFToNSCast(type_ref); if ([type isEqualToString:@kIOPropertyMediumTypeRotationalKey]) { *has_seek_penalty = true; return true; } else if ([type isEqualToString:@kIOPropertyMediumTypeSolidStateKey]) { *has_seek_penalty = false; return true; } // TODO(dbeam): should I look for these Rotational/Solid State keys in // |characteristics|? What if I find device characteristic but there's no // type? Assume rotational? return false; } } // namespace metrics