Upstream version 5.34.92.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / api / music_manager_private / device_id_linux.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 <map>
8
9 #include "base/bind.h"
10 #include "base/file_util.h"
11 #include "base/files/file_enumerator.h"
12 #include "base/files/file_path.h"
13 #include "base/threading/thread_restrictions.h"
14 #include "content/public/browser/browser_thread.h"
15
16 namespace {
17
18 const char kDiskByUuidDirectoryName[] = "/dev/disk/by-uuid";
19 const char* kDeviceNames[] = {
20   "sda1", "hda1", "dm-0", "xvda1", "sda2", "hda2", "dm-1", "xvda2",
21 };
22
23 // Map from device name to disk uuid
24 typedef std::map<base::FilePath, base::FilePath> DiskEntries;
25
26 void GetDiskUuid(const extensions::api::DeviceId::IdCallback& callback) {
27   base::ThreadRestrictions::AssertIOAllowed();
28
29   DiskEntries disk_uuids;
30   base::FileEnumerator files(base::FilePath(kDiskByUuidDirectoryName),
31                              false,  // Recursive.
32                              base::FileEnumerator::FILES);
33   do {
34     base::FilePath file_path = files.Next();
35     if (file_path.empty())
36       break;
37
38     base::FilePath target_path;
39     if (!base::ReadSymbolicLink(file_path, &target_path))
40       continue;
41
42     base::FilePath device_name = target_path.BaseName();
43     base::FilePath disk_uuid = file_path.BaseName();
44     disk_uuids[device_name] = disk_uuid;
45   } while (true);
46
47   // Look for first device name matching an entry of |kDeviceNames|.
48   std::string result;
49   for (size_t i = 0; i < arraysize(kDeviceNames); i++) {
50     DiskEntries::iterator it =
51         disk_uuids.find(base::FilePath(kDeviceNames[i]));
52     if (it != disk_uuids.end()) {
53       DVLOG(1) << "Returning uuid: \"" << it->second.value()
54                << "\" for device \"" << it->first.value() << "\"";
55       result = it->second.value();
56       break;
57     }
58   }
59
60   // Log failure (at most once) for diagnostic purposes.
61   static bool error_logged = false;
62   if (result.empty() && !error_logged) {
63     error_logged = true;
64     LOG(ERROR) << "Could not find appropriate disk uuid.";
65     for (DiskEntries::iterator it = disk_uuids.begin();
66         it != disk_uuids.end(); ++it) {
67       LOG(ERROR) << "  DeviceID=" << it->first.value() << ", uuid="
68                  << it->second.value();
69     }
70   }
71
72   content::BrowserThread::PostTask(
73       content::BrowserThread::UI,
74       FROM_HERE,
75       base::Bind(callback, result));
76 }
77
78 }  // namespace
79
80 namespace extensions {
81 namespace api {
82
83 // static
84 void DeviceId::GetRawDeviceId(const IdCallback& callback) {
85   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
86
87   content::BrowserThread::PostTask(
88       content::BrowserThread::FILE,
89       FROM_HERE,
90       base::Bind(GetDiskUuid, callback));
91 }
92
93 }  // namespace api
94 }  // namespace extensions