Commit 0aa2d994 authored by Stephane Zermatten's avatar Stephane Zermatten Committed by Commit Bot

[Autofill Assistant] Add GetTouchableArea to UiDelegate.

This change makes the current touchable area available to the UI code,
through UIDelegate. It also renames UIController::UpdateTouchableArea to
UIController::OnTouchableAreaChanged to be consistent with the other
methods on UIController.

The goal of this change is to make it possible to attach the UI to a new
controller.

This is a pure refactoring. It should not have any visible effect.

Bug: 806868
Change-Id: Ifa6dca04d45071f73ce431bcadc36e58c37fe582
Reviewed-on: https://chromium-review.googlesource.com/c/1447872Reviewed-by: default avatarStephane Zermatten <szermatt@chromium.org>
Reviewed-by: default avatarMathias Carlen <mcarlen@chromium.org>
Commit-Queue: Stephane Zermatten <szermatt@chromium.org>
Cr-Commit-Position: refs/heads/master@{#629095}
parent ac9e64d2
...@@ -279,7 +279,8 @@ void UiControllerAndroid::SetOverlayState(OverlayState state) { ...@@ -279,7 +279,8 @@ void UiControllerAndroid::SetOverlayState(OverlayState state) {
state); state);
} }
void UiControllerAndroid::SetTouchableArea(const std::vector<RectF>& areas) { void UiControllerAndroid::OnTouchableAreaChanged(
const std::vector<RectF>& areas) {
JNIEnv* env = AttachCurrentThread(); JNIEnv* env = AttachCurrentThread();
std::vector<float> flattened; std::vector<float> flattened;
for (const auto& rect : areas) { for (const auto& rect : areas) {
......
...@@ -53,7 +53,7 @@ class UiControllerAndroid : public UiController { ...@@ -53,7 +53,7 @@ class UiControllerAndroid : public UiController {
void OnDetailsChanged(const Details* details) override; void OnDetailsChanged(const Details* details) override;
void ShowProgressBar(int progress) override; void ShowProgressBar(int progress) override;
void HideProgressBar() override; void HideProgressBar() override;
void SetTouchableArea(const std::vector<RectF>& areas) override; void OnTouchableAreaChanged(const std::vector<RectF>& areas) override;
// Called by AssistantOverlayDelegate: // Called by AssistantOverlayDelegate:
void OnUnexpectedTaps(); void OnUnexpectedTaps();
......
...@@ -478,6 +478,11 @@ Metrics::DropOutReason Controller::GetDropOutReason() const { ...@@ -478,6 +478,11 @@ Metrics::DropOutReason Controller::GetDropOutReason() const {
return stop_reason_; return stop_reason_;
} }
void Controller::GetTouchableArea(std::vector<RectF>* area) const {
if (touchable_element_area_)
touchable_element_area_->GetArea(area);
}
void Controller::OnNoRunnableScriptsAnymore() { void Controller::OnNoRunnableScriptsAnymore() {
if (script_tracker()->running()) if (script_tracker()->running())
return; return;
...@@ -624,7 +629,7 @@ ElementArea* Controller::touchable_element_area() { ...@@ -624,7 +629,7 @@ ElementArea* Controller::touchable_element_area() {
if (!touchable_element_area_) { if (!touchable_element_area_) {
touchable_element_area_ = std::make_unique<ElementArea>(this); touchable_element_area_ = std::make_unique<ElementArea>(this);
touchable_element_area_->SetOnUpdate(base::BindRepeating( touchable_element_area_->SetOnUpdate(base::BindRepeating(
&UiController::SetTouchableArea, &UiController::OnTouchableAreaChanged,
// Unretained is safe, since touchable_element_area_ is guaranteed to be // Unretained is safe, since touchable_element_area_ is guaranteed to be
// deleted before the UI controller. // deleted before the UI controller.
base::Unretained(GetUiController()))); base::Unretained(GetUiController())));
......
...@@ -133,6 +133,7 @@ class Controller : public ScriptExecutorDelegate, ...@@ -133,6 +133,7 @@ class Controller : public ScriptExecutorDelegate,
const Details* GetDetails() const override; const Details* GetDetails() const override;
std::string GetDebugContext() override; std::string GetDebugContext() override;
Metrics::DropOutReason GetDropOutReason() const override; Metrics::DropOutReason GetDropOutReason() const override;
void GetTouchableArea(std::vector<RectF>* area) const override;
// Overrides ScriptTracker::Listener: // Overrides ScriptTracker::Listener:
void OnNoRunnableScriptsAnymore() override; void OnNoRunnableScriptsAnymore() override;
......
...@@ -92,6 +92,15 @@ bool ElementArea::IsEmpty() const { ...@@ -92,6 +92,15 @@ bool ElementArea::IsEmpty() const {
return true; return true;
} }
void ElementArea::GetArea(std::vector<RectF>* area) {
for (auto& rectangle : rectangles_) {
RectF rect;
if (rectangle.FillRect(&rect)) {
area->emplace_back(rect);
}
}
}
ElementArea::ElementPosition::ElementPosition() = default; ElementArea::ElementPosition::ElementPosition() = default;
ElementArea::ElementPosition::ElementPosition(const ElementPosition& orig) = ElementArea::ElementPosition::ElementPosition(const ElementPosition& orig) =
default; default;
...@@ -181,14 +190,9 @@ void ElementArea::ReportUpdate() { ...@@ -181,14 +190,9 @@ void ElementArea::ReportUpdate() {
} }
} }
std::vector<RectF> areas; std::vector<RectF> area;
for (auto& rectangle : rectangles_) { GetArea(&area);
RectF rect; on_update_.Run(area);
if (rectangle.FillRect(&rect)) {
areas.emplace_back(rect);
}
}
on_update_.Run(areas);
} }
} // namespace autofill_assistant } // namespace autofill_assistant
...@@ -60,6 +60,11 @@ class ElementArea { ...@@ -60,6 +60,11 @@ class ElementArea {
on_update_ = cb; on_update_ = cb;
} }
// Adds the current touchable area to the vector, if any are available.
//
// Note that the vector is not cleared before rectangles are added.
void GetArea(std::vector<RectF>* area);
private: private:
// A rectangle that corresponds to the area of the visual viewport covered by // A rectangle that corresponds to the area of the visual viewport covered by
// an element. Coordinates are values between 0 and 1, relative to the size of // an element. Coordinates are values between 0 and 1, relative to the size of
......
...@@ -89,7 +89,7 @@ class ElementAreaTest : public testing::Test, public ScriptExecutorDelegate { ...@@ -89,7 +89,7 @@ class ElementAreaTest : public testing::Test, public ScriptExecutorDelegate {
element_area_.SetFromProto(area); element_area_.SetFromProto(area);
} }
void OnUpdate(const std::vector<RectF>& area) { highlighted_area_ = area; } void OnUpdate(const std::vector<RectF>& area) { reported_area_ = area; }
// scoped_task_environment_ must be first to guarantee other field // scoped_task_environment_ must be first to guarantee other field
// creation run in that environment. // creation run in that environment.
...@@ -98,18 +98,26 @@ class ElementAreaTest : public testing::Test, public ScriptExecutorDelegate { ...@@ -98,18 +98,26 @@ class ElementAreaTest : public testing::Test, public ScriptExecutorDelegate {
MockWebController mock_web_controller_; MockWebController mock_web_controller_;
std::map<std::string, std::string> parameters_; std::map<std::string, std::string> parameters_;
ElementArea element_area_; ElementArea element_area_;
std::vector<RectF> highlighted_area_; std::vector<RectF> reported_area_;
}; };
TEST_F(ElementAreaTest, Empty) { TEST_F(ElementAreaTest, Empty) {
EXPECT_TRUE(element_area_.IsEmpty()); EXPECT_TRUE(element_area_.IsEmpty());
EXPECT_THAT(highlighted_area_, IsEmpty()); EXPECT_THAT(reported_area_, IsEmpty());
std::vector<RectF> rectangles;
element_area_.GetArea(&rectangles);
EXPECT_THAT(rectangles, IsEmpty());
} }
TEST_F(ElementAreaTest, ElementNotFound) { TEST_F(ElementAreaTest, ElementNotFound) {
SetElement("#not_found"); SetElement("#not_found");
EXPECT_TRUE(element_area_.IsEmpty()); EXPECT_TRUE(element_area_.IsEmpty());
EXPECT_THAT(highlighted_area_, IsEmpty()); EXPECT_THAT(reported_area_, IsEmpty());
std::vector<RectF> rectangles;
element_area_.GetArea(&rectangles);
EXPECT_THAT(rectangles, IsEmpty());
} }
TEST_F(ElementAreaTest, OneRectangle) { TEST_F(ElementAreaTest, OneRectangle) {
...@@ -119,7 +127,20 @@ TEST_F(ElementAreaTest, OneRectangle) { ...@@ -119,7 +127,20 @@ TEST_F(ElementAreaTest, OneRectangle) {
SetElement("#found"); SetElement("#found");
EXPECT_FALSE(element_area_.IsEmpty()); EXPECT_FALSE(element_area_.IsEmpty());
EXPECT_THAT(highlighted_area_, std::vector<RectF> rectangles;
element_area_.GetArea(&rectangles);
EXPECT_THAT(rectangles,
ElementsAre(MatchingRectF(0.25f, 0.25f, 0.75f, 0.75f)));
}
TEST_F(ElementAreaTest, CallOnUpdate) {
EXPECT_CALL(mock_web_controller_,
OnGetElementPosition(Eq(Selector({"#found"})), _))
.WillOnce(RunOnceCallback<1>(true, RectF(0.25f, 0.25f, 0.75f, 0.75f)));
SetElement("#found");
EXPECT_FALSE(element_area_.IsEmpty());
EXPECT_THAT(reported_area_,
ElementsAre(MatchingRectF(0.25f, 0.25f, 0.75f, 0.75f))); ElementsAre(MatchingRectF(0.25f, 0.25f, 0.75f, 0.75f)));
} }
...@@ -137,9 +158,10 @@ TEST_F(ElementAreaTest, TwoRectangles) { ...@@ -137,9 +158,10 @@ TEST_F(ElementAreaTest, TwoRectangles) {
element_area_.SetFromProto(area_proto); element_area_.SetFromProto(area_proto);
EXPECT_FALSE(element_area_.IsEmpty()); EXPECT_FALSE(element_area_.IsEmpty());
EXPECT_THAT(highlighted_area_, std::vector<RectF> rectangles;
ElementsAre(MatchingRectF(0.0f, 0.0f, 0.25f, 0.25f), element_area_.GetArea(&rectangles);
MatchingRectF(0.25f, 0.25f, 1.0f, 1.0f))); EXPECT_THAT(rectangles, ElementsAre(MatchingRectF(0.0f, 0.0f, 0.25f, 0.25f),
MatchingRectF(0.25f, 0.25f, 1.0f, 1.0f)));
} }
TEST_F(ElementAreaTest, OneRectangleTwoElements) { TEST_F(ElementAreaTest, OneRectangleTwoElements) {
...@@ -157,8 +179,9 @@ TEST_F(ElementAreaTest, OneRectangleTwoElements) { ...@@ -157,8 +179,9 @@ TEST_F(ElementAreaTest, OneRectangleTwoElements) {
element_area_.SetFromProto(area_proto); element_area_.SetFromProto(area_proto);
EXPECT_FALSE(element_area_.IsEmpty()); EXPECT_FALSE(element_area_.IsEmpty());
EXPECT_THAT(highlighted_area_, std::vector<RectF> rectangles;
ElementsAre(MatchingRectF(0.1f, 0.2f, 0.6f, 0.5f))); element_area_.GetArea(&rectangles);
EXPECT_THAT(rectangles, ElementsAre(MatchingRectF(0.1f, 0.2f, 0.6f, 0.5f)));
} }
TEST_F(ElementAreaTest, DoNotReportIncompleteRectangles) { TEST_F(ElementAreaTest, DoNotReportIncompleteRectangles) {
...@@ -180,7 +203,11 @@ TEST_F(ElementAreaTest, DoNotReportIncompleteRectangles) { ...@@ -180,7 +203,11 @@ TEST_F(ElementAreaTest, DoNotReportIncompleteRectangles) {
EXPECT_TRUE(element_area_.HasElements()); EXPECT_TRUE(element_area_.HasElements());
EXPECT_FALSE(element_area_.IsEmpty()); EXPECT_FALSE(element_area_.IsEmpty());
EXPECT_THAT(highlighted_area_, IsEmpty()); EXPECT_THAT(reported_area_, IsEmpty());
std::vector<RectF> rectangles;
element_area_.GetArea(&rectangles);
EXPECT_THAT(rectangles, ElementsAre(MatchingRectF(0.1f, 0.3f, 0.2f, 0.4f)));
} }
TEST_F(ElementAreaTest, OneRectangleFourElements) { TEST_F(ElementAreaTest, OneRectangleFourElements) {
...@@ -205,11 +232,12 @@ TEST_F(ElementAreaTest, OneRectangleFourElements) { ...@@ -205,11 +232,12 @@ TEST_F(ElementAreaTest, OneRectangleFourElements) {
rectangle_proto->add_elements()->add_selectors("#element4"); rectangle_proto->add_elements()->add_selectors("#element4");
element_area_.SetFromProto(area_proto); element_area_.SetFromProto(area_proto);
EXPECT_THAT(highlighted_area_, std::vector<RectF> rectangles;
ElementsAre(MatchingRectF(0.0f, 0.0f, 1.0f, 1.0f))); element_area_.GetArea(&rectangles);
EXPECT_THAT(rectangles, ElementsAre(MatchingRectF(0.0f, 0.0f, 1.0f, 1.0f)));
} }
TEST_F(ElementAreaTest, OneRectangleMissingElements) { TEST_F(ElementAreaTest, OneRectangleMissingElementsReported) {
EXPECT_CALL(mock_web_controller_, EXPECT_CALL(mock_web_controller_,
OnGetElementPosition(Eq(Selector({"#element1"})), _)) OnGetElementPosition(Eq(Selector({"#element1"})), _))
.WillOnce(RunOnceCallback<1>(true, RectF(0.1f, 0.1f, 0.2f, 0.2f))); .WillOnce(RunOnceCallback<1>(true, RectF(0.1f, 0.1f, 0.2f, 0.2f)));
...@@ -223,7 +251,11 @@ TEST_F(ElementAreaTest, OneRectangleMissingElements) { ...@@ -223,7 +251,11 @@ TEST_F(ElementAreaTest, OneRectangleMissingElements) {
rectangle_proto->add_elements()->add_selectors("#element2"); rectangle_proto->add_elements()->add_selectors("#element2");
element_area_.SetFromProto(area_proto); element_area_.SetFromProto(area_proto);
EXPECT_THAT(highlighted_area_, std::vector<RectF> rectangles;
element_area_.GetArea(&rectangles);
EXPECT_THAT(rectangles, ElementsAre(MatchingRectF(0.1f, 0.1f, 0.2f, 0.2f)));
EXPECT_THAT(reported_area_,
ElementsAre(MatchingRectF(0.1f, 0.1f, 0.2f, 0.2f))); ElementsAre(MatchingRectF(0.1f, 0.1f, 0.2f, 0.2f)));
} }
...@@ -242,8 +274,9 @@ TEST_F(ElementAreaTest, FullWidthRectangle) { ...@@ -242,8 +274,9 @@ TEST_F(ElementAreaTest, FullWidthRectangle) {
rectangle_proto->set_full_width(true); rectangle_proto->set_full_width(true);
element_area_.SetFromProto(area_proto); element_area_.SetFromProto(area_proto);
EXPECT_THAT(highlighted_area_, std::vector<RectF> rectangles;
ElementsAre(MatchingRectF(0.0f, 0.3f, 1.0f, 0.8f))); element_area_.GetArea(&rectangles);
EXPECT_THAT(rectangles, ElementsAre(MatchingRectF(0.0f, 0.3f, 1.0f, 0.8f)));
} }
TEST_F(ElementAreaTest, ElementMovesAfterUpdate) { TEST_F(ElementAreaTest, ElementMovesAfterUpdate) {
...@@ -255,12 +288,18 @@ TEST_F(ElementAreaTest, ElementMovesAfterUpdate) { ...@@ -255,12 +288,18 @@ TEST_F(ElementAreaTest, ElementMovesAfterUpdate) {
SetElement("#element"); SetElement("#element");
EXPECT_THAT(highlighted_area_, EXPECT_THAT(reported_area_,
ElementsAre(MatchingRectF(0.0f, 0.25f, 1.0f, 0.5f))); ElementsAre(MatchingRectF(0.0f, 0.25f, 1.0f, 0.5f)));
element_area_.UpdatePositions(); element_area_.UpdatePositions();
EXPECT_THAT(highlighted_area_, // Updated area is available
std::vector<RectF> rectangles;
element_area_.GetArea(&rectangles);
EXPECT_THAT(rectangles, ElementsAre(MatchingRectF(0.0f, 0.5f, 1.0f, 0.75f)));
// Updated area is reported
EXPECT_THAT(reported_area_,
ElementsAre(MatchingRectF(0.0f, 0.5f, 1.0f, 0.75f))); ElementsAre(MatchingRectF(0.0f, 0.5f, 1.0f, 0.75f)));
} }
...@@ -273,13 +312,19 @@ TEST_F(ElementAreaTest, ElementMovesWithTime) { ...@@ -273,13 +312,19 @@ TEST_F(ElementAreaTest, ElementMovesWithTime) {
SetElement("#element"); SetElement("#element");
EXPECT_THAT(highlighted_area_, EXPECT_THAT(reported_area_,
ElementsAre(MatchingRectF(0.0f, 0.25f, 1.0f, 0.5f))); ElementsAre(MatchingRectF(0.0f, 0.25f, 1.0f, 0.5f)));
scoped_task_environment_.FastForwardBy( scoped_task_environment_.FastForwardBy(
base::TimeDelta::FromMilliseconds(100)); base::TimeDelta::FromMilliseconds(100));
EXPECT_THAT(highlighted_area_, // Updated area is available
std::vector<RectF> rectangles;
element_area_.GetArea(&rectangles);
EXPECT_THAT(rectangles, ElementsAre(MatchingRectF(0.0f, 0.5f, 1.0f, 0.75f)));
// Updated area is reported
EXPECT_THAT(reported_area_,
ElementsAre(MatchingRectF(0.0f, 0.5f, 1.0f, 0.75f))); ElementsAre(MatchingRectF(0.0f, 0.5f, 1.0f, 0.75f)));
} }
} // namespace } // namespace
......
...@@ -37,7 +37,7 @@ class MockUiController : public UiController { ...@@ -37,7 +37,7 @@ class MockUiController : public UiController {
MOCK_METHOD1(OnDetailsChanged, void(const Details* details)); MOCK_METHOD1(OnDetailsChanged, void(const Details* details));
MOCK_METHOD1(ShowProgressBar, void(int progress)); MOCK_METHOD1(ShowProgressBar, void(int progress));
MOCK_METHOD0(HideProgressBar, void()); MOCK_METHOD0(HideProgressBar, void());
MOCK_METHOD1(SetTouchableArea, void(const std::vector<RectF>& areas)); MOCK_METHOD1(OnTouchableAreaChanged, void(const std::vector<RectF>& areas));
MOCK_CONST_METHOD0(Terminate, bool()); MOCK_CONST_METHOD0(Terminate, bool());
MOCK_METHOD0(ExpandBottomSheet, void()); MOCK_METHOD0(ExpandBottomSheet, void());
MOCK_CONST_METHOD0(GetDropOutReason, Metrics::DropOutReason()); MOCK_CONST_METHOD0(GetDropOutReason, Metrics::DropOutReason());
......
...@@ -68,7 +68,7 @@ class UiController { ...@@ -68,7 +68,7 @@ class UiController {
// //
// |areas| is expressed in coordinates relative to the width or height of the // |areas| is expressed in coordinates relative to the width or height of the
// visible viewport, as a number between 0 and 1. It can be empty. // visible viewport, as a number between 0 and 1. It can be empty.
virtual void SetTouchableArea(const std::vector<RectF>& areas) = 0; virtual void OnTouchableAreaChanged(const std::vector<RectF>& areas) = 0;
protected: protected:
UiController() = default; UiController() = default;
......
...@@ -6,8 +6,10 @@ ...@@ -6,8 +6,10 @@
#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_UI_DELEGATE_H_ #define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_UI_DELEGATE_H_
#include <string> #include <string>
#include <vector>
#include "components/autofill_assistant/browser/metrics.h" #include "components/autofill_assistant/browser/metrics.h"
#include "components/autofill_assistant/browser/rectf.h"
#include "components/autofill_assistant/browser/state.h" #include "components/autofill_assistant/browser/state.h"
namespace autofill_assistant { namespace autofill_assistant {
...@@ -42,6 +44,15 @@ class UiDelegate { ...@@ -42,6 +44,15 @@ class UiDelegate {
// Returns the drop out reason for the last state transition to STOPPED. // Returns the drop out reason for the last state transition to STOPPED.
virtual Metrics::DropOutReason GetDropOutReason() const = 0; virtual Metrics::DropOutReason GetDropOutReason() const = 0;
// Adds the rectangles that correspond to the current touchable area to the
// given vector.
//
// |areas| is expressed in coordinates relative to the width or height of the
// visible viewport, as a number between 0 and 1. It can be empty.
//
// Note that the vector is not cleared before rectangles are added.
virtual void GetTouchableArea(std::vector<RectF>* area) const = 0;
protected: protected:
UiDelegate() = default; UiDelegate() = default;
}; };
......
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