This source file includes following definitions.
- GetDeviceLocationFromStorageName
- GetStorageIdFromStorageName
- GetDeviceIdFromStorageInfo
- GetFormattedIdString
- GetDeviceLabelFromStorageInfo
- GetStorageInfo
- notifications_
- notifications_
- MediaTransferProtocolDeviceObserverLinux
- GetStorageInfoForPath
- EjectDevice
- StorageChanged
- EnumerateStorages
- GetLocationForDeviceId
#include "components/storage_monitor/media_transfer_protocol_device_observer_linux.h"
#include <vector>
#include "base/files/file_path.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/utf_string_conversions.h"
#include "components/storage_monitor/media_storage_util.h"
#include "components/storage_monitor/removable_device_constants.h"
#include "device/media_transfer_protocol/mtp_storage_info.pb.h"
namespace storage_monitor {
namespace {
const char kRootPath[] = "/";
std::string GetDeviceLocationFromStorageName(const std::string& storage_name) {
DCHECK(!storage_name.empty());
return kRootPath + storage_name;
}
std::string GetStorageIdFromStorageName(const std::string& storage_name) {
std::vector<std::string> name_parts;
base::SplitString(storage_name, ':', &name_parts);
return name_parts.size() == 3 ? name_parts[2] : std::string();
}
std::string GetDeviceIdFromStorageInfo(const MtpStorageInfo& storage_info) {
const std::string storage_id =
GetStorageIdFromStorageName(storage_info.storage_name());
if (storage_id.empty())
return std::string();
const std::string vendor_id = base::UintToString(storage_info.vendor_id());
const std::string model_id = base::UintToString(storage_info.product_id());
return StorageInfo::MakeDeviceId(
StorageInfo::MTP_OR_PTP,
kVendorModelVolumeStoragePrefix + vendor_id + ":" + model_id + ":" +
storage_info.volume_identifier() + ":" + storage_id);
}
std::string GetFormattedIdString(const std::string& data_store_id) {
return ("(" + data_store_id + ")");
}
base::string16 GetDeviceLabelFromStorageInfo(
const MtpStorageInfo& storage_info) {
std::string device_label;
const std::string& vendor_name = storage_info.vendor();
device_label = vendor_name;
const std::string& product_name = storage_info.product();
if (!product_name.empty()) {
if (!device_label.empty())
device_label += " ";
device_label += product_name;
}
if (!device_label.empty()) {
const std::string& volume_id = storage_info.volume_identifier();
if (!volume_id.empty()) {
device_label += GetFormattedIdString(volume_id);
} else {
const std::string data_store_id =
GetStorageIdFromStorageName(storage_info.storage_name());
if (!data_store_id.empty())
device_label += GetFormattedIdString(data_store_id);
}
}
return base::UTF8ToUTF16(device_label);
}
void GetStorageInfo(const std::string& storage_name,
device::MediaTransferProtocolManager* mtp_manager,
std::string* id,
base::string16* label,
std::string* location) {
DCHECK(!storage_name.empty());
const MtpStorageInfo* storage_info =
mtp_manager->GetStorageInfo(storage_name);
if (!storage_info)
return;
*id = GetDeviceIdFromStorageInfo(*storage_info);
*label = GetDeviceLabelFromStorageInfo(*storage_info);
*location = GetDeviceLocationFromStorageName(storage_name);
}
}
MediaTransferProtocolDeviceObserverLinux::
MediaTransferProtocolDeviceObserverLinux(
StorageMonitor::Receiver* receiver,
device::MediaTransferProtocolManager* mtp_manager)
: mtp_manager_(mtp_manager),
get_storage_info_func_(&GetStorageInfo),
notifications_(receiver) {
mtp_manager_->AddObserver(this);
EnumerateStorages();
}
MediaTransferProtocolDeviceObserverLinux::
MediaTransferProtocolDeviceObserverLinux(
StorageMonitor::Receiver* receiver,
device::MediaTransferProtocolManager* mtp_manager,
GetStorageInfoFunc get_storage_info_func)
: mtp_manager_(mtp_manager),
get_storage_info_func_(get_storage_info_func),
notifications_(receiver) {
}
MediaTransferProtocolDeviceObserverLinux::
~MediaTransferProtocolDeviceObserverLinux() {
mtp_manager_->RemoveObserver(this);
}
bool MediaTransferProtocolDeviceObserverLinux::GetStorageInfoForPath(
const base::FilePath& path,
StorageInfo* storage_info) const {
DCHECK(storage_info);
if (!path.IsAbsolute())
return false;
std::vector<base::FilePath::StringType> path_components;
path.GetComponents(&path_components);
if (path_components.size() < 2)
return false;
StorageLocationToInfoMap::const_iterator info_it =
storage_map_.find(GetDeviceLocationFromStorageName(path_components[1]));
if (info_it == storage_map_.end())
return false;
*storage_info = info_it->second;
return true;
}
void MediaTransferProtocolDeviceObserverLinux::EjectDevice(
const std::string& device_id,
base::Callback<void(StorageMonitor::EjectStatus)> callback) {
std::string location;
if (!GetLocationForDeviceId(device_id, &location)) {
callback.Run(StorageMonitor::EJECT_NO_SUCH_DEVICE);
return;
}
StorageChanged(false, location);
callback.Run(StorageMonitor::EJECT_OK);
}
void MediaTransferProtocolDeviceObserverLinux::StorageChanged(
bool is_attached,
const std::string& storage_name) {
DCHECK(!storage_name.empty());
if (is_attached) {
std::string device_id;
base::string16 storage_label;
std::string location;
get_storage_info_func_(storage_name, mtp_manager_,
&device_id, &storage_label, &location);
MediaStorageUtil::RecordDeviceInfoHistogram(false, device_id,
storage_label);
if (device_id.empty() || storage_label.empty())
return;
DCHECK(!ContainsKey(storage_map_, location));
StorageInfo storage_info(device_id, location, storage_label,
base::string16(), base::string16(), 0);
storage_map_[location] = storage_info;
notifications_->ProcessAttach(storage_info);
} else {
StorageLocationToInfoMap::iterator it =
storage_map_.find(GetDeviceLocationFromStorageName(storage_name));
if (it == storage_map_.end())
return;
notifications_->ProcessDetach(it->second.device_id());
storage_map_.erase(it);
}
}
void MediaTransferProtocolDeviceObserverLinux::EnumerateStorages() {
typedef std::vector<std::string> StorageList;
StorageList storages = mtp_manager_->GetStorages();
for (StorageList::const_iterator storage_iter = storages.begin();
storage_iter != storages.end(); ++storage_iter) {
StorageChanged(true, *storage_iter);
}
}
bool MediaTransferProtocolDeviceObserverLinux::GetLocationForDeviceId(
const std::string& device_id, std::string* location) const {
for (StorageLocationToInfoMap::const_iterator it = storage_map_.begin();
it != storage_map_.end(); ++it) {
if (it->second.device_id() == device_id) {
*location = it->first;
return true;
}
}
return false;
}
}