// Copyright 2018 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "components/storage_monitor/mtp_manager_client_chromeos.h" #include #include "base/bind.h" #include "base/containers/contains.h" #include "base/strings/utf_string_conversions.h" #include "components/storage_monitor/storage_info.h" #include "components/storage_monitor/storage_info_utils.h" namespace storage_monitor { MtpManagerClientChromeOS::MtpManagerClientChromeOS( StorageMonitor::Receiver* receiver, device::mojom::MtpManager* mtp_manager) : mtp_manager_(mtp_manager), notifications_(receiver) { mtp_manager_->EnumerateStoragesAndSetClient( receiver_.BindNewEndpointAndPassRemote(), base::BindOnce(&MtpManagerClientChromeOS::OnReceivedStorages, weak_ptr_factory_.GetWeakPtr())); } MtpManagerClientChromeOS::~MtpManagerClientChromeOS() {} bool MtpManagerClientChromeOS::GetStorageInfoForPath( const base::FilePath& path, StorageInfo* storage_info) const { DCHECK(storage_info); if (!path.IsAbsolute()) return false; std::vector path_components = path.GetComponents(); if (path_components.size() < 2) return false; // First and second component of the path specifies the device location. // E.g.: If |path| is "/usb:2,2:65537/DCIM/Folder_a", "/usb:2,2:65537" is the // device location. const auto 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 MtpManagerClientChromeOS::EjectDevice( const std::string& device_id, base::OnceCallback callback) { std::string location; if (!GetLocationForDeviceId(device_id, &location)) { std::move(callback).Run(StorageMonitor::EJECT_NO_SUCH_DEVICE); return; } // TODO(thestig): Change this to tell the MTP manager to eject the device. StorageDetached(location); std::move(callback).Run(StorageMonitor::EJECT_OK); } // device::mojom::MtpManagerClient override. void MtpManagerClientChromeOS::StorageAttached( device::mojom::MtpStorageInfoPtr mtp_storage_info) { if (!mtp_storage_info) return; // Create StorageMonitor format StorageInfo and update the local map. std::string device_id = GetDeviceIdFromStorageInfo(*mtp_storage_info); std::u16string storage_label = GetDeviceLabelFromStorageInfo(*mtp_storage_info); std::string location = GetDeviceLocationFromStorageName(mtp_storage_info->storage_name); std::u16string vendor_name = base::UTF8ToUTF16(mtp_storage_info->vendor); std::u16string product_name = base::UTF8ToUTF16(mtp_storage_info->product); if (device_id.empty() || storage_label.empty()) return; DCHECK(!base::Contains(storage_map_, location)); StorageInfo storage_info(device_id, location, storage_label, vendor_name, product_name, 0); storage_map_[location] = storage_info; // Notify StorageMonitor observers about the event. notifications_->ProcessAttach(storage_info); } // device::mojom::MtpManagerClient override. void MtpManagerClientChromeOS::StorageDetached( const std::string& storage_name) { DCHECK(!storage_name.empty()); StorageLocationToInfoMap::iterator it = storage_map_.find(GetDeviceLocationFromStorageName(storage_name)); if (it == storage_map_.end()) return; // Notify StorageMonitor observers about the event. notifications_->ProcessDetach(it->second.device_id()); storage_map_.erase(it); } void MtpManagerClientChromeOS::OnReceivedStorages( std::vector storage_info_list) { for (auto& storage_info : storage_info_list) StorageAttached(std::move(storage_info)); } bool MtpManagerClientChromeOS::GetLocationForDeviceId( const std::string& device_id, std::string* location) const { for (const auto& it : storage_map_) { if (it.second.device_id() == device_id) { *location = it.first; return true; } } return false; } } // namespace storage_monitor