blob: 6a33f5d32fa23065aee073cc41cfa2663a5ecb9a [file] [log] [blame]
Avi Drissman4a8573c2022-09-09 19:35:541// Copyright 2013 The Chromium Authors
[email protected]55d9bed2011-03-25 20:37:592// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Yeunjoo Choief8a4a42022-11-08 04:21:055#include "chrome/browser/ash/fileapi/file_system_backend.h"
[email protected]55d9bed2011-03-25 20:37:596
avi8a07d53892015-12-24 22:13:537#include <stddef.h>
8
dcheng24002d02016-04-08 02:42:409#include <memory>
nya7b442602017-03-03 16:56:1110#include <utility>
dcheng24002d02016-04-08 02:42:4011
Yeunjoo Choi9b62f1a2021-06-23 13:17:0012#include "ash/webui/file_manager/url_constants.h"
Hans Wennborg1790e6b2020-04-24 19:10:3313#include "base/check_op.h"
yawanoe3893dbb2015-04-14 02:26:0214#include "base/command_line.h"
Daniel Brinkers9dacf9e12023-03-09 07:39:0515#include "base/functional/callback_helpers.h"
Hans Wennborg1790e6b2020-04-24 19:10:3316#include "base/notreached.h"
Ryan Hamilton7f3bd3d2022-04-23 00:07:3917#include "base/strings/escape.h"
Sam McNallyf41b98e2019-03-21 06:15:2318#include "base/task/task_traits.h"
Gabriel Charette055039132020-02-26 23:02:0619#include "base/task/thread_pool.h"
Henrique Ferreiroe828b7b02021-03-23 23:00:5920#include "chrome/browser/ash/arc/fileapi/arc_documents_provider_util.h"
Yeunjoo Choief8a4a42022-11-08 04:21:0521#include "chrome/browser/ash/fileapi/file_access_permissions.h"
Joel Hockeyd096e542023-08-07 06:01:2422#include "chrome/browser/ash/fileapi/file_system_backend.h"
Yeunjoo Choief8a4a42022-11-08 04:21:0523#include "chrome/browser/ash/fileapi/file_system_backend_delegate.h"
24#include "chrome/browser/ash/fileapi/observable_file_system_operation_impl.h"
Yeunjoo Choi15ab1ac2021-02-04 17:15:0725#include "chrome/browser/ash/profiles/profile_helper.h"
[email protected]bee0df312014-04-28 06:59:5826#include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
hirono10020e182014-09-24 05:31:5927#include "chrome/common/url_constants.h"
Yeunjoo Choif8f9bc72022-07-20 02:55:3928#include "chromeos/ash/components/dbus/cros_disks/cros_disks_client.h"
Eriko Kurimotodd765d12024-09-25 02:10:3929#include "chromeos/ash/components/file_manager/app_id.h"
Daniel Brinkers9dacf9e12023-03-09 07:39:0530#include "components/file_access/scoped_file_access_delegate.h"
Hidehiko Abed67cabd2023-01-17 18:34:5031#include "components/user_manager/user.h"
Joel Hockey9d2024942023-08-09 03:23:5632#include "extensions/common/extension.h"
DongJun Kimfebb3c22019-10-21 02:08:0633#include "storage/browser/file_system/async_file_util.h"
34#include "storage/browser/file_system/external_mount_points.h"
35#include "storage/browser/file_system/file_stream_reader.h"
36#include "storage/browser/file_system/file_stream_writer.h"
37#include "storage/browser/file_system/file_system_context.h"
38#include "storage/browser/file_system/file_system_operation.h"
39#include "storage/browser/file_system/file_system_operation_context.h"
40#include "storage/browser/file_system/file_system_url.h"
DongJun Kimd6930ea2019-10-24 08:49:2541#include "storage/common/file_system/file_system_mount_option.h"
42#include "storage/common/file_system/file_system_types.h"
43#include "storage/common/file_system/file_system_util.h"
Kyra Seevers104537e2021-08-11 16:22:4444#include "third_party/blink/public/common/storage_key/storage_key.h"
45#include "url/gurl.h"
46#include "url/origin.h"
[email protected]c6c3f932012-03-16 07:45:2747
Yeunjoo Choi3d9ed38a2022-11-10 02:51:2448namespace ash {
hirono431103fc2016-09-01 08:33:4249namespace {
50
David Black8f8c1eb2020-12-09 04:02:2351// Returns the `AccountId` associated with the specified `profile`.
52AccountId GetAccountId(Profile* profile) {
53 user_manager::User* user =
54 profile ? ProfileHelper::Get()->GetUserByProfile(profile) : nullptr;
55 return user ? user->GetAccountId() : AccountId();
56}
57
Joel Hockey9d2024942023-08-09 03:23:5658// Returns true if the BackendFunction and OperationType correspond to the
59// GetMetadata() and CreateFileStreamReader() calls used when loading a
60// filesystem: URL via FileSystemUrlLoaderFactory.
61bool IsReadOperation(BackendFunction backend_function,
62 storage::OperationType operation_type) {
63 if (backend_function == BackendFunction::kCreateFileSystemOperation &&
64 operation_type == storage::OperationType::kGetMetadata) {
65 return true;
66 }
67 if (backend_function == BackendFunction::kCreateFileStreamReader) {
68 return true;
69 }
70 return false;
71}
72
hirono431103fc2016-09-01 08:33:4273} // namespace
[email protected]bf48bed2012-02-24 20:49:0774
[email protected]9fb9294a2012-08-21 14:55:3775// static
[email protected]cd501a72014-08-22 19:58:3176bool FileSystemBackend::CanHandleURL(const storage::FileSystemURL& url) {
[email protected]9fb9294a2012-08-21 14:55:3777 if (!url.is_valid())
78 return false;
Austin Sullivan92338512021-01-28 23:32:5979 return url.type() == storage::kFileSystemTypeLocal ||
[email protected]cd501a72014-08-22 19:58:3180 url.type() == storage::kFileSystemTypeProvided ||
hashimotoa53e7e82016-10-26 06:30:4781 url.type() == storage::kFileSystemTypeDeviceMediaAsFileStorage ||
nyaf5df1e32016-12-14 04:36:1782 url.type() == storage::kFileSystemTypeArcContent ||
Sam McNallyd8b7d822018-08-21 03:18:1883 url.type() == storage::kFileSystemTypeArcDocumentsProvider ||
Anand K. Mistry5b28d1bc2019-10-30 06:53:5984 url.type() == storage::kFileSystemTypeDriveFs ||
Noel Gordonf9277482022-02-04 01:13:5085 url.type() == storage::kFileSystemTypeSmbFs ||
86 url.type() == storage::kFileSystemTypeFuseBox;
[email protected]bf48bed2012-02-24 20:49:0787}
88
[email protected]f19bbf62013-07-09 01:22:3289FileSystemBackend::FileSystemBackend(
David Black8f8c1eb2020-12-09 04:02:2390 Profile* profile,
hashimotoa53e7e82016-10-26 06:30:4791 std::unique_ptr<FileSystemBackendDelegate> file_system_provider_delegate,
92 std::unique_ptr<FileSystemBackendDelegate> mtp_delegate,
93 std::unique_ptr<FileSystemBackendDelegate> arc_content_delegate,
nyaf5df1e32016-12-14 04:36:1794 std::unique_ptr<FileSystemBackendDelegate> arc_documents_provider_delegate,
Sam McNallyd8b7d822018-08-21 03:18:1895 std::unique_ptr<FileSystemBackendDelegate> drivefs_delegate,
Anand K. Mistry7694c362020-03-17 23:33:3496 std::unique_ptr<FileSystemBackendDelegate> smbfs_delegate,
[email protected]cd501a72014-08-22 19:58:3197 scoped_refptr<storage::ExternalMountPoints> mount_points,
98 storage::ExternalMountPoints* system_mount_points)
David Black8f8c1eb2020-12-09 04:02:2399 : account_id_(GetAccountId(profile)),
100 file_access_permissions_(new FileAccessPermissions()),
[email protected]cd501a72014-08-22 19:58:31101 local_file_util_(storage::AsyncFileUtil::CreateForLocalFileSystem()),
hashimotoa53e7e82016-10-26 06:30:47102 file_system_provider_delegate_(std::move(file_system_provider_delegate)),
103 mtp_delegate_(std::move(mtp_delegate)),
104 arc_content_delegate_(std::move(arc_content_delegate)),
nyaf5df1e32016-12-14 04:36:17105 arc_documents_provider_delegate_(
106 std::move(arc_documents_provider_delegate)),
Sam McNallyd8b7d822018-08-21 03:18:18107 drivefs_delegate_(std::move(drivefs_delegate)),
Anand K. Mistry7694c362020-03-17 23:33:34108 smbfs_delegate_(std::move(smbfs_delegate)),
[email protected]9d5d6982013-01-18 03:12:54109 mount_points_(mount_points),
hashimotoa53e7e82016-10-26 06:30:47110 system_mount_points_(system_mount_points) {}
[email protected]3c3621b2013-06-07 06:12:34111
Sorin Jianu091a41a2024-12-03 00:51:44112FileSystemBackend::~FileSystemBackend() = default;
[email protected]3c3621b2013-06-07 06:12:34113
Joel Hockeyd096e542023-08-07 06:01:24114// static
115FileSystemBackend* FileSystemBackend::Get(
116 const storage::FileSystemContext& context) {
117 return static_cast<FileSystemBackend*>(
118 context.GetFileSystemBackend(storage::kFileSystemTypeExternal));
119}
120
[email protected]f19bbf62013-07-09 01:22:32121void FileSystemBackend::AddSystemMountPoints() {
[email protected]3c3621b2013-06-07 06:12:34122 // RegisterFileSystem() is no-op if the mount point with the same name
123 // already exists, hence it's safe to call without checking if a mount
124 // point already exists or not.
[email protected]a5a8b412013-03-04 15:03:11125 system_mount_points_->RegisterFileSystem(
Austin Sullivan92338512021-01-28 23:32:59126 kSystemMountNameArchive, storage::kFileSystemTypeLocal,
[email protected]cd501a72014-08-22 19:58:31127 storage::FileSystemMountOption(),
Yeunjoo Choi3d9ed38a2022-11-10 02:51:24128 CrosDisksClient::GetArchiveMountPoint());
[email protected]a5a8b412013-03-04 15:03:11129 system_mount_points_->RegisterFileSystem(
Austin Sullivan92338512021-01-28 23:32:59130 kSystemMountNameRemovable, storage::kFileSystemTypeLocal,
mtomasz92252d52014-12-11 01:49:47131 storage::FileSystemMountOption(storage::FlushPolicy::FLUSH_ON_COMPLETION),
Yeunjoo Choi3d9ed38a2022-11-10 02:51:24132 CrosDisksClient::GetRemovableDiskMountPoint());
[email protected]55d9bed2011-03-25 20:37:59133}
134
[email protected]cd501a72014-08-22 19:58:31135bool FileSystemBackend::CanHandleType(storage::FileSystemType type) const {
[email protected]420fb562013-04-18 01:46:34136 switch (type) {
[email protected]cd501a72014-08-22 19:58:31137 case storage::kFileSystemTypeExternal:
Austin Sullivan92338512021-01-28 23:32:59138 case storage::kFileSystemTypeLocal:
139 case storage::kFileSystemTypeLocalForPlatformApp:
[email protected]cd501a72014-08-22 19:58:31140 case storage::kFileSystemTypeDeviceMediaAsFileStorage:
141 case storage::kFileSystemTypeProvided:
hashimotoa53e7e82016-10-26 06:30:47142 case storage::kFileSystemTypeArcContent:
nyaf5df1e32016-12-14 04:36:17143 case storage::kFileSystemTypeArcDocumentsProvider:
Sam McNallyd8b7d822018-08-21 03:18:18144 case storage::kFileSystemTypeDriveFs:
Anand K. Mistry5b28d1bc2019-10-30 06:53:59145 case storage::kFileSystemTypeSmbFs:
Noel Gordonf9277482022-02-04 01:13:50146 case storage::kFileSystemTypeFuseBox:
[email protected]420fb562013-04-18 01:46:34147 return true;
148 default:
149 return false;
150 }
151}
152
Bo Majewskia382a372021-01-29 04:48:17153void FileSystemBackend::Initialize(storage::FileSystemContext* context) {}
[email protected]3fc17aed2013-07-24 10:01:50154
[email protected]cd501a72014-08-22 19:58:31155void FileSystemBackend::ResolveURL(const storage::FileSystemURL& url,
156 storage::OpenFileSystemMode mode,
Nathan Eliasonbca1174c2022-05-12 16:00:57157 ResolveURLCallback callback) {
[email protected]0fa422a2014-02-26 04:56:40158 std::string id;
[email protected]cd501a72014-08-22 19:58:31159 storage::FileSystemType type;
[email protected]7896ddc2014-06-20 10:40:16160 std::string cracked_id;
[email protected]0fa422a2014-02-26 04:56:40161 base::FilePath path;
[email protected]cd501a72014-08-22 19:58:31162 storage::FileSystemMountOption option;
Bo Majewskia382a372021-01-29 04:48:17163 if (!mount_points_->CrackVirtualPath(url.virtual_path(), &id, &type,
164 &cracked_id, &path, &option) &&
165 !system_mount_points_->CrackVirtualPath(url.virtual_path(), &id, &type,
166 &cracked_id, &path, &option)) {
[email protected]0fa422a2014-02-26 04:56:40167 // Not under a mount point, so return an error, since the root is not
168 // accessible.
[email protected]cd501a72014-08-22 19:58:31169 GURL root_url = GURL(storage::GetExternalFileSystemRootURIString(
Erik Anderson1606ab82019-02-04 22:15:25170 url.origin().GetURL(), std::string()));
tzik3abe87e2017-08-23 03:23:11171 std::move(callback).Run(root_url, std::string(),
172 base::File::FILE_ERROR_SECURITY);
[email protected]0fa422a2014-02-26 04:56:40173 return;
174 }
175
176 std::string name;
177 // Construct a URL restricted to the found mount point.
178 std::string root_url =
Erik Anderson1606ab82019-02-04 22:15:25179 storage::GetExternalFileSystemRootURIString(url.origin().GetURL(), id);
[email protected]0fa422a2014-02-26 04:56:40180
181 // For removable and archives, the file system root is the external mount
182 // point plus the inner mount point.
183 if (id == "archive" || id == "removable") {
Jeremy Roman9ec5db92022-02-14 19:46:34184 std::vector<std::string> components = url.virtual_path().GetComponents();
[email protected]0fa422a2014-02-26 04:56:40185 DCHECK_EQ(id, components.at(0));
186 if (components.size() < 2) {
187 // Unable to access /archive and /removable directories directly. The
188 // inner mount name must be specified.
tzik3abe87e2017-08-23 03:23:11189 std::move(callback).Run(GURL(root_url), std::string(),
190 base::File::FILE_ERROR_SECURITY);
[email protected]0fa422a2014-02-26 04:56:40191 return;
192 }
Peter Marshall58d4c132022-08-17 06:17:34193 std::string inner_mount_name = base::EscapePath(components[1]);
[email protected]0fa422a2014-02-26 04:56:40194 root_url += inner_mount_name + "/";
195 name = inner_mount_name;
nya4b8fa622017-01-12 10:57:26196 } else if (id == arc::kDocumentsProviderMountPointName) {
197 // For ARC documents provider file system, volumes are mounted per document
198 // provider root, so we need to fix up |root_url| to point to an individual
199 // root.
200 std::string authority;
Momoko Hattori416709e2024-02-13 15:43:18201 std::string root_id;
nya4b8fa622017-01-12 10:57:26202 base::FilePath unused_path;
Momoko Hattori416709e2024-02-13 15:43:18203 if (!arc::ParseDocumentsProviderUrl(url, &authority, &root_id,
nya4b8fa622017-01-12 10:57:26204 &unused_path)) {
tzik3abe87e2017-08-23 03:23:11205 std::move(callback).Run(GURL(root_url), std::string(),
206 base::File::FILE_ERROR_SECURITY);
nya4b8fa622017-01-12 10:57:26207 return;
208 }
209 base::FilePath mount_path =
Momoko Hattori416709e2024-02-13 15:43:18210 arc::GetDocumentsProviderMountPath(authority, root_id);
nya4b8fa622017-01-12 10:57:26211 base::FilePath relative_mount_path;
212 base::FilePath(arc::kDocumentsProviderMountPointPath)
213 .AppendRelativePath(mount_path, &relative_mount_path);
214 root_url +=
Ryan Hamilton7f3bd3d2022-04-23 00:07:39215 base::EscapePath(storage::FilePathToString(relative_mount_path)) + "/";
Momoko Hattori416709e2024-02-13 15:43:18216 name = authority + ":" + root_id;
[email protected]0fa422a2014-02-26 04:56:40217 } else {
218 name = id;
219 }
220
tzik3abe87e2017-08-23 03:23:11221 std::move(callback).Run(GURL(root_url), name, base::File::FILE_OK);
[email protected]55d9bed2011-03-25 20:37:59222}
223
[email protected]cd501a72014-08-22 19:58:31224storage::FileSystemQuotaUtil* FileSystemBackend::GetQuotaUtil() {
[email protected]4d038592013-02-18 16:50:23225 // No quota support.
Claudio DeSouza03dd22122022-09-02 23:47:21226 return nullptr;
[email protected]4d038592013-02-18 16:50:23227}
228
mtomasz110ffbe92014-09-11 10:35:40229const storage::UpdateObserverList* FileSystemBackend::GetUpdateObservers(
230 storage::FileSystemType type) const {
Claudio DeSouza03dd22122022-09-02 23:47:21231 return nullptr;
mtomasz110ffbe92014-09-11 10:35:40232}
233
234const storage::ChangeObserverList* FileSystemBackend::GetChangeObservers(
235 storage::FileSystemType type) const {
Claudio DeSouza03dd22122022-09-02 23:47:21236 return nullptr;
mtomasz110ffbe92014-09-11 10:35:40237}
238
239const storage::AccessObserverList* FileSystemBackend::GetAccessObservers(
240 storage::FileSystemType type) const {
Claudio DeSouza03dd22122022-09-02 23:47:21241 return nullptr;
mtomasz110ffbe92014-09-11 10:35:40242}
243
[email protected]f19bbf62013-07-09 01:22:32244bool FileSystemBackend::IsAccessAllowed(
Joel Hockey9d2024942023-08-09 03:23:56245 BackendFunction backend_function,
246 storage::OperationType operation_type,
[email protected]cd501a72014-08-22 19:58:31247 const storage::FileSystemURL& url) const {
[email protected]5b7e42e62013-01-24 22:01:51248 if (!url.is_valid())
[email protected]b777b332011-04-16 04:01:08249 return false;
[email protected]24dceaf2011-04-20 09:05:52250
[email protected]5b7e42e62013-01-24 22:01:51251 // No extra check is needed for isolated file systems.
[email protected]cd501a72014-08-22 19:58:31252 if (url.mount_type() == storage::kFileSystemTypeIsolated)
[email protected]5b7e42e62013-01-24 22:01:51253 return true;
254
255 if (!CanHandleURL(url))
256 return false;
257
Bo Majewski762d913a2021-06-30 03:54:25258 const url::Origin origin = url.origin();
mtomasza6775be2015-03-18 06:45:27259 // If there is no origin set, then it's an internal access.
Bo Majewski762d913a2021-06-30 03:54:25260 if (origin.opaque())
mtomasza6775be2015-03-18 06:45:27261 return true;
262
Alex Danilocf0eff82021-02-17 03:07:01263 // The chrome://file-manager can access its filesystem origin.
Yeunjoo Choi3d9ed38a2022-11-10 02:51:24264 if (origin.GetURL() == file_manager::kChromeUIFileManagerURL) {
Alex Danilocf0eff82021-02-17 03:07:01265 return true;
266 }
Alex Danilocf0eff82021-02-17 03:07:01267
Joel Hockey9d2024942023-08-09 03:23:56268 // ImageLoader extension has read-only access via FileSystemUrlLoaderFactory.
269 if (origin.GetURL() == extensions::Extension::GetBaseURLFromExtensionId(
270 ::file_manager::kImageLoaderExtensionId) &&
271 IsReadOperation(backend_function, operation_type)) {
272 return true;
273 }
274
Bo Majewski762d913a2021-06-30 03:54:25275 return file_access_permissions_->HasAccessPermission(origin,
[email protected]5aeeb7c62012-08-27 11:34:13276 url.virtual_path());
[email protected]b777b332011-04-16 04:01:08277}
278
Bo Majewski762d913a2021-06-30 03:54:25279void FileSystemBackend::GrantFileAccessToOrigin(
280 const url::Origin& origin,
Bo Majewskia382a372021-01-29 04:48:17281 const base::FilePath& virtual_path) {
[email protected]f037de82012-10-03 06:07:57282 std::string id;
[email protected]cd501a72014-08-22 19:58:31283 storage::FileSystemType type;
[email protected]7896ddc2014-06-20 10:40:16284 std::string cracked_id;
[email protected]a3ef4832013-02-02 05:12:33285 base::FilePath path;
[email protected]cd501a72014-08-22 19:58:31286 storage::FileSystemMountOption option;
[email protected]7896ddc2014-06-20 10:40:16287 if (!mount_points_->CrackVirtualPath(virtual_path, &id, &type, &cracked_id,
288 &path, &option) &&
289 !system_mount_points_->CrackVirtualPath(virtual_path, &id, &type,
290 &cracked_id, &path, &option)) {
[email protected]9d5d6982013-01-18 03:12:54291 return;
292 }
[email protected]f037de82012-10-03 06:07:57293
Bo Majewski762d913a2021-06-30 03:54:25294 file_access_permissions_->GrantAccessPermission(origin, virtual_path);
[email protected]b777b332011-04-16 04:01:08295}
296
Bo Majewski762d913a2021-06-30 03:54:25297void FileSystemBackend::RevokeAccessForOrigin(const url::Origin& origin) {
298 file_access_permissions_->RevokePermissions(origin);
[email protected]b777b332011-04-16 04:01:08299}
300
[email protected]f19bbf62013-07-09 01:22:32301std::vector<base::FilePath> FileSystemBackend::GetRootDirectories() const {
[email protected]cd501a72014-08-22 19:58:31302 std::vector<storage::MountPoints::MountPointInfo> mount_points;
[email protected]9d5d6982013-01-18 03:12:54303 mount_points_->AddMountPointInfosTo(&mount_points);
304 system_mount_points_->AddMountPointInfosTo(&mount_points);
305
[email protected]a3ef4832013-02-02 05:12:33306 std::vector<base::FilePath> root_dirs;
[email protected]9d5d6982013-01-18 03:12:54307 for (size_t i = 0; i < mount_points.size(); ++i)
308 root_dirs.push_back(mount_points[i].path);
[email protected]b777b332011-04-16 04:01:08309 return root_dirs;
[email protected]55d9bed2011-03-25 20:37:59310}
311
[email protected]cd501a72014-08-22 19:58:31312storage::AsyncFileUtil* FileSystemBackend::GetAsyncFileUtil(
313 storage::FileSystemType type) {
[email protected]d1bd77e2014-04-22 10:13:29314 switch (type) {
[email protected]cd501a72014-08-22 19:58:31315 case storage::kFileSystemTypeProvided:
[email protected]d1bd77e2014-04-22 10:13:29316 return file_system_provider_delegate_->GetAsyncFileUtil(type);
Austin Sullivan92338512021-01-28 23:32:59317 case storage::kFileSystemTypeLocal:
Noel Gordonf9277482022-02-04 01:13:50318 case storage::kFileSystemTypeFuseBox:
[email protected]d1bd77e2014-04-22 10:13:29319 return local_file_util_.get();
[email protected]cd501a72014-08-22 19:58:31320 case storage::kFileSystemTypeDeviceMediaAsFileStorage:
[email protected]bee0df312014-04-28 06:59:58321 return mtp_delegate_->GetAsyncFileUtil(type);
hashimotoa53e7e82016-10-26 06:30:47322 case storage::kFileSystemTypeArcContent:
323 return arc_content_delegate_->GetAsyncFileUtil(type);
nyaf5df1e32016-12-14 04:36:17324 case storage::kFileSystemTypeArcDocumentsProvider:
325 return arc_documents_provider_delegate_->GetAsyncFileUtil(type);
Sam McNallyd8b7d822018-08-21 03:18:18326 case storage::kFileSystemTypeDriveFs:
327 return drivefs_delegate_->GetAsyncFileUtil(type);
Anand K. Mistry7694c362020-03-17 23:33:34328 case storage::kFileSystemTypeSmbFs:
329 return smbfs_delegate_->GetAsyncFileUtil(type);
[email protected]d1bd77e2014-04-22 10:13:29330 default:
Peter Boström9503e9a2024-11-04 18:54:21331 NOTREACHED();
[email protected]d1bd77e2014-04-22 10:13:29332 }
[email protected]ccb14ed2011-07-06 10:50:50333}
334
mtomaszb75244fd2014-08-28 05:37:34335storage::WatcherManager* FileSystemBackend::GetWatcherManager(
336 storage::FileSystemType type) {
mtomaszacaff0812014-11-06 09:50:57337 if (type == storage::kFileSystemTypeProvided)
338 return file_system_provider_delegate_->GetWatcherManager(type);
339
Anand K. Mistry0bfd71e2019-04-24 01:45:04340 if (type == storage::kFileSystemTypeDeviceMediaAsFileStorage) {
yawanoe3893dbb2015-04-14 02:26:02341 return mtp_delegate_->GetWatcherManager(type);
342 }
343
nya7b442602017-03-03 16:56:11344 if (type == storage::kFileSystemTypeArcDocumentsProvider)
345 return arc_documents_provider_delegate_->GetWatcherManager(type);
346
mtomaszacaff0812014-11-06 09:50:57347 // TODO(mtomasz): Add support for other backends.
Claudio DeSouza03dd22122022-09-02 23:47:21348 return nullptr;
mtomaszb75244fd2014-08-28 05:37:34349}
350
[email protected]cd501a72014-08-22 19:58:31351storage::CopyOrMoveFileValidatorFactory*
[email protected]f19bbf62013-07-09 01:22:32352FileSystemBackend::GetCopyOrMoveFileValidatorFactory(
[email protected]cd501a72014-08-22 19:58:31353 storage::FileSystemType type,
354 base::File::Error* error_code) {
[email protected]98407ee2013-04-04 08:52:17355 DCHECK(error_code);
[email protected]141bcc52014-01-27 21:36:00356 *error_code = base::File::FILE_OK;
Claudio DeSouza03dd22122022-09-02 23:47:21357 return nullptr;
[email protected]98407ee2013-04-04 08:52:17358}
359
Victor Costanc49feb72021-08-16 19:19:20360std::unique_ptr<storage::FileSystemOperation>
361FileSystemBackend::CreateFileSystemOperation(
Joel Hockey75a10582023-08-09 02:58:29362 storage::OperationType type,
[email protected]cd501a72014-08-22 19:58:31363 const storage::FileSystemURL& url,
364 storage::FileSystemContext* context,
[email protected]141bcc52014-01-27 21:36:00365 base::File::Error* error_code) const {
[email protected]9d5d6982013-01-18 03:12:54366 DCHECK(url.is_valid());
367
Joel Hockey9d2024942023-08-09 03:23:56368 if (!IsAccessAllowed(BackendFunction::kCreateFileSystemOperation, type,
369 url)) {
[email protected]141bcc52014-01-27 21:36:00370 *error_code = base::File::FILE_ERROR_SECURITY;
Claudio DeSouza03dd22122022-09-02 23:47:21371 return nullptr;
[email protected]ce5cbed82013-07-01 11:52:31372 }
373
[email protected]cd501a72014-08-22 19:58:31374 if (url.type() == storage::kFileSystemTypeDeviceMediaAsFileStorage) {
[email protected]bee0df312014-04-28 06:59:58375 // MTP file operations run on MediaTaskRunner.
Victor Costanc49feb72021-08-16 19:19:20376 return std::make_unique<ObservableFileSystemOperationImpl>(
Joel Hockey75a10582023-08-09 02:58:29377 account_id_, type, url, context,
Jinho Bang341ce5b02018-01-17 22:46:03378 std::make_unique<storage::FileSystemOperationContext>(
ricea46ad5f42016-08-24 02:44:55379 context, MediaFileSystemBackend::MediaTaskRunner().get()));
[email protected]bee0df312014-04-28 06:59:58380 }
Austin Sullivan92338512021-01-28 23:32:59381 if (url.type() == storage::kFileSystemTypeLocal ||
Anand K. Mistry5b28d1bc2019-10-30 06:53:59382 url.type() == storage::kFileSystemTypeDriveFs ||
Noel Gordonf9277482022-02-04 01:13:50383 url.type() == storage::kFileSystemTypeSmbFs ||
384 url.type() == storage::kFileSystemTypeFuseBox) {
Victor Costanc49feb72021-08-16 19:19:20385 return std::make_unique<ObservableFileSystemOperationImpl>(
Joel Hockey75a10582023-08-09 02:58:29386 account_id_, type, url, context,
Sam McNallyf41b98e2019-03-21 06:15:23387 std::make_unique<storage::FileSystemOperationContext>(
Gabriel Charette055039132020-02-26 23:02:06388 context, base::ThreadPool::CreateSequencedTaskRunner(
389 {base::MayBlock(), base::TaskPriority::USER_VISIBLE})
Sam McNallyf41b98e2019-03-21 06:15:23390 .get()));
391 }
[email protected]bee0df312014-04-28 06:59:58392
Austin Tankiang0bf02522019-12-03 04:17:28393 DCHECK(url.type() == storage::kFileSystemTypeProvided ||
nyaf5df1e32016-12-14 04:36:17394 url.type() == storage::kFileSystemTypeArcContent ||
Sam McNallyf41b98e2019-03-21 06:15:23395 url.type() == storage::kFileSystemTypeArcDocumentsProvider);
Victor Costanc49feb72021-08-16 19:19:20396 return std::make_unique<ObservableFileSystemOperationImpl>(
Joel Hockey75a10582023-08-09 02:58:29397 account_id_, type, url, context,
Jinho Bang341ce5b02018-01-17 22:46:03398 std::make_unique<storage::FileSystemOperationContext>(context));
[email protected]3eb080d2012-01-16 04:20:06399}
400
[email protected]8ed6b692014-02-24 18:30:59401bool FileSystemBackend::SupportsStreaming(
[email protected]cd501a72014-08-22 19:58:31402 const storage::FileSystemURL& url) const {
Austin Tankiang0bf02522019-12-03 04:17:28403 return url.type() == storage::kFileSystemTypeProvided ||
hashimotoa53e7e82016-10-26 06:30:47404 url.type() == storage::kFileSystemTypeDeviceMediaAsFileStorage ||
nyaf5df1e32016-12-14 04:36:17405 url.type() == storage::kFileSystemTypeArcContent ||
Shuhei Takahashida9d3dd2017-08-09 07:21:29406 url.type() == storage::kFileSystemTypeArcDocumentsProvider;
[email protected]8ed6b692014-02-24 18:30:59407}
408
[email protected]c83c9192014-08-19 08:44:55409bool FileSystemBackend::HasInplaceCopyImplementation(
[email protected]cd501a72014-08-22 19:58:31410 storage::FileSystemType type) const {
[email protected]c83c9192014-08-19 08:44:55411 switch (type) {
[email protected]cd501a72014-08-22 19:58:31412 case storage::kFileSystemTypeProvided:
413 case storage::kFileSystemTypeDeviceMediaAsFileStorage:
Sam McNally47f2eac2018-08-28 06:45:05414 case storage::kFileSystemTypeDriveFs:
[email protected]c83c9192014-08-19 08:44:55415 return true;
Naoki Fukino419a6392019-04-17 07:24:14416 // TODO(fukino): Support in-place copy for DocumentsProvider.
417 // crbug.com/953603.
418 case storage::kFileSystemTypeArcDocumentsProvider:
Austin Sullivan92338512021-01-28 23:32:59419 case storage::kFileSystemTypeLocal:
hashimotoa53e7e82016-10-26 06:30:47420 case storage::kFileSystemTypeArcContent:
Alison Gale9f64b0ccd2024-04-16 00:04:06421 // TODO(crbug.com/41445433): Implement in-place copy in SmbFs.
Anand K. Mistry5b28d1bc2019-10-30 06:53:59422 case storage::kFileSystemTypeSmbFs:
Noel Gordonf9277482022-02-04 01:13:50423 case storage::kFileSystemTypeFuseBox:
[email protected]c83c9192014-08-19 08:44:55424 return false;
425 default:
Peter Boström9503e9a2024-11-04 18:54:21426 NOTREACHED();
[email protected]c83c9192014-08-19 08:44:55427 }
[email protected]c83c9192014-08-19 08:44:55428}
429
dcheng24002d02016-04-08 02:42:40430std::unique_ptr<storage::FileStreamReader>
431FileSystemBackend::CreateFileStreamReader(
[email protected]cd501a72014-08-22 19:58:31432 const storage::FileSystemURL& url,
avi8a07d53892015-12-24 22:13:53433 int64_t offset,
434 int64_t max_bytes_to_read,
[email protected]a1057832012-10-15 13:28:06435 const base::Time& expected_modification_time,
Daniel Brinkers9dacf9e12023-03-09 07:39:05436 storage::FileSystemContext* context,
437 file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
438 file_access) const {
[email protected]ebb4bcea2013-05-13 11:17:38439 DCHECK(url.is_valid());
440
Joel Hockey9d2024942023-08-09 03:23:56441 if (!IsAccessAllowed(BackendFunction::kCreateFileStreamReader,
442 storage::OperationType::kNone, url)) {
Lei Zhang70a276802021-04-08 03:36:46443 return nullptr;
Joel Hockey9d2024942023-08-09 03:23:56444 }
[email protected]ce5cbed82013-07-01 11:52:31445
[email protected]d1bd77e2014-04-22 10:13:29446 switch (url.type()) {
[email protected]cd501a72014-08-22 19:58:31447 case storage::kFileSystemTypeProvided:
[email protected]d1bd77e2014-04-22 10:13:29448 return file_system_provider_delegate_->CreateFileStreamReader(
mtomasz85aa9d72014-09-16 23:40:38449 url, offset, max_bytes_to_read, expected_modification_time, context);
Daniel Brinkers9dacf9e12023-03-09 07:39:05450 // The dlp file_access callback is needed for the local filesystem only.
Austin Sullivan92338512021-01-28 23:32:59451 case storage::kFileSystemTypeLocal:
Daniel Brinkers9dacf9e12023-03-09 07:39:05452 return storage::FileStreamReader::CreateForLocalFile(
453 base::ThreadPool::CreateTaskRunner(
454 {base::MayBlock(), base::TaskPriority::USER_VISIBLE})
455 .get(),
456 url.path(), offset, expected_modification_time,
457 std::move(file_access));
Sam McNallyd8b7d822018-08-21 03:18:18458 case storage::kFileSystemTypeDriveFs:
Anand K. Mistry5b28d1bc2019-10-30 06:53:59459 case storage::kFileSystemTypeSmbFs:
Noel Gordonf9277482022-02-04 01:13:50460 case storage::kFileSystemTypeFuseBox:
Yeunjoo Choief8a4a42022-11-08 04:21:05461 return storage::FileStreamReader::CreateForLocalFile(
462 base::ThreadPool::CreateTaskRunner(
463 {base::MayBlock(), base::TaskPriority::USER_VISIBLE})
464 .get(),
465 url.path(), offset, expected_modification_time);
[email protected]cd501a72014-08-22 19:58:31466 case storage::kFileSystemTypeDeviceMediaAsFileStorage:
[email protected]bee0df312014-04-28 06:59:58467 return mtp_delegate_->CreateFileStreamReader(
mtomasz85aa9d72014-09-16 23:40:38468 url, offset, max_bytes_to_read, expected_modification_time, context);
hashimotoa53e7e82016-10-26 06:30:47469 case storage::kFileSystemTypeArcContent:
470 return arc_content_delegate_->CreateFileStreamReader(
471 url, offset, max_bytes_to_read, expected_modification_time, context);
nyaf5df1e32016-12-14 04:36:17472 case storage::kFileSystemTypeArcDocumentsProvider:
473 return arc_documents_provider_delegate_->CreateFileStreamReader(
474 url, offset, max_bytes_to_read, expected_modification_time, context);
[email protected]d1bd77e2014-04-22 10:13:29475 default:
Peter Boström9503e9a2024-11-04 18:54:21476 NOTREACHED();
[email protected]ebb4bcea2013-05-13 11:17:38477 }
[email protected]ad117b12012-04-19 05:40:19478}
479
dcheng24002d02016-04-08 02:42:40480std::unique_ptr<storage::FileStreamWriter>
481FileSystemBackend::CreateFileStreamWriter(
[email protected]cd501a72014-08-22 19:58:31482 const storage::FileSystemURL& url,
avi8a07d53892015-12-24 22:13:53483 int64_t offset,
[email protected]cd501a72014-08-22 19:58:31484 storage::FileSystemContext* context) const {
[email protected]9d5d6982013-01-18 03:12:54485 DCHECK(url.is_valid());
486
Joel Hockey9d2024942023-08-09 03:23:56487 if (!IsAccessAllowed(BackendFunction::kCreateFileStreamWriter,
488 storage::OperationType::kNone, url)) {
Lei Zhang70a276802021-04-08 03:36:46489 return nullptr;
Joel Hockey9d2024942023-08-09 03:23:56490 }
[email protected]ce5cbed82013-07-01 11:52:31491
[email protected]d1bd77e2014-04-22 10:13:29492 switch (url.type()) {
[email protected]cd501a72014-08-22 19:58:31493 case storage::kFileSystemTypeProvided:
Bo Majewskia382a372021-01-29 04:48:17494 return file_system_provider_delegate_->CreateFileStreamWriter(url, offset,
495 context);
Austin Sullivan92338512021-01-28 23:32:59496 case storage::kFileSystemTypeLocal:
Sam McNallyd8b7d822018-08-21 03:18:18497 case storage::kFileSystemTypeDriveFs:
Anand K. Mistry5b28d1bc2019-10-30 06:53:59498 case storage::kFileSystemTypeSmbFs:
Noel Gordonf9277482022-02-04 01:13:50499 case storage::kFileSystemTypeFuseBox:
Ayu Ishii360d62d2019-02-15 22:50:09500 return storage::FileStreamWriter::CreateForLocalFile(
Gabriel Charette055039132020-02-26 23:02:06501 base::ThreadPool::CreateTaskRunner(
502 {base::MayBlock(), base::TaskPriority::USER_VISIBLE})
Sam McNallyf41b98e2019-03-21 06:15:23503 .get(),
504 url.path(), offset, storage::FileStreamWriter::OPEN_EXISTING_FILE);
[email protected]cd501a72014-08-22 19:58:31505 case storage::kFileSystemTypeDeviceMediaAsFileStorage:
[email protected]bee0df312014-04-28 06:59:58506 return mtp_delegate_->CreateFileStreamWriter(url, offset, context);
Naoki Fukinob244b102019-04-04 05:59:17507 case storage::kFileSystemTypeArcDocumentsProvider:
508 return arc_documents_provider_delegate_->CreateFileStreamWriter(
509 url, offset, context);
hashimotoa53e7e82016-10-26 06:30:47510 // Read only file systems.
hashimotoa53e7e82016-10-26 06:30:47511 case storage::kFileSystemTypeArcContent:
Lei Zhang70a276802021-04-08 03:36:46512 return nullptr;
[email protected]d1bd77e2014-04-22 10:13:29513 default:
Peter Boström9503e9a2024-11-04 18:54:21514 NOTREACHED();
[email protected]43420a12014-04-21 03:20:48515 }
[email protected]7e84b912012-05-16 04:42:01516}
517
mtomasza6775be2015-03-18 06:45:27518bool FileSystemBackend::GetVirtualPath(const base::FilePath& filesystem_path,
519 base::FilePath* virtual_path) const {
[email protected]9d5d6982013-01-18 03:12:54520 return mount_points_->GetVirtualPath(filesystem_path, virtual_path) ||
521 system_mount_points_->GetVirtualPath(filesystem_path, virtual_path);
[email protected]9fb9294a2012-08-21 14:55:37522}
523
mtomasza6775be2015-03-18 06:45:27524storage::FileSystemURL FileSystemBackend::CreateInternalURL(
525 storage::FileSystemContext* context,
526 const base::FilePath& entry_path) const {
527 base::FilePath virtual_path;
528 if (!GetVirtualPath(entry_path, &virtual_path))
529 return storage::FileSystemURL();
530
531 return context->CreateCrackedFileSystemURL(
Kyra Seevers104537e2021-08-11 16:22:44532 blink::StorageKey(), storage::kFileSystemTypeExternal, virtual_path);
mtomasza6775be2015-03-18 06:45:27533}
534
Yeunjoo Choi3d9ed38a2022-11-10 02:51:24535} // namespace ash