Commit a481610b authored by Karandeep Bhatia's avatar Karandeep Bhatia Committed by Chromium LUCI CQ

DNR: Queue certain API calls.

Queue updateDynamicRules and updateSessionRules API calls to ensure:
  1. They only execute once the initial rulesets are loaded from disk.
  2. Successive API calls for the same extension execute in a FIFO
     order.
  3. Only one of these calls for an extension executes at a time.

Requirement #3 is needed to implement a shared rules limit for session
and dynamic rules. The first requirement is needed for only dynamic
rules to ensure the initial state for dynamic rules is first loaded up.

This replaces the existing base::OneShot mechanism for fulfilling
requirement #1. To ensure consistency, we also do the same for
updateEnabledRulesets API calls.

Doc=https://docs.google.com/document/d/1FZuuQkG8Tl4ee_K3Ls37iFhjynqStfDjApPvB1N8qsw/edit?usp=sharing&resourcekey=0-kZHQzo1D3pIDAFgYoTSV5g
BUG=1043200

Change-Id: I4efef10c6d917c600f90f985c105164aa141610b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2579716
Commit-Queue: Karan Bhatia <karandeepb@chromium.org>
Reviewed-by: default avatarDevlin <rdevlin.cronin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#843232}
parent f61e1b46
......@@ -189,7 +189,7 @@ DeclarativeNetRequestUpdateSessionRulesFunction::Run() {
base::BindOnce(&DeclarativeNetRequestUpdateSessionRulesFunction::
OnSessionRulesUpdated,
this));
return did_respond() ? AlreadyResponded() : RespondLater();
return RespondLater();
}
void DeclarativeNetRequestUpdateSessionRulesFunction::OnSessionRulesUpdated(
......
......@@ -11,10 +11,10 @@
#include <string>
#include <vector>
#include "base/containers/flat_map.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/one_shot_event.h"
#include "base/optional.h"
#include "base/scoped_observer.h"
#include "extensions/browser/api/declarative_net_request/action_tracker.h"
......@@ -52,6 +52,9 @@ struct LoadRequestData;
class RulesMonitorService : public BrowserContextKeyedAPI,
public ExtensionRegistryObserver {
public:
using ApiCallback =
base::OnceCallback<void(base::Optional<std::string> error)>;
// An observer used in tests.
class TestObserver {
public:
......@@ -79,22 +82,18 @@ class RulesMonitorService : public BrowserContextKeyedAPI,
// Updates the dynamic rules for the |extension| and then invokes
// |callback| with an optional error.
using DynamicRuleUpdateUICallback =
base::OnceCallback<void(base::Optional<std::string> error)>;
void UpdateDynamicRules(
const Extension& extension,
std::vector<int> rule_ids_to_remove,
std::vector<api::declarative_net_request::Rule> rules_to_add,
DynamicRuleUpdateUICallback callback);
ApiCallback callback);
// Updates the set of enabled static rulesets for the |extension| and then
// invokes |callback| with an optional error.
using UpdateEnabledRulesetsUICallback =
base::OnceCallback<void(base::Optional<std::string> error)>;
void UpdateEnabledStaticRulesets(const Extension& extension,
std::set<RulesetID> ids_to_disable,
std::set<RulesetID> ids_to_enable,
UpdateEnabledRulesetsUICallback callback);
ApiCallback callback);
// Returns the list of session scoped rules for |extension_id| as a
// base::ListValue.
......@@ -111,7 +110,7 @@ class RulesMonitorService : public BrowserContextKeyedAPI,
const Extension& extension,
std::vector<int> rule_ids_to_remove,
std::vector<api::declarative_net_request::Rule> rules_to_add,
base::OnceCallback<void(base::Optional<std::string> error)> callback);
ApiCallback callback);
RulesetManager* ruleset_manager() { return &ruleset_manager_; }
......@@ -127,6 +126,7 @@ class RulesMonitorService : public BrowserContextKeyedAPI,
private:
class FileSequenceBridge;
class ApiCallQueue;
friend class BrowserContextKeyedAPIFactory<RulesMonitorService>;
......@@ -158,21 +158,20 @@ class RulesMonitorService : public BrowserContextKeyedAPI,
const ExtensionId& extension_id,
std::vector<int> rule_ids_to_remove,
std::vector<api::declarative_net_request::Rule> rules_to_add,
DynamicRuleUpdateUICallback callback);
ApiCallback callback);
// Internal helper for UpdateEnabledStaticRulesets.
void UpdateEnabledStaticRulesetsInternal(
const ExtensionId& extension_id,
void UpdateEnabledStaticRulesetsInternal(const ExtensionId& extension_id,
std::set<RulesetID> ids_to_disable,
std::set<RulesetID> ids_to_enable,
UpdateEnabledRulesetsUICallback callback);
ApiCallback callback);
// Internal helper for UpdateSessionRules.
void UpdateSessionRulesInternal(
const ExtensionId& extension_id,
std::vector<int> rule_ids_to_remove,
std::vector<api::declarative_net_request::Rule> rules_to_add,
base::OnceCallback<void(base::Optional<std::string> error)> callback);
ApiCallback callback);
// Invoked when we have loaded the rulesets in |load_data| on
// |file_task_runner_| in response to OnExtensionLoaded.
......@@ -180,21 +179,14 @@ class RulesMonitorService : public BrowserContextKeyedAPI,
// Invoked when rulesets are loaded in response to
// UpdateEnabledStaticRulesets.
void OnNewStaticRulesetsLoaded(UpdateEnabledRulesetsUICallback callback,
void OnNewStaticRulesetsLoaded(ApiCallback callback,
std::set<RulesetID> ids_to_disable,
std::set<RulesetID> ids_to_enable,
LoadRequestData load_data);
// Helper to execute a |task| only once the initial ruleset load for the
// |extension| is complete. Should be called in response to API function calls
// which modify rulesets on disk in order to prevent a race with the initial
// ruleset load.
void ExecuteOrQueueAPICall(const Extension& extension,
base::OnceClosure task);
// Invoked when the dynamic rules for the extension have been updated in
// response to UpdateDynamicRules.
void OnDynamicRulesUpdated(DynamicRuleUpdateUICallback callback,
void OnDynamicRulesUpdated(ApiCallback callback,
LoadRequestData load_data,
base::Optional<std::string> error);
......@@ -243,18 +235,18 @@ class RulesMonitorService : public BrowserContextKeyedAPI,
// Non-owned pointer.
TestObserver* test_observer_ = nullptr;
// Stores the tasks to be performed once ruleset loading is done for an
// extension. This is only maintained for extensions which are undergoing a
// ruleset load in response to OnExtensionLoaded.
std::map<ExtensionId, std::unique_ptr<base::OneShotEvent>>
tasks_pending_on_load_;
// Api call queues to ensure only one api call of the given type proceeds at a
// time. Only maintained for enabled extensions.
std::map<ExtensionId, ApiCallQueue> update_enabled_rulesets_queue_map_;
std::map<ExtensionId, ApiCallQueue>
update_dynamic_or_session_rules_queue_map_;
// Session scoped rules value corresponding to extensions.
// TODO(crbug.com/1152430): Currently we are storing session scoped rules in
// two forms: one as a base::ListValue and second in the indexed format as
// part of RulesetMatcher, leading to double memory usage. We should be able
// to do away with the base::ListValue representation.
std::map<ExtensionId, base::ListValue> session_rules_;
base::flat_map<ExtensionId, base::ListValue> session_rules_;
// Must be the last member variable. See WeakPtrFactory documentation for
// details.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment