blob: e77d20887afe618779f3ddd91f19f3d9c575ee7a [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "camera_general_survey_handler.h"
#include <memory>
#include "base/containers/flat_set.h"
#include "base/run_loop.h"
#include "base/test/task_environment.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using ::testing::Exactly;
using ::testing::Return;
namespace ash {
namespace {
class MockDelegate : public CameraGeneralSurveyHandler::Delegate {
public:
MOCK_METHOD(void,
AddActiveCameraClientObserver,
(media::CameraActiveClientObserver * observer),
(override));
MOCK_METHOD(void,
RemoveActiveCameraClientObserver,
(media::CameraActiveClientObserver * observer),
(override));
MOCK_METHOD(bool, ShouldShowSurvey, (), (const, override));
MOCK_METHOD(void, ShowSurvey, (), (override));
};
cros::mojom::CameraClientType kSupportedCameraTypes[] = {
cros::mojom::CameraClientType::CHROME,
cros::mojom::CameraClientType::ANDROID,
cros::mojom::CameraClientType::PLUGINVM,
cros::mojom::CameraClientType::ASH_CHROME,
cros::mojom::CameraClientType::LACROS_CHROME};
constexpr base::TimeDelta kMinCameraOpenDurationForSurveyTest =
base::Seconds(100);
// Any duration shorter than |kMinCameraOpenDurationForSurveyTest|
constexpr base::TimeDelta kShortOpenDuration = base::Seconds(10);
// Any duration longer than |kMinCameraOpenDurationForSurveyTest|
constexpr base::TimeDelta kLongOpenDuration = base::Seconds(110);
constexpr base::TimeDelta kCameraSurveyTriggerTimerDurationTest =
base::Seconds(5);
// Any duration shorter than |kCameraSurveyTriggerTimerDurationTest|
constexpr base::TimeDelta kShortCloseDuration = base::Seconds(1);
// Any duration longer than |kCameraSurveyTriggerTimerDurationTest|
constexpr base::TimeDelta kLongCloseDuration = base::Seconds(10);
class CameraGeneralSurveyHandlerTest : public testing::Test {
protected:
CameraGeneralSurveyHandlerTest() {
delegate_ = nullptr;
survey_handler_ = nullptr;
}
void InitializeSurveyHandler(std::unique_ptr<MockDelegate> delegate,
bool is_enabled = true) {
survey_handler_ = std::make_unique<CameraGeneralSurveyHandler>(
is_enabled, std::move(delegate), kMinCameraOpenDurationForSurveyTest,
kCameraSurveyTriggerTimerDurationTest);
}
// testing::Test:
void SetUp() override {
auto delegate = std::make_unique<MockDelegate>();
delegate_ = delegate.get();
InitializeSurveyHandler(std::move(delegate));
}
void TearDown() override {
survey_handler_ = nullptr;
// The delegate_ pointer was already deleted because survey_handler_
// took ownership.
delegate_ = nullptr;
}
base::test::TaskEnvironment task_environment_{
base::test::TaskEnvironment::TimeSource::MOCK_TIME};
MockDelegate* delegate_ = nullptr;
std::unique_ptr<CameraGeneralSurveyHandler> survey_handler_;
};
class CameraGeneralSurveyHandlerInitializationTest
: public CameraGeneralSurveyHandlerTest,
public testing::WithParamInterface<bool> {
protected:
// testing::Test:
void SetUp() override {
auto delegate = std::make_unique<MockDelegate>();
delegate_ = delegate.get();
EXPECT_CALL(*delegate_, AddActiveCameraClientObserver)
.Times(Exactly(GetParam() ? 1 : 0));
InitializeSurveyHandler(std::move(delegate), GetParam());
}
// testing::Test:
void TearDown() override {
EXPECT_CALL(*delegate_, RemoveActiveCameraClientObserver)
.Times(Exactly(GetParam() ? 1 : 0));
CameraGeneralSurveyHandlerTest::TearDown();
}
};
TEST_P(CameraGeneralSurveyHandlerInitializationTest, InitializeNoOp) {
task_environment_.AdvanceClock(kLongOpenDuration);
}
INSTANTIATE_TEST_SUITE_P(CameraGeneralSurveyFeatureEnablement,
CameraGeneralSurveyHandlerInitializationTest,
testing::Values(true, false));
class CameraGeneralSurveyHandlerOpenCloseTest
: public CameraGeneralSurveyHandlerTest,
public testing::WithParamInterface<cros::mojom::CameraClientType> {
protected:
void SetUp() override {
auto delegate = std::make_unique<MockDelegate>();
delegate_ = delegate.get();
EXPECT_CALL(*delegate_, AddActiveCameraClientObserver).Times(Exactly(1));
InitializeSurveyHandler(std::move(delegate));
}
void TearDown() override {
EXPECT_CALL(*delegate_, RemoveActiveCameraClientObserver).Times(Exactly(1));
CameraGeneralSurveyHandlerTest::TearDown();
}
// Simulates opening a camera and then keeping it open for |duration|
void OpenCamera(base::TimeDelta duration = base::Seconds(0)) {
survey_handler_->OnActiveClientChange(GetParam(),
/*is_new_active_client*/ true,
base::flat_set<std::string>({"0"}));
task_environment_.AdvanceClock(duration);
}
// Simulates closing all camera and then keeping it closed for |duration|
void CloseCamera(base::TimeDelta duration = base::Seconds(0)) {
survey_handler_->OnActiveClientChange(GetParam(),
/*is_new_active_client*/ false,
base::flat_set<std::string>({}));
task_environment_.AdvanceClock(duration);
}
};
TEST_P(CameraGeneralSurveyHandlerOpenCloseTest, CameraOpenNotYetClosed) {
// It shouldn't show survey when camera is still open.
EXPECT_CALL(*delegate_, ShowSurvey).Times(Exactly(0));
OpenCamera(kLongOpenDuration);
}
TEST_P(CameraGeneralSurveyHandlerOpenCloseTest, CameraOpenShortTime) {
// It shouldn't show survey after camera was just open for a duration
// shorter than |kMinCameraOpenDurationForSurveyTest|.
EXPECT_CALL(*delegate_, ShowSurvey).Times(Exactly(0));
OpenCamera(kShortOpenDuration);
CloseCamera();
}
TEST_P(CameraGeneralSurveyHandlerOpenCloseTest, CameraReopenImmediately) {
// It shouldn't show survey after camera was just closed for a duration
// shorter than |kCameraSurveyTriggerTimerDurationTest| (after being
// open for duration longer than |kMinCameraOpenDurationForSurveyTest|).
// Switching between front and back camera falls into this test scenario.
EXPECT_CALL(*delegate_, ShowSurvey).Times(Exactly(0));
EXPECT_CALL(*delegate_, ShouldShowSurvey).WillOnce(Return(true));
OpenCamera(kLongOpenDuration);
CloseCamera(kShortCloseDuration);
OpenCamera(kLongOpenDuration);
base::RunLoop().RunUntilIdle();
}
TEST_P(CameraGeneralSurveyHandlerOpenCloseTest, ShowSurvey) {
// It should show survey exactly once after all conditions fulfilled.
EXPECT_CALL(*delegate_, ShowSurvey).Times(Exactly(1));
EXPECT_CALL(*delegate_, ShouldShowSurvey).WillOnce(Return(true));
OpenCamera(kLongOpenDuration);
CloseCamera(kLongCloseDuration);
base::RunLoop().RunUntilIdle();
}
TEST_P(CameraGeneralSurveyHandlerOpenCloseTest, UserNotSelectedForSurvey) {
// All conditions have been fulfilled except that the user is not selected
// for the survey, therefore it shouldn't show the survey.
EXPECT_CALL(*delegate_, ShowSurvey).Times(Exactly(0));
EXPECT_CALL(*delegate_, ShouldShowSurvey).WillOnce(Return(false));
OpenCamera(kLongOpenDuration);
CloseCamera(kLongCloseDuration);
base::RunLoop().RunUntilIdle();
}
INSTANTIATE_TEST_SUITE_P(CameraGeneralSurveyAllCameraClientTypes,
CameraGeneralSurveyHandlerOpenCloseTest,
testing::ValuesIn(kSupportedCameraTypes));
} // namespace
} // namespace ash