OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // MediaDeviceNotificationsLinux implementation. | 5 // MediaDeviceNotificationsLinux implementation. |
6 | 6 |
7 #include "chrome/browser/media_gallery/media_device_notifications_linux.h" | 7 #include "chrome/browser/media_gallery/media_device_notifications_linux.h" |
8 | 8 |
9 #include <libudev.h> | 9 #include <libudev.h> |
10 #include <mntent.h> | 10 #include <mntent.h> |
11 #include <stdio.h> | 11 #include <stdio.h> |
12 | 12 |
13 #include <vector> | 13 #include <vector> |
14 | 14 |
15 #include "base/bind.h" | 15 #include "base/bind.h" |
16 #include "base/file_path.h" | 16 #include "base/file_path.h" |
17 #include "base/memory/scoped_generic_obj.h" | 17 #include "base/memory/scoped_generic_obj.h" |
18 #include "base/metrics/histogram.h" | 18 #include "base/metrics/histogram.h" |
19 #include "base/stl_util.h" | 19 #include "base/stl_util.h" |
20 #include "base/string_number_conversions.h" | 20 #include "base/string_number_conversions.h" |
21 #include "base/string_util.h" | 21 #include "base/string_util.h" |
22 #include "base/system_monitor/system_monitor.h" | 22 #include "base/system_monitor/system_monitor.h" |
23 #include "base/utf_string_conversions.h" | 23 #include "base/utf_string_conversions.h" |
24 #include "chrome/browser/media_gallery/media_device_notifications_utils.h" | 24 #include "chrome/browser/media_gallery/media_device_notifications_utils.h" |
25 #include "chrome/browser/media_gallery/media_storage_util.h" | |
25 | 26 |
26 namespace { | 27 namespace { |
27 | 28 |
28 // List of file systems we care about. | 29 // List of file systems we care about. |
29 const char* const kKnownFileSystems[] = { | 30 const char* const kKnownFileSystems[] = { |
30 "ext2", | 31 "ext2", |
31 "ext3", | 32 "ext3", |
32 "ext4", | 33 "ext4", |
33 "fat", | 34 "fat", |
34 "hfsplus", | 35 "hfsplus", |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
75 // ScopedGenericObj functor for UdevDeviceObjectRelease(). | 76 // ScopedGenericObj functor for UdevDeviceObjectRelease(). |
76 class ScopedReleaseUdevDeviceObject { | 77 class ScopedReleaseUdevDeviceObject { |
77 public: | 78 public: |
78 void operator()(struct udev_device* device) const { | 79 void operator()(struct udev_device* device) const { |
79 udev_device_unref(device); | 80 udev_device_unref(device); |
80 } | 81 } |
81 }; | 82 }; |
82 | 83 |
83 // Get the device information using udev library. | 84 // Get the device information using udev library. |
84 // On success, returns true and fill in |id| and |name|. | 85 // On success, returns true and fill in |id| and |name|. |
85 bool GetDeviceInfo(const std::string& device_path, | 86 bool GetDeviceInfo(const std::string& device_path, std::string* id, |
86 std::string* id, | |
87 string16* name) { | 87 string16* name) { |
88 DCHECK(!device_path.empty()); | 88 DCHECK(!device_path.empty()); |
89 | 89 |
90 ScopedGenericObj<struct udev*, ScopedReleaseUdevObject> udev_obj(udev_new()); | 90 ScopedGenericObj<struct udev*, ScopedReleaseUdevObject> udev_obj(udev_new()); |
91 if (!udev_obj.get()) | 91 if (!udev_obj.get()) |
92 return false; | 92 return false; |
93 | 93 |
94 struct stat device_stat; | 94 struct stat device_stat; |
95 if (stat(device_path.c_str(), &device_stat) < 0) | 95 if (stat(device_path.c_str(), &device_stat) < 0) |
96 return false; | 96 return false; |
97 | 97 |
98 char device_type; | 98 char device_type; |
99 if (S_ISCHR(device_stat.st_mode)) | 99 if (S_ISCHR(device_stat.st_mode)) |
100 device_type = 'c'; | 100 device_type = 'c'; |
101 else if (S_ISBLK(device_stat.st_mode)) | 101 else if (S_ISBLK(device_stat.st_mode)) |
102 device_type = 'b'; | 102 device_type = 'b'; |
103 else | 103 else |
104 return false; // Not a supported type. | 104 return false; // Not a supported type. |
105 | 105 |
106 ScopedGenericObj<struct udev_device*, ScopedReleaseUdevDeviceObject> | 106 ScopedGenericObj<struct udev_device*, ScopedReleaseUdevDeviceObject> |
107 device(udev_device_new_from_devnum(udev_obj, device_type, | 107 device(udev_device_new_from_devnum(udev_obj, device_type, |
108 device_stat.st_rdev)); | 108 device_stat.st_rdev)); |
109 if (!device.get()) | 109 if (!device.get()) |
110 return false; | 110 return false; |
111 | 111 |
112 // Construct a device name using label or manufacturer(vendor and model) | 112 // Construct a device name using label or manufacturer(vendor and model) |
113 // details. | 113 // details. |
114 std::string device_label; | 114 if (name) { |
kmadhusu
2012/08/20 17:13:50
Are you planning to call this function with NULL o
| |
115 const char* device_name = NULL; | 115 std::string device_label; |
116 if ((device_name = udev_device_get_property_value(device, kLabel)) || | 116 const char* device_name = NULL; |
117 (device_name = udev_device_get_property_value(device, kSerial))) { | 117 if ((device_name = udev_device_get_property_value(device, kLabel)) || |
118 device_label = device_name; | 118 (device_name = udev_device_get_property_value(device, kSerial))) { |
119 } else { | 119 device_label = device_name; |
120 // Format: VendorInfo ModelInfo | 120 } else { |
121 // E.g.: KnCompany Model2010 | 121 // Format: VendorInfo ModelInfo |
122 const char* vendor_name = NULL; | 122 // E.g.: KnCompany Model2010 |
123 if ((vendor_name = udev_device_get_property_value(device, kVendor))) | 123 const char* vendor_name = NULL; |
124 device_label = vendor_name; | 124 if ((vendor_name = udev_device_get_property_value(device, kVendor))) |
125 device_label = vendor_name; | |
125 | 126 |
126 const char* model_name = NULL; | 127 const char* model_name = NULL; |
127 if ((model_name = udev_device_get_property_value(device, kModel))) { | 128 if ((model_name = udev_device_get_property_value(device, kModel))) { |
128 if (!device_label.empty()) | 129 if (!device_label.empty()) |
129 device_label += kSpaceDelim; | 130 device_label += kSpaceDelim; |
130 device_label += model_name; | 131 device_label += model_name; |
132 } | |
131 } | 133 } |
134 | |
135 if (IsStringUTF8(device_label)) | |
136 *name = UTF8ToUTF16(device_label); | |
132 } | 137 } |
133 | 138 |
134 if (IsStringUTF8(device_label)) | 139 if (id) { |
135 *name = UTF8ToUTF16(device_label); | 140 std::string unique_id; |
141 const char* uuid = NULL; | |
142 if ((uuid = udev_device_get_property_value(device, kFsUUID))) { | |
143 unique_id = std::string(kFSUniqueIdPrefix) + uuid; | |
144 } else { | |
145 // If one of the vendor, model, serial information is missing, its value | |
146 // in the string is empty. | |
147 // Format: VendorModelSerial:VendorInfo:ModelInfo:SerialShortInfo | |
148 // E.g.: VendorModelSerial:Kn:DataTravel_12.10:8000000000006CB02CDB | |
149 const char* vendor = udev_device_get_property_value(device, kVendorID); | |
150 const char* model = udev_device_get_property_value(device, kModelID); | |
151 const char* serial_short = udev_device_get_property_value(device, | |
152 kSerialShort); | |
153 if (!vendor && !model && !serial_short) | |
154 return false; | |
136 | 155 |
137 const char* uuid = NULL; | 156 unique_id = std::string(kVendorModelSerialPrefix) + |
138 if ((uuid = udev_device_get_property_value(device, kFsUUID))) { | 157 (vendor ? vendor : "") + kNonSpaceDelim + |
139 *id = std::string(kFSUniqueIdPrefix) + uuid; | 158 (model ? model : "") + kNonSpaceDelim + |
140 } else { | 159 (serial_short ? serial_short : ""); |
141 // If one of the vendor, model, serial information is missing, its value in | 160 } |
142 // the string is empty. | 161 *id = chrome::MediaStorageUtil::MakeDeviceId( |
143 // Format: VendorModelSerial:VendorInfo:ModelInfo:SerialShortInfo | 162 chrome::MediaStorageUtil::USB_MASS_STORAGE_WITH_DCIM, unique_id); |
144 // E.g.: VendorModelSerial:Kn:DataTravel_12.10:8000000000006CB02CDB | |
145 const char* vendor = udev_device_get_property_value(device, kVendorID); | |
146 const char* model = udev_device_get_property_value(device, kModelID); | |
147 const char* serial_short = udev_device_get_property_value(device, | |
148 kSerialShort); | |
149 if (!vendor && !model && !serial_short) | |
150 return false; | |
151 | |
152 *id = std::string(kVendorModelSerialPrefix) + | |
153 (vendor ? vendor : "") + kNonSpaceDelim + | |
154 (model ? model : "") + kNonSpaceDelim + | |
155 (serial_short ? serial_short : ""); | |
156 } | 163 } |
157 | 164 |
158 return true; | 165 return true; |
159 } | 166 } |
160 | 167 |
161 } // namespace | 168 } // namespace |
162 | 169 |
163 namespace chrome { | 170 namespace chrome { |
164 | 171 |
165 using base::SystemMonitor; | 172 using base::SystemMonitor; |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
332 } | 339 } |
333 } | 340 } |
334 } | 341 } |
335 | 342 |
336 void MediaDeviceNotificationsLinux::CheckAndAddMediaDevice( | 343 void MediaDeviceNotificationsLinux::CheckAndAddMediaDevice( |
337 const std::string& mount_device, | 344 const std::string& mount_device, |
338 const std::string& mount_point) { | 345 const std::string& mount_point) { |
339 if (!IsMediaDevice(mount_point)) | 346 if (!IsMediaDevice(mount_point)) |
340 return; | 347 return; |
341 | 348 |
342 std::string device_id; | 349 std::string id; |
343 string16 device_name; | 350 string16 name; |
344 bool result = (*get_device_info_func_)(mount_device, &device_id, | 351 bool result = (*get_device_info_func_)(mount_device, &id, &name); |
345 &device_name); | |
346 | 352 |
347 // Keep track of GetDeviceInfo result, to see how often we fail to get device | 353 // Keep track of GetDeviceInfo result, to see how often we fail to get device |
348 // details. | 354 // details. |
349 UMA_HISTOGRAM_BOOLEAN("MediaDeviceNotification.device_info_available", | 355 UMA_HISTOGRAM_BOOLEAN("MediaDeviceNotification.device_info_available", |
350 result); | 356 result); |
351 if (!result) | 357 if (!result) |
352 return; | 358 return; |
353 | 359 |
354 // Keep track of device uuid, to see how often we receive empty values. | 360 // Keep track of device uuid, to see how often we receive empty values. |
355 UMA_HISTOGRAM_BOOLEAN("MediaDeviceNotification.device_uuid_available", | 361 UMA_HISTOGRAM_BOOLEAN("MediaDeviceNotification.device_uuid_available", |
356 !device_id.empty()); | 362 !id.empty()); |
357 UMA_HISTOGRAM_BOOLEAN("MediaDeviceNotification.device_name_available", | 363 UMA_HISTOGRAM_BOOLEAN("MediaDeviceNotification.device_name_available", |
358 !device_name.empty()); | 364 !name.empty()); |
359 | 365 |
360 if (device_id.empty() || device_name.empty()) | 366 if (id.empty() || name.empty()) |
361 return; | 367 return; |
362 | 368 |
363 MountDeviceAndId mount_device_and_id; | 369 MountDeviceAndId mount_device_and_id; |
364 mount_device_and_id.mount_device = mount_device; | 370 mount_device_and_id.mount_device = mount_device; |
365 mount_device_and_id.device_id = device_id; | 371 mount_device_and_id.device_id = id; |
366 mount_info_map_[mount_point] = mount_device_and_id; | 372 mount_info_map_[mount_point] = mount_device_and_id; |
367 | 373 |
368 base::SystemMonitor* system_monitor = base::SystemMonitor::Get(); | 374 base::SystemMonitor* system_monitor = base::SystemMonitor::Get(); |
369 system_monitor->ProcessMediaDeviceAttached(device_id, | 375 system_monitor->ProcessMediaDeviceAttached(id, name, mount_point); |
370 device_name, | |
371 SystemMonitor::TYPE_PATH, | |
372 mount_point); | |
373 } | 376 } |
374 | 377 |
375 void MediaDeviceNotificationsLinux::RemoveOldDevice( | 378 void MediaDeviceNotificationsLinux::RemoveOldDevice( |
376 const std::string& device_id) { | 379 const std::string& device_id) { |
377 base::SystemMonitor* system_monitor = base::SystemMonitor::Get(); | 380 base::SystemMonitor* system_monitor = base::SystemMonitor::Get(); |
378 system_monitor->ProcessMediaDeviceDetached(device_id); | 381 system_monitor->ProcessMediaDeviceDetached(device_id); |
379 } | 382 } |
380 | 383 |
381 } // namespace chrome | 384 } // namespace chrome |
OLD | NEW |