1 // Copyright 2014 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 "components/storage_monitor/storage_info.h"
6
7 #include "base/logging.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "components/storage_monitor/media_storage_util.h"
10 #include "ui/base/l10n/l10n_util.h"
11 #include "ui/base/text/bytes_formatting.h"
12
13 namespace {
14
15 // Prefix constants for different device id spaces.
16 const char kRemovableMassStorageWithDCIMPrefix[] = "dcim:";
17 const char kRemovableMassStorageNoDCIMPrefix[] = "nodcim:";
18 const char kFixedMassStoragePrefix[] = "path:";
19 const char kMtpPtpPrefix[] = "mtp:";
20 const char kMacImageCapturePrefix[] = "ic:";
21 const char kITunesPrefix[] = "itunes:";
22 const char kPicasaPrefix[] = "picasa:";
23 const char kIPhotoPrefix[] = "iphoto:";
24
GetDisplayNameForDevice(uint64 storage_size_in_bytes,const base::string16 & name)25 base::string16 GetDisplayNameForDevice(uint64 storage_size_in_bytes,
26 const base::string16& name) {
27 DCHECK(!name.empty());
28 return (storage_size_in_bytes == 0) ?
29 name :
30 ui::FormatBytes(storage_size_in_bytes) + base::ASCIIToUTF16(" ") + name;
31 }
32
GetFullProductName(const base::string16 & vendor_name,const base::string16 & model_name)33 base::string16 GetFullProductName(const base::string16& vendor_name,
34 const base::string16& model_name) {
35 if (vendor_name.empty() && model_name.empty())
36 return base::string16();
37
38 base::string16 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 + base::UTF8ToUTF16(", ") + model_name;
45
46 return product_name;
47 }
48
49 } // namespace
50
51 namespace storage_monitor {
52
StorageInfo()53 StorageInfo::StorageInfo() : total_size_in_bytes_(0) {
54 }
55
StorageInfo(const std::string & device_id_in,const base::FilePath::StringType & device_location,const base::string16 & label,const base::string16 & vendor,const base::string16 & model,uint64 size_in_bytes)56 StorageInfo::StorageInfo(const std::string& device_id_in,
57 const base::FilePath::StringType& device_location,
58 const base::string16& label,
59 const base::string16& vendor,
60 const base::string16& model,
61 uint64 size_in_bytes)
62 : device_id_(device_id_in),
63 location_(device_location),
64 storage_label_(label),
65 vendor_name_(vendor),
66 model_name_(model),
67 total_size_in_bytes_(size_in_bytes) {
68 }
69
~StorageInfo()70 StorageInfo::~StorageInfo() {
71 }
72
73 // static
MakeDeviceId(Type type,const std::string & unique_id)74 std::string StorageInfo::MakeDeviceId(Type type, const std::string& unique_id) {
75 DCHECK(!unique_id.empty());
76 switch (type) {
77 case REMOVABLE_MASS_STORAGE_WITH_DCIM:
78 return std::string(kRemovableMassStorageWithDCIMPrefix) + unique_id;
79 case REMOVABLE_MASS_STORAGE_NO_DCIM:
80 return std::string(kRemovableMassStorageNoDCIMPrefix) + unique_id;
81 case FIXED_MASS_STORAGE:
82 return std::string(kFixedMassStoragePrefix) + unique_id;
83 case MTP_OR_PTP:
84 return std::string(kMtpPtpPrefix) + unique_id;
85 case MAC_IMAGE_CAPTURE:
86 return std::string(kMacImageCapturePrefix) + unique_id;
87 case ITUNES:
88 return std::string(kITunesPrefix) + unique_id;
89 case PICASA:
90 return std::string(kPicasaPrefix) + unique_id;
91 case IPHOTO:
92 return std::string(kIPhotoPrefix) + unique_id;
93 }
94 NOTREACHED();
95 return std::string();
96 }
97
98 // static
CrackDeviceId(const std::string & device_id,Type * type,std::string * unique_id)99 bool StorageInfo::CrackDeviceId(const std::string& device_id,
100 Type* type, std::string* unique_id) {
101 size_t prefix_length = device_id.find_first_of(':');
102 std::string prefix = prefix_length != std::string::npos
103 ? device_id.substr(0, prefix_length + 1)
104 : std::string();
105
106 Type found_type;
107 if (prefix == kRemovableMassStorageWithDCIMPrefix) {
108 found_type = REMOVABLE_MASS_STORAGE_WITH_DCIM;
109 } else if (prefix == kRemovableMassStorageNoDCIMPrefix) {
110 found_type = REMOVABLE_MASS_STORAGE_NO_DCIM;
111 } else if (prefix == kFixedMassStoragePrefix) {
112 found_type = FIXED_MASS_STORAGE;
113 } else if (prefix == kMtpPtpPrefix) {
114 found_type = MTP_OR_PTP;
115 } else if (prefix == kMacImageCapturePrefix) {
116 found_type = MAC_IMAGE_CAPTURE;
117 } else if (prefix == kITunesPrefix) {
118 found_type = ITUNES;
119 } else if (prefix == kPicasaPrefix) {
120 found_type = PICASA;
121 } else if (prefix == kIPhotoPrefix) {
122 found_type = IPHOTO;
123 } else {
124 NOTREACHED();
125 return false;
126 }
127 if (type)
128 *type = found_type;
129
130 if (unique_id)
131 *unique_id = device_id.substr(prefix_length + 1);
132 return true;
133 }
134
135 // static
IsMediaDevice(const std::string & device_id)136 bool StorageInfo::IsMediaDevice(const std::string& device_id) {
137 Type type;
138 return CrackDeviceId(device_id, &type, NULL) &&
139 (type == REMOVABLE_MASS_STORAGE_WITH_DCIM || type == MTP_OR_PTP ||
140 type == MAC_IMAGE_CAPTURE);
141 }
142
143 // static
IsRemovableDevice(const std::string & device_id)144 bool StorageInfo::IsRemovableDevice(const std::string& device_id) {
145 Type type;
146 return CrackDeviceId(device_id, &type, NULL) &&
147 (type == REMOVABLE_MASS_STORAGE_WITH_DCIM ||
148 type == REMOVABLE_MASS_STORAGE_NO_DCIM ||
149 type == MTP_OR_PTP ||
150 type == MAC_IMAGE_CAPTURE);
151 }
152
153 // static
IsMassStorageDevice(const std::string & device_id)154 bool StorageInfo::IsMassStorageDevice(const std::string& device_id) {
155 Type type;
156 return CrackDeviceId(device_id, &type, NULL) &&
157 (type == REMOVABLE_MASS_STORAGE_WITH_DCIM ||
158 type == REMOVABLE_MASS_STORAGE_NO_DCIM ||
159 type == FIXED_MASS_STORAGE ||
160 type == ITUNES ||
161 type == IPHOTO ||
162 type == PICASA);
163 }
164
165 // static
IsITunesDevice(const std::string & device_id)166 bool StorageInfo::IsITunesDevice(const std::string& device_id) {
167 Type type;
168 return CrackDeviceId(device_id, &type, NULL) && type == ITUNES;
169 }
170
171 // static
IsIPhotoDevice(const std::string & device_id)172 bool StorageInfo::IsIPhotoDevice(const std::string& device_id) {
173 Type type;
174 return CrackDeviceId(device_id, &type, NULL) && type == IPHOTO;
175 }
176
177 // static
IsPicasaDevice(const std::string & device_id)178 bool StorageInfo::IsPicasaDevice(const std::string& device_id) {
179 Type type;
180 return CrackDeviceId(device_id, &type, NULL) && type == PICASA;
181 }
182
183 // static
IsMTPDevice(const std::string & device_id)184 bool StorageInfo::IsMTPDevice(const std::string& device_id) {
185 Type type;
186 return CrackDeviceId(device_id, &type, NULL) && type == MTP_OR_PTP;
187 }
188
GetDisplayName(bool with_size) const189 base::string16 StorageInfo::GetDisplayName(bool with_size) const {
190 return GetDisplayNameWithOverride(base::string16(), with_size);
191 }
192
GetDisplayNameWithOverride(const base::string16 & override_display_name,bool with_size) const193 base::string16 StorageInfo::GetDisplayNameWithOverride(
194 const base::string16& override_display_name, bool with_size) const {
195 if (!IsRemovableDevice(device_id_)) {
196 if (!storage_label_.empty())
197 return storage_label_;
198 return base::FilePath(location_).LossyDisplayName();
199 }
200
201 base::string16 name = override_display_name;
202 if (name.empty())
203 name = storage_label_;
204 if (name.empty())
205 name = GetFullProductName(vendor_name_, model_name_);
206 if (name.empty())
207 name = base::ASCIIToUTF16("Unlabeled device");
208
209 if (with_size)
210 name = GetDisplayNameForDevice(total_size_in_bytes_, name);
211 return name;
212 }
213
214 } // namespace storage_monitor
215