Commit 363dc227 authored by Clemens Arbesser's avatar Clemens Arbesser Committed by Commit Bot

[Autofill Assistant] Split java events from native events.

The groundwork for this was already done a while back. This CL splits
the creation of interaction events into two independent parts:
  native -> java, with dynamic resolution of views by identifier
  java -> native, with static resolution at time of creation

This has the advantage that all native->java interactions can be created at any time, in particular, before or during views creation. This is in preparation for implicit view interactions, i.e., interactions that are implicitly defined as part of a view definition and which need to be created during view creation.

This is a refactoring only and should not contain user-facing changes.

Bug: b/145043394
Change-Id: I19fe9e320e8fd7336102ed017eeb730a24a021f4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2119860
Commit-Queue: Clemens Arbesser <arbesser@google.com>
Reviewed-by: default avatarMarian Fechete <marianfe@google.com>
Cr-Commit-Position: refs/heads/master@{#753614}
parent 4020d9a4
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "chrome/android/features/autofill_assistant/jni_headers/AssistantDrawable_jni.h" #include "chrome/android/features/autofill_assistant/jni_headers/AssistantDrawable_jni.h"
#include "chrome/android/features/autofill_assistant/jni_headers/AssistantViewFactory_jni.h" #include "chrome/android/features/autofill_assistant/jni_headers/AssistantViewFactory_jni.h"
#include "chrome/browser/android/autofill_assistant/assistant_generic_ui_delegate.h" #include "chrome/browser/android/autofill_assistant/assistant_generic_ui_delegate.h"
#include "chrome/browser/android/autofill_assistant/generic_ui_events_android.h"
#include "chrome/browser/android/autofill_assistant/interaction_handler_android.h" #include "chrome/browser/android/autofill_assistant/interaction_handler_android.h"
#include "chrome/browser/android/autofill_assistant/ui_controller_android_utils.h" #include "chrome/browser/android/autofill_assistant/ui_controller_android_utils.h"
#include "components/autofill_assistant/browser/event_handler.h" #include "components/autofill_assistant/browser/event_handler.h"
...@@ -210,6 +211,10 @@ base::android::ScopedJavaGlobalRef<jobject> CreateJavaView( ...@@ -210,6 +211,10 @@ base::android::ScopedJavaGlobalRef<jobject> CreateJavaView(
break; break;
} }
case ViewProto::kTextInputView: case ViewProto::kTextInputView:
if (proto.text_input_view().model_identifier().empty()) {
VLOG(1) << "Failed to create text input view: model_identifier not set";
return nullptr;
}
jview = Java_AssistantViewFactory_createTextInputView( jview = Java_AssistantViewFactory_createTextInputView(
env, jcontext, jdelegate, jidentifier, env, jcontext, jdelegate, jidentifier,
static_cast<int>(proto.text_input_view().type()), static_cast<int>(proto.text_input_view().type()),
...@@ -308,7 +313,7 @@ GenericUiControllerAndroid::CreateFromProto( ...@@ -308,7 +313,7 @@ GenericUiControllerAndroid::CreateFromProto(
jdelegate, proto.root_view(), views.get()) jdelegate, proto.root_view(), views.get())
: nullptr; : nullptr;
// Create interactions. // Create proto interactions (i.e., native -> java).
auto interaction_handler = std::make_unique<InteractionHandlerAndroid>( auto interaction_handler = std::make_unique<InteractionHandlerAndroid>(
event_handler, user_model, basic_interactions, views.get(), jcontext, event_handler, user_model, basic_interactions, views.get(), jcontext,
jdelegate); jdelegate);
...@@ -316,6 +321,12 @@ GenericUiControllerAndroid::CreateFromProto( ...@@ -316,6 +321,12 @@ GenericUiControllerAndroid::CreateFromProto(
return nullptr; return nullptr;
} }
// Create java listeners (i.e., java -> native).
if (!android_events::CreateJavaListenersFromProto(env, views.get(), jdelegate,
proto.interactions())) {
return nullptr;
}
// Set initial state. // Set initial state.
interaction_handler->StartListening(); interaction_handler->StartListening();
user_model->MergeWithProto(proto.model(), user_model->MergeWithProto(proto.model(),
......
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
namespace autofill_assistant { namespace autofill_assistant {
namespace android_events { namespace android_events {
namespace {
void SetOnClickListener(JNIEnv* env, void SetOnClickListener(JNIEnv* env,
base::android::ScopedJavaGlobalRef<jobject> jview, base::android::ScopedJavaGlobalRef<jobject> jview,
base::android::ScopedJavaGlobalRef<jobject> jdelegate, base::android::ScopedJavaGlobalRef<jobject> jdelegate,
...@@ -19,5 +21,42 @@ void SetOnClickListener(JNIEnv* env, ...@@ -19,5 +21,42 @@ void SetOnClickListener(JNIEnv* env,
jdelegate); jdelegate);
} }
} // namespace
bool CreateJavaListenersFromProto(
JNIEnv* env,
std::map<std::string, base::android::ScopedJavaGlobalRef<jobject>>* views,
base::android::ScopedJavaGlobalRef<jobject> jdelegate,
const InteractionsProto& proto) {
for (const auto& interaction_proto : proto.interactions()) {
const auto& event_proto = interaction_proto.trigger_event();
switch (event_proto.kind_case()) {
case EventProto::kOnViewClicked: {
auto jview =
views->find(event_proto.on_view_clicked().view_identifier());
if (jview == views->end()) {
VLOG(1) << "Invalid click event, no view with id='"
<< event_proto.on_view_clicked().view_identifier()
<< "' found";
return false;
}
SetOnClickListener(env, jview->second, jdelegate,
event_proto.on_view_clicked());
break;
}
case EventProto::kOnValueChanged:
case EventProto::kOnUserActionCalled:
case EventProto::kOnTextLinkClicked:
// Skip events not related to java views.
break;
case EventProto::KIND_NOT_SET:
VLOG(1)
<< "Error creating java listener for trigger event: kind not set";
return false;
}
}
return true;
}
} // namespace android_events } // namespace android_events
} // namespace autofill_assistant } // namespace autofill_assistant
...@@ -14,11 +14,14 @@ ...@@ -14,11 +14,14 @@
namespace autofill_assistant { namespace autofill_assistant {
namespace android_events { namespace android_events {
// Sets a click listener for |jview|. // Creates java listeners for all view events in |proto| such that |jdelegate|
void SetOnClickListener(JNIEnv* env, // is notified when appropriate (e.g., OnClickListeners). Returns true on
base::android::ScopedJavaGlobalRef<jobject> jview, // success, false on failure.
base::android::ScopedJavaGlobalRef<jobject> jdelegate, bool CreateJavaListenersFromProto(
const OnViewClickedEventProto& proto); JNIEnv* env,
std::map<std::string, base::android::ScopedJavaGlobalRef<jobject>>* views,
base::android::ScopedJavaGlobalRef<jobject> jdelegate,
const InteractionsProto& proto);
} // namespace android_events } // namespace android_events
} // namespace autofill_assistant } // namespace autofill_assistant
......
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
#include "base/optional.h" #include "base/optional.h"
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
#include "chrome/browser/android/autofill_assistant/generic_ui_controller_android.h" #include "chrome/browser/android/autofill_assistant/generic_ui_controller_android.h"
#include "chrome/browser/android/autofill_assistant/generic_ui_events_android.h"
#include "chrome/browser/android/autofill_assistant/generic_ui_interactions_android.h" #include "chrome/browser/android/autofill_assistant/generic_ui_interactions_android.h"
#include "components/autofill_assistant/browser/basic_interactions.h" #include "components/autofill_assistant/browser/basic_interactions.h"
#include "components/autofill_assistant/browser/interactions.pb.h" #include "components/autofill_assistant/browser/interactions.pb.h"
...@@ -42,21 +41,27 @@ base::Optional<EventHandler::EventKey> CreateEventKeyFromProto( ...@@ -42,21 +41,27 @@ base::Optional<EventHandler::EventKey> CreateEventKeyFromProto(
base::android::ScopedJavaGlobalRef<jobject> jdelegate) { base::android::ScopedJavaGlobalRef<jobject> jdelegate) {
switch (proto.kind_case()) { switch (proto.kind_case()) {
case EventProto::kOnValueChanged: case EventProto::kOnValueChanged:
if (proto.on_value_changed().model_identifier().empty()) {
VLOG(1) << "Invalid OnValueChangedEventProto: no model_identifier "
"specified";
return base::nullopt;
}
return base::Optional<EventHandler::EventKey>( return base::Optional<EventHandler::EventKey>(
{proto.kind_case(), proto.on_value_changed().model_identifier()}); {proto.kind_case(), proto.on_value_changed().model_identifier()});
case EventProto::kOnViewClicked: { case EventProto::kOnViewClicked:
auto jview = views->find(proto.on_view_clicked().view_identifier()); if (proto.on_view_clicked().view_identifier().empty()) {
if (jview == views->end()) { VLOG(1) << "Invalid OnViewClickedEventProto: no view_identifier "
VLOG(1) << "Invalid OnViewClickedEventProto: no view with id='" "specified";
<< proto.on_view_clicked().view_identifier() << "' found";
return base::nullopt; return base::nullopt;
} }
android_events::SetOnClickListener(env, jview->second, jdelegate,
proto.on_view_clicked());
return base::Optional<EventHandler::EventKey>( return base::Optional<EventHandler::EventKey>(
{proto.kind_case(), proto.on_view_clicked().view_identifier()}); {proto.kind_case(), proto.on_view_clicked().view_identifier()});
}
case EventProto::kOnUserActionCalled: case EventProto::kOnUserActionCalled:
if (proto.on_user_action_called().user_action_identifier().empty()) {
VLOG(1) << "Invalid OnUserActionCalled: no user_action_identifier "
"specified";
return base::nullopt;
}
return base::Optional<EventHandler::EventKey>( return base::Optional<EventHandler::EventKey>(
{proto.kind_case(), {proto.kind_case(),
proto.on_user_action_called().user_action_identifier()}); proto.on_user_action_called().user_action_identifier()});
...@@ -85,8 +90,8 @@ CreateInteractionCallbackFromProto( ...@@ -85,8 +90,8 @@ CreateInteractionCallbackFromProto(
switch (proto.kind_case()) { switch (proto.kind_case()) {
case CallbackProto::kSetValue: case CallbackProto::kSetValue:
if (proto.set_value().model_identifier().empty()) { if (proto.set_value().model_identifier().empty()) {
VLOG(1) VLOG(1) << "Error creating SetValue interaction: model_identifier "
<< "Error creating SetValue interaction: model_identifier not set"; "not set";
return base::nullopt; return base::nullopt;
} }
return base::Optional<InteractionHandlerAndroid::InteractionCallback>( return base::Optional<InteractionHandlerAndroid::InteractionCallback>(
......
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