summaryrefslogtreecommitdiffstats
path: root/chrome/browser/system_monitor/disk_info_mac.mm
blob: f404a9511bec4cc384a37b57a609c9283b1b6186 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
// Copyright (c) 2012 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 "chrome/browser/system_monitor/disk_info_mac.h"

#include "base/mac/foundation_util.h"
#include "base/sys_string_conversions.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/system_monitor/media_device_notifications_utils.h"
#include "chrome/browser/system_monitor/media_storage_util.h"
#include "content/public/browser/browser_thread.h"

namespace chrome {
namespace {

string16 GetUTF16FromDictionary(CFDictionaryRef dictionary, CFStringRef key) {
  CFStringRef value =
      base::mac::GetValueFromDictionary<CFStringRef>(dictionary, key);
  if (!value)
    return string16();
  return base::SysCFStringRefToUTF16(value);
}

string16 JoinName(const string16& name, const string16& addition) {
  if (addition.empty())
    return name;
  if (name.empty())
    return addition;
  return name + static_cast<char16>(' ') + addition;
}

MediaStorageUtil::Type GetDeviceType(bool is_removable, bool has_dcim) {
  if (!is_removable)
    return MediaStorageUtil::FIXED_MASS_STORAGE;
  if (has_dcim)
    return MediaStorageUtil::REMOVABLE_MASS_STORAGE_WITH_DCIM;
  return MediaStorageUtil::REMOVABLE_MASS_STORAGE_NO_DCIM;
}

}  // namespace

DiskInfoMac::DiskInfoMac() : total_size_in_bytes_(0) {
}

DiskInfoMac::~DiskInfoMac() {
}

// static
DiskInfoMac DiskInfoMac::BuildDiskInfoOnFileThread(CFDictionaryRef dict) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
  DiskInfoMac info;

  CFStringRef bsd_name = base::mac::GetValueFromDictionary<CFStringRef>(
      dict, kDADiskDescriptionMediaBSDNameKey);
  if (bsd_name)
    info.bsd_name_ = base::SysCFStringRefToUTF8(bsd_name);

  CFURLRef url = base::mac::GetValueFromDictionary<CFURLRef>(
      dict, kDADiskDescriptionVolumePathKey);
  NSURL* nsurl = base::mac::CFToNSCast(url);
  info.mount_point_ = base::mac::NSStringToFilePath([nsurl path]);
  CFNumberRef size_number =
      base::mac::GetValueFromDictionary<CFNumberRef>(
          dict, kDADiskDescriptionMediaSizeKey);
  if (size_number) {
    CFNumberGetValue(size_number, kCFNumberLongLongType,
                     &(info.total_size_in_bytes_));
  }

  string16 vendor_name = GetUTF16FromDictionary(
      dict, kDADiskDescriptionDeviceVendorKey);
  string16 model_name = GetUTF16FromDictionary(
      dict, kDADiskDescriptionDeviceModelKey);
  string16 volume_name = GetUTF16FromDictionary(
      dict, kDADiskDescriptionVolumeNameKey);

  if (!volume_name.empty()) {
    info.device_name_ = volume_name;
  } else {
    info.device_name_ = GetFullProductName(UTF16ToUTF8(vendor_name),
                                           UTF16ToUTF8(model_name));
  }
  info.model_name_ = UTF16ToUTF8(model_name);

  CFUUIDRef uuid = base::mac::GetValueFromDictionary<CFUUIDRef>(
      dict, kDADiskDescriptionVolumeUUIDKey);
  std::string unique_id;
  if (uuid) {
    base::mac::ScopedCFTypeRef<CFStringRef> uuid_string(
        CFUUIDCreateString(NULL, uuid));
    if (uuid_string.get())
      unique_id = base::SysCFStringRefToUTF8(uuid_string);
  }
  if (unique_id.empty()) {
    string16 revision = GetUTF16FromDictionary(
        dict, kDADiskDescriptionDeviceRevisionKey);
    string16 unique_id2 = vendor_name;
    unique_id2 = JoinName(unique_id2, model_name);
    unique_id2 = JoinName(unique_id2, revision);
    unique_id = UTF16ToUTF8(unique_id2);
  }

  CFBooleanRef is_removable_ref =
      base::mac::GetValueFromDictionary<CFBooleanRef>(
          dict, kDADiskDescriptionMediaRemovableKey);
  bool is_removable = is_removable_ref && CFBooleanGetValue(is_removable_ref);
  // Checking for DCIM only matters on removable devices.
  bool has_dcim = is_removable && IsMediaDevice(info.mount_point_.value());
  info.type_ = GetDeviceType(is_removable, has_dcim);
  if (!unique_id.empty())
    info.device_id_ = MediaStorageUtil::MakeDeviceId(info.type_, unique_id);

  return info;
}

}  // namesapce chrome