Skip to content

Commit

Permalink
[Android] Hide active text handle.
Browse files Browse the repository at this point in the history
We want to hide the active text handle when the HandleObserver is
activated.

We only want to make the handle invisible but still keep it functioning.
So in this CL we are setting its alpha to control the visibility.

Bug: 798017, 814868
Change-Id: I1d3018ab6a40307eae67c5f0146e84c0c297bcf3
Reviewed-on: https://chromium-review.googlesource.com/1011552
Reviewed-by: Richard Coles <torne@chromium.org>
Reviewed-by: Mohsen Izadi <mohsen@chromium.org>
Reviewed-by: Pedro Amaral <amaralp@chromium.org>
Reviewed-by: Bo <boliu@chromium.org>
Commit-Queue: Shimi Zhang <ctzsm@chromium.org>
Cr-Commit-Position: refs/heads/master@{#552196}
  • Loading branch information
Shimi Zhang authored and Commit Bot committed Apr 19, 2018
1 parent ba177d2 commit fa804f3
Show file tree
Hide file tree
Showing 11 changed files with 193 additions and 3 deletions.
5 changes: 3 additions & 2 deletions base/android/build_info.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const char* StrDupParam(const std::vector<std::string>& params, int index) {
return strdup(params[index].c_str());
}

int SdkIntParam(const std::vector<std::string>& params, int index) {
int GetIntParam(const std::vector<std::string>& params, int index) {
int ret = 0;
bool success = StringToInt(params[index], &ret);
DCHECK(success);
Expand Down Expand Up @@ -59,7 +59,7 @@ BuildInfo::BuildInfo(const std::vector<std::string>& params)
android_build_id_(StrDupParam(params, 2)),
manufacturer_(StrDupParam(params, 3)),
model_(StrDupParam(params, 4)),
sdk_int_(SdkIntParam(params, 5)),
sdk_int_(GetIntParam(params, 5)),
build_type_(StrDupParam(params, 6)),
board_(StrDupParam(params, 7)),
host_package_name_(StrDupParam(params, 8)),
Expand All @@ -76,6 +76,7 @@ BuildInfo::BuildInfo(const std::vector<std::string>& params)
custom_themes_(StrDupParam(params, 19)),
resources_version_(StrDupParam(params, 20)),
extracted_file_suffix_(params[21]),
is_at_least_p_(GetIntParam(params, 22)),
java_exception_info_(NULL) {}

// static
Expand Down
3 changes: 3 additions & 0 deletions base/android/build_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ class BASE_EXPORT BuildInfo {
return java_exception_info_;
}

bool is_at_least_p() const { return is_at_least_p_; }

void SetJavaExceptionInfo(const std::string& info);

void ClearJavaExceptionInfo();
Expand Down Expand Up @@ -163,6 +165,7 @@ class BASE_EXPORT BuildInfo {
const char* const resources_version_;
// Not needed by breakpad.
const std::string extracted_file_suffix_;
const int is_at_least_p_;
// This is set via set_java_exception_info, not at constructor time.
const char* java_exception_info_;

Expand Down
1 change: 1 addition & 0 deletions base/android/java/src/org/chromium/base/BuildInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ private static String[] getAll() {
buildInfo.androidBuildFingerprint, buildInfo.gmsVersionCode,
buildInfo.installerPackageName, buildInfo.abiString, BuildConfig.FIREBASE_APP_ID,
buildInfo.customThemes, buildInfo.resourcesVersion, buildInfo.extractedFileSuffix,
isAtLeastP() ? "1" : "0",
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "components/viz/service/surfaces/surface_hittest.h"
#include "content/browser/accessibility/browser_accessibility_manager_android.h"
#include "content/browser/accessibility/web_contents_accessibility_android.h"
#include "content/browser/android/content_feature_list.h"
#include "content/browser/android/gesture_listener_manager.h"
#include "content/browser/android/ime_adapter_android.h"
#include "content/browser/android/overscroll_controller_android.h"
Expand Down Expand Up @@ -114,6 +115,10 @@ std::unique_ptr<ui::TouchSelectionController> CreateSelectionController(
config.enable_longpress_drag_selection =
base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableLongpressDragSelection);
config.hide_active_handle =
base::FeatureList::IsEnabled(
content::android::kEnhancedSelectionInsertionHandle) &&
base::android::BuildInfo::GetInstance()->is_at_least_p();
return std::make_unique<ui::TouchSelectionController>(client, config);
}

Expand Down
4 changes: 4 additions & 0 deletions ui/touch_selection/touch_handle.cc
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,10 @@ void TouchHandle::UpdateHandleLayout() {
drawable_->SetOrigin(ComputeHandleOrigin());
}

void TouchHandle::SetTransparent() {
SetAlpha(0.f);
}

gfx::PointF TouchHandle::ComputeHandleOrigin() const {
gfx::PointF focus = mirror_vertical_ ? focus_top_ : focus_bottom_;
gfx::RectF drawable_bounds = drawable_->GetVisibleBounds();
Expand Down
4 changes: 4 additions & 0 deletions ui/touch_selection/touch_handle.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ class UI_TOUCH_SELECTION_EXPORT TouchHandle : public TouchSelectionDraggable {
// for the same frame update due to more than one parameter updates.
void UpdateHandleLayout();

// Set the handle to transparent. Handle will be set to opaque again in
// EndDrag() call.
void SetTransparent();

const gfx::PointF& focus_bottom() const { return focus_bottom_; }
TouchHandleOrientation orientation() const { return orientation_; }
float alpha() const { return alpha_; }
Expand Down
13 changes: 12 additions & 1 deletion ui/touch_selection/touch_selection_controller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ TouchSelectionController::Config::Config()
: max_tap_duration(base::TimeDelta::FromMilliseconds(300)),
tap_slop(8),
enable_adaptive_handle_orientation(false),
enable_longpress_drag_selection(false) {}
enable_longpress_drag_selection(false),
hide_active_handle(false) {}

TouchSelectionController::Config::~Config() {
}
Expand Down Expand Up @@ -341,6 +342,8 @@ void TouchSelectionController::OnDragBegin(
const gfx::PointF& drag_position) {
if (&draggable == insertion_handle_.get()) {
DCHECK_EQ(active_status_, INSERTION_ACTIVE);
if (config_.hide_active_handle)
insertion_handle_->SetTransparent();
client_->OnSelectionEvent(INSERTION_HANDLE_DRAG_STARTED);
anchor_drag_to_selection_start_ = true;
return;
Expand All @@ -359,6 +362,14 @@ void TouchSelectionController::OnDragBegin(
(drag_position - GetEndPosition()).LengthSquared();
}

if (config_.hide_active_handle) {
if (&draggable == start_selection_handle_.get()) {
start_selection_handle_->SetTransparent();
} else if (&draggable == end_selection_handle_.get()) {
end_selection_handle_->SetTransparent();
}
}

gfx::PointF base = GetStartPosition() + GetStartLineOffset();
gfx::PointF extent = GetEndPosition() + GetEndLineOffset();
if (anchor_drag_to_selection_start_)
Expand Down
3 changes: 3 additions & 0 deletions ui/touch_selection/touch_selection_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ class UI_TOUCH_SELECTION_EXPORT TouchSelectionController
// Controls whether drag selection after a longpress is enabled.
// Defaults to false.
bool enable_longpress_drag_selection;

// Should we hide the active handle.
bool hide_active_handle;
};

TouchSelectionController(TouchSelectionControllerClient* client,
Expand Down
7 changes: 7 additions & 0 deletions ui/touch_selection/touch_selection_controller_test_api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ float TouchSelectionControllerTestApi::GetEndAlpha() const {
return 0.f;
}

float TouchSelectionControllerTestApi::GetInsertionHandleAlpha() const {
if (controller_->active_status_ == TouchSelectionController::INSERTION_ACTIVE)
return controller_->insertion_handle_->alpha();

return 0.f;
}

TouchHandleOrientation
TouchSelectionControllerTestApi::GetStartHandleOrientation() const {
if (controller_->active_status_ != TouchSelectionController::SELECTION_ACTIVE)
Expand Down
1 change: 1 addition & 0 deletions ui/touch_selection/touch_selection_controller_test_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class TouchSelectionControllerTestApi {
bool GetEndVisible() const;
float GetStartAlpha() const;
float GetEndAlpha() const;
float GetInsertionHandleAlpha() const;
TouchHandleOrientation GetStartHandleOrientation() const;
TouchHandleOrientation GetEndHandleOrientation() const;

Expand Down
150 changes: 150 additions & 0 deletions ui/touch_selection/touch_selection_controller_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,12 @@ class TouchSelectionControllerTest : public testing::Test,
controller_.reset(new TouchSelectionController(this, config));
}

void SetHideActiveHandle(bool hide) {
TouchSelectionController::Config config = DefaultConfig();
config.hide_active_handle = hide;
controller_.reset(new TouchSelectionController(this, config));
}

void SetAnimationEnabled(bool enabled) { animation_enabled_ = enabled; }
void SetDraggingEnabled(bool enabled) { dragging_enabled_ = enabled; }

Expand Down Expand Up @@ -1456,4 +1462,148 @@ TEST_F(TouchSelectionControllerTest, SelectionUpdateDragPosition) {
EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STOPPED));
}

TEST_F(TouchSelectionControllerTest, NoHideActiveInsertionHandle) {
SetHideActiveHandle(false);
TouchSelectionControllerTestApi test_controller(&controller());

base::TimeTicks event_time = base::TimeTicks::Now();
float line_height = 10.f;
gfx::RectF insertion_rect(10, 0, 0, line_height);
bool visible = true;
OnTapEvent();

ChangeInsertion(insertion_rect, visible);
EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_SHOWN));

SetDraggingEnabled(true);
EXPECT_EQ(1.f, test_controller.GetInsertionHandleAlpha());
MockMotionEvent event(MockMotionEvent::Action::DOWN, event_time, 10, 5);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_EQ(1.f, test_controller.GetInsertionHandleAlpha());
}

TEST_F(TouchSelectionControllerTest, HideActiveInsertionHandle) {
SetHideActiveHandle(true);
TouchSelectionControllerTestApi test_controller(&controller());

base::TimeTicks event_time = base::TimeTicks::Now();
float line_height = 10.f;
gfx::RectF insertion_rect(10, 0, 0, line_height);
bool visible = true;
OnTapEvent();

ChangeInsertion(insertion_rect, visible);
EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_SHOWN));

SetDraggingEnabled(true);
EXPECT_EQ(1.f, test_controller.GetInsertionHandleAlpha());
MockMotionEvent event(MockMotionEvent::Action::DOWN, event_time, 10, 5);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_EQ(0.f, test_controller.GetInsertionHandleAlpha());

event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 10, 5);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_EQ(0.f, test_controller.GetInsertionHandleAlpha());

event_time += base::TimeDelta::FromMilliseconds(2 * kDefaultTapTimeoutMs);
// UP will reset the alpha to visible.
event = MockMotionEvent(MockMotionEvent::Action::UP, event_time, 0, 0);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_EQ(1.f, test_controller.GetInsertionHandleAlpha());
}

TEST_F(TouchSelectionControllerTest, NoHideActiveSelectionHandle) {
SetHideActiveHandle(false);
TouchSelectionControllerTestApi test_controller(&controller());

base::TimeTicks event_time = base::TimeTicks::Now();
float line_height = 10.f;
gfx::RectF start_rect(10, 0, 0, line_height);
gfx::RectF end_rect(50, 0, 0, line_height);
bool visible = true;
OnLongPressEvent();

ChangeSelection(start_rect, visible, end_rect, visible);

// Start handle.
SetDraggingEnabled(true);
EXPECT_EQ(1.f, test_controller.GetStartAlpha());
EXPECT_EQ(1.f, test_controller.GetEndAlpha());
MockMotionEvent event(MockMotionEvent::Action::DOWN, event_time, 10, 5);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_EQ(1.f, test_controller.GetStartAlpha());
EXPECT_EQ(1.f, test_controller.GetEndAlpha());

event = MockMotionEvent(MockMotionEvent::Action::UP, event_time, 10, 5);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_EQ(1.f, test_controller.GetStartAlpha());
EXPECT_EQ(1.f, test_controller.GetEndAlpha());

// End handle.
event = MockMotionEvent(MockMotionEvent::Action::DOWN, event_time, 50, 5);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_EQ(1.f, test_controller.GetStartAlpha());
EXPECT_EQ(1.f, test_controller.GetEndAlpha());

event_time += base::TimeDelta::FromMilliseconds(2 * kDefaultTapTimeoutMs);
event = MockMotionEvent(MockMotionEvent::Action::UP, event_time, 50, 5);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_EQ(1.f, test_controller.GetStartAlpha());
EXPECT_EQ(1.f, test_controller.GetEndAlpha());
}

TEST_F(TouchSelectionControllerTest, HideActiveSelectionHandle) {
SetHideActiveHandle(true);
TouchSelectionControllerTestApi test_controller(&controller());

base::TimeTicks event_time = base::TimeTicks::Now();
float line_height = 10.f;
gfx::RectF start_rect(10, 0, 0, line_height);
gfx::RectF end_rect(50, 0, 0, line_height);
bool visible = true;
OnLongPressEvent();

ChangeSelection(start_rect, visible, end_rect, visible);

// Start handle.
SetDraggingEnabled(true);
EXPECT_EQ(1.f, test_controller.GetStartAlpha());
EXPECT_EQ(1.f, test_controller.GetEndAlpha());
MockMotionEvent event(MockMotionEvent::Action::DOWN, event_time, 10, 5);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_EQ(0.f, test_controller.GetStartAlpha());
EXPECT_EQ(1.f, test_controller.GetEndAlpha());

event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 10, 5);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_EQ(0.f, test_controller.GetStartAlpha());
EXPECT_EQ(1.f, test_controller.GetEndAlpha());

event_time += base::TimeDelta::FromMilliseconds(2 * kDefaultTapTimeoutMs);
// UP will reset alpha to be visible.
event = MockMotionEvent(MockMotionEvent::Action::UP, event_time, 10, 5);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_EQ(1.f, test_controller.GetStartAlpha());
EXPECT_EQ(1.f, test_controller.GetEndAlpha());

// End handle.
event = MockMotionEvent(MockMotionEvent::Action::DOWN, event_time, 50, 5);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_EQ(1.f, test_controller.GetStartAlpha());
EXPECT_EQ(0.f, test_controller.GetEndAlpha());

event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 50, 5);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));

EXPECT_EQ(1.f, test_controller.GetStartAlpha());
EXPECT_EQ(0.f, test_controller.GetEndAlpha());

event_time += base::TimeDelta::FromMilliseconds(2 * kDefaultTapTimeoutMs);
// UP will reset alpha to be visible.
event = MockMotionEvent(MockMotionEvent::Action::UP, event_time, 50, 5);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_EQ(1.f, test_controller.GetStartAlpha());
EXPECT_EQ(1.f, test_controller.GetEndAlpha());
}

} // namespace ui

0 comments on commit fa804f3

Please sign in to comment.