blob: 05b689a8fc044cc5f23bd5cd77518231edba34fb [file] [log] [blame]
// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef EXTENSIONS_BROWSER_API_DECLARATIVE_RULES_CACHE_DELEGATE_H__
#define EXTENSIONS_BROWSER_API_DECLARATIVE_RULES_CACHE_DELEGATE_H__
#include <memory>
#include <set>
#include <string>
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/observer_list.h"
#include "base/time/time.h"
#include "base/values.h"
#include "content/public/browser/browser_thread.h"
#include "extensions/common/extension_id.h"
namespace content {
class BrowserContext;
}
namespace extensions {
class ExtensionRegistry;
class RulesRegistry;
// RulesCacheDelegate implements the part of the RulesRegistry which works on
// the UI thread. It should only be used on the UI thread.
// If `log_storage_init_delay` is set, the delay caused by loading and
// registering rules on initialization will be logged with UMA.
class RulesCacheDelegate {
public:
class Observer {
public:
// Called when `UpdateRules` is called on the `RulesCacheDelegate`.
virtual void OnUpdateRules() = 0;
protected:
virtual ~Observer() {}
};
// Determines the type of a cache, indicating whether or not its rules are
// persisted to storage.
enum class Type {
// An ephemeral RulesCacheDelegate never persists to storage when
// |UpdateRules()| is called. It merely tracks rule state on the UI thread.
kEphemeral,
// Persistent RulesCacheDelegate writes the new rule set into storage every
// time |UpdateRules()| is called, in addition to tracking rule state on the
// UI thread.
kPersistent,
};
explicit RulesCacheDelegate(Type type);
virtual ~RulesCacheDelegate();
Type type() const { return type_; }
// Returns a key for the state store. The associated preference is a boolean
// indicating whether there are some declarative rules stored in the rule
// store.
static std::string GetRulesStoredKey(const std::string& event_name,
bool incognito);
// Initialize the storage functionality.
void Init(RulesRegistry* registry);
void UpdateRules(const ExtensionId& extension_id, base::Value::List value);
// Indicates whether or not this registry has any registered rules cached.
bool HasRules() const;
// Adds or removes an observer.
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
base::WeakPtr<RulesCacheDelegate> GetWeakPtr() {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
return weak_ptr_factory_.GetWeakPtr();
}
private:
FRIEND_TEST_ALL_PREFIXES(RulesRegistryWithCacheTest,
DeclarativeRulesStored);
FRIEND_TEST_ALL_PREFIXES(RulesRegistryWithCacheTest,
RulesStoredFlagMultipleRegistries);
const Type type_;
static const char kRulesStoredKey[];
// Check if we are done reading all data from storage on startup, and notify
// the RulesRegistry on its thread if so. The notification is delivered
// exactly once.
void CheckIfReady();
// Schedules retrieving rules for already loaded extensions where
// appropriate.
void ReadRulesForInstalledExtensions();
// Read/write a list of rules serialized to Values.
void ReadFromStorage(const ExtensionId& extension_id);
void ReadFromStorageCallback(const ExtensionId& extension_id,
std::optional<base::Value> value);
// Check the preferences whether the extension with `extension_id` has some
// rules stored on disk. If this information is not in the preferences, true
// is returned as a safe default value.
bool GetDeclarativeRulesStored(const ExtensionId& extension_id) const;
// Modify the preference to `rules_stored`.
void SetDeclarativeRulesStored(const ExtensionId& extension_id,
bool rules_stored);
raw_ptr<content::BrowserContext> browser_context_;
// Indicates whether the ruleset is non-empty. Valid for both `kEphemeral` and
// `kPersistent` cache types.
bool has_nonempty_ruleset_ = false;
// The key under which rules are stored. Only used for `kPersistent` caches.
std::string storage_key_;
// The key under which we store whether the rules have been stored. Only used
// for `kPersistent` caches.
std::string rules_stored_key_;
// A set of extension IDs that have rules we are reading from storage.
std::set<std::string> waiting_for_extensions_;
// Weak pointer to post tasks to the owning rules registry.
base::WeakPtr<RulesRegistry> registry_;
// The thread `registry_` lives on.
content::BrowserThread::ID rules_registry_thread_;
// We notified the RulesRegistry that the rules are loaded.
bool notified_registry_;
base::ObserverList<Observer>::Unchecked observers_;
raw_ptr<const ExtensionRegistry> extension_registry_ = nullptr;
// Use this factory to generate weak pointers bound to the UI thread.
base::WeakPtrFactory<RulesCacheDelegate> weak_ptr_factory_{this};
};
} // namespace extensions
#endif // EXTENSIONS_BROWSER_API_DECLARATIVE_RULES_CACHE_DELEGATE_H__