- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / api / music_manager_private / device_id_mac.cc
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/extensions/api/music_manager_private/device_id.h"
6
7 #include <CoreFoundation/CoreFoundation.h>
8 #include <DiskArbitration/DASession.h>
9 #include <DiskArbitration/DADisk.h>
10 #include <sys/mount.h>
11
12 #include "base/bind.h"
13 #include "base/mac/foundation_util.h"
14 #include "base/mac/scoped_cftyperef.h"
15 #include "base/strings/sys_string_conversions.h"
16 #include "content/public/browser/browser_thread.h"
17
18 namespace {
19
20 const char kRootDirectory[] = "/";
21
22 // Return the BSD name (e.g. '/dev/disk1') of the root directory by enumerating
23 // through the mounted volumes .
24 // Return "" if an error occured.
25 std::string FindBSDNameOfSystemDisk() {
26   struct statfs* mounted_volumes;
27   int num_volumes = getmntinfo(&mounted_volumes, 0);
28   if (num_volumes == 0) {
29     VLOG(1) << "Cannot enumerate list of mounted volumes.";
30     return std::string();
31   }
32
33   for (int i = 0; i < num_volumes; i++) {
34     struct statfs* vol = &mounted_volumes[i];
35     if (std::string(vol->f_mntonname) == kRootDirectory) {
36       return std::string(vol->f_mntfromname);
37     }
38   }
39
40   VLOG(1) << "Cannot find disk mounted as '" << kRootDirectory << "'.";
41   return std::string();
42 }
43
44 // Return the Volume UUID property of a BSD disk name (e.g. '/dev/disk1').
45 // Return "" if an error occured.
46 std::string GetVolumeUUIDFromBSDName(const std::string& bsd_name) {
47   const CFAllocatorRef allocator = NULL;
48
49   base::ScopedCFTypeRef<DASessionRef> session(DASessionCreate(allocator));
50   if (session.get() == NULL) {
51     VLOG(1) << "Error creating DA Session.";
52     return std::string();
53   }
54
55   base::ScopedCFTypeRef<DADiskRef> disk(
56       DADiskCreateFromBSDName(allocator, session, bsd_name.c_str()));
57   if (disk.get() == NULL) {
58     VLOG(1) << "Error creating DA disk from BSD disk name.";
59     return std::string();
60   }
61
62   base::ScopedCFTypeRef<CFDictionaryRef> disk_description(
63       DADiskCopyDescription(disk));
64   if (disk_description.get() == NULL) {
65     VLOG(1) << "Error getting disk description.";
66     return std::string();
67   }
68
69   CFUUIDRef volume_uuid = base::mac::GetValueFromDictionary<CFUUIDRef>(
70       disk_description,
71       kDADiskDescriptionVolumeUUIDKey);
72   if (volume_uuid == NULL) {
73     VLOG(1) << "Error getting volume UUID of disk.";
74     return std::string();
75   }
76
77   base::ScopedCFTypeRef<CFStringRef> volume_uuid_string(
78       CFUUIDCreateString(allocator, volume_uuid));
79   if (volume_uuid_string.get() == NULL) {
80     VLOG(1) << "Error creating string from CSStringRef.";
81     return std::string();
82   }
83
84   return base::SysCFStringRefToUTF8(volume_uuid_string.get());
85 }
86
87 // Return Volume UUID property of disk mounted as "/".
88 void GetVolumeUUID(const extensions::api::DeviceId::IdCallback& callback) {
89   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
90
91   std::string result;
92   std::string bsd_name = FindBSDNameOfSystemDisk();
93   if (!bsd_name.empty()) {
94     VLOG(4) << "BSD name of root directory: '" << bsd_name << "'";
95     result = GetVolumeUUIDFromBSDName(bsd_name);
96   }
97   content::BrowserThread::PostTask(
98       content::BrowserThread::UI,
99       FROM_HERE,
100       base::Bind(callback, result));
101 }
102
103 }
104
105 namespace extensions {
106 namespace api {
107
108 // MacOS: Return Volume UUID property of disk mounted as "/".
109 /* static */
110 void DeviceId::GetMachineId(const IdCallback& callback) {
111   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
112
113   content::BrowserThread::PostTask(
114       content::BrowserThread::FILE,
115       FROM_HERE,
116       base::Bind(GetVolumeUUID, callback));
117 }
118
119 }  // namespace api
120 }  // namespace extensions