15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_quota_client.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/location.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/sequenced_task_runner.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/single_thread_task_runner.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/task_runner_util.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_util.h"
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_context.h"
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_quota_util.h"
221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_usage_cache.h"
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/sandbox_file_system_backend.h"
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/fileapi/file_system_util.h"
25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::StorageType;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace storage {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void GetOriginsForTypeOnFileTaskRunner(
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileSystemContext* context,
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StorageType storage_type,
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::set<GURL>* origins_ptr) {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileSystemType type = QuotaStorageTypeToFileSystemType(storage_type);
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(type != kFileSystemTypeUnknown);
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileSystemQuotaUtil* quota_util = context->GetQuotaUtil(type);
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!quota_util)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  quota_util->GetOriginsForTypeOnFileTaskRunner(type, origins_ptr);
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void GetOriginsForHostOnFileTaskRunner(
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileSystemContext* context,
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StorageType storage_type,
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& host,
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::set<GURL>* origins_ptr) {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileSystemType type = QuotaStorageTypeToFileSystemType(storage_type);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(type != kFileSystemTypeUnknown);
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileSystemQuotaUtil* quota_util = context->GetQuotaUtil(type);
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!quota_util)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  quota_util->GetOriginsForHostOnFileTaskRunner(type, host, origins_ptr);
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void DidGetOrigins(const storage::QuotaClient::GetOriginsCallback& callback,
6103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                   std::set<GURL>* origins_ptr) {
6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  callback.Run(*origins_ptr);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)storage::QuotaStatusCode DeleteOriginOnFileTaskRunner(
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileSystemContext* context,
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& origin,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileSystemType type) {
697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  FileSystemBackend* provider = context->GetFileSystemBackend(type);
70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!provider || !provider->GetQuotaUtil())
7103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return storage::kQuotaErrorNotSupported;
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error result =
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      provider->GetQuotaUtil()->DeleteOriginDataOnFileTaskRunner(
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          context, context->quota_manager_proxy(), origin, type);
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (result == base::File::FILE_OK)
7603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return storage::kQuotaStatusOk;
7703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return storage::kQuotaErrorInvalidModification;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileSystemQuotaClient::FileSystemQuotaClient(
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileSystemContext* file_system_context,
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool is_incognito)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : file_system_context_(file_system_context),
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_incognito_(is_incognito) {
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileSystemQuotaClient::~FileSystemQuotaClient() {}
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)storage::QuotaClient::ID FileSystemQuotaClient::id() const {
9203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return storage::QuotaClient::kFileSystem;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileSystemQuotaClient::OnQuotaManagerDestroyed() {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete this;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileSystemQuotaClient::GetOriginUsage(
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& origin_url,
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StorageType storage_type,
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GetUsageCallback& callback) {
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!callback.is_null());
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_incognito_) {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We don't support FileSystem in incognito mode yet.
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback.Run(0);
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileSystemType type = QuotaStorageTypeToFileSystemType(storage_type);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(type != kFileSystemTypeUnknown);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileSystemQuotaUtil* quota_util = file_system_context_->GetQuotaUtil(type);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!quota_util) {
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback.Run(0);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::PostTaskAndReplyWithResult(
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      file_task_runner(),
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // It is safe to pass Unretained(quota_util) since context owns it.
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&FileSystemQuotaUtil::GetOriginUsageOnFileTaskRunner,
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(quota_util),
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 file_system_context_,
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 origin_url,
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 type),
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback);
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileSystemQuotaClient::GetOriginsForType(
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StorageType storage_type,
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GetOriginsCallback& callback) {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!callback.is_null());
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_incognito_) {
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We don't support FileSystem in incognito mode yet.
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::set<GURL> origins;
14090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    callback.Run(origins);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::set<GURL>* origins_ptr = new std::set<GURL>();
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_task_runner()->PostTaskAndReply(
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&GetOriginsForTypeOnFileTaskRunner,
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 file_system_context_,
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 storage_type,
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(origins_ptr)),
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&DidGetOrigins,
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 callback,
15390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                 base::Owned(origins_ptr)));
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileSystemQuotaClient::GetOriginsForHost(
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StorageType storage_type,
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& host,
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GetOriginsCallback& callback) {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!callback.is_null());
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_incognito_) {
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We don't support FileSystem in incognito mode yet.
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::set<GURL> origins;
16590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    callback.Run(origins);
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::set<GURL>* origins_ptr = new std::set<GURL>();
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_task_runner()->PostTaskAndReply(
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&GetOriginsForHostOnFileTaskRunner,
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 file_system_context_,
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 storage_type,
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 host,
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(origins_ptr)),
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&DidGetOrigins,
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 callback,
17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                 base::Owned(origins_ptr)));
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileSystemQuotaClient::DeleteOriginData(
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& origin,
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StorageType type,
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const DeletionCallback& callback) {
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileSystemType fs_type = QuotaStorageTypeToFileSystemType(type);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(fs_type != kFileSystemTypeUnknown);
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::PostTaskAndReplyWithResult(
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      file_task_runner(),
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&DeleteOriginOnFileTaskRunner,
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 file_system_context_,
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 origin,
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 fs_type),
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool FileSystemQuotaClient::DoesSupport(
20003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::StorageType storage_type) const {
20158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  FileSystemType type = QuotaStorageTypeToFileSystemType(storage_type);
20258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(type != kFileSystemTypeUnknown);
20358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return file_system_context_->IsSandboxFileSystem(type);
20458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
20558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::SequencedTaskRunner* FileSystemQuotaClient::file_task_runner() const {
207a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return file_system_context_->default_file_task_runner();
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}  // namespace storage
211