| // Copyright 2022 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/ash/crosapi/volume_manager_ash.h" |
| |
| #include <utility> |
| #include <vector> |
| |
| #include "base/memory/weak_ptr.h" |
| #include "chrome/browser/ash/file_manager/volume_manager.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/profiles/profile_manager.h" |
| |
| namespace crosapi { |
| |
| namespace { |
| |
| bool IsVolumeAvailableToLacros(const file_manager::Volume& volume) { |
| // Use type (available only in ash-chrome) to decide whether a volume can be |
| // used by lacros-chrome. This is needed because virtual file system support |
| // for lacros is WIP. |
| // TODO(crbug.com/1296438): Adjust as needed re. VFS support progress, being |
| // mindful of version skew and its limits. |
| auto type = volume.type(); |
| return type == file_manager::VOLUME_TYPE_DOWNLOADS_DIRECTORY || |
| type == file_manager::VOLUME_TYPE_REMOVABLE_DISK_PARTITION || |
| type == file_manager::VOLUME_TYPE_MOUNTED_ARCHIVE_FILE || |
| type == file_manager::VOLUME_TYPE_SMB; |
| } |
| |
| crosapi::mojom::VolumePtr ConvertVolumeToMojom( |
| const file_manager::Volume& src_volume) { |
| crosapi::mojom::VolumePtr dst_volume = crosapi::mojom::Volume::New(); |
| dst_volume->volume_id = src_volume.volume_id(); |
| dst_volume->volume_label = src_volume.volume_label(); |
| dst_volume->writable = !src_volume.is_read_only(); |
| // TODO(crbug.com/1296438): Deprecate once VFS works fully, being mindful of |
| // version skew and its limits. |
| dst_volume->is_available_to_lacros = IsVolumeAvailableToLacros(src_volume); |
| dst_volume->mount_path = src_volume.mount_path(); |
| return dst_volume; |
| } |
| |
| std::vector<crosapi::mojom::VolumePtr> ConvertVolumeListToMojom( |
| std::vector<base::WeakPtr<file_manager::Volume>> src_volume_list) { |
| std::vector<crosapi::mojom::VolumePtr> dst_volume_list; |
| for (const auto& src_volume : src_volume_list) { |
| if (src_volume.get()) |
| dst_volume_list.emplace_back(ConvertVolumeToMojom(*src_volume)); |
| } |
| return dst_volume_list; |
| } |
| |
| // Returns volume list converted to crosapi form. |
| std::vector<crosapi::mojom::VolumePtr> ReadVolumeList() { |
| content::BrowserContext* browser_context = |
| ProfileManager::GetPrimaryUserProfile(); |
| const std::vector<base::WeakPtr<file_manager::Volume>> volume_list = |
| file_manager::VolumeManager::Get(browser_context)->GetVolumeList(); |
| return ConvertVolumeListToMojom(volume_list); |
| } |
| |
| } // namespace |
| |
| VolumeManagerAsh::VolumeManagerAsh() = default; |
| |
| VolumeManagerAsh::~VolumeManagerAsh() = default; |
| |
| void VolumeManagerAsh::BindReceiver( |
| mojo::PendingReceiver<mojom::VolumeManager> receiver) { |
| receivers_.Add(this, std::move(receiver)); |
| } |
| |
| void VolumeManagerAsh::AddVolumeListObserver( |
| mojo::PendingRemote<mojom::VolumeListObserver> observer) { |
| if (!is_observing_volume_manager_) { |
| Profile* profile = ProfileManager::GetPrimaryUserProfile(); |
| auto* volume_manager = file_manager::VolumeManager::Get(profile); |
| volume_manager->AddObserver(this); |
| is_observing_volume_manager_ = true; |
| } |
| |
| mojo::Remote<mojom::VolumeListObserver> remote(std::move(observer)); |
| // Note: The observer is NOT provided with the initial value. |
| |
| volume_list_observers_.Add(std::move(remote)); |
| } |
| |
| void VolumeManagerAsh::GetFullVolumeList(GetFullVolumeListCallback callback) { |
| std::move(callback).Run(ReadVolumeList()); |
| } |
| |
| void VolumeManagerAsh::GetVolumeMountInfo(const std::string& volume_id, |
| GetVolumeMountInfoCallback callback) { |
| content::BrowserContext* browser_context = |
| ProfileManager::GetPrimaryUserProfile(); |
| |
| base::WeakPtr<file_manager::Volume> src_volume = |
| file_manager::VolumeManager::Get(browser_context) |
| ->FindVolumeById(volume_id); |
| std::move(callback).Run(src_volume.get() ? ConvertVolumeToMojom(*src_volume) |
| : nullptr); |
| } |
| |
| void VolumeManagerAsh::OnVolumeMounted(ash::MountError error_code, |
| const file_manager::Volume& volume) { |
| DispatchVolumeList(); |
| } |
| |
| void VolumeManagerAsh::OnVolumeUnmounted(ash::MountError error_code, |
| const file_manager::Volume& volume) { |
| DispatchVolumeList(); |
| } |
| |
| void VolumeManagerAsh::OnShutdownStart( |
| file_manager::VolumeManager* volume_manager) { |
| // Using DCHECK since this function gets called only if observing. |
| DCHECK(is_observing_volume_manager_); |
| volume_manager->RemoveObserver(this); |
| is_observing_volume_manager_ = false; |
| } |
| |
| void VolumeManagerAsh::DispatchVolumeList() { |
| if (volume_list_observers_.empty()) |
| return; |
| std::vector<crosapi::mojom::VolumePtr> volume_list = ReadVolumeList(); |
| for (auto& observer : volume_list_observers_) { |
| std::vector<crosapi::mojom::VolumePtr> volume_list_copy; |
| for (auto& volume : volume_list) { |
| volume_list_copy.emplace_back(volume->Clone()); |
| } |
| observer->OnVolumeListChanged(std::move(volume_list_copy)); |
| } |
| } |
| |
| } // namespace crosapi |