disk_cache.cc 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include <utility>
  5. #include "base/barrier_closure.h"
  6. #include "base/bind.h"
  7. #include "base/callback.h"
  8. #include "base/files/file_path.h"
  9. #include "base/files/file_util.h"
  10. #include "base/memory/raw_ptr.h"
  11. #include "base/metrics/field_trial.h"
  12. #include "base/task/bind_post_task.h"
  13. #include "base/task/single_thread_task_runner.h"
  14. #include "base/task/thread_pool/thread_pool_instance.h"
  15. #include "base/threading/sequenced_task_runner_handle.h"
  16. #include "build/build_config.h"
  17. #include "net/base/cache_type.h"
  18. #include "net/base/net_errors.h"
  19. #include "net/disk_cache/backend_cleanup_tracker.h"
  20. #include "net/disk_cache/blockfile/backend_impl.h"
  21. #include "net/disk_cache/cache_util.h"
  22. #include "net/disk_cache/disk_cache.h"
  23. #include "net/disk_cache/memory/mem_backend_impl.h"
  24. #include "net/disk_cache/simple/simple_backend_impl.h"
  25. #include "net/disk_cache/simple/simple_file_enumerator.h"
  26. #include "net/disk_cache/simple/simple_util.h"
  27. namespace {
  28. using FileEnumerator = disk_cache::BackendFileOperations::FileEnumerator;
  29. // Builds an instance of the backend depending on platform, type, experiments
  30. // etc. Takes care of the retry state. This object will self-destroy when
  31. // finished.
  32. class CacheCreator {
  33. public:
  34. CacheCreator(const base::FilePath& path,
  35. disk_cache::ResetHandling reset_handling,
  36. int64_t max_bytes,
  37. net::CacheType type,
  38. net::BackendType backend_type,
  39. scoped_refptr<disk_cache::BackendFileOperationsFactory>
  40. file_operations_factory,
  41. #if BUILDFLAG(IS_ANDROID)
  42. base::android::ApplicationStatusListener* app_status_listener,
  43. #endif
  44. net::NetLog* net_log,
  45. base::OnceClosure post_cleanup_callback,
  46. disk_cache::BackendResultCallback callback);
  47. CacheCreator(const CacheCreator&) = delete;
  48. CacheCreator& operator=(const CacheCreator&) = delete;
  49. // Wait for any previous backends for given path to finish clean up and then
  50. // attempt to create a new one. This will never succeed synchronously, though
  51. // it may fail synchronously.
  52. net::Error TryCreateCleanupTrackerAndRun();
  53. // Creates the backend, the cleanup context for it having been already
  54. // established... or purposefully left as null. This will never succeed
  55. // synchronously, though it may fail synchronously.
  56. net::Error Run();
  57. private:
  58. ~CacheCreator();
  59. void DoCallback(int result);
  60. void OnIOComplete(int result);
  61. void OnCacheCleanupComplete(int original_error, bool cleanup_result);
  62. const base::FilePath path_;
  63. disk_cache::ResetHandling reset_handling_;
  64. bool retry_ = false;
  65. int64_t max_bytes_;
  66. net::CacheType type_;
  67. net::BackendType backend_type_;
  68. scoped_refptr<disk_cache::BackendFileOperationsFactory>
  69. file_operations_factory_;
  70. std::unique_ptr<disk_cache::BackendFileOperations> file_operations_;
  71. #if BUILDFLAG(IS_ANDROID)
  72. raw_ptr<base::android::ApplicationStatusListener> app_status_listener_;
  73. #endif
  74. base::OnceClosure post_cleanup_callback_;
  75. disk_cache::BackendResultCallback callback_;
  76. std::unique_ptr<disk_cache::Backend> created_cache_;
  77. raw_ptr<net::NetLog> net_log_;
  78. scoped_refptr<disk_cache::BackendCleanupTracker> cleanup_tracker_;
  79. };
  80. CacheCreator::CacheCreator(
  81. const base::FilePath& path,
  82. disk_cache::ResetHandling reset_handling,
  83. int64_t max_bytes,
  84. net::CacheType type,
  85. net::BackendType backend_type,
  86. scoped_refptr<disk_cache::BackendFileOperationsFactory> file_operations,
  87. #if BUILDFLAG(IS_ANDROID)
  88. base::android::ApplicationStatusListener* app_status_listener,
  89. #endif
  90. net::NetLog* net_log,
  91. base::OnceClosure post_cleanup_callback,
  92. disk_cache::BackendResultCallback callback)
  93. : path_(path),
  94. reset_handling_(reset_handling),
  95. max_bytes_(max_bytes),
  96. type_(type),
  97. backend_type_(backend_type),
  98. file_operations_factory_(std::move(file_operations)),
  99. #if BUILDFLAG(IS_ANDROID)
  100. app_status_listener_(app_status_listener),
  101. #endif
  102. post_cleanup_callback_(std::move(post_cleanup_callback)),
  103. callback_(std::move(callback)),
  104. net_log_(net_log) {
  105. }
  106. CacheCreator::~CacheCreator() = default;
  107. net::Error CacheCreator::Run() {
  108. #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_FUCHSIA)
  109. static const bool kSimpleBackendIsDefault = true;
  110. #else
  111. static const bool kSimpleBackendIsDefault = false;
  112. #endif
  113. if (!retry_ && reset_handling_ == disk_cache::ResetHandling::kReset) {
  114. // Pretend that we failed to create a cache, so that we can handle `kReset`
  115. // and `kResetOnError` in a unified way, in CacheCreator::OnIOComplete.
  116. base::SequencedTaskRunnerHandle::Get()->PostTask(
  117. FROM_HERE, base::BindOnce(&CacheCreator::OnIOComplete,
  118. base::Unretained(this), net::ERR_FAILED));
  119. return net::ERR_IO_PENDING;
  120. }
  121. if (backend_type_ == net::CACHE_BACKEND_SIMPLE ||
  122. (backend_type_ == net::CACHE_BACKEND_DEFAULT &&
  123. kSimpleBackendIsDefault)) {
  124. auto cache = std::make_unique<disk_cache::SimpleBackendImpl>(
  125. file_operations_factory_, path_, cleanup_tracker_.get(),
  126. /* file_tracker = */ nullptr, max_bytes_, type_, net_log_);
  127. disk_cache::SimpleBackendImpl* simple_cache = cache.get();
  128. created_cache_ = std::move(cache);
  129. #if BUILDFLAG(IS_ANDROID)
  130. if (app_status_listener_)
  131. simple_cache->set_app_status_listener(app_status_listener_);
  132. #endif
  133. simple_cache->Init(
  134. base::BindOnce(&CacheCreator::OnIOComplete, base::Unretained(this)));
  135. return net::ERR_IO_PENDING;
  136. }
  137. // Avoid references to blockfile functions on Android to reduce binary size.
  138. #if BUILDFLAG(IS_ANDROID)
  139. return net::ERR_FAILED;
  140. #else
  141. auto cache = std::make_unique<disk_cache::BackendImpl>(
  142. path_, cleanup_tracker_.get(),
  143. /*cache_thread = */ nullptr, type_, net_log_);
  144. disk_cache::BackendImpl* new_cache = cache.get();
  145. created_cache_ = std::move(cache);
  146. new_cache->SetMaxSize(max_bytes_);
  147. new_cache->Init(
  148. base::BindOnce(&CacheCreator::OnIOComplete, base::Unretained(this)));
  149. return net::ERR_IO_PENDING;
  150. #endif
  151. }
  152. net::Error CacheCreator::TryCreateCleanupTrackerAndRun() {
  153. // Before creating a cache Backend, a BackendCleanupTracker object is needed
  154. // so there is a place to keep track of outstanding I/O even after the backend
  155. // object itself is destroyed, so that further use of the directory
  156. // doesn't race with those outstanding disk I/O ops.
  157. // This method's purpose it to grab exlusive ownership of a fresh
  158. // BackendCleanupTracker for the cache path, and then move on to Run(),
  159. // which will take care of creating the actual cache backend. It's possible
  160. // that something else is currently making use of the directory, in which
  161. // case BackendCleanupTracker::TryCreate will fail, but will just have
  162. // TryCreateCleanupTrackerAndRun run again at an opportune time to make
  163. // another attempt.
  164. // The resulting BackendCleanupTracker is stored into a scoped_refptr member
  165. // so that it's kept alive while |this| CacheCreator exists , so that in the
  166. // case Run() needs to retry Backend creation the same BackendCleanupTracker
  167. // is used for both attempts, and |post_cleanup_callback_| gets called after
  168. // the second try, not the first one.
  169. cleanup_tracker_ = disk_cache::BackendCleanupTracker::TryCreate(
  170. path_, base::BindOnce(base::IgnoreResult(
  171. &CacheCreator::TryCreateCleanupTrackerAndRun),
  172. base::Unretained(this)));
  173. if (!cleanup_tracker_)
  174. return net::ERR_IO_PENDING;
  175. if (!post_cleanup_callback_.is_null())
  176. cleanup_tracker_->AddPostCleanupCallback(std::move(post_cleanup_callback_));
  177. return Run();
  178. }
  179. void CacheCreator::DoCallback(int net_error) {
  180. DCHECK_NE(net::ERR_IO_PENDING, net_error);
  181. disk_cache::BackendResult result;
  182. if (net_error == net::OK) {
  183. result = disk_cache::BackendResult::Make(std::move(created_cache_));
  184. } else {
  185. LOG(ERROR) << "Unable to create cache";
  186. result = disk_cache::BackendResult::MakeError(
  187. static_cast<net::Error>(net_error));
  188. created_cache_.reset();
  189. }
  190. std::move(callback_).Run(std::move(result));
  191. delete this;
  192. }
  193. // If the initialization of the cache fails, and |reset_handling| isn't set to
  194. // kNeverReset, we will discard the whole cache and create a new one.
  195. void CacheCreator::OnIOComplete(int result) {
  196. DCHECK_NE(result, net::ERR_IO_PENDING);
  197. if (result == net::OK ||
  198. reset_handling_ == disk_cache::ResetHandling::kNeverReset || retry_) {
  199. return DoCallback(result);
  200. }
  201. // We are supposed to try again, so delete the object and all files and do so.
  202. retry_ = true;
  203. created_cache_.reset();
  204. if (!file_operations_) {
  205. if (file_operations_factory_) {
  206. file_operations_ = file_operations_factory_->Create(
  207. base::SequencedTaskRunnerHandle::Get());
  208. } else {
  209. file_operations_ = std::make_unique<disk_cache::TrivialFileOperations>();
  210. }
  211. }
  212. file_operations_->CleanupDirectory(
  213. path_, base::BindOnce(&CacheCreator::OnCacheCleanupComplete,
  214. base::Unretained(this), result));
  215. }
  216. void CacheCreator::OnCacheCleanupComplete(int original_result,
  217. bool cleanup_result) {
  218. if (!cleanup_result) {
  219. // Cleaning up the cache directory fails, so this operation should be
  220. // considered failed.
  221. DCHECK_NE(original_result, net::OK);
  222. DCHECK_NE(original_result, net::ERR_IO_PENDING);
  223. DoCallback(original_result);
  224. return;
  225. }
  226. // The worker thread may be deleting files, but the original folder
  227. // is not there anymore... let's create a new set of files.
  228. int rv = Run();
  229. DCHECK_EQ(net::ERR_IO_PENDING, rv);
  230. }
  231. class TrivialFileEnumerator final : public FileEnumerator {
  232. public:
  233. using FileEnumerationEntry =
  234. disk_cache::BackendFileOperations::FileEnumerationEntry;
  235. explicit TrivialFileEnumerator(const base::FilePath& path)
  236. : enumerator_(path) {}
  237. ~TrivialFileEnumerator() override = default;
  238. absl::optional<FileEnumerationEntry> Next() override {
  239. return enumerator_.Next();
  240. }
  241. bool HasError() const override { return enumerator_.HasError(); }
  242. private:
  243. disk_cache::SimpleFileEnumerator enumerator_;
  244. };
  245. class UnboundTrivialFileOperations
  246. : public disk_cache::UnboundBackendFileOperations {
  247. public:
  248. std::unique_ptr<disk_cache::BackendFileOperations> Bind(
  249. scoped_refptr<base::SequencedTaskRunner> task_runner) override {
  250. return std::make_unique<disk_cache::TrivialFileOperations>();
  251. }
  252. };
  253. } // namespace
  254. namespace disk_cache {
  255. BackendResult::BackendResult() = default;
  256. BackendResult::~BackendResult() = default;
  257. BackendResult::BackendResult(BackendResult&&) = default;
  258. BackendResult& BackendResult::operator=(BackendResult&&) = default;
  259. // static
  260. BackendResult BackendResult::MakeError(net::Error error_in) {
  261. DCHECK_NE(error_in, net::OK);
  262. BackendResult result;
  263. result.net_error = error_in;
  264. return result;
  265. }
  266. // static
  267. BackendResult BackendResult::Make(std::unique_ptr<Backend> backend_in) {
  268. DCHECK(backend_in);
  269. BackendResult result;
  270. result.net_error = net::OK;
  271. result.backend = std::move(backend_in);
  272. return result;
  273. }
  274. BackendResult CreateCacheBackendImpl(
  275. net::CacheType type,
  276. net::BackendType backend_type,
  277. scoped_refptr<BackendFileOperationsFactory> file_operations,
  278. const base::FilePath& path,
  279. int64_t max_bytes,
  280. ResetHandling reset_handling,
  281. #if BUILDFLAG(IS_ANDROID)
  282. base::android::ApplicationStatusListener* app_status_listener,
  283. #endif
  284. net::NetLog* net_log,
  285. base::OnceClosure post_cleanup_callback,
  286. BackendResultCallback callback) {
  287. DCHECK(!callback.is_null());
  288. if (type == net::MEMORY_CACHE) {
  289. std::unique_ptr<MemBackendImpl> mem_backend_impl =
  290. disk_cache::MemBackendImpl::CreateBackend(max_bytes, net_log);
  291. if (mem_backend_impl) {
  292. mem_backend_impl->SetPostCleanupCallback(
  293. std::move(post_cleanup_callback));
  294. return BackendResult::Make(std::move(mem_backend_impl));
  295. } else {
  296. if (!post_cleanup_callback.is_null())
  297. base::SequencedTaskRunnerHandle::Get()->PostTask(
  298. FROM_HERE, std::move(post_cleanup_callback));
  299. return BackendResult::MakeError(net::ERR_FAILED);
  300. }
  301. }
  302. bool had_post_cleanup_callback = !post_cleanup_callback.is_null();
  303. CacheCreator* creator = new CacheCreator(
  304. path, reset_handling, max_bytes, type, backend_type,
  305. std::move(file_operations),
  306. #if BUILDFLAG(IS_ANDROID)
  307. std::move(app_status_listener),
  308. #endif
  309. net_log, std::move(post_cleanup_callback), std::move(callback));
  310. if (type == net::DISK_CACHE) {
  311. DCHECK(!had_post_cleanup_callback);
  312. return BackendResult::MakeError(creator->Run());
  313. }
  314. return BackendResult::MakeError(creator->TryCreateCleanupTrackerAndRun());
  315. }
  316. BackendResult CreateCacheBackend(
  317. net::CacheType type,
  318. net::BackendType backend_type,
  319. scoped_refptr<BackendFileOperationsFactory> file_operations,
  320. const base::FilePath& path,
  321. int64_t max_bytes,
  322. ResetHandling reset_handling,
  323. net::NetLog* net_log,
  324. BackendResultCallback callback) {
  325. return CreateCacheBackendImpl(type, backend_type, std::move(file_operations),
  326. path, max_bytes, reset_handling,
  327. #if BUILDFLAG(IS_ANDROID)
  328. nullptr,
  329. #endif
  330. net_log, base::OnceClosure(),
  331. std::move(callback));
  332. }
  333. #if BUILDFLAG(IS_ANDROID)
  334. NET_EXPORT BackendResult CreateCacheBackend(
  335. net::CacheType type,
  336. net::BackendType backend_type,
  337. scoped_refptr<BackendFileOperationsFactory> file_operations,
  338. const base::FilePath& path,
  339. int64_t max_bytes,
  340. ResetHandling reset_handling,
  341. net::NetLog* net_log,
  342. BackendResultCallback callback,
  343. base::android::ApplicationStatusListener* app_status_listener) {
  344. return CreateCacheBackendImpl(type, backend_type, std::move(file_operations),
  345. path, max_bytes, reset_handling,
  346. std::move(app_status_listener), net_log,
  347. base::OnceClosure(), std::move(callback));
  348. }
  349. #endif
  350. BackendResult CreateCacheBackend(
  351. net::CacheType type,
  352. net::BackendType backend_type,
  353. scoped_refptr<BackendFileOperationsFactory> file_operations,
  354. const base::FilePath& path,
  355. int64_t max_bytes,
  356. ResetHandling reset_handling,
  357. net::NetLog* net_log,
  358. base::OnceClosure post_cleanup_callback,
  359. BackendResultCallback callback) {
  360. return CreateCacheBackendImpl(type, backend_type, std::move(file_operations),
  361. path, max_bytes, reset_handling,
  362. #if BUILDFLAG(IS_ANDROID)
  363. nullptr,
  364. #endif
  365. net_log, std::move(post_cleanup_callback),
  366. std::move(callback));
  367. }
  368. void FlushCacheThreadForTesting() {
  369. // For simple backend.
  370. base::ThreadPoolInstance::Get()->FlushForTesting();
  371. // Block backend.
  372. BackendImpl::FlushForTesting();
  373. }
  374. void FlushCacheThreadAsynchronouslyForTesting(base::OnceClosure callback) {
  375. auto repeating_callback = base::BarrierClosure(2, std::move(callback));
  376. // For simple backend.
  377. base::ThreadPoolInstance::Get()->FlushAsyncForTesting( // IN-TEST
  378. base::BindPostTask(base::SequencedTaskRunnerHandle::Get(),
  379. repeating_callback));
  380. // Block backend.
  381. BackendImpl::FlushAsynchronouslyForTesting(repeating_callback);
  382. }
  383. int64_t Backend::CalculateSizeOfEntriesBetween(
  384. base::Time initial_time,
  385. base::Time end_time,
  386. Int64CompletionOnceCallback callback) {
  387. return net::ERR_NOT_IMPLEMENTED;
  388. }
  389. uint8_t Backend::GetEntryInMemoryData(const std::string& key) {
  390. return 0;
  391. }
  392. void Backend::SetEntryInMemoryData(const std::string& key, uint8_t data) {}
  393. EntryResult::EntryResult() = default;
  394. EntryResult::~EntryResult() = default;
  395. EntryResult::EntryResult(EntryResult&& other) {
  396. net_error_ = other.net_error_;
  397. entry_ = std::move(other.entry_);
  398. opened_ = other.opened_;
  399. other.net_error_ = net::ERR_FAILED;
  400. other.opened_ = false;
  401. }
  402. EntryResult& EntryResult::operator=(EntryResult&& other) {
  403. net_error_ = other.net_error_;
  404. entry_ = std::move(other.entry_);
  405. opened_ = other.opened_;
  406. other.net_error_ = net::ERR_FAILED;
  407. other.opened_ = false;
  408. return *this;
  409. }
  410. // static
  411. EntryResult EntryResult::MakeOpened(Entry* new_entry) {
  412. DCHECK(new_entry);
  413. EntryResult result;
  414. result.net_error_ = net::OK;
  415. result.entry_.reset(new_entry);
  416. result.opened_ = true;
  417. return result;
  418. }
  419. // static
  420. EntryResult EntryResult::MakeCreated(Entry* new_entry) {
  421. DCHECK(new_entry);
  422. EntryResult result;
  423. result.net_error_ = net::OK;
  424. result.entry_.reset(new_entry);
  425. result.opened_ = false;
  426. return result;
  427. }
  428. // static
  429. EntryResult EntryResult::MakeError(net::Error status) {
  430. DCHECK_NE(status, net::OK);
  431. EntryResult result;
  432. result.net_error_ = status;
  433. return result;
  434. }
  435. Entry* EntryResult::ReleaseEntry() {
  436. Entry* ret = entry_.release();
  437. net_error_ = net::ERR_FAILED;
  438. opened_ = false;
  439. return ret;
  440. }
  441. TrivialFileOperations::TrivialFileOperations() {
  442. DETACH_FROM_SEQUENCE(sequence_checker_);
  443. }
  444. TrivialFileOperations::~TrivialFileOperations() {
  445. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  446. }
  447. bool TrivialFileOperations::CreateDirectory(const base::FilePath& path) {
  448. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  449. #if DCHECK_IS_ON()
  450. DCHECK(bound_);
  451. #endif
  452. // This is needed for some unittests.
  453. if (path.empty()) {
  454. return false;
  455. }
  456. DCHECK(path.IsAbsolute());
  457. bool result = base::CreateDirectory(path);
  458. return result;
  459. }
  460. bool TrivialFileOperations::PathExists(const base::FilePath& path) {
  461. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  462. #if DCHECK_IS_ON()
  463. DCHECK(bound_);
  464. #endif
  465. // This is needed for some unittests.
  466. if (path.empty()) {
  467. return false;
  468. }
  469. DCHECK(path.IsAbsolute());
  470. bool result = base::PathExists(path);
  471. return result;
  472. }
  473. bool TrivialFileOperations::DirectoryExists(const base::FilePath& path) {
  474. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  475. DCHECK(path.IsAbsolute());
  476. #if DCHECK_IS_ON()
  477. DCHECK(bound_);
  478. #endif
  479. bool result = base::DirectoryExists(path);
  480. return result;
  481. }
  482. base::File TrivialFileOperations::OpenFile(const base::FilePath& path,
  483. uint32_t flags) {
  484. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  485. DCHECK(path.IsAbsolute());
  486. #if DCHECK_IS_ON()
  487. DCHECK(bound_);
  488. #endif
  489. base::File file(path, flags);
  490. return file;
  491. }
  492. bool TrivialFileOperations::DeleteFile(const base::FilePath& path,
  493. DeleteFileMode mode) {
  494. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  495. DCHECK(path.IsAbsolute());
  496. #if DCHECK_IS_ON()
  497. DCHECK(bound_);
  498. #endif
  499. bool result = false;
  500. switch (mode) {
  501. case DeleteFileMode::kDefault:
  502. result = base::DeleteFile(path);
  503. break;
  504. case DeleteFileMode::kEnsureImmediateAvailability:
  505. result = disk_cache::simple_util::SimpleCacheDeleteFile(path);
  506. break;
  507. }
  508. return result;
  509. }
  510. bool TrivialFileOperations::ReplaceFile(const base::FilePath& from_path,
  511. const base::FilePath& to_path,
  512. base::File::Error* error) {
  513. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  514. DCHECK(from_path.IsAbsolute());
  515. DCHECK(to_path.IsAbsolute());
  516. #if DCHECK_IS_ON()
  517. DCHECK(bound_);
  518. #endif
  519. return base::ReplaceFile(from_path, to_path, error);
  520. }
  521. absl::optional<base::File::Info> TrivialFileOperations::GetFileInfo(
  522. const base::FilePath& path) {
  523. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  524. DCHECK(path.IsAbsolute());
  525. #if DCHECK_IS_ON()
  526. DCHECK(bound_);
  527. #endif
  528. base::File::Info file_info;
  529. if (!base::GetFileInfo(path, &file_info)) {
  530. return absl::nullopt;
  531. }
  532. return file_info;
  533. }
  534. std::unique_ptr<FileEnumerator> TrivialFileOperations::EnumerateFiles(
  535. const base::FilePath& path) {
  536. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  537. DCHECK(path.IsAbsolute());
  538. #if DCHECK_IS_ON()
  539. DCHECK(bound_);
  540. #endif
  541. return std::make_unique<TrivialFileEnumerator>(path);
  542. }
  543. void TrivialFileOperations::CleanupDirectory(
  544. const base::FilePath& path,
  545. base::OnceCallback<void(bool)> callback) {
  546. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  547. // This is needed for some unittests.
  548. if (path.empty()) {
  549. base::SequencedTaskRunnerHandle::Get()->PostTask(
  550. FROM_HERE, base::BindOnce(std::move(callback), false));
  551. return;
  552. }
  553. DCHECK(path.IsAbsolute());
  554. #if DCHECK_IS_ON()
  555. DCHECK(bound_);
  556. #endif
  557. disk_cache::CleanupDirectory(path, std::move(callback));
  558. }
  559. std::unique_ptr<UnboundBackendFileOperations> TrivialFileOperations::Unbind() {
  560. #if DCHECK_IS_ON()
  561. DCHECK(bound_);
  562. bound_ = false;
  563. #endif
  564. return std::make_unique<UnboundTrivialFileOperations>();
  565. }
  566. TrivialFileOperationsFactory::TrivialFileOperationsFactory() = default;
  567. TrivialFileOperationsFactory::~TrivialFileOperationsFactory() = default;
  568. std::unique_ptr<BackendFileOperations> TrivialFileOperationsFactory::Create(
  569. scoped_refptr<base::SequencedTaskRunner> task_runner) {
  570. return std::make_unique<TrivialFileOperations>();
  571. }
  572. std::unique_ptr<UnboundBackendFileOperations>
  573. TrivialFileOperationsFactory::CreateUnbound() {
  574. return std::make_unique<UnboundTrivialFileOperations>();
  575. }
  576. } // namespace disk_cache