1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
// Copyright 2023 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/file_system_access/cloud_identifier/cloud_identifier_util_ash.h"
#include <memory>
#include <optional>
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/strings/string_util.h"
#include "chrome/browser/ash/crosapi/crosapi_util.h"
#include "chrome/browser/ash/drive/drive_integration_service.h"
#include "chrome/browser/ash/drive/file_system_util.h"
#include "chrome/browser/ash/file_manager/fileapi_util.h"
#include "chrome/browser/ash/file_system_provider/mount_path_util.h"
#include "chrome/browser/ash/file_system_provider/provided_file_system_interface.h"
#include "chrome/browser/ash/profiles/profile_helper.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chromeos/ash/components/drivefs/drivefs_util.h"
#include "chromeos/ash/components/drivefs/mojom/drivefs.mojom.h"
#include "chromeos/crosapi/mojom/file_system_access_cloud_identifier.mojom.h"
#include "components/drive/file_errors.h"
#include "content/public/browser/browser_thread.h"
#include "storage/browser/file_system/file_system_context.h"
namespace {
constexpr char kDriveFsProviderName[] = "drive.google.com";
// Files/directories which have not yet been uploaded have not received a proper
// ID yet and will have a "local" ID instead. This prefix is defined upstream at
// http://google3/apps/drive/cello/common/item_util.h
constexpr char kDriveFsLocalPrefix[] = "local-";
bool MatchesExpectedDriveFsType(crosapi::mojom::HandleType expected_handle_type,
drivefs::mojom::FileMetadata::Type type) {
switch (expected_handle_type) {
case crosapi::mojom::HandleType::kUnknown:
return false;
case crosapi::mojom::HandleType::kFile:
return drivefs::IsAFile(type);
case crosapi::mojom::HandleType::kDirectory:
return drivefs::IsADirectory(type);
}
}
bool MatchesExpectedProvidedFsType(
crosapi::mojom::HandleType expected_handle_type,
bool is_directory) {
switch (expected_handle_type) {
case crosapi::mojom::HandleType::kUnknown:
return false;
case crosapi::mojom::HandleType::kFile:
return !is_directory;
case crosapi::mojom::HandleType::kDirectory:
return is_directory;
}
}
void DidGetDriveFSMetadata(crosapi::mojom::HandleType expected_handle_type,
crosapi::FileSystemAccessCloudIdentifierProviderAsh::
GetCloudIdentifierCallback callback,
drive::FileError error,
drivefs::mojom::FileMetadataPtr metadata) {
if (error != drive::FILE_ERROR_OK || metadata.is_null() ||
!metadata->item_id.has_value() ||
base::StartsWith(metadata->item_id.value(), kDriveFsLocalPrefix) ||
!MatchesExpectedDriveFsType(expected_handle_type, metadata->type)) {
std::move(callback).Run(nullptr);
return;
}
const std::string& item_id = metadata->item_id.value();
crosapi::mojom::FileSystemAccessCloudIdentifierPtr cloud_identifier =
crosapi::mojom::FileSystemAccessCloudIdentifier::New(kDriveFsProviderName,
item_id);
std::move(callback).Run(std::move(cloud_identifier));
}
void DidGetProvidedFilesystemMetada(
crosapi::mojom::HandleType expected_handle_type,
crosapi::FileSystemAccessCloudIdentifierProviderAsh::
GetCloudIdentifierCallback callback,
std::unique_ptr<ash::file_system_provider::EntryMetadata> metadata,
base::File::Error result) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
if (result != base::File::FILE_OK || !metadata ||
!metadata->cloud_identifier || !metadata->is_directory.get() ||
!MatchesExpectedProvidedFsType(expected_handle_type,
*metadata->is_directory)) {
std::move(callback).Run(nullptr);
return;
}
crosapi::mojom::FileSystemAccessCloudIdentifierPtr cloud_identifier =
crosapi::mojom::FileSystemAccessCloudIdentifier::New(
metadata->cloud_identifier->provider_name,
metadata->cloud_identifier->id);
std::move(callback).Run(std::move(cloud_identifier));
}
} // namespace
namespace cloud_identifier {
void GetCloudIdentifier(const base::FilePath& virtual_path,
crosapi::mojom::HandleType handle_type,
crosapi::FileSystemAccessCloudIdentifierProviderAsh::
GetCloudIdentifierCallback callback) {
Profile* profile =
g_browser_process->profile_manager()->GetActiveUserProfile();
CHECK(profile);
storage::FileSystemContext* file_system_context =
file_manager::util::GetFileManagerFileSystemContext(profile);
CHECK(file_system_context);
const storage::FileSystemURL url =
file_system_context->CreateCrackedFileSystemURL(
blink::StorageKey(), storage::kFileSystemTypeExternal, virtual_path);
CHECK(url.is_valid());
if (url.type() == storage::kFileSystemTypeDriveFs) {
auto* drive_integration_service =
drive::util::GetIntegrationServiceByProfile(profile);
drive_integration_service->GetMetadata(
url.path(), base::BindOnce(&DidGetDriveFSMetadata, handle_type,
std::move(callback)));
return;
}
if (url.type() == storage::FileSystemType::kFileSystemTypeProvided) {
ash::file_system_provider::util::FileSystemURLParser parser(url);
if (!parser.Parse()) {
std::move(callback).Run(nullptr);
return;
}
ash::file_system_provider::ProvidedFileSystemInterface::MetadataFieldMask
fields = ash::file_system_provider::ProvidedFileSystemInterface::
METADATA_FIELD_CLOUD_IDENTIFIER |
ash::file_system_provider::ProvidedFileSystemInterface::
METADATA_FIELD_IS_DIRECTORY;
parser.file_system()->GetMetadata(
parser.file_path(), fields,
base::BindOnce(&DidGetProvidedFilesystemMetada, handle_type,
std::move(callback)));
return;
}
// Unsupported file system type.
std::move(callback).Run(nullptr);
}
} // namespace cloud_identifier
|