Commit 0f6eb8cc authored by Toni Barzic's avatar Toni Barzic Committed by Commit Bot

Few tweaks to home to overview nudge

Adjust the number of successful gestures needed to stop showing the
nudge from 7 to 3.

Hide the nudge if the user taps it.

Move the nudge (and hotseat) 2 dips up (further from the screen edge).

BUG=1060368, 1060373, 1060372

Change-Id: I0b0e292648948a4c3d7ee40825ea38c36908779a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2097496
Commit-Queue: Toni Baržić <tbarzic@chromium.org>
Reviewed-by: default avatarManu Cornet <manucornet@chromium.org>
Cr-Commit-Position: refs/heads/master@{#749200}
parent a3fbeb9a
......@@ -95,6 +95,11 @@ class ASH_EXPORT HomeLauncherGestureHandler
Mode mode() const { return mode_; }
SwipeHomeToOverviewController*
swipe_home_to_overview_controller_for_testing() {
return swipe_home_to_overview_controller_.get();
}
private:
class ScopedWindowModifier;
......
......@@ -6,6 +6,7 @@
#include "ash/public/cpp/shelf_types.h"
#include "ash/public/cpp/shell_window_ids.h"
#include "ash/shelf/shelf.h"
#include "ash/system/tray/tray_constants.h"
#include "ash/wm/collision_detection/collision_detection_utils.h"
#include "ui/aura/window.h"
......@@ -41,15 +42,17 @@ ContextualNudge::ContextualNudge(views::View* anchor,
Position position,
const gfx::Insets& margins,
const base::string16& text,
SkColor text_color)
SkColor text_color,
const base::RepeatingClosure& tap_callback)
: views::BubbleDialogDelegateView(anchor,
GetArrowForPosition(position),
views::BubbleBorder::NO_ASSETS) {
views::BubbleBorder::NO_ASSETS),
tap_callback_(tap_callback) {
set_color(SK_ColorTRANSPARENT);
set_margins(margins);
set_close_on_deactivate(false);
set_accept_events(!tap_callback.is_null());
SetCanActivate(false);
set_accept_events(false);
set_adjust_if_offscreen(false);
set_shadow(views::BubbleBorder::NO_ASSETS);
DialogDelegate::set_buttons(ui::DIALOG_BUTTON_NONE);
......@@ -94,4 +97,26 @@ ui::LayerType ContextualNudge::GetLayerType() const {
return ui::LAYER_NOT_DRAWN;
}
void ContextualNudge::OnGestureEvent(ui::GestureEvent* event) {
if (event->type() == ui::ET_GESTURE_TAP && tap_callback_) {
event->StopPropagation();
tap_callback_.Run();
return;
}
// Pass on non tap events to the shelf (so it can handle swipe gestures that
// start on top of the nudge). Convert event to screen coordinates, as this is
// what Shelf::ProcessGestureEvent() expects.
ui::GestureEvent event_in_screen(*event);
gfx::Point location_in_screen(event->location());
View::ConvertPointToScreen(this, &location_in_screen);
event_in_screen.set_location(location_in_screen);
Shelf* shelf = Shelf::ForWindow(GetWidget()->GetNativeWindow());
if (shelf->ProcessGestureEvent(event_in_screen))
event->StopPropagation();
else
views::BubbleDialogDelegateView::OnGestureEvent(event);
}
} // namespace ash
......@@ -6,6 +6,7 @@
#define ASH_SHELF_CONTEXTUAL_NUDGE_H_
#include "ash/ash_export.h"
#include "base/callback.h"
#include "ui/views/bubble/bubble_dialog_delegate_view.h"
#include "ui/views/controls/label.h"
......@@ -31,12 +32,14 @@ class ASH_EXPORT ContextualNudge : public views::BubbleDialogDelegateView {
// |margins| - The margins added to the nudge bubble.
// |text| - The nudge text.
// |text_color| - The nudge text label foreground color.
// |tap_callback| - If set, the callback called when the user taps the nuge.
ContextualNudge(views::View* anchor,
aura::Window* parent_window,
Position position,
const gfx::Insets& margins,
const base::string16& text,
SkColor text_color);
SkColor text_color,
const base::RepeatingClosure& tap_callback);
~ContextualNudge() override;
ContextualNudge(const ContextualNudge&) = delete;
......@@ -51,8 +54,11 @@ class ASH_EXPORT ContextualNudge : public views::BubbleDialogDelegateView {
// BubbleDialogDelegateView:
gfx::Size CalculatePreferredSize() const override;
ui::LayerType GetLayerType() const override;
void OnGestureEvent(ui::GestureEvent* event) override;
private:
base::RepeatingClosure tap_callback_;
views::Label* label_;
};
......
......@@ -90,8 +90,12 @@ bool ShouldShowNudge(PrefService* prefs, TooltipType type) {
if (!features::AreContextualNudgesEnabled())
return false;
if (GetSuccessCount(prefs, type) >= kSuccessLimit)
const int success_count = GetSuccessCount(prefs, type);
if (success_count >= kSuccessLimit ||
(type == TooltipType::kHomeToOverview &&
success_count >= kSuccessLimitHomeToOverview)) {
return false;
}
const int shown_count = GetShownCount(prefs, type);
if (shown_count >= kNotificationLimit)
......
......@@ -25,6 +25,7 @@ enum class TooltipType {
// hasn't performed the gesture |kSuccessLimit| times successfully.
constexpr int kNotificationLimit = 3;
constexpr int kSuccessLimit = 7;
constexpr int kSuccessLimitHomeToOverview = 3;
// Minimum time between showing contextual nudges to the user.
constexpr base::TimeDelta kMinInterval = base::TimeDelta::FromDays(1);
......
......@@ -177,7 +177,8 @@ void DragHandle::ShowDragHandleTooltip() {
gfx::Insets(), l10n_util::GetStringUTF16(IDS_ASH_DRAG_HANDLE_NUDGE),
AshColorProvider::Get()->GetContentLayerColor(
AshColorProvider::ContentLayerType::kTextPrimary,
AshColorProvider::AshColorMode::kDark));
AshColorProvider::AshColorMode::kDark),
base::RepeatingClosure());
drag_handle_nudge_->GetWidget()->Show();
drag_handle_nudge_->label()->layer()->SetOpacity(0.0f);
......
......@@ -48,7 +48,7 @@ constexpr base::TimeDelta kNudgeTranformComponentDuration =
// The baseline vertical offset from default kShown state bounds added to
// hotseat position when the nudge is shown - this is the offset that the
// hotseat will have once show throb animation completes.
constexpr int kHotseatBaselineNudgeOffset = -20;
constexpr int kHotseatBaselineNudgeOffset = -22;
// The number of times the nudge should be moved up and down when the nudge is
// shown.
......@@ -167,7 +167,9 @@ void HomeToOverviewNudgeController::ShowNudge() {
l10n_util::GetStringUTF16(IDS_ASH_HOME_TO_OVERVIEW_CONTEXTUAL_NUDGE),
AshColorProvider::Get()->GetContentLayerColor(
AshColorProvider::ContentLayerType::kTextPrimary,
AshColorProvider::AshColorMode::kDark));
AshColorProvider::AshColorMode::kDark),
base::BindRepeating(&HomeToOverviewNudgeController::HandleNudgeTap,
weak_factory_.GetWeakPtr()));
UpdateNudgeAnchorBounds();
......@@ -291,6 +293,9 @@ void HomeToOverviewNudgeController::HideNudge() {
widget_observer_.RemoveAll();
nudge_ = nullptr;
// Invalidated nudge tap handler callbacks.
weak_factory_.InvalidateWeakPtrs();
}
void HomeToOverviewNudgeController::UpdateNudgeAnchorBounds() {
......@@ -307,4 +312,8 @@ void HomeToOverviewNudgeController::UpdateNudgeAnchorBounds() {
gfx::Size(shelf_bounds.width(), hotseat_bounds.height())));
}
void HomeToOverviewNudgeController::HandleNudgeTap() {
HideNudge();
}
} // namespace ash
......@@ -8,6 +8,7 @@
#include <memory>
#include "ash/ash_export.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_observer.h"
#include "base/timer/timer.h"
#include "ui/views/widget/widget.h"
......@@ -58,6 +59,9 @@ class ASH_EXPORT HomeToOverviewNudgeController : views::WidgetObserver {
// Updates the nudge anchor bounds for the current hotseat and shelf bounds.
void UpdateNudgeAnchorBounds();
// Passed to |nudge_| as its tap gesture handler.
void HandleNudgeTap();
bool nudge_allowed_for_shelf_state_ = false;
HotseatWidget* const hotseat_widget_;
......@@ -69,6 +73,8 @@ class ASH_EXPORT HomeToOverviewNudgeController : views::WidgetObserver {
// Observes hotseat widget to detect the hotseat bounds changes, and the
// nudge widget to detect that the widget is being destroyed.
ScopedObserver<views::Widget, views::WidgetObserver> widget_observer_{this};
base::WeakPtrFactory<HomeToOverviewNudgeController> weak_factory_{this};
};
} // namespace ash
......
......@@ -4,6 +4,9 @@
#include "ash/shelf/home_to_overview_nudge_controller.h"
#include "ash/home_screen/home_launcher_gesture_handler.h"
#include "ash/home_screen/home_screen_controller.h"
#include "ash/home_screen/swipe_home_to_overview_controller.h"
#include "ash/public/cpp/ash_features.h"
#include "ash/shelf/contextual_nudge.h"
#include "ash/shelf/contextual_tooltip.h"
......@@ -489,6 +492,138 @@ TEST_F(HomeToOverviewNudgeControllerTest, NoCrashIfNudgeWidgetGetsClosed) {
EXPECT_FALSE(GetNudgeController()->nudge_for_testing());
}
// Tests that tapping on the nudge hides the nudge.
TEST_F(HomeToOverviewNudgeControllerTest, TapOnTheNudgeClosedTheNudge) {
TabletModeControllerTestApi().EnterTabletMode();
CreateUserSessions(1);
ScopedWindowList windows = CreateAndMinimizeWindows(2);
ASSERT_TRUE(GetNudgeController());
ASSERT_TRUE(GetNudgeController()->HasShowTimerForTesting());
GetNudgeController()->FireShowTimerForTesting();
ASSERT_TRUE(GetNudgeController()->nudge_for_testing());
views::Widget* nudge_widget = GetNudgeWidget();
WidgetCloseObserver widget_close_observer(nudge_widget);
GetEventGenerator()->GestureTapAt(
nudge_widget->GetWindowBoundsInScreen().CenterPoint());
EXPECT_FALSE(GetNudgeController()->nudge_for_testing());
EXPECT_TRUE(widget_close_observer.WidgetClosed());
EXPECT_EQ(gfx::Transform(),
GetHotseatWidget()->GetLayer()->GetTargetTransform());
}
// Tests that the nudge stops showing up if the user performs the gesture few
// times.
TEST_F(HomeToOverviewNudgeControllerTest, NoNudgeAfterSuccessfulGestures) {
TabletModeControllerTestApi().EnterTabletMode();
CreateUserSessions(1);
ScopedWindowList windows = CreateAndMinimizeWindows(2);
EXPECT_FALSE(GetNudgeController()->nudge_for_testing());
ASSERT_TRUE(GetNudgeController()->HasShowTimerForTesting());
GetNudgeController()->FireShowTimerForTesting();
// Perform home to overview gesture kSuccessLimitHomeToOverview times.
for (int i = 0; i < contextual_tooltip::kSuccessLimitHomeToOverview; ++i) {
SCOPED_TRACE(testing::Message() << "Attempt " << i);
// Perform home to overview gesture.
wm::ActivateWindow(windows[0].get());
WindowState::Get(windows[0].get())->Minimize();
// Simluate swipe up and hold gesture on the home screen (which should
// transition to overview).
const gfx::Point start = GetPrimaryShelf()
->hotseat_widget()
->GetWindowBoundsInScreen()
.CenterPoint();
GetEventGenerator()->GestureScrollSequenceWithCallback(
start, start + gfx::Vector2d(0, -100),
base::TimeDelta::FromMilliseconds(50),
/*num_steps = */ 12,
base::BindRepeating(
[](ui::EventType type, const gfx::Vector2dF& offset) {
if (type != ui::ET_GESTURE_SCROLL_UPDATE)
return;
// If the swipe home to overview controller started the timer to
// transition to overview (which happens after swipe moves far
// enough), run it to trigger transition to overview.
SwipeHomeToOverviewController* swipe_controller =
Shell::Get()
->home_screen_controller()
->home_launcher_gesture_handler()
->swipe_home_to_overview_controller_for_testing();
ASSERT_TRUE(swipe_controller);
base::OneShotTimer* transition_timer =
swipe_controller->overview_transition_timer_for_testing();
if (transition_timer->IsRunning())
transition_timer->FireNow();
}));
// No point oof continuing the test if transition to overview failed.
ASSERT_TRUE(Shell::Get()->overview_controller()->InOverviewSession());
}
// The nudge should not be shown next time the user transitions to home.
test_clock_.Advance(base::TimeDelta::FromHours(25));
ScopedWindowList extra_window = CreateAndMinimizeWindows(1);
EXPECT_FALSE(GetNudgeController()->nudge_for_testing());
EXPECT_FALSE(GetNudgeController()->HasShowTimerForTesting());
EXPECT_EQ(gfx::Transform(),
GetHotseatWidget()->GetLayer()->GetTargetTransform());
}
// Tests that swipe up and hold gesture that starts on top of contextual nudge
// widget works - i.e. that home still transitions to overview.
TEST_F(HomeToOverviewNudgeControllerTest, HomeToOverviewGestureFromNudge) {
TabletModeControllerTestApi().EnterTabletMode();
CreateUserSessions(1);
ScopedWindowList windows = CreateAndMinimizeWindows(2);
EXPECT_FALSE(GetNudgeController()->nudge_for_testing());
ASSERT_TRUE(GetNudgeController()->HasShowTimerForTesting());
GetNudgeController()->FireShowTimerForTesting();
// Simluate swipe up and hold gesture on home screen from the nudge widget.
const gfx::Point start =
GetNudgeWidget()->GetWindowBoundsInScreen().CenterPoint();
GetEventGenerator()->GestureScrollSequenceWithCallback(
start, start + gfx::Vector2d(0, -100),
base::TimeDelta::FromMilliseconds(50),
/*num_steps = */ 12,
base::BindRepeating([](ui::EventType type, const gfx::Vector2dF& offset) {
if (type != ui::ET_GESTURE_SCROLL_UPDATE)
return;
// If the swipe home to overview controller started the timer to
// transition to overview (which happens after swipe moves far
// enough), run it to trigger transition to overview.
SwipeHomeToOverviewController* swipe_controller =
Shell::Get()
->home_screen_controller()
->home_launcher_gesture_handler()
->swipe_home_to_overview_controller_for_testing();
ASSERT_TRUE(swipe_controller);
base::OneShotTimer* transition_timer =
swipe_controller->overview_transition_timer_for_testing();
if (transition_timer->IsRunning())
transition_timer->FireNow();
}));
EXPECT_TRUE(Shell::Get()->overview_controller()->InOverviewSession());
}
// Tests that nudge and hotseat get repositioned appropriatelly if the display
// bounds change.
TEST_F(HomeToOverviewNudgeControllerTest,
......
......@@ -43,7 +43,8 @@ LoginShelfGestureController::LoginShelfGestureController(
is_oobe ? gfx::kGoogleGrey700 : gfx::kGoogleGrey100;
nudge_ = new ContextualNudge(drag_handle, nullptr /*parent_window*/,
ContextualNudge::Position::kTop, gfx::Insets(4),
gesture_nudge, nudge_text_color);
gesture_nudge, nudge_text_color,
base::RepeatingClosure());
nudge_->GetWidget()->Show();
nudge_->GetWidget()->AddObserver(this);
}
......
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