blob: 4c08e338bad36212b4a71a2c5d43da06ff8e7334 [file] [log] [blame]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SERVICES_NETWORK_SHARED_DICTIONARY_SHARED_DICTIONARY_MANAGER_H_
#define SERVICES_NETWORK_SHARED_DICTIONARY_SHARED_DICTIONARY_MANAGER_H_
#include <map>
#include <memory>
#include "base/component_export.h"
#include "base/containers/lru_cache.h"
#include "base/containers/unique_ptr_adapters.h"
#include "base/functional/callback.h"
#include "base/memory/memory_pressure_listener.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "net/disk_cache/disk_cache.h"
#include "net/extras/shared_dictionary/shared_dictionary_usage_info.h"
#include "net/shared_dictionary/shared_dictionary_getter.h"
#include "net/shared_dictionary/shared_dictionary_isolation_key.h"
#include "services/network/public/mojom/network_context.mojom.h"
namespace base {
class FilePath;
} // namespace base
namespace disk_cache {
class BackendFileOperationsFactory;
} // namespace disk_cache
namespace network {
namespace cors {
class CorsURLLoaderSharedDictionaryTest;
} // namespace cors
namespace mojom {
enum class RequestDestination;
} // namespace mojom
class SharedDictionaryStorage;
// This class is attached to NetworkContext and manages the dictionaries for
// CompressionDictionaryTransport feature.
class COMPONENT_EXPORT(NETWORK_SERVICE) SharedDictionaryManager
: public base::MemoryPressureListener {
public:
// Returns a SharedDictionaryManager which keeps the whole dictionary
// information in memory.
static std::unique_ptr<SharedDictionaryManager> CreateInMemory(
uint64_t cache_max_size,
uint64_t cache_max_count);
// Returns a SharedDictionaryManager which keeps the dictionary information
// on disk.
static std::unique_ptr<SharedDictionaryManager> CreateOnDisk(
const base::FilePath& database_path,
const base::FilePath& cache_directory_path,
uint64_t cache_max_size,
uint64_t cache_max_count,
#if BUILDFLAG(IS_ANDROID)
disk_cache::ApplicationStatusListenerGetter app_status_listener_getter,
#endif // BUILDFLAG(IS_ANDROID)
scoped_refptr<disk_cache::BackendFileOperationsFactory>
file_operations_factory);
SharedDictionaryManager(const SharedDictionaryManager&) = delete;
SharedDictionaryManager& operator=(const SharedDictionaryManager&) = delete;
~SharedDictionaryManager() override;
// Returns a SharedDictionaryStorage for the `isolation_key`.
scoped_refptr<SharedDictionaryStorage> GetStorage(
const net::SharedDictionaryIsolationKey& isolation_key);
// Called when the SharedDictionaryStorage for the `isolation_key` is
// deleted.
void OnStorageDeleted(const net::SharedDictionaryIsolationKey& isolation_key);
// Sets the max size of shared dictionary cache.
virtual void SetCacheMaxSize(uint64_t cache_max_size) = 0;
virtual void ClearData(base::Time start_time,
base::Time end_time,
base::RepeatingCallback<bool(const GURL&)> url_matcher,
base::OnceClosure callback) = 0;
virtual void ClearDataForIsolationKey(
const net::SharedDictionaryIsolationKey& isolation_key,
base::OnceClosure callback) = 0;
virtual void GetUsageInfo(
base::OnceCallback<void(
const std::vector<net::SharedDictionaryUsageInfo>&)> callback) = 0;
virtual void GetSharedDictionaryInfo(
const net::SharedDictionaryIsolationKey& isolation_key,
base::OnceCallback<void(
std::vector<network::mojom::SharedDictionaryInfoPtr>)> callback) = 0;
virtual void GetOriginsBetween(
base::Time start_time,
base::Time end_time,
base::OnceCallback<void(const std::vector<url::Origin>&)> callback) = 0;
virtual void HandleMemoryPressure(
base::MemoryPressureLevel memory_pressure_level) = 0;
net::SharedDictionaryGetter MaybeCreateSharedDictionaryGetter(
int request_load_flags,
mojom::RequestDestination request_destination);
void PreloadSharedDictionaryInfoForDocument(
const std::vector<GURL>& urls,
mojo::PendingReceiver<mojom::PreloadedSharedDictionaryInfoHandle>
preload_handle);
bool HasPreloadedSharedDictionaryInfo() const;
protected:
SharedDictionaryManager();
// Called to create a SharedDictionaryStorage for the `isolation_key`. This is
// called only when there is no matching storage in `storages_`.
virtual scoped_refptr<SharedDictionaryStorage> CreateStorage(
const net::SharedDictionaryIsolationKey& isolation_key) = 0;
scoped_refptr<net::SharedDictionary> GetDictionaryImpl(
mojom::RequestDestination request_destination,
const std::optional<net::SharedDictionaryIsolationKey>& isolation_key,
const GURL& request_url);
base::WeakPtr<SharedDictionaryManager> GetWeakPtr();
std::map<net::SharedDictionaryIsolationKey, raw_ptr<SharedDictionaryStorage>>&
storages() {
return storages_;
}
private:
friend class cors::CorsURLLoaderSharedDictionaryTest;
class PreloadedDictionaries;
size_t GetStorageCountForTesting();
void OnMemoryPressure(base::MemoryPressureLevel level) override;
void DeletePreloadedDictionaries(
PreloadedDictionaries* preloaded_dictionaries);
base::LRUCache<net::SharedDictionaryIsolationKey,
scoped_refptr<SharedDictionaryStorage>>
cached_storages_;
std::unique_ptr<base::AsyncMemoryPressureListenerRegistration>
memory_pressure_listener_registration_;
base::MemoryPressureLevel memory_pressure_level_ =
base::MEMORY_PRESSURE_LEVEL_NONE;
std::map<net::SharedDictionaryIsolationKey, raw_ptr<SharedDictionaryStorage>>
storages_;
std::set<std::unique_ptr<PreloadedDictionaries>, base::UniquePtrComparator>
preloaded_dictionaries_set_;
base::WeakPtrFactory<SharedDictionaryManager> weak_factory_{this};
};
// Creates a network::mojom::SharedDictionaryInfo from a `DictionaryInfoType`.
// This is a template method because SharedDictionaryManagerOnDisk and
// SharedDictionaryManagerInMemory are using different class for
// DictionaryInfoType.
template <class DictionaryInfoType>
network::mojom::SharedDictionaryInfoPtr ToMojoSharedDictionaryInfo(
const DictionaryInfoType& info) {
auto mojo_info = network::mojom::SharedDictionaryInfo::New();
mojo_info->match = info.match();
for (const auto dest : info.match_dest()) {
mojo_info->match_dest.push_back(dest);
}
std::sort(mojo_info->match_dest.begin(), mojo_info->match_dest.end());
mojo_info->id = info.id();
mojo_info->dictionary_url = info.url();
mojo_info->last_fetch_time = info.last_fetch_time();
mojo_info->response_time = info.response_time();
mojo_info->expiration = info.expiration();
mojo_info->last_used_time = info.last_used_time();
mojo_info->size = info.size();
mojo_info->hash = info.hash();
return mojo_info;
}
} // namespace network
#endif // SERVICES_NETWORK_SHARED_DICTIONARY_SHARED_DICTIONARY_MANAGER_H_