Commit 109944a2 authored by Stephane Zermatten's avatar Stephane Zermatten Committed by Commit Bot

[Autofill Assistant] Support delayed actions.

With this change, the script executor follows
AssistantActionProto.action_delay_ms, when it is set.

Bug: 806868
Change-Id: I4cb7ba2074f316cb27bffb61f9f14dc200639792
Reviewed-on: https://chromium-review.googlesource.com/1186737
Commit-Queue: Ganggui Tang <gogerald@chromium.org>
Reviewed-by: default avatarGanggui Tang <gogerald@chromium.org>
Cr-Commit-Position: refs/heads/master@{#585922}
parent ef337163
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/callback.h" #include "base/callback.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "components/autofill_assistant/browser/assistant_protocol_utils.h" #include "components/autofill_assistant/browser/assistant_protocol_utils.h"
#include "components/autofill_assistant/browser/assistant_service.h" #include "components/autofill_assistant/browser/assistant_service.h"
#include "components/autofill_assistant/browser/assistant_ui_controller.h" #include "components/autofill_assistant/browser/assistant_ui_controller.h"
...@@ -117,6 +119,20 @@ void AssistantScriptExecutor::ProcessNextAction() { ...@@ -117,6 +119,20 @@ void AssistantScriptExecutor::ProcessNextAction() {
std::unique_ptr<AssistantAction> action = std::move(actions_.front()); std::unique_ptr<AssistantAction> action = std::move(actions_.front());
actions_.pop_front(); actions_.pop_front();
int delay_ms = action->proto().action_delay_ms();
if (delay_ms > 0) {
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE,
base::BindOnce(&AssistantScriptExecutor::ProcessAction,
weak_ptr_factory_.GetWeakPtr(), std::move(action)),
base::TimeDelta::FromMilliseconds(delay_ms));
} else {
ProcessAction(std::move(action));
}
}
void AssistantScriptExecutor::ProcessAction(
std::unique_ptr<AssistantAction> action) {
AssistantAction* action_ptr = action.get(); AssistantAction* action_ptr = action.get();
action_ptr->ProcessAction( action_ptr->ProcessAction(
this, base::BindOnce(&AssistantScriptExecutor::OnProcessedAction, this, base::BindOnce(&AssistantScriptExecutor::OnProcessedAction,
......
...@@ -52,6 +52,7 @@ class AssistantScriptExecutor : public AssistantActionDelegate { ...@@ -52,6 +52,7 @@ class AssistantScriptExecutor : public AssistantActionDelegate {
private: private:
void OnGetAssistantActions(bool result, const std::string& response); void OnGetAssistantActions(bool result, const std::string& response);
void ProcessNextAction(); void ProcessNextAction();
void ProcessAction(std::unique_ptr<AssistantAction> action);
void GetNextAssistantActions(); void GetNextAssistantActions();
void OnProcessedAction(std::unique_ptr<AssistantAction> action, bool status); void OnProcessedAction(std::unique_ptr<AssistantAction> action, bool status);
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "components/autofill_assistant/browser/assistant_script_executor.h" #include "components/autofill_assistant/browser/assistant_script_executor.h"
#include "base/test/mock_callback.h" #include "base/test/mock_callback.h"
#include "base/test/scoped_task_environment.h"
#include "components/autofill_assistant/browser/assistant_service.h" #include "components/autofill_assistant/browser/assistant_service.h"
#include "components/autofill_assistant/browser/client_memory.h" #include "components/autofill_assistant/browser/client_memory.h"
#include "components/autofill_assistant/browser/mock_assistant_service.h" #include "components/autofill_assistant/browser/mock_assistant_service.h"
...@@ -40,7 +41,9 @@ class AssistantScriptExecutorTest : public testing::Test, ...@@ -40,7 +41,9 @@ class AssistantScriptExecutorTest : public testing::Test,
} }
protected: protected:
AssistantScriptExecutorTest() {} AssistantScriptExecutorTest()
: scoped_task_environment_(
base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME) {}
AssistantService* GetAssistantService() override { AssistantService* GetAssistantService() override {
return &mock_assistant_service_; return &mock_assistant_service_;
...@@ -62,6 +65,9 @@ class AssistantScriptExecutorTest : public testing::Test, ...@@ -62,6 +65,9 @@ class AssistantScriptExecutorTest : public testing::Test,
return output; return output;
} }
// scoped_task_environment_ must be first to guarantee other field
// creation run in that environment.
base::test::ScopedTaskEnvironment scoped_task_environment_;
AssistantScript script_; AssistantScript script_;
ClientMemory memory_; ClientMemory memory_;
StrictMock<MockAssistantService> mock_assistant_service_; StrictMock<MockAssistantService> mock_assistant_service_;
...@@ -169,5 +175,32 @@ TEST_F(AssistantScriptExecutorTest, InterruptActionListOnError) { ...@@ -169,5 +175,32 @@ TEST_F(AssistantScriptExecutorTest, InterruptActionListOnError) {
processed_actions2_capture[0].action().tell().message()); processed_actions2_capture[0].action().tell().message());
} }
TEST_F(AssistantScriptExecutorTest, RunDelayedAction) {
ActionsResponseProto actions_response;
actions_response.set_server_payload("payload");
ActionProto* action = actions_response.add_actions();
action->mutable_tell()->set_message("delayed");
action->set_action_delay_ms(1000);
EXPECT_CALL(mock_assistant_service_, OnGetAssistantActions(_, _))
.WillOnce(RunOnceCallback<1>(true, Serialize(actions_response)));
std::vector<ProcessedActionProto> processed_actions_capture;
EXPECT_CALL(mock_assistant_service_, OnGetNextAssistantActions(_, _, _))
.WillOnce(DoAll(SaveArg<1>(&processed_actions_capture),
RunOnceCallback<2>(true, "")));
// executor_callback_.Run() not expected to be run just yet, as the action is
// delayed.
executor_->Run(executor_callback_.Get());
EXPECT_TRUE(scoped_task_environment_.MainThreadHasPendingTask());
// Moving forward in time triggers action execution.
EXPECT_CALL(executor_callback_, Run(true));
scoped_task_environment_.FastForwardBy(
base::TimeDelta::FromMilliseconds(1000));
EXPECT_FALSE(scoped_task_environment_.MainThreadHasPendingTask());
}
} // namespace } // namespace
} // namespace autofill_assistant } // namespace autofill_assistant
...@@ -95,6 +95,9 @@ message ActionsResponseProto { ...@@ -95,6 +95,9 @@ message ActionsResponseProto {
// An action could be performed. // An action could be performed.
message ActionProto { message ActionProto {
// Wait these many milliseconds before executing the action, if set.
optional int32 action_delay_ms = 3;
// Opaque data that should not be interpreted by the client. The client must // Opaque data that should not be interpreted by the client. The client must
// pass this back unchanged in the next request // pass this back unchanged in the next request
optional bytes server_payload = 4; optional bytes server_payload = 4;
......
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