1 // Copyright 2018 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/mtp_manager_client_chromeos.h"
9 #include "base/containers/contains.h"
10 #include "base/functional/bind.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "components/storage_monitor/storage_info.h"
13 #include "components/storage_monitor/storage_info_utils.h"
15 namespace storage_monitor {
17 MtpManagerClientChromeOS::MtpManagerClientChromeOS(
18 StorageMonitor::Receiver* receiver,
19 device::mojom::MtpManager* mtp_manager)
20 : mtp_manager_(mtp_manager), notifications_(receiver) {
21 mtp_manager_->EnumerateStoragesAndSetClient(
22 receiver_.BindNewEndpointAndPassRemote(),
23 base::BindOnce(&MtpManagerClientChromeOS::OnReceivedStorages,
24 weak_ptr_factory_.GetWeakPtr()));
27 MtpManagerClientChromeOS::~MtpManagerClientChromeOS() {}
29 bool MtpManagerClientChromeOS::GetStorageInfoForPath(
30 const base::FilePath& path,
31 StorageInfo* storage_info) const {
34 if (!path.IsAbsolute())
37 std::vector<base::FilePath::StringType> path_components =
39 if (path_components.size() < 2)
42 // First and second component of the path specifies the device location.
43 // E.g.: If |path| is "/usb:2,2:65537/DCIM/Folder_a", "/usb:2,2:65537" is the
46 storage_map_.find(GetDeviceLocationFromStorageName(path_components[1]));
47 if (info_it == storage_map_.end())
50 *storage_info = info_it->second;
54 void MtpManagerClientChromeOS::EjectDevice(
55 const std::string& device_id,
56 base::OnceCallback<void(StorageMonitor::EjectStatus)> callback) {
58 if (!GetLocationForDeviceId(device_id, &location)) {
59 std::move(callback).Run(StorageMonitor::EJECT_NO_SUCH_DEVICE);
63 // TODO(thestig): Change this to tell the MTP manager to eject the device.
65 StorageDetached(location);
66 std::move(callback).Run(StorageMonitor::EJECT_OK);
69 // device::mojom::MtpManagerClient override.
70 void MtpManagerClientChromeOS::StorageAttached(
71 device::mojom::MtpStorageInfoPtr mtp_storage_info) {
72 if (!mtp_storage_info)
75 // Create StorageMonitor format StorageInfo and update the local map.
76 std::string device_id = GetDeviceIdFromStorageInfo(*mtp_storage_info);
77 std::u16string storage_label =
78 GetDeviceLabelFromStorageInfo(*mtp_storage_info);
79 std::string location =
80 GetDeviceLocationFromStorageName(mtp_storage_info->storage_name);
81 std::u16string vendor_name = base::UTF8ToUTF16(mtp_storage_info->vendor);
82 std::u16string product_name = base::UTF8ToUTF16(mtp_storage_info->product);
84 if (device_id.empty() || storage_label.empty())
87 DCHECK(!base::Contains(storage_map_, location));
89 StorageInfo storage_info(device_id, location, storage_label, vendor_name,
91 storage_map_[location] = storage_info;
93 // Notify StorageMonitor observers about the event.
94 notifications_->ProcessAttach(storage_info);
97 // device::mojom::MtpManagerClient override.
98 void MtpManagerClientChromeOS::StorageDetached(
99 const std::string& storage_name) {
100 DCHECK(!storage_name.empty());
102 StorageLocationToInfoMap::iterator it =
103 storage_map_.find(GetDeviceLocationFromStorageName(storage_name));
104 if (it == storage_map_.end())
107 // Notify StorageMonitor observers about the event.
108 notifications_->ProcessDetach(it->second.device_id());
109 storage_map_.erase(it);
112 void MtpManagerClientChromeOS::OnReceivedStorages(
113 std::vector<device::mojom::MtpStorageInfoPtr> storage_info_list) {
114 for (auto& storage_info : storage_info_list)
115 StorageAttached(std::move(storage_info));
118 bool MtpManagerClientChromeOS::GetLocationForDeviceId(
119 const std::string& device_id,
120 std::string* location) const {
121 for (const auto& it : storage_map_) {
122 if (it.second.device_id() == device_id) {
123 *location = it.first;
130 } // namespace storage_monitor