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) {
state);
}
void UiControllerAndroid::SetTouchableArea(const std::vector<RectF>& areas) {
void UiControllerAndroid::OnTouchableAreaChanged(
const std::vector<RectF>& areas) {
JNIEnv* env = AttachCurrentThread();
std::vector<float> flattened;
for (const auto& rect : areas) {
......
......@@ -53,7 +53,7 @@ class UiControllerAndroid : public UiController {
void OnDetailsChanged(const Details* details) override;
void ShowProgressBar(int progress) override;
void HideProgressBar() override;
void SetTouchableArea(const std::vector<RectF>& areas) override;
void OnTouchableAreaChanged(const std::vector<RectF>& areas) override;
// Called by AssistantOverlayDelegate:
void OnUnexpectedTaps();
......
......@@ -478,6 +478,11 @@ Metrics::DropOutReason Controller::GetDropOutReason() const {
return stop_reason_;
}
void Controller::GetTouchableArea(std::vector<RectF>* area) const {
if (touchable_element_area_)
touchable_element_area_->GetArea(area);
}
void Controller::OnNoRunnableScriptsAnymore() {
if (script_tracker()->running())
return;
......@@ -624,7 +629,7 @@ ElementArea* Controller::touchable_element_area() {
if (!touchable_element_area_) {
touchable_element_area_ = std::make_unique<ElementArea>(this);
touchable_element_area_->SetOnUpdate(base::BindRepeating(
&UiController::SetTouchableArea,
&UiController::OnTouchableAreaChanged,
// Unretained is safe, since touchable_element_area_ is guaranteed to be
// deleted before the UI controller.
base::Unretained(GetUiController())));
......
......@@ -133,6 +133,7 @@ class Controller : public ScriptExecutorDelegate,
const Details* GetDetails() const override;
std::string GetDebugContext() override;
Metrics::DropOutReason GetDropOutReason() const override;
void GetTouchableArea(std::vector<RectF>* area) const override;
// Overrides ScriptTracker::Listener:
void OnNoRunnableScriptsAnymore() override;
......
......@@ -92,6 +92,15 @@ bool ElementArea::IsEmpty() const {
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(const ElementPosition& orig) =
default;
......@@ -181,14 +190,9 @@ void ElementArea::ReportUpdate() {
}
}
std::vector<RectF> areas;
for (auto& rectangle : rectangles_) {
RectF rect;
if (rectangle.FillRect(&rect)) {
areas.emplace_back(rect);
}
}
on_update_.Run(areas);
std::vector<RectF> area;
GetArea(&area);
on_update_.Run(area);
}
} // namespace autofill_assistant
......@@ -60,6 +60,11 @@ class ElementArea {
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:
// 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
......
......@@ -89,7 +89,7 @@ class ElementAreaTest : public testing::Test, public ScriptExecutorDelegate {
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
// creation run in that environment.
......@@ -98,18 +98,26 @@ class ElementAreaTest : public testing::Test, public ScriptExecutorDelegate {
MockWebController mock_web_controller_;
std::map<std::string, std::string> parameters_;
ElementArea element_area_;
std::vector<RectF> highlighted_area_;
std::vector<RectF> reported_area_;
};
TEST_F(ElementAreaTest, Empty) {
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) {
SetElement("#not_found");
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) {
......@@ -119,7 +127,20 @@ TEST_F(ElementAreaTest, OneRectangle) {
SetElement("#found");
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)));
}
......@@ -137,9 +158,10 @@ TEST_F(ElementAreaTest, TwoRectangles) {
element_area_.SetFromProto(area_proto);
EXPECT_FALSE(element_area_.IsEmpty());
EXPECT_THAT(highlighted_area_,
ElementsAre(MatchingRectF(0.0f, 0.0f, 0.25f, 0.25f),
MatchingRectF(0.25f, 0.25f, 1.0f, 1.0f)));
std::vector<RectF> rectangles;
element_area_.GetArea(&rectangles);
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) {
......@@ -157,8 +179,9 @@ TEST_F(ElementAreaTest, OneRectangleTwoElements) {
element_area_.SetFromProto(area_proto);
EXPECT_FALSE(element_area_.IsEmpty());
EXPECT_THAT(highlighted_area_,
ElementsAre(MatchingRectF(0.1f, 0.2f, 0.6f, 0.5f)));
std::vector<RectF> rectangles;
element_area_.GetArea(&rectangles);
EXPECT_THAT(rectangles, ElementsAre(MatchingRectF(0.1f, 0.2f, 0.6f, 0.5f)));
}
TEST_F(ElementAreaTest, DoNotReportIncompleteRectangles) {
......@@ -180,7 +203,11 @@ TEST_F(ElementAreaTest, DoNotReportIncompleteRectangles) {
EXPECT_TRUE(element_area_.HasElements());
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) {
......@@ -205,11 +232,12 @@ TEST_F(ElementAreaTest, OneRectangleFourElements) {
rectangle_proto->add_elements()->add_selectors("#element4");
element_area_.SetFromProto(area_proto);
EXPECT_THAT(highlighted_area_,
ElementsAre(MatchingRectF(0.0f, 0.0f, 1.0f, 1.0f)));
std::vector<RectF> rectangles;
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_,
OnGetElementPosition(Eq(Selector({"#element1"})), _))
.WillOnce(RunOnceCallback<1>(true, RectF(0.1f, 0.1f, 0.2f, 0.2f)));
......@@ -223,7 +251,11 @@ TEST_F(ElementAreaTest, OneRectangleMissingElements) {
rectangle_proto->add_elements()->add_selectors("#element2");
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)));
}
......@@ -242,8 +274,9 @@ TEST_F(ElementAreaTest, FullWidthRectangle) {
rectangle_proto->set_full_width(true);
element_area_.SetFromProto(area_proto);
EXPECT_THAT(highlighted_area_,
ElementsAre(MatchingRectF(0.0f, 0.3f, 1.0f, 0.8f)));
std::vector<RectF> rectangles;
element_area_.GetArea(&rectangles);
EXPECT_THAT(rectangles, ElementsAre(MatchingRectF(0.0f, 0.3f, 1.0f, 0.8f)));
}
TEST_F(ElementAreaTest, ElementMovesAfterUpdate) {
......@@ -255,12 +288,18 @@ TEST_F(ElementAreaTest, ElementMovesAfterUpdate) {
SetElement("#element");
EXPECT_THAT(highlighted_area_,
EXPECT_THAT(reported_area_,
ElementsAre(MatchingRectF(0.0f, 0.25f, 1.0f, 0.5f)));
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)));
}
......@@ -273,13 +312,19 @@ TEST_F(ElementAreaTest, ElementMovesWithTime) {
SetElement("#element");
EXPECT_THAT(highlighted_area_,
EXPECT_THAT(reported_area_,
ElementsAre(MatchingRectF(0.0f, 0.25f, 1.0f, 0.5f)));
scoped_task_environment_.FastForwardBy(
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)));
}
} // namespace
......
......@@ -37,7 +37,7 @@ class MockUiController : public UiController {
MOCK_METHOD1(OnDetailsChanged, void(const Details* details));
MOCK_METHOD1(ShowProgressBar, void(int progress));
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_METHOD0(ExpandBottomSheet, void());
MOCK_CONST_METHOD0(GetDropOutReason, Metrics::DropOutReason());
......
......@@ -68,7 +68,7 @@ class UiController {
//
// |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.
virtual void SetTouchableArea(const std::vector<RectF>& areas) = 0;
virtual void OnTouchableAreaChanged(const std::vector<RectF>& areas) = 0;
protected:
UiController() = default;
......
......@@ -6,8 +6,10 @@
#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_UI_DELEGATE_H_
#include <string>
#include <vector>
#include "components/autofill_assistant/browser/metrics.h"
#include "components/autofill_assistant/browser/rectf.h"
#include "components/autofill_assistant/browser/state.h"
namespace autofill_assistant {
......@@ -42,6 +44,15 @@ class UiDelegate {
// Returns the drop out reason for the last state transition to STOPPED.
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:
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