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() { ...@@ -189,7 +189,7 @@ DeclarativeNetRequestUpdateSessionRulesFunction::Run() {
base::BindOnce(&DeclarativeNetRequestUpdateSessionRulesFunction:: base::BindOnce(&DeclarativeNetRequestUpdateSessionRulesFunction::
OnSessionRulesUpdated, OnSessionRulesUpdated,
this)); this));
return did_respond() ? AlreadyResponded() : RespondLater(); return RespondLater();
} }
void DeclarativeNetRequestUpdateSessionRulesFunction::OnSessionRulesUpdated( void DeclarativeNetRequestUpdateSessionRulesFunction::OnSessionRulesUpdated(
......
...@@ -11,10 +11,10 @@ ...@@ -11,10 +11,10 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "base/containers/flat_map.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/one_shot_event.h"
#include "base/optional.h" #include "base/optional.h"
#include "base/scoped_observer.h" #include "base/scoped_observer.h"
#include "extensions/browser/api/declarative_net_request/action_tracker.h" #include "extensions/browser/api/declarative_net_request/action_tracker.h"
...@@ -52,6 +52,9 @@ struct LoadRequestData; ...@@ -52,6 +52,9 @@ struct LoadRequestData;
class RulesMonitorService : public BrowserContextKeyedAPI, class RulesMonitorService : public BrowserContextKeyedAPI,
public ExtensionRegistryObserver { public ExtensionRegistryObserver {
public: public:
using ApiCallback =
base::OnceCallback<void(base::Optional<std::string> error)>;
// An observer used in tests. // An observer used in tests.
class TestObserver { class TestObserver {
public: public:
...@@ -79,22 +82,18 @@ class RulesMonitorService : public BrowserContextKeyedAPI, ...@@ -79,22 +82,18 @@ class RulesMonitorService : public BrowserContextKeyedAPI,
// Updates the dynamic rules for the |extension| and then invokes // Updates the dynamic rules for the |extension| and then invokes
// |callback| with an optional error. // |callback| with an optional error.
using DynamicRuleUpdateUICallback =
base::OnceCallback<void(base::Optional<std::string> error)>;
void UpdateDynamicRules( void UpdateDynamicRules(
const Extension& extension, const Extension& extension,
std::vector<int> rule_ids_to_remove, std::vector<int> rule_ids_to_remove,
std::vector<api::declarative_net_request::Rule> rules_to_add, 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 // Updates the set of enabled static rulesets for the |extension| and then
// invokes |callback| with an optional error. // invokes |callback| with an optional error.
using UpdateEnabledRulesetsUICallback =
base::OnceCallback<void(base::Optional<std::string> error)>;
void UpdateEnabledStaticRulesets(const Extension& extension, void UpdateEnabledStaticRulesets(const Extension& extension,
std::set<RulesetID> ids_to_disable, std::set<RulesetID> ids_to_disable,
std::set<RulesetID> ids_to_enable, std::set<RulesetID> ids_to_enable,
UpdateEnabledRulesetsUICallback callback); ApiCallback callback);
// Returns the list of session scoped rules for |extension_id| as a // Returns the list of session scoped rules for |extension_id| as a
// base::ListValue. // base::ListValue.
...@@ -111,7 +110,7 @@ class RulesMonitorService : public BrowserContextKeyedAPI, ...@@ -111,7 +110,7 @@ class RulesMonitorService : public BrowserContextKeyedAPI,
const Extension& extension, const Extension& extension,
std::vector<int> rule_ids_to_remove, std::vector<int> rule_ids_to_remove,
std::vector<api::declarative_net_request::Rule> rules_to_add, 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_; } RulesetManager* ruleset_manager() { return &ruleset_manager_; }
...@@ -127,6 +126,7 @@ class RulesMonitorService : public BrowserContextKeyedAPI, ...@@ -127,6 +126,7 @@ class RulesMonitorService : public BrowserContextKeyedAPI,
private: private:
class FileSequenceBridge; class FileSequenceBridge;
class ApiCallQueue;
friend class BrowserContextKeyedAPIFactory<RulesMonitorService>; friend class BrowserContextKeyedAPIFactory<RulesMonitorService>;
...@@ -158,21 +158,20 @@ class RulesMonitorService : public BrowserContextKeyedAPI, ...@@ -158,21 +158,20 @@ class RulesMonitorService : public BrowserContextKeyedAPI,
const ExtensionId& extension_id, const ExtensionId& extension_id,
std::vector<int> rule_ids_to_remove, std::vector<int> rule_ids_to_remove,
std::vector<api::declarative_net_request::Rule> rules_to_add, std::vector<api::declarative_net_request::Rule> rules_to_add,
DynamicRuleUpdateUICallback callback); ApiCallback callback);
// Internal helper for UpdateEnabledStaticRulesets. // Internal helper for UpdateEnabledStaticRulesets.
void UpdateEnabledStaticRulesetsInternal( void UpdateEnabledStaticRulesetsInternal(const ExtensionId& extension_id,
const ExtensionId& extension_id, std::set<RulesetID> ids_to_disable,
std::set<RulesetID> ids_to_disable, std::set<RulesetID> ids_to_enable,
std::set<RulesetID> ids_to_enable, ApiCallback callback);
UpdateEnabledRulesetsUICallback callback);
// Internal helper for UpdateSessionRules. // Internal helper for UpdateSessionRules.
void UpdateSessionRulesInternal( void UpdateSessionRulesInternal(
const ExtensionId& extension_id, const ExtensionId& extension_id,
std::vector<int> rule_ids_to_remove, std::vector<int> rule_ids_to_remove,
std::vector<api::declarative_net_request::Rule> rules_to_add, 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 // Invoked when we have loaded the rulesets in |load_data| on
// |file_task_runner_| in response to OnExtensionLoaded. // |file_task_runner_| in response to OnExtensionLoaded.
...@@ -180,21 +179,14 @@ class RulesMonitorService : public BrowserContextKeyedAPI, ...@@ -180,21 +179,14 @@ class RulesMonitorService : public BrowserContextKeyedAPI,
// Invoked when rulesets are loaded in response to // Invoked when rulesets are loaded in response to
// UpdateEnabledStaticRulesets. // UpdateEnabledStaticRulesets.
void OnNewStaticRulesetsLoaded(UpdateEnabledRulesetsUICallback callback, void OnNewStaticRulesetsLoaded(ApiCallback callback,
std::set<RulesetID> ids_to_disable, std::set<RulesetID> ids_to_disable,
std::set<RulesetID> ids_to_enable, std::set<RulesetID> ids_to_enable,
LoadRequestData load_data); 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 // Invoked when the dynamic rules for the extension have been updated in
// response to UpdateDynamicRules. // response to UpdateDynamicRules.
void OnDynamicRulesUpdated(DynamicRuleUpdateUICallback callback, void OnDynamicRulesUpdated(ApiCallback callback,
LoadRequestData load_data, LoadRequestData load_data,
base::Optional<std::string> error); base::Optional<std::string> error);
...@@ -243,18 +235,18 @@ class RulesMonitorService : public BrowserContextKeyedAPI, ...@@ -243,18 +235,18 @@ class RulesMonitorService : public BrowserContextKeyedAPI,
// Non-owned pointer. // Non-owned pointer.
TestObserver* test_observer_ = nullptr; TestObserver* test_observer_ = nullptr;
// Stores the tasks to be performed once ruleset loading is done for an // Api call queues to ensure only one api call of the given type proceeds at a
// extension. This is only maintained for extensions which are undergoing a // time. Only maintained for enabled extensions.
// ruleset load in response to OnExtensionLoaded. std::map<ExtensionId, ApiCallQueue> update_enabled_rulesets_queue_map_;
std::map<ExtensionId, std::unique_ptr<base::OneShotEvent>> std::map<ExtensionId, ApiCallQueue>
tasks_pending_on_load_; update_dynamic_or_session_rules_queue_map_;
// Session scoped rules value corresponding to extensions. // Session scoped rules value corresponding to extensions.
// TODO(crbug.com/1152430): Currently we are storing session scoped rules in // 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 // 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 // part of RulesetMatcher, leading to double memory usage. We should be able
// to do away with the base::ListValue representation. // 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 // Must be the last member variable. See WeakPtrFactory documentation for
// details. // 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