blob: 370e539b5b52342b0b406a533577cda18ef4c6b7 [file] [log] [blame]
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/controls/contextual_tooltip.h"
#include "ash/constants/ash_features.h"
#include "ash/session/session_controller_impl.h"
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "base/json/values_util.h"
#include "base/strings/string_util.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/simple_test_clock.h"
#include "base/time/time.h"
#include "base/values.h"
#include "components/prefs/scoped_user_pref_update.h"
#include "ui/aura/window.h"
#include "ui/wm/core/window_util.h"
namespace ash {
namespace contextual_tooltip {
class ContextualTooltipTest : public AshTestBase,
public testing::WithParamInterface<bool> {
public:
ContextualTooltipTest() {
if (GetParam()) {
scoped_feature_list_.InitAndEnableFeature(
features::kHideShelfControlsInTabletMode);
} else {
scoped_feature_list_.InitAndDisableFeature(
features::kHideShelfControlsInTabletMode);
}
}
~ContextualTooltipTest() override = default;
base::SimpleTestClock* clock() { return &test_clock_; }
// AshTestBase:
void SetUp() override {
AshTestBase::SetUp();
contextual_tooltip::OverrideClockForTesting(&test_clock_);
test_clock_.Advance(base::Seconds(360));
}
void TearDown() override {
contextual_tooltip::ClearClockOverrideForTesting();
AshTestBase::TearDown();
}
PrefService* GetPrefService() {
return Shell::Get()->session_controller()->GetLastActiveUserPrefService();
}
private:
base::test::ScopedFeatureList scoped_feature_list_;
base::SimpleTestClock test_clock_;
};
using ContextualTooltipDisabledTest = ContextualTooltipTest;
INSTANTIATE_TEST_SUITE_P(All,
ContextualTooltipDisabledTest,
testing::Values(false));
INSTANTIATE_TEST_SUITE_P(All, ContextualTooltipTest, testing::Values(true));
// Checks that nudges are not shown when the feature flag is disabled.
TEST_P(ContextualTooltipDisabledTest, FeatureFlagDisabled) {
EXPECT_FALSE(contextual_tooltip::ShouldShowNudge(
GetPrefService(), TooltipType::kInAppToHome, nullptr));
}
TEST_P(ContextualTooltipTest, ShouldShowPersistentDragHandleNudge) {
base::TimeDelta recheck_delay;
EXPECT_TRUE(contextual_tooltip::ShouldShowNudge(
GetPrefService(), TooltipType::kInAppToHome, &recheck_delay));
EXPECT_TRUE(recheck_delay.is_zero());
EXPECT_TRUE(contextual_tooltip::GetNudgeTimeout(GetPrefService(),
TooltipType::kInAppToHome)
.is_zero());
}
// Checks that drag handle nudge has a timeout if it is not the first time it is
// being shown.
TEST_P(ContextualTooltipTest, NonPersistentDragHandleNudgeTimeout) {
for (int shown_count = 1;
shown_count < contextual_tooltip::kNotificationLimit; shown_count++) {
contextual_tooltip::HandleNudgeShown(GetPrefService(),
TooltipType::kInAppToHome);
clock()->Advance(contextual_tooltip::kMinInterval);
EXPECT_TRUE(contextual_tooltip::ShouldShowNudge(
GetPrefService(), TooltipType::kInAppToHome, nullptr));
EXPECT_EQ(contextual_tooltip::GetNudgeTimeout(GetPrefService(),
TooltipType::kInAppToHome),
contextual_tooltip::kNudgeShowDuration);
}
}
// Checks that drag handle nudge should be shown after kMinInterval has passed
// since the last time it was shown but not before the time interval has passed.
TEST_P(ContextualTooltipTest, ShouldShowTimedDragHandleNudge) {
contextual_tooltip::HandleNudgeShown(GetPrefService(),
TooltipType::kInAppToHome);
base::TimeDelta recheck_delay;
for (int shown_count = 1;
shown_count < contextual_tooltip::kNotificationLimit; shown_count++) {
EXPECT_FALSE(contextual_tooltip::ShouldShowNudge(
GetPrefService(), TooltipType::kInAppToHome, &recheck_delay));
EXPECT_EQ(contextual_tooltip::kMinInterval, recheck_delay);
clock()->Advance(contextual_tooltip::kMinInterval / 2);
EXPECT_FALSE(contextual_tooltip::ShouldShowNudge(
GetPrefService(), TooltipType::kInAppToHome, &recheck_delay));
EXPECT_EQ(
contextual_tooltip::kMinInterval - contextual_tooltip::kMinInterval / 2,
recheck_delay);
clock()->Advance(contextual_tooltip::kMinInterval / 2);
EXPECT_TRUE(contextual_tooltip::ShouldShowNudge(
GetPrefService(), TooltipType::kInAppToHome, nullptr));
contextual_tooltip::HandleNudgeShown(GetPrefService(),
TooltipType::kInAppToHome);
}
clock()->Advance(contextual_tooltip::kMinInterval);
EXPECT_FALSE(contextual_tooltip::ShouldShowNudge(
GetPrefService(), TooltipType::kInAppToHome, &recheck_delay));
EXPECT_TRUE(recheck_delay.is_zero());
EXPECT_EQ(contextual_tooltip::GetNudgeTimeout(GetPrefService(),
TooltipType::kInAppToHome),
contextual_tooltip::kNudgeShowDuration);
}
// Tests that if the user has successfully performed the gesture for at least
// |kSuccessLimit|, the corresponding nudge should not be shown.
TEST_P(ContextualTooltipTest, ShouldNotShowNudgeAfterSuccessLimit) {
EXPECT_TRUE(contextual_tooltip::ShouldShowNudge(
GetPrefService(), TooltipType::kInAppToHome, nullptr));
for (int success_count = 0;
success_count < contextual_tooltip::kSuccessLimitInAppToHome;
success_count++) {
contextual_tooltip::HandleGesturePerformed(GetPrefService(),
TooltipType::kInAppToHome);
}
base::TimeDelta recheck_delay;
EXPECT_FALSE(contextual_tooltip::ShouldShowNudge(
GetPrefService(), TooltipType::kInAppToHome, &recheck_delay));
EXPECT_TRUE(recheck_delay.is_zero());
}
// Should not show back gesture nudge if drag handle nudge is expected to be
// shown.
TEST_P(ContextualTooltipTest,
DoNotShowBackGestureNudgeIfDragHandleNudgeIsExpected) {
EXPECT_TRUE(contextual_tooltip::ShouldShowNudge(
GetPrefService(), TooltipType::kInAppToHome, nullptr));
// The drag handle nudge is expected to show, so back gesture nudge should not
// be shown at the same time.
base::TimeDelta recheck_delay;
EXPECT_FALSE(contextual_tooltip::ShouldShowNudge(
GetPrefService(), TooltipType::kBackGesture, &recheck_delay));
EXPECT_EQ(contextual_tooltip::kMinIntervalBetweenBackAndDragHandleNudge,
recheck_delay);
// After the nudge is shown, back gesture should remain hidden until
// sufficient amount of time passes.
contextual_tooltip::HandleNudgeShown(GetPrefService(),
TooltipType::kInAppToHome);
EXPECT_FALSE(contextual_tooltip::ShouldShowNudge(
GetPrefService(), TooltipType::kBackGesture, &recheck_delay));
EXPECT_EQ(contextual_tooltip::kMinIntervalBetweenBackAndDragHandleNudge,
recheck_delay);
clock()->Advance(
contextual_tooltip::kMinIntervalBetweenBackAndDragHandleNudge / 2);
EXPECT_FALSE(contextual_tooltip::ShouldShowNudge(
GetPrefService(), TooltipType::kBackGesture, &recheck_delay));
EXPECT_EQ(
contextual_tooltip::kMinIntervalBetweenBackAndDragHandleNudge -
contextual_tooltip::kMinIntervalBetweenBackAndDragHandleNudge / 2,
recheck_delay);
clock()->Advance(recheck_delay);
EXPECT_TRUE(contextual_tooltip::ShouldShowNudge(
GetPrefService(), TooltipType::kBackGesture, nullptr));
// After the drag handle becomes eligible to show again, the back gesture
// should be disabled.
clock()->Advance(contextual_tooltip::kMinInterval);
EXPECT_FALSE(contextual_tooltip::ShouldShowNudge(
GetPrefService(), TooltipType::kBackGesture, &recheck_delay));
EXPECT_EQ(contextual_tooltip::kMinIntervalBetweenBackAndDragHandleNudge,
recheck_delay);
}
// Tests that back gesture is allowed if the shelf is hidden, even if drag
// handle would normally be available.
TEST_P(ContextualTooltipTest, AllowBackGestureForHiddenShelf) {
EXPECT_TRUE(contextual_tooltip::ShouldShowNudge(
GetPrefService(), TooltipType::kInAppToHome, nullptr));
// The drag handle nudge is expected to show, so back gesture nudge should not
// be shown at the same time.
EXPECT_FALSE(contextual_tooltip::ShouldShowNudge(
GetPrefService(), TooltipType::kBackGesture, nullptr));
// If drag handle nudge is disabled because the shelf is hidden, the back
// gesture nudge should be allowed.
contextual_tooltip::SetDragHandleNudgeDisabledForHiddenShelf(true);
EXPECT_FALSE(contextual_tooltip::ShouldShowNudge(
GetPrefService(), TooltipType::kInAppToHome, nullptr));
EXPECT_TRUE(contextual_tooltip::ShouldShowNudge(
GetPrefService(), TooltipType::kBackGesture, nullptr));
// Disallow back gesture nudge if the shelf becomes visible.
contextual_tooltip::SetDragHandleNudgeDisabledForHiddenShelf(false);
EXPECT_TRUE(contextual_tooltip::ShouldShowNudge(
GetPrefService(), TooltipType::kInAppToHome, nullptr));
EXPECT_FALSE(contextual_tooltip::ShouldShowNudge(
GetPrefService(), TooltipType::kBackGesture, nullptr));
}
// Tests that the drag handle nudge should not be shown while back gesture is
// showing, or soon after it's been shown.
TEST_P(ContextualTooltipTest,
DoNotShowDragHandleNudgeIfBackGestureNudgeIsShown) {
EXPECT_TRUE(contextual_tooltip::ShouldShowNudge(
GetPrefService(), TooltipType::kInAppToHome, nullptr));
// Drag handle nudge not allowed if back gesture is showing.
contextual_tooltip::SetDragHandleNudgeDisabledForHiddenShelf(true);
contextual_tooltip::SetBackGestureNudgeShowing(true);
contextual_tooltip::SetDragHandleNudgeDisabledForHiddenShelf(false);
base::TimeDelta recheck_delay;
EXPECT_FALSE(contextual_tooltip::ShouldShowNudge(
GetPrefService(), TooltipType::kInAppToHome, &recheck_delay));
EXPECT_EQ(contextual_tooltip::kMinIntervalBetweenBackAndDragHandleNudge,
recheck_delay);
// Allow drag handle only if sufficient amount of time passes since showing
// the back gesture nudge.
contextual_tooltip::SetBackGestureNudgeShowing(false);
contextual_tooltip::HandleNudgeShown(GetPrefService(),
TooltipType::kBackGesture);
recheck_delay = base::TimeDelta();
EXPECT_FALSE(contextual_tooltip::ShouldShowNudge(
GetPrefService(), TooltipType::kInAppToHome, &recheck_delay));
EXPECT_EQ(contextual_tooltip::kMinIntervalBetweenBackAndDragHandleNudge,
recheck_delay);
clock()->Advance(
contextual_tooltip::kMinIntervalBetweenBackAndDragHandleNudge / 2);
EXPECT_FALSE(contextual_tooltip::ShouldShowNudge(
GetPrefService(), TooltipType::kInAppToHome, &recheck_delay));
clock()->Advance(recheck_delay);
EXPECT_TRUE(contextual_tooltip::ShouldShowNudge(
GetPrefService(), TooltipType::kInAppToHome, nullptr));
}
} // namespace contextual_tooltip
} // namespace ash