1 // Copyright 2014 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/storage_monitor/storage_info.h"
9 #include "base/check_op.h"
10 #include "base/notreached.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "components/storage_monitor/media_storage_util.h"
13 #include "ui/base/l10n/l10n_util.h"
14 #include "ui/base/text/bytes_formatting.h"
18 // Prefix constants for different device id spaces.
19 const char kRemovableMassStorageWithDCIMPrefix[] = "dcim:";
20 const char kRemovableMassStorageNoDCIMPrefix[] = "nodcim:";
21 const char kFixedMassStoragePrefix[] = "path:";
22 const char kMtpPtpPrefix[] = "mtp:";
23 const char kMacImageCapturePrefix[] = "ic:";
25 std::u16string GetDisplayNameForDevice(uint64_t storage_size_in_bytes,
26 const std::u16string& name) {
27 DCHECK(!name.empty());
28 return (storage_size_in_bytes == 0)
30 : ui::FormatBytes(storage_size_in_bytes) + u" " + name;
33 std::u16string GetFullProductName(const std::u16string& vendor_name,
34 const std::u16string& model_name) {
35 if (vendor_name.empty() && model_name.empty())
36 return std::u16string();
38 std::u16string product_name;
39 if (vendor_name.empty())
40 product_name = model_name;
41 else if (model_name.empty())
42 product_name = vendor_name;
43 else if (!vendor_name.empty() && !model_name.empty())
44 product_name = vendor_name + u", " + model_name;
51 namespace storage_monitor {
53 StorageInfo::StorageInfo() : total_size_in_bytes_(0) {
56 StorageInfo::StorageInfo(const StorageInfo& other) = default;
58 StorageInfo::StorageInfo(const std::string& device_id_in,
59 const base::FilePath::StringType& device_location,
60 const std::u16string& label,
61 const std::u16string& vendor,
62 const std::u16string& model,
63 uint64_t size_in_bytes)
64 : device_id_(device_id_in),
65 location_(device_location),
66 storage_label_(label),
69 total_size_in_bytes_(size_in_bytes) {}
71 StorageInfo::~StorageInfo() {
75 std::string StorageInfo::MakeDeviceId(Type type, const std::string& unique_id) {
76 DCHECK(!unique_id.empty());
78 case REMOVABLE_MASS_STORAGE_WITH_DCIM:
79 return std::string(kRemovableMassStorageWithDCIMPrefix) + unique_id;
80 case REMOVABLE_MASS_STORAGE_NO_DCIM:
81 return std::string(kRemovableMassStorageNoDCIMPrefix) + unique_id;
82 case FIXED_MASS_STORAGE:
83 return std::string(kFixedMassStoragePrefix) + unique_id;
85 return std::string(kMtpPtpPrefix) + unique_id;
86 case MAC_IMAGE_CAPTURE:
87 return std::string(kMacImageCapturePrefix) + unique_id;
94 bool StorageInfo::CrackDeviceId(const std::string& device_id,
95 Type* type, std::string* unique_id) {
96 size_t prefix_length = device_id.find_first_of(':');
97 std::string prefix = prefix_length != std::string::npos
98 ? device_id.substr(0, prefix_length + 1)
102 if (prefix == kRemovableMassStorageWithDCIMPrefix) {
103 found_type = REMOVABLE_MASS_STORAGE_WITH_DCIM;
104 } else if (prefix == kRemovableMassStorageNoDCIMPrefix) {
105 found_type = REMOVABLE_MASS_STORAGE_NO_DCIM;
106 } else if (prefix == kFixedMassStoragePrefix) {
107 found_type = FIXED_MASS_STORAGE;
108 } else if (prefix == kMtpPtpPrefix) {
109 found_type = MTP_OR_PTP;
110 } else if (prefix == kMacImageCapturePrefix) {
111 found_type = MAC_IMAGE_CAPTURE;
113 // Users may have legacy device IDs in their profiles, like iPhoto, iTunes,
114 // or Picasa. Just reject them as invalid devices here.
121 *unique_id = device_id.substr(prefix_length + 1);
126 bool StorageInfo::IsMediaDevice(const std::string& device_id) {
128 return CrackDeviceId(device_id, &type, nullptr) &&
129 (type == REMOVABLE_MASS_STORAGE_WITH_DCIM || type == MTP_OR_PTP ||
130 type == MAC_IMAGE_CAPTURE);
134 bool StorageInfo::IsRemovableDevice(const std::string& device_id) {
136 return CrackDeviceId(device_id, &type, nullptr) &&
137 (type == REMOVABLE_MASS_STORAGE_WITH_DCIM ||
138 type == REMOVABLE_MASS_STORAGE_NO_DCIM || type == MTP_OR_PTP ||
139 type == MAC_IMAGE_CAPTURE);
143 bool StorageInfo::IsMassStorageDevice(const std::string& device_id) {
145 return CrackDeviceId(device_id, &type, nullptr) &&
146 (type == REMOVABLE_MASS_STORAGE_WITH_DCIM ||
147 type == REMOVABLE_MASS_STORAGE_NO_DCIM || type == FIXED_MASS_STORAGE);
151 bool StorageInfo::IsMTPDevice(const std::string& device_id) {
153 return CrackDeviceId(device_id, &type, nullptr) && type == MTP_OR_PTP;
156 std::u16string StorageInfo::GetDisplayName(bool with_size) const {
157 return GetDisplayNameWithOverride(std::u16string(), with_size);
160 std::u16string StorageInfo::GetDisplayNameWithOverride(
161 const std::u16string& override_display_name,
162 bool with_size) const {
163 if (!IsRemovableDevice(device_id_)) {
164 if (!storage_label_.empty())
165 return storage_label_;
166 return base::FilePath(location_).LossyDisplayName();
169 std::u16string name = override_display_name;
171 name = storage_label_;
173 name = GetFullProductName(vendor_name_, model_name_);
175 name = u"Unlabeled device";
178 name = GetDisplayNameForDevice(total_size_in_bytes_, name);
182 } // namespace storage_monitor