// Copyright 2022 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef COMPONENTS_UPDATE_CLIENT_CRX_CACHE_H_ #define COMPONENTS_UPDATE_CLIENT_CRX_CACHE_H_ #include #include "base/callback.h" #include "base/files/file_path.h" #include "base/memory/ref_counted.h" #include "base/sequence_checker.h" #include "base/task/task_runner.h" #include "base/task/thread_pool.h" #include "components/update_client/update_client_errors.h" #include "third_party/abseil-cpp/absl/types/optional.h" namespace update_client { // CRX cache for storing and looking up the previous CRX for a given product // so that it can be used in the Puffin patching process. class CrxCache : public base::RefCountedThreadSafe { public: CrxCache(const CrxCache&) = delete; CrxCache& operator=(const CrxCache&) = delete; // Contains the result of the Adding a new CRX. struct Options { Options() = default; // Path in the CRX cache to the newly added CRX. base::FilePath crx_cache_root_path; }; // Constructs an CrxCache to facilitate lookups and updates on a given path. explicit CrxCache(const Options& options); // Contains the result of a CrxCache request. struct Result { Result() = default; // Unpack error: kNone indicates success. UnpackerError error = UnpackerError::kNone; // Path in the CRX cache to the newly added CRX. base::FilePath crx_cache_path; }; // Requests a lookup of the previous CRX for the requested component given // `id` and `fp`. void Get(const std::string& id, const std::string& fp, base::OnceCallback callback); // Requests an entry for the current CRX to be added given the path `crx`, // `id` and `fp`. An entry with the same `id` is overwritten. This helps // to reduce cache size. This method takes ownership of the file, moves it, // and can only be accessed via the new path in the cache, given by `result`. // `callback` is called with the result. void Put(const base::FilePath& crx, const std::string& id, const std::string& fp, base::OnceCallback callback); private: friend class base::RefCountedThreadSafe; // Builds a full path to a crx in the cache, based on `id` and `fp`. base::FilePath BuildCrxFilePath(const std::string& id, const std::string& fp); // Processes a given Get request on the internal SequencedTaskRunner. Result ProcessGet(const std::string& id, const std::string& fp); // Processes a given Put request on the internal SequencedTaskRunner. Result ProcessPut(const base::FilePath& crx, const std::string& id, const std::string& fp); // Removes any stale entries for the given product, should any exist. Runs as // a best effort and ignores any failed delete errors. void RemoveAll(const std::string& id); // Moves the CRX located at `original_crx_path` into its new location in the // cache located at `crx_cache_path`. Returns UnpackerError::kNone on success. UnpackerError MoveFileToCache(const base::FilePath& src_path, const base::FilePath& dest_path); // Ensures the object is released on its sequence. void EndRequest(base::OnceCallback callback, Result result); virtual ~CrxCache(); SEQUENCE_CHECKER(main_sequence_checker_); base::FilePath crx_cache_root_path_; scoped_refptr task_runner_ = base::ThreadPool::CreateSequencedTaskRunner({base::MayBlock()}); }; } // namespace update_client #endif // COMPONENTS_UPDATE_CLIENT_CRX_CACHE_H_