| // Copyright (c) 2012 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 "content/browser/fileapi/browser_file_system_helper.h" | 
 |  | 
 | #include <stddef.h> | 
 | #include <string> | 
 | #include <utility> | 
 | #include <vector> | 
 |  | 
 | #include "base/command_line.h" | 
 | #include "base/files/file_path.h" | 
 | #include "base/sequenced_task_runner.h" | 
 | #include "base/threading/sequenced_worker_pool.h" | 
 | #include "content/browser/child_process_security_policy_impl.h" | 
 | #include "content/public/browser/browser_context.h" | 
 | #include "content/public/browser/browser_thread.h" | 
 | #include "content/public/browser/content_browser_client.h" | 
 | #include "content/public/common/content_client.h" | 
 | #include "content/public/common/content_switches.h" | 
 | #include "storage/browser/fileapi/external_mount_points.h" | 
 | #include "storage/browser/fileapi/file_permission_policy.h" | 
 | #include "storage/browser/fileapi/file_system_backend.h" | 
 | #include "storage/browser/fileapi/file_system_context.h" | 
 | #include "storage/browser/fileapi/file_system_operation_runner.h" | 
 | #include "storage/browser/fileapi/file_system_options.h" | 
 | #include "storage/browser/quota/quota_manager.h" | 
 | #include "url/url_constants.h" | 
 |  | 
 | namespace content { | 
 |  | 
 | namespace { | 
 |  | 
 | using storage::FileSystemOptions; | 
 |  | 
 | FileSystemOptions CreateBrowserFileSystemOptions(bool is_incognito) { | 
 |   FileSystemOptions::ProfileMode profile_mode = | 
 |       is_incognito ? FileSystemOptions::PROFILE_MODE_INCOGNITO | 
 |                    : FileSystemOptions::PROFILE_MODE_NORMAL; | 
 |   std::vector<std::string> additional_allowed_schemes; | 
 |   GetContentClient()->browser()->GetAdditionalAllowedSchemesForFileSystem( | 
 |       &additional_allowed_schemes); | 
 |   if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 
 |           switches::kAllowFileAccessFromFiles)) { | 
 |     additional_allowed_schemes.push_back(url::kFileScheme); | 
 |   } | 
 |   return FileSystemOptions(profile_mode, additional_allowed_schemes, NULL); | 
 | } | 
 |  | 
 | }  // namespace | 
 |  | 
 | scoped_refptr<storage::FileSystemContext> CreateFileSystemContext( | 
 |     BrowserContext* browser_context, | 
 |     const base::FilePath& profile_path, | 
 |     bool is_incognito, | 
 |     storage::QuotaManagerProxy* quota_manager_proxy) { | 
 |   base::SequencedWorkerPool* pool = BrowserThread::GetBlockingPool(); | 
 |   scoped_refptr<base::SequencedTaskRunner> file_task_runner = | 
 |       pool->GetSequencedTaskRunnerWithShutdownBehavior( | 
 |           pool->GetNamedSequenceToken("FileAPI"), | 
 |           base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); | 
 |  | 
 |   // Setting up additional filesystem backends. | 
 |   ScopedVector<storage::FileSystemBackend> additional_backends; | 
 |   GetContentClient()->browser()->GetAdditionalFileSystemBackends( | 
 |       browser_context, | 
 |       profile_path, | 
 |       &additional_backends); | 
 |  | 
 |   // Set up the auto mount handlers for url requests. | 
 |   std::vector<storage::URLRequestAutoMountHandler> | 
 |       url_request_auto_mount_handlers; | 
 |   GetContentClient()->browser()->GetURLRequestAutoMountHandlers( | 
 |       &url_request_auto_mount_handlers); | 
 |  | 
 |   scoped_refptr<storage::FileSystemContext> file_system_context = | 
 |       new storage::FileSystemContext( | 
 |           BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO).get(), | 
 |           file_task_runner.get(), | 
 |           BrowserContext::GetMountPoints(browser_context), | 
 |           browser_context->GetSpecialStoragePolicy(), quota_manager_proxy, | 
 |           std::move(additional_backends), url_request_auto_mount_handlers, | 
 |           profile_path, CreateBrowserFileSystemOptions(is_incognito)); | 
 |  | 
 |   std::vector<storage::FileSystemType> types; | 
 |   file_system_context->GetFileSystemTypes(&types); | 
 |   for (size_t i = 0; i < types.size(); ++i) { | 
 |     ChildProcessSecurityPolicyImpl::GetInstance() | 
 |         ->RegisterFileSystemPermissionPolicy( | 
 |             types[i], | 
 |             storage::FileSystemContext::GetPermissionPolicy(types[i])); | 
 |   } | 
 |  | 
 |   return file_system_context; | 
 | } | 
 |  | 
 | bool FileSystemURLIsValid(storage::FileSystemContext* context, | 
 |                           const storage::FileSystemURL& url) { | 
 |   if (!url.is_valid()) | 
 |     return false; | 
 |  | 
 |   return context->GetFileSystemBackend(url.type()) != NULL; | 
 | } | 
 |  | 
 | void SyncGetPlatformPath(storage::FileSystemContext* context, | 
 |                          int process_id, | 
 |                          const GURL& path, | 
 |                          base::FilePath* platform_path) { | 
 |   DCHECK(context->default_file_task_runner()-> | 
 |          RunsTasksOnCurrentThread()); | 
 |   DCHECK(platform_path); | 
 |   *platform_path = base::FilePath(); | 
 |   storage::FileSystemURL url(context->CrackURL(path)); | 
 |   if (!FileSystemURLIsValid(context, url)) | 
 |     return; | 
 |  | 
 |   // Make sure if this file is ok to be read (in the current architecture | 
 |   // which means roughly same as the renderer is allowed to get the platform | 
 |   // path to the file). | 
 |   ChildProcessSecurityPolicyImpl* policy = | 
 |       ChildProcessSecurityPolicyImpl::GetInstance(); | 
 |   if (!policy->CanReadFileSystemFile(process_id, url)) | 
 |     return; | 
 |  | 
 |   context->operation_runner()->SyncGetPlatformPath(url, platform_path); | 
 |  | 
 |   // The path is to be attached to URLLoader so we grant read permission | 
 |   // for the file. (We need to check first because a parent directory may | 
 |   // already have the permissions and we don't need to grant it to the file.) | 
 |   if (!policy->CanReadFile(process_id, *platform_path)) | 
 |     policy->GrantReadFile(process_id, *platform_path); | 
 | } | 
 |  | 
 | }  // namespace content |