Commit 11a2ea0b authored by Clemens Arbesser's avatar Clemens Arbesser Committed by Commit Bot

[Autofill Assistant] Adds the native coordinator for trigger scripts.

This is currently not yet wired up to the android UI, but is otherwise
fully functional. There are some smaller follow-ups that I extracted
from this CL:
- Update to metrics enums
- Wiring it up to android

Bug: b/171776026
Change-Id: I7a05d97ccabb8c2bbaa3bb574d74772e9c4dbfb0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2517696
Commit-Queue: Clemens Arbesser <arbesser@google.com>
Reviewed-by: default avatarMarian Fechete <marianfe@google.com>
Cr-Commit-Position: refs/heads/master@{#825274}
parent 05f9f025
...@@ -354,6 +354,10 @@ source_set("unit_tests") { ...@@ -354,6 +354,10 @@ source_set("unit_tests") {
"test_util.h", "test_util.h",
"trigger_context_unittest.cc", "trigger_context_unittest.cc",
"trigger_scripts/dynamic_trigger_conditions_unittest.cc", "trigger_scripts/dynamic_trigger_conditions_unittest.cc",
"trigger_scripts/mock_dynamic_trigger_conditions.cc",
"trigger_scripts/mock_dynamic_trigger_conditions.h",
"trigger_scripts/mock_static_trigger_conditions.cc",
"trigger_scripts/mock_static_trigger_conditions.h",
"trigger_scripts/static_trigger_conditions_unittest.cc", "trigger_scripts/static_trigger_conditions_unittest.cc",
"trigger_scripts/trigger_script_coordinator_unittest.cc", "trigger_scripts/trigger_script_coordinator_unittest.cc",
"trigger_scripts/trigger_script_unittest.cc", "trigger_scripts/trigger_script_unittest.cc",
......
...@@ -286,11 +286,32 @@ bool ProtocolUtils::ParseActions(ActionDelegate* delegate, ...@@ -286,11 +286,32 @@ bool ProtocolUtils::ParseActions(ActionDelegate* delegate,
return true; return true;
} }
// static
std::string ProtocolUtils::CreateGetTriggerScriptsRequest(
const GURL& url,
const ClientContextProto& client_context,
const std::map<std::string, std::string>& script_parameters) {
GetTriggerScriptsRequestProto request_proto;
request_proto.set_url(url.spec());
*request_proto.mutable_client_context() = client_context;
if (!script_parameters.empty()) {
AppendScriptParametersToRepeatedField(
script_parameters, request_proto.mutable_debug_script_parameters());
}
std::string serialized_request_proto;
bool success = request_proto.SerializeToString(&serialized_request_proto);
DCHECK(success);
return serialized_request_proto;
}
// static // static
bool ProtocolUtils::ParseTriggerScripts( bool ProtocolUtils::ParseTriggerScripts(
const std::string& response, const std::string& response,
std::vector<std::unique_ptr<TriggerScript>>* trigger_scripts) { std::vector<std::unique_ptr<TriggerScript>>* trigger_scripts,
std::vector<std::string>* additional_allowed_domains) {
DCHECK(trigger_scripts); DCHECK(trigger_scripts);
DCHECK(additional_allowed_domains);
GetTriggerScriptsResponseProto response_proto; GetTriggerScriptsResponseProto response_proto;
if (!response_proto.ParseFromString(response)) { if (!response_proto.ParseFromString(response)) {
...@@ -302,6 +323,11 @@ bool ProtocolUtils::ParseTriggerScripts( ...@@ -302,6 +323,11 @@ bool ProtocolUtils::ParseTriggerScripts(
trigger_scripts->emplace_back( trigger_scripts->emplace_back(
std::make_unique<TriggerScript>(trigger_script_proto)); std::make_unique<TriggerScript>(trigger_script_proto));
} }
for (const auto& allowed_domain :
response_proto.additional_allowed_domains()) {
additional_allowed_domains->emplace_back(allowed_domain);
}
return true; return true;
} }
......
...@@ -54,6 +54,12 @@ class ProtocolUtils { ...@@ -54,6 +54,12 @@ class ProtocolUtils {
const RoundtripTimingStats& timing_stats, const RoundtripTimingStats& timing_stats,
const ClientContextProto& client_context); const ClientContextProto& client_context);
// Create request to get the available trigger scripts for |url|.
static std::string CreateGetTriggerScriptsRequest(
const GURL& url,
const ClientContextProto& client_context,
const std::map<std::string, std::string>& script_parameters);
// Create an action from the |action|. // Create an action from the |action|.
static std::unique_ptr<Action> CreateAction(ActionDelegate* delegate, static std::unique_ptr<Action> CreateAction(ActionDelegate* delegate,
const ActionProto& action); const ActionProto& action);
...@@ -79,7 +85,8 @@ class ProtocolUtils { ...@@ -79,7 +85,8 @@ class ProtocolUtils {
// |trigger_scripts|. Returns false if parsing failed, else true. // |trigger_scripts|. Returns false if parsing failed, else true.
static bool ParseTriggerScripts( static bool ParseTriggerScripts(
const std::string& response, const std::string& response,
std::vector<std::unique_ptr<TriggerScript>>* trigger_scripts); std::vector<std::unique_ptr<TriggerScript>>* trigger_scripts,
std::vector<std::string>* additional_allowed_domains);
private: private:
// To avoid instantiate this class by accident. // To avoid instantiate this class by accident.
......
...@@ -327,19 +327,35 @@ TEST_F(ProtocolUtilsTest, ParseActionsUpdateScriptListFullFeatured) { ...@@ -327,19 +327,35 @@ TEST_F(ProtocolUtilsTest, ParseActionsUpdateScriptListFullFeatured) {
TEST_F(ProtocolUtilsTest, ParseTriggerScriptsParseError) { TEST_F(ProtocolUtilsTest, ParseTriggerScriptsParseError) {
std::vector<std::unique_ptr<TriggerScript>> trigger_scripts; std::vector<std::unique_ptr<TriggerScript>> trigger_scripts;
EXPECT_FALSE(ProtocolUtils::ParseTriggerScripts("invalid", &trigger_scripts)); std::vector<std::string> additional_allowed_domains;
EXPECT_FALSE(ProtocolUtils::ParseTriggerScripts("invalid", &trigger_scripts,
&additional_allowed_domains));
EXPECT_TRUE(trigger_scripts.empty()); EXPECT_TRUE(trigger_scripts.empty());
} }
TEST_F(ProtocolUtilsTest, CreateGetTriggerScriptsRequest) {
std::map<std::string, std::string> parameters = {{"key_a", "value_a"},
{"key_b", "value_b"}};
GetTriggerScriptsRequestProto request;
EXPECT_TRUE(
request.ParseFromString(ProtocolUtils::CreateGetTriggerScriptsRequest(
GURL("http://example.com/"), client_context_proto_, parameters)));
AssertClientContext(request.client_context());
AssertScriptParameters(request.debug_script_parameters(), parameters);
EXPECT_EQ("http://example.com/", request.url());
}
TEST_F(ProtocolUtilsTest, ParseTriggerScriptsValid) { TEST_F(ProtocolUtilsTest, ParseTriggerScriptsValid) {
GetTriggerScriptsResponseProto proto; GetTriggerScriptsResponseProto proto;
proto.add_additional_allowed_domains("example.com");
proto.add_additional_allowed_domains("other-example.com");
TriggerScriptProto trigger_script_1; TriggerScriptProto trigger_script_1;
*trigger_script_1.mutable_trigger_condition()->mutable_selector() = *trigger_script_1.mutable_trigger_condition()->mutable_selector() =
ToSelectorProto("fake_element_1"); ToSelectorProto("fake_element_1");
TriggerScriptProto trigger_script_2; TriggerScriptProto trigger_script_2;
trigger_script_2.set_on_trigger_condition_no_longer_true(
TriggerScriptProto::CANCEL_SESSION);
*proto.add_trigger_scripts() = trigger_script_1; *proto.add_trigger_scripts() = trigger_script_1;
*proto.add_trigger_scripts() = trigger_script_2; *proto.add_trigger_scripts() = trigger_script_2;
...@@ -348,12 +364,16 @@ TEST_F(ProtocolUtilsTest, ParseTriggerScriptsValid) { ...@@ -348,12 +364,16 @@ TEST_F(ProtocolUtilsTest, ParseTriggerScriptsValid) {
proto.SerializeToString(&proto_str); proto.SerializeToString(&proto_str);
std::vector<std::unique_ptr<TriggerScript>> trigger_scripts; std::vector<std::unique_ptr<TriggerScript>> trigger_scripts;
EXPECT_TRUE(ProtocolUtils::ParseTriggerScripts(proto_str, &trigger_scripts)); std::vector<std::string> additional_allowed_domains;
EXPECT_TRUE(ProtocolUtils::ParseTriggerScripts(proto_str, &trigger_scripts,
&additional_allowed_domains));
EXPECT_THAT( EXPECT_THAT(
trigger_scripts, trigger_scripts,
ElementsAre( ElementsAre(
Pointee(Property(&TriggerScript::AsProto, Eq(trigger_script_1))), Pointee(Property(&TriggerScript::AsProto, Eq(trigger_script_1))),
Pointee(Property(&TriggerScript::AsProto, Eq(trigger_script_2))))); Pointee(Property(&TriggerScript::AsProto, Eq(trigger_script_2)))));
EXPECT_THAT(additional_allowed_domains,
ElementsAre("example.com", "other-example.com"));
} }
} // namespace } // namespace
......
...@@ -438,8 +438,8 @@ message Empty {} ...@@ -438,8 +438,8 @@ message Empty {}
// RPC request to fetch the available trigger scripts for a particular domain. // RPC request to fetch the available trigger scripts for a particular domain.
message GetTriggerScriptsRequestProto { message GetTriggerScriptsRequestProto {
// The domain for which to fetch the trigger scripts. // The exact url for which to fetch the trigger scripts.
optional string domain = 1; optional string url = 1;
// The client context. // The client context.
// NOTE: Currently, this will only contain the Chrome version number for // NOTE: Currently, this will only contain the Chrome version number for
// privacy reasons. // privacy reasons.
...@@ -452,6 +452,11 @@ message GetTriggerScriptsRequestProto { ...@@ -452,6 +452,11 @@ message GetTriggerScriptsRequestProto {
message GetTriggerScriptsResponseProto { message GetTriggerScriptsResponseProto {
// The available trigger scripts, if any. // The available trigger scripts, if any.
repeated TriggerScriptProto trigger_scripts = 1; repeated TriggerScriptProto trigger_scripts = 1;
// A list of additional domains and subdomains. Trigger scripts will
// automatically cancel the ongoing session if the user navigates away from
// the original domain or any of the additional domains.
repeated string additional_allowed_domains = 2;
} }
// A trigger script contains the full specification for a trigger script that is // A trigger script contains the full specification for a trigger script that is
...@@ -478,12 +483,11 @@ message TriggerScriptProto { ...@@ -478,12 +483,11 @@ message TriggerScriptProto {
// The |trigger_condition| must be true for the script to trigger. // The |trigger_condition| must be true for the script to trigger.
optional TriggerScriptConditionProto trigger_condition = 1; optional TriggerScriptConditionProto trigger_condition = 1;
// The action that should automatically be executed when a trigger condition
// is first true and then stops being true.
optional TriggerScriptAction on_trigger_condition_no_longer_true = 2;
// The user interface to show. // The user interface to show.
optional TriggerScriptUIProto user_interface = 3; optional TriggerScriptUIProto user_interface = 3;
reserved 2;
} }
message TriggerScriptConditionProto { message TriggerScriptConditionProto {
......
...@@ -22,7 +22,7 @@ namespace autofill_assistant { ...@@ -22,7 +22,7 @@ namespace autofill_assistant {
class DynamicTriggerConditions { class DynamicTriggerConditions {
public: public:
DynamicTriggerConditions(); DynamicTriggerConditions();
~DynamicTriggerConditions(); virtual ~DynamicTriggerConditions();
// Adds the selector trigger conditions specified in |proto| to the list of // Adds the selector trigger conditions specified in |proto| to the list of
// selectors to be queried in |Update|. // selectors to be queried in |Update|.
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/autofill_assistant/browser/trigger_scripts/mock_dynamic_trigger_conditions.h"
namespace autofill_assistant {
MockDynamicTriggerConditions::MockDynamicTriggerConditions() = default;
MockDynamicTriggerConditions::~MockDynamicTriggerConditions() = default;
} // namespace autofill_assistant
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_TRIGGER_SCRIPTS_MOCK_DYNAMIC_TRIGGER_CONDITIONS_H_
#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_TRIGGER_SCRIPTS_MOCK_DYNAMIC_TRIGGER_CONDITIONS_H_
#include "components/autofill_assistant/browser/trigger_scripts/dynamic_trigger_conditions.h"
#include "testing/gmock/include/gmock/gmock.h"
namespace autofill_assistant {
class MockDynamicTriggerConditions : public DynamicTriggerConditions {
public:
MockDynamicTriggerConditions();
~MockDynamicTriggerConditions() override;
MOCK_CONST_METHOD1(GetSelectorMatches,
base::Optional<bool>(const Selector& selector));
void Update(WebController* web_controller,
base::OnceCallback<void(void)> callback) override {
OnUpdate(web_controller, callback);
}
MOCK_METHOD2(OnUpdate,
void(WebController* web_controller,
base::OnceCallback<void(void)>& callback));
};
} // namespace autofill_assistant
#endif // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_TRIGGER_SCRIPTS_MOCK_DYNAMIC_TRIGGER_CONDITIONS_H_
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/autofill_assistant/browser/trigger_scripts/mock_static_trigger_conditions.h"
namespace autofill_assistant {
MockStaticTriggerConditions::MockStaticTriggerConditions() = default;
MockStaticTriggerConditions::~MockStaticTriggerConditions() = default;
} // namespace autofill_assistant
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_TRIGGER_SCRIPTS_MOCK_STATIC_TRIGGER_CONDITIONS_H_
#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_TRIGGER_SCRIPTS_MOCK_STATIC_TRIGGER_CONDITIONS_H_
#include "components/autofill_assistant/browser/trigger_scripts/static_trigger_conditions.h"
#include "testing/gmock/include/gmock/gmock.h"
namespace autofill_assistant {
class MockStaticTriggerConditions : public StaticTriggerConditions {
public:
MockStaticTriggerConditions();
~MockStaticTriggerConditions() override;
MOCK_METHOD4(Init,
void(Client* client,
const GURL& url,
TriggerContext* trigger_context,
base::OnceCallback<void(void)> callback));
MOCK_METHOD1(set_is_first_time_user, void(bool));
MOCK_CONST_METHOD0(is_first_time_user, bool());
MOCK_CONST_METHOD0(has_stored_login_credentials, bool());
MOCK_CONST_METHOD1(is_in_experiment, bool(int experiment_id));
};
} // namespace autofill_assistant
#endif // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_TRIGGER_SCRIPTS_MOCK_STATIC_TRIGGER_CONDITIONS_H_
...@@ -31,6 +31,10 @@ void StaticTriggerConditions::Init(Client* client, ...@@ -31,6 +31,10 @@ void StaticTriggerConditions::Init(Client* client,
weak_ptr_factory_.GetWeakPtr())); weak_ptr_factory_.GetWeakPtr()));
} }
void StaticTriggerConditions::set_is_first_time_user(bool first_time_user) {
is_first_time_user_ = first_time_user;
}
bool StaticTriggerConditions::is_first_time_user() const { bool StaticTriggerConditions::is_first_time_user() const {
return is_first_time_user_; return is_first_time_user_;
} }
......
...@@ -22,7 +22,7 @@ namespace autofill_assistant { ...@@ -22,7 +22,7 @@ namespace autofill_assistant {
class StaticTriggerConditions { class StaticTriggerConditions {
public: public:
StaticTriggerConditions(); StaticTriggerConditions();
~StaticTriggerConditions(); virtual ~StaticTriggerConditions();
// Initializes the field values according to |url| and the current state of // Initializes the field values according to |url| and the current state of
// |client|. Invokes |callback| when done. |client| and |trigger_context| must // |client|. Invokes |callback| when done. |client| and |trigger_context| must
...@@ -33,6 +33,7 @@ class StaticTriggerConditions { ...@@ -33,6 +33,7 @@ class StaticTriggerConditions {
const GURL& url, const GURL& url,
TriggerContext* trigger_context, TriggerContext* trigger_context,
base::OnceCallback<void(void)> callback); base::OnceCallback<void(void)> callback);
virtual void set_is_first_time_user(bool first_time_user);
virtual bool is_first_time_user() const; virtual bool is_first_time_user() const;
virtual bool has_stored_login_credentials() const; virtual bool has_stored_login_credentials() const;
virtual bool is_in_experiment(int experiment_id) const; virtual bool is_in_experiment(int experiment_id) const;
......
...@@ -55,5 +55,11 @@ TEST_F(StaticTriggerConditionsTest, Init) { ...@@ -55,5 +55,11 @@ TEST_F(StaticTriggerConditionsTest, Init) {
EXPECT_TRUE(static_trigger_conditions_.is_in_experiment(4)); EXPECT_TRUE(static_trigger_conditions_.is_in_experiment(4));
} }
TEST_F(StaticTriggerConditionsTest, SetIsFirstTimeUser) {
EXPECT_TRUE(static_trigger_conditions_.is_first_time_user());
static_trigger_conditions_.set_is_first_time_user(false);
EXPECT_FALSE(static_trigger_conditions_.is_first_time_user());
}
} // namespace } // namespace
} // namespace autofill_assistant } // namespace autofill_assistant
...@@ -77,4 +77,12 @@ TriggerScriptProto TriggerScript::AsProto() const { ...@@ -77,4 +77,12 @@ TriggerScriptProto TriggerScript::AsProto() const {
return proto_; return proto_;
} }
bool TriggerScript::waiting_for_precondition_no_longer_true() const {
return waiting_for_precondition_no_longer_true_;
}
void TriggerScript::waiting_for_precondition_no_longer_true(bool waiting) {
waiting_for_precondition_no_longer_true_ = waiting;
}
} // namespace autofill_assistant } // namespace autofill_assistant
...@@ -28,10 +28,16 @@ class TriggerScript { ...@@ -28,10 +28,16 @@ class TriggerScript {
TriggerScriptProto AsProto() const; TriggerScriptProto AsProto() const;
// Whether the trigger script is currently waiting for its precondition to be
// fulfilled or for its precondition to stop being fulfilled.
bool waiting_for_precondition_no_longer_true() const;
void waiting_for_precondition_no_longer_true(bool waiting);
private: private:
friend class TriggerScriptTest; friend class TriggerScriptTest;
TriggerScriptProto proto_; TriggerScriptProto proto_;
bool waiting_for_precondition_no_longer_true_ = false;
}; };
} // namespace autofill_assistant } // namespace autofill_assistant
......
...@@ -12,11 +12,17 @@ ...@@ -12,11 +12,17 @@
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/observer_list.h" #include "base/observer_list.h"
#include "base/observer_list_types.h" #include "base/observer_list_types.h"
#include "base/time/time.h"
#include "components/autofill_assistant/browser/client.h" #include "components/autofill_assistant/browser/client.h"
#include "components/autofill_assistant/browser/metrics.h"
#include "components/autofill_assistant/browser/service.pb.h" #include "components/autofill_assistant/browser/service.pb.h"
#include "components/autofill_assistant/browser/service/service_request_sender.h" #include "components/autofill_assistant/browser/service/service_request_sender.h"
#include "components/autofill_assistant/browser/trigger_context.h"
#include "components/autofill_assistant/browser/trigger_scripts/dynamic_trigger_conditions.h"
#include "components/autofill_assistant/browser/trigger_scripts/static_trigger_conditions.h"
#include "components/autofill_assistant/browser/trigger_scripts/trigger_script.h" #include "components/autofill_assistant/browser/trigger_scripts/trigger_script.h"
#include "components/autofill_assistant/browser/web/web_controller.h" #include "components/autofill_assistant/browser/web/web_controller.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_observer.h"
#include "url/gurl.h" #include "url/gurl.h"
...@@ -37,21 +43,29 @@ class TriggerScriptCoordinator : public content::WebContentsObserver { ...@@ -37,21 +43,29 @@ class TriggerScriptCoordinator : public content::WebContentsObserver {
virtual void OnTriggerScriptShown(const TriggerScriptUIProto& proto) = 0; virtual void OnTriggerScriptShown(const TriggerScriptUIProto& proto) = 0;
virtual void OnTriggerScriptHidden() = 0; virtual void OnTriggerScriptHidden() = 0;
virtual void OnTriggerScriptFinished(int state) = 0; // TODO(b/171776026): Add new states to our metrics and use them in the
// coordinator.
virtual void OnTriggerScriptFinished(
Metrics::LiteScriptFinishedState state) = 0;
}; };
// |client| and |web_contents| must outlive this instance. // |client| and |web_contents| must outlive this instance.
TriggerScriptCoordinator(Client* client, TriggerScriptCoordinator(
std::unique_ptr<WebController> web_controller, Client* client,
std::unique_ptr<ServiceRequestSender> request_sender, std::unique_ptr<WebController> web_controller,
const GURL& get_trigger_scripts_server); std::unique_ptr<ServiceRequestSender> request_sender,
const GURL& get_trigger_scripts_server,
std::unique_ptr<StaticTriggerConditions> static_trigger_conditions,
std::unique_ptr<DynamicTriggerConditions> dynamic_trigger_conditions);
~TriggerScriptCoordinator() override; ~TriggerScriptCoordinator() override;
TriggerScriptCoordinator(const TriggerScriptCoordinator&) = delete; TriggerScriptCoordinator(const TriggerScriptCoordinator&) = delete;
TriggerScriptCoordinator& operator=(const TriggerScriptCoordinator&) = delete; TriggerScriptCoordinator& operator=(const TriggerScriptCoordinator&) = delete;
// Retrieves all trigger scripts for |url| and starts evaluating their // Retrieves all trigger scripts for |deeplink_url| and starts evaluating
// preconditions. Observers will be notified of all relevant status updates. // their trigger conditions. Observers will be notified of all relevant status
void Start(const GURL& url); // updates.
void Start(const GURL& deeplink_url,
std::unique_ptr<TriggerContext> trigger_context);
// Performs |action|. This is usually invoked by the UI as a result of user // Performs |action|. This is usually invoked by the UI as a result of user
// interactions. // interactions.
...@@ -62,17 +76,74 @@ class TriggerScriptCoordinator : public content::WebContentsObserver { ...@@ -62,17 +76,74 @@ class TriggerScriptCoordinator : public content::WebContentsObserver {
void RemoveObserver(const Observer* observer); void RemoveObserver(const Observer* observer);
private: private:
struct PendingTriggerScript { friend class TriggerScriptCoordinatorTest;
TriggerScript trigger_script;
bool waiting_for_precondition_no_longer_true = false;
};
// From content::WebContentsObserver. // From content::WebContentsObserver.
void DidFinishNavigation(
content::NavigationHandle* navigation_handle) override;
void OnVisibilityChanged(content::Visibility visibility) override; void OnVisibilityChanged(content::Visibility visibility) override;
void StartCheckingTriggerConditions();
void StopCheckingTriggerConditions();
void ShowTriggerScript(int index);
void HideTriggerScript();
void CheckDynamicTriggerConditions();
void OnDynamicTriggerConditionsEvaluated();
void OnGetTriggerScripts(int http_status, const std::string& response);
void NotifyOnTriggerScriptFinished(Metrics::LiteScriptFinishedState state);
// Used to retrieve deps and also to request shutdown and, if applicable,
// start of the regular script.
Client* client_;
// The original deeplink to request trigger scripts for.
GURL deeplink_url_;
// List of additional domains. If the user leaves the (sub)domain of
// |deeplink_url_| or |additional_allowed_domains_|, the session stops.
std::vector<std::string> additional_allowed_domains_;
// The trigger context for the most recent |Start|. This is stored as a member
// to allow pausing and resuming the same trigger flow.
std::unique_ptr<TriggerContext> trigger_context_;
// Keeps track of whether the tab is currently visible or not. While
// invisible, trigger scripts are hidden and condition evaluation is
// suspended.
bool web_contents_visible_ = true;
// Whether the coordinator is currently checking trigger conditions.
bool is_checking_trigger_conditions_ = false;
// Index of the trigger script that is currently being shown. -1 if no script
// is being shown.
int visible_trigger_script_ = -1;
// Used to request trigger scripts from the backend.
std::unique_ptr<ServiceRequestSender> request_sender_;
// The URL of the server that should be contacted by |request_sender_|.
GURL get_trigger_scripts_server_;
// The web controller to evaluate element conditions.
std::unique_ptr<WebController> web_controller_;
// The list of currently registered observers. // The list of currently registered observers.
base::ObserverList<Observer> observers_; base::ObserverList<Observer> observers_;
// The list of trigger scripts that were fetched from the backend.
std::vector<std::unique_ptr<TriggerScript>> trigger_scripts_;
// Evaluate and cache the results for static and dynamic trigger conditions.
std::unique_ptr<StaticTriggerConditions> static_trigger_conditions_;
std::unique_ptr<DynamicTriggerConditions> dynamic_trigger_conditions_;
// The time between consecutive evaluations of dynamic trigger conditions.
// TODO(arbesser): Maybe make this configurable in proto?
base::TimeDelta periodic_element_check_interval_ =
base::TimeDelta::FromSeconds(1);
base::WeakPtrFactory<TriggerScriptCoordinator> weak_ptr_factory_{this}; base::WeakPtrFactory<TriggerScriptCoordinator> weak_ptr_factory_{this};
}; };
......
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
#include "base/test/mock_callback.h" #include "base/test/mock_callback.h"
#include "components/autofill_assistant/browser/service.pb.h" #include "components/autofill_assistant/browser/service.pb.h"
#include "components/autofill_assistant/browser/trigger_scripts/dynamic_trigger_conditions.h" #include "components/autofill_assistant/browser/trigger_scripts/dynamic_trigger_conditions.h"
#include "components/autofill_assistant/browser/trigger_scripts/mock_dynamic_trigger_conditions.h"
#include "components/autofill_assistant/browser/trigger_scripts/mock_static_trigger_conditions.h"
#include "components/autofill_assistant/browser/trigger_scripts/static_trigger_conditions.h" #include "components/autofill_assistant/browser/trigger_scripts/static_trigger_conditions.h"
#include "testing/gmock/include/gmock/gmock.h" #include "testing/gmock/include/gmock/gmock.h"
...@@ -16,32 +18,6 @@ namespace autofill_assistant { ...@@ -16,32 +18,6 @@ namespace autofill_assistant {
using ::testing::NiceMock; using ::testing::NiceMock;
using ::testing::Return; using ::testing::Return;
class MockStaticTriggerConditions : public StaticTriggerConditions {
public:
MOCK_METHOD4(Init,
void(Client* client,
const GURL& url,
TriggerContext* trigger_context,
base::OnceCallback<void(void)> callback));
MOCK_CONST_METHOD0(is_first_time_user, bool());
MOCK_CONST_METHOD0(has_stored_login_credentials, bool());
MOCK_CONST_METHOD1(is_in_experiment, bool(int experiment_id));
};
class MockDynamicTriggerConditions : public DynamicTriggerConditions {
public:
MOCK_CONST_METHOD1(GetSelectorMatches,
base::Optional<bool>(const Selector& selector));
void Update(WebController* web_controller,
base::OnceCallback<void(void)> callback) override {
OnUpdate(web_controller, callback);
}
MOCK_METHOD2(OnUpdate,
void(WebController* web_controller,
base::OnceCallback<void(void)>& callback));
};
class TriggerScriptTest : public testing::Test { class TriggerScriptTest : public testing::Test {
public: public:
TriggerScriptTest() : trigger_script_(TriggerScriptProto()) {} TriggerScriptTest() : trigger_script_(TriggerScriptProto()) {}
......
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