blob: 152b445ec092667d4ef667d8fcd3cb883eeeb0a3 [file] [log] [blame]
// Copyright 2018 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 <utility>
#include "base/callback.h"
#include "components/autofill_assistant/browser/actions/action.h"
#include "components/autofill_assistant/browser/actions/action_delegate.h"
#include "components/autofill_assistant/browser/client_status.h"
namespace autofill_assistant {
Action::Action(ActionDelegate* delegate, const ActionProto& proto)
: proto_(proto), delegate_(delegate) {}
Action::~Action() {}
bool Action::ShouldInterruptOnPause() const {
return false;
}
void Action::ProcessAction(ProcessActionCallback callback) {
action_stopwatch_.StartActiveTime();
processed_action_proto_ = std::make_unique<ProcessedActionProto>();
InternalProcessAction(base::BindOnce(&Action::RecordActionTimes,
weak_ptr_factory_.GetWeakPtr(),
std::move(callback)));
}
void Action::RecordActionTimes(
ProcessActionCallback callback,
std::unique_ptr<ProcessedActionProto> processed_action_proto) {
// Record times.
action_stopwatch_.Stop();
processed_action_proto->mutable_timing_stats()->set_delay_ms(
proto_.action_delay_ms());
processed_action_proto->mutable_timing_stats()->set_active_time_ms(
action_stopwatch_.TotalActiveTime().InMilliseconds());
processed_action_proto->mutable_timing_stats()->set_wait_time_ms(
action_stopwatch_.TotalWaitTime().InMilliseconds());
std::move(callback).Run(std::move(processed_action_proto));
}
void Action::UpdateProcessedAction(ProcessedActionStatusProto status_proto) {
UpdateProcessedAction(ClientStatus(status_proto));
}
void Action::UpdateProcessedAction(const ClientStatus& status) {
// Safety check in case process action is run twice.
*processed_action_proto_->mutable_action() = proto_;
status.FillProto(processed_action_proto_.get());
}
void Action::OnWaitForElementTimed(
base::OnceCallback<void(const ClientStatus&)> callback,
const ClientStatus& element_status,
base::TimeDelta wait_time) {
action_stopwatch_.TransferToWaitTime(wait_time);
std::move(callback).Run(element_status);
}
// static
std::vector<std::string> Action::ExtractVector(
const google::protobuf::RepeatedPtrField<std::string>& repeated_strings) {
std::vector<std::string> vector;
for (const auto& string : repeated_strings) {
vector.emplace_back(string);
}
return vector;
}
std::ostream& operator<<(std::ostream& out, const Action& action) {
out << action.proto().action_info_case();
return out;
}
std::ostream& operator<<(std::ostream& out,
const ActionProto::ActionInfoCase& action_case) {
#ifdef NDEBUG
out << static_cast<int>(action_case);
return out;
#else
switch (action_case) {
case ActionProto::ActionInfoCase::kClick:
out << "Click";
break;
case ActionProto::ActionInfoCase::kSetFormValue:
out << "KeyboardInput";
break;
case ActionProto::ActionInfoCase::kSelectOption:
out << "SelectOption";
break;
case ActionProto::ActionInfoCase::kNavigate:
out << "Navigate";
break;
case ActionProto::ActionInfoCase::kPrompt:
out << "Prompt";
break;
case ActionProto::ActionInfoCase::kTell:
out << "Tell";
break;
case ActionProto::ActionInfoCase::kShowCast:
out << "ShowCast";
break;
case ActionProto::ActionInfoCase::kWaitForDom:
out << "WaitForDom";
break;
case ActionProto::ActionInfoCase::kUseCard:
out << "UseCard";
break;
case ActionProto::ActionInfoCase::kUseAddress:
out << "UseAddress";
break;
case ActionProto::ActionInfoCase::kUploadDom:
out << "UploadDom";
break;
case ActionProto::ActionInfoCase::kShowProgressBar:
out << "ShowProgressBar";
break;
case ActionProto::ActionInfoCase::kHighlightElement:
out << "HighlightElement";
break;
case ActionProto::ActionInfoCase::kShowDetails:
out << "ShowDetails";
break;
case ActionProto::ActionInfoCase::kStop:
out << "Stop";
break;
case ActionProto::ActionInfoCase::kCollectUserData:
out << "CollectUserData";
break;
case ActionProto::ActionInfoCase::kSetAttribute:
out << "SetAttribute";
break;
case ActionProto::ActionInfoCase::kShowInfoBox:
out << "ShowInfoBox";
break;
case ActionProto::ActionInfoCase::kExpectNavigation:
out << "ExpectNavigation";
break;
case ActionProto::ActionInfoCase::kWaitForNavigation:
out << "WaitForNavigation";
break;
case ActionProto::ActionInfoCase::kConfigureBottomSheet:
out << "ConfigureBottomSheet";
break;
case ActionProto::ActionInfoCase::kShowForm:
out << "ShowForm";
break;
case ActionProto::ActionInfoCase::kPopupMessage:
out << "PopupMessage";
break;
case ActionProto::ActionInfoCase::kWaitForDocument:
out << "WaitForDocument";
break;
case ActionProto::ActionInfoCase::kShowGenericUi:
out << "ShowGenericUi";
break;
case ActionProto::ActionInfoCase::kGeneratePasswordForFormField:
out << "GeneratePasswordForFormField";
break;
case ActionProto::kSaveGeneratedPassword:
out << "SaveGeneratedPassword";
break;
case ActionProto::ActionInfoCase::kConfigureUiState:
out << "ConfigureUiState";
break;
case ActionProto::ActionInfoCase::kPresaveGeneratedPassword:
out << "PresaveGeneratedPassword";
break;
case ActionProto::ActionInfoCase::kGetElementStatus:
out << "GetElementStatus";
break;
case ActionProto::ActionInfoCase::kScrollIntoView:
out << "ScrollIntoView";
break;
case ActionProto::ActionInfoCase::kWaitForDocumentToBecomeInteractive:
out << "WaitForDocumentToBecomeInteractive";
break;
case ActionProto::ActionInfoCase::kWaitForDocumentToBecomeComplete:
out << "WaitForDocumentToBecomeComplete";
break;
case ActionProto::ActionInfoCase::kSendClickEvent:
out << "SendClickEvent";
break;
case ActionProto::ActionInfoCase::kSendTapEvent:
out << "SendTapEvent";
break;
case ActionProto::ActionInfoCase::kJsClick:
out << "JsClick";
break;
case ActionProto::ActionInfoCase::kSendKeystrokeEvents:
out << "SendKeystrokeEvents";
break;
case ActionProto::ActionInfoCase::kSendChangeEvent:
out << "SendChangeEvent";
break;
case ActionProto::ActionInfoCase::kSetElementAttribute:
out << "SetElementAttribute";
break;
case ActionProto::ActionInfoCase::kSelectFieldValue:
out << "SelectFieldValue";
break;
case ActionProto::ActionInfoCase::kFocusField:
out << "FocusField";
break;
case ActionProto::ActionInfoCase::kWaitForElementToBecomeStable:
out << "WaitForElementToBecomeStable";
break;
case ActionProto::ActionInfoCase::kCheckElementIsOnTop:
out << "CheckElementIsOnTop";
break;
case ActionProto::ActionInfoCase::kReleaseElements:
out << "ReleaseElements";
break;
case ActionProto::ActionInfoCase::kDispatchJsEvent:
out << "DispatchJsEvent";
break;
case ActionProto::ActionInfoCase::kSendKeyEvent:
out << "SendKeyEvent";
break;
case ActionProto::ActionInfoCase::kSelectOptionElement:
out << "SelectOptionElement";
break;
case ActionProto::ActionInfoCase::kCheckElementTag:
out << "CheckElementTag";
break;
case ActionProto::ActionInfoCase::kCheckOptionElement:
out << "CheckOptionElement";
break;
case ActionProto::ActionInfoCase::kSetPersistentUi:
out << "SetPersistentUi";
break;
case ActionProto::ActionInfoCase::kClearPersistentUi:
out << "ClearPersistentUi";
break;
case ActionProto::ActionInfoCase::ACTION_INFO_NOT_SET:
out << "ACTION_INFO_NOT_SET";
break;
// Intentionally no default case to make compilation fail if a new value
// was added to the enum but not to this list.
}
return out;
#endif // NDEBUG
}
} // namespace autofill_assistant