1fa7767c5Sopenharmony_ci/*
2fa7767c5Sopenharmony_ci * Copyright (c) 2021-2021 Huawei Device Co., Ltd.
3fa7767c5Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4fa7767c5Sopenharmony_ci * you may not use this file except in compliance with the License.
5fa7767c5Sopenharmony_ci * You may obtain a copy of the License at
6fa7767c5Sopenharmony_ci *
7fa7767c5Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8fa7767c5Sopenharmony_ci *
9fa7767c5Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10fa7767c5Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11fa7767c5Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fa7767c5Sopenharmony_ci * See the License for the specific language governing permissions and
13fa7767c5Sopenharmony_ci * limitations under the License.
14fa7767c5Sopenharmony_ci */
15fa7767c5Sopenharmony_ci
16fa7767c5Sopenharmony_ci#include "gtest/gtest.h"
17fa7767c5Sopenharmony_ci#define private public
18fa7767c5Sopenharmony_ci#define protected public
19fa7767c5Sopenharmony_ci
20fa7767c5Sopenharmony_ci#include "foundation/osal/utils/util.h"
21fa7767c5Sopenharmony_ci#include "scene/player/internal/state_machine.h"
22fa7767c5Sopenharmony_ci#include "scene/player/play_executor.h"
23fa7767c5Sopenharmony_ci
24fa7767c5Sopenharmony_cinamespace OHOS {
25fa7767c5Sopenharmony_cinamespace Media {
26fa7767c5Sopenharmony_cinamespace Test {
27fa7767c5Sopenharmony_ciclass PlayExecutorStub : public PlayExecutor {
28fa7767c5Sopenharmony_cipublic:
29fa7767c5Sopenharmony_ci    PlayExecutorStub() noexcept : isLooping_(false), stateMachine_(nullptr)
30fa7767c5Sopenharmony_ci    {
31fa7767c5Sopenharmony_ci    }
32fa7767c5Sopenharmony_ci    bool IsSingleLoop() override
33fa7767c5Sopenharmony_ci    {
34fa7767c5Sopenharmony_ci        return isLooping_;
35fa7767c5Sopenharmony_ci    }
36fa7767c5Sopenharmony_ci    void SetLooping(bool looping)
37fa7767c5Sopenharmony_ci    {
38fa7767c5Sopenharmony_ci        isLooping_ = looping;
39fa7767c5Sopenharmony_ci    }
40fa7767c5Sopenharmony_ci    void SetStateMachine(const StateMachine* stateMachine)
41fa7767c5Sopenharmony_ci    {
42fa7767c5Sopenharmony_ci        stateMachine_ = stateMachine;
43fa7767c5Sopenharmony_ci    }
44fa7767c5Sopenharmony_ci    ErrorCode DoSetSource(const std::shared_ptr<MediaSource>& source) override
45fa7767c5Sopenharmony_ci    {
46fa7767c5Sopenharmony_ci        return source ? ErrorCode::SUCCESS : ErrorCode::ERROR_INVALID_PARAMETER_VALUE;
47fa7767c5Sopenharmony_ci    }
48fa7767c5Sopenharmony_ci    ErrorCode DoOnReady() override
49fa7767c5Sopenharmony_ci    {
50fa7767c5Sopenharmony_ci        return ErrorCode::SUCCESS;
51fa7767c5Sopenharmony_ci    }
52fa7767c5Sopenharmony_ci    ErrorCode DoOnComplete() override
53fa7767c5Sopenharmony_ci    {
54fa7767c5Sopenharmony_ci        if (!isLooping_ && stateMachine_) {
55fa7767c5Sopenharmony_ci            stateMachine_->SendEventAsync(Intent::STOP);
56fa7767c5Sopenharmony_ci        }
57fa7767c5Sopenharmony_ci        return ErrorCode::SUCCESS;
58fa7767c5Sopenharmony_ci    }
59fa7767c5Sopenharmony_ci    ErrorCode DoOnError(ErrorCode) override
60fa7767c5Sopenharmony_ci    {
61fa7767c5Sopenharmony_ci        return ErrorCode::SUCCESS;
62fa7767c5Sopenharmony_ci    }
63fa7767c5Sopenharmony_ci
64fa7767c5Sopenharmony_ciprivate:
65fa7767c5Sopenharmony_ci    bool isLooping_;
66fa7767c5Sopenharmony_ci    const StateMachine* stateMachine_;
67fa7767c5Sopenharmony_ci};
68fa7767c5Sopenharmony_ci
69fa7767c5Sopenharmony_ciPlayExecutorStub g_playExecutorStub;
70fa7767c5Sopenharmony_ci
71fa7767c5Sopenharmony_ciclass TestStateMachine : public ::testing::Test {
72fa7767c5Sopenharmony_ciprotected:
73fa7767c5Sopenharmony_ci    void SetUp() override
74fa7767c5Sopenharmony_ci    {
75fa7767c5Sopenharmony_ci        g_playExecutorStub.SetStateMachine(&stateMachine);
76fa7767c5Sopenharmony_ci        stateMachine.Start();
77fa7767c5Sopenharmony_ci    }
78fa7767c5Sopenharmony_ci
79fa7767c5Sopenharmony_ci    void TearDown() override
80fa7767c5Sopenharmony_ci    {
81fa7767c5Sopenharmony_ci    }
82fa7767c5Sopenharmony_ci
83fa7767c5Sopenharmony_ci    static StateMachine stateMachine;
84fa7767c5Sopenharmony_ci};
85fa7767c5Sopenharmony_ci
86fa7767c5Sopenharmony_ciStateMachine TestStateMachine::stateMachine(g_playExecutorStub);
87fa7767c5Sopenharmony_ci
88fa7767c5Sopenharmony_ciTEST_F(TestStateMachine, test_Idle_state)
89fa7767c5Sopenharmony_ci{
90fa7767c5Sopenharmony_ci    EXPECT_TRUE(stateMachine.GetCurrentState() == "IdleState");
91fa7767c5Sopenharmony_ci}
92fa7767c5Sopenharmony_ci
93fa7767c5Sopenharmony_ciTEST_F(TestStateMachine, test_set_invalid_source)
94fa7767c5Sopenharmony_ci{
95fa7767c5Sopenharmony_ci    EXPECT_TRUE(stateMachine.GetCurrentState() == "IdleState");
96fa7767c5Sopenharmony_ci    EXPECT_EQ(ErrorCode::ERROR_INVALID_PARAMETER_TYPE, stateMachine.SendEvent(Intent::SET_SOURCE));
97fa7767c5Sopenharmony_ci    EXPECT_TRUE(stateMachine.GetCurrentState() == "IdleState");
98fa7767c5Sopenharmony_ci}
99fa7767c5Sopenharmony_ci
100fa7767c5Sopenharmony_ciTEST_F(TestStateMachine, test_set_valid_source)
101fa7767c5Sopenharmony_ci{
102fa7767c5Sopenharmony_ci    EXPECT_TRUE(stateMachine.GetCurrentState() == "IdleState");
103fa7767c5Sopenharmony_ci    auto source = std::make_shared<MediaSource>("FakeUri");
104fa7767c5Sopenharmony_ci    EXPECT_EQ(ErrorCode::SUCCESS, stateMachine.SendEvent(Intent::SET_SOURCE, source));
105fa7767c5Sopenharmony_ci    EXPECT_TRUE(stateMachine.GetCurrentState() == "InitState");
106fa7767c5Sopenharmony_ci}
107fa7767c5Sopenharmony_ci
108fa7767c5Sopenharmony_ciTEST_F(TestStateMachine, test_prepare_after_set_source)
109fa7767c5Sopenharmony_ci{
110fa7767c5Sopenharmony_ci    EXPECT_TRUE(stateMachine.GetCurrentState() == "InitState");
111fa7767c5Sopenharmony_ci    EXPECT_EQ(ErrorCode::SUCCESS, stateMachine.SendEvent(Intent::PREPARE));
112fa7767c5Sopenharmony_ci    EXPECT_TRUE(stateMachine.GetCurrentState() == "PreparingState");
113fa7767c5Sopenharmony_ci}
114fa7767c5Sopenharmony_ci
115fa7767c5Sopenharmony_ciTEST_F(TestStateMachine, test_set_notify_error_in_preparing)
116fa7767c5Sopenharmony_ci{
117fa7767c5Sopenharmony_ci    EXPECT_TRUE(stateMachine.GetCurrentState() == "PreparingState");
118fa7767c5Sopenharmony_ci    EXPECT_EQ(ErrorCode::SUCCESS, stateMachine.SendEvent(Intent::NOTIFY_ERROR));
119fa7767c5Sopenharmony_ci    EXPECT_TRUE(stateMachine.GetCurrentState() == "InitState");
120fa7767c5Sopenharmony_ci}
121fa7767c5Sopenharmony_ci
122fa7767c5Sopenharmony_ciTEST_F(TestStateMachine, test_notify_ready)
123fa7767c5Sopenharmony_ci{
124fa7767c5Sopenharmony_ci    EXPECT_TRUE(stateMachine.GetCurrentState() == "InitState");
125fa7767c5Sopenharmony_ci    auto source = std::make_shared<MediaSource>("FakeUri");
126fa7767c5Sopenharmony_ci    EXPECT_EQ(ErrorCode::SUCCESS, stateMachine.SendEvent(Intent::SET_SOURCE, source));
127fa7767c5Sopenharmony_ci    EXPECT_TRUE(stateMachine.GetCurrentState() == "InitState");
128fa7767c5Sopenharmony_ci    EXPECT_EQ(ErrorCode::SUCCESS, stateMachine.SendEvent(Intent::PREPARE));
129fa7767c5Sopenharmony_ci    EXPECT_TRUE(stateMachine.GetCurrentState() == "PreparingState");
130fa7767c5Sopenharmony_ci    EXPECT_EQ(ErrorCode::SUCCESS, stateMachine.SendEvent(Intent::NOTIFY_READY));
131fa7767c5Sopenharmony_ci    EXPECT_TRUE(stateMachine.GetCurrentState() == "ReadyState");
132fa7767c5Sopenharmony_ci}
133fa7767c5Sopenharmony_ci
134fa7767c5Sopenharmony_ciTEST_F(TestStateMachine, test_play_after_ready)
135fa7767c5Sopenharmony_ci{
136fa7767c5Sopenharmony_ci    EXPECT_TRUE(stateMachine.GetCurrentState() == "ReadyState");
137fa7767c5Sopenharmony_ci    EXPECT_EQ(ErrorCode::SUCCESS, stateMachine.SendEvent(Intent::PLAY));
138fa7767c5Sopenharmony_ci    EXPECT_TRUE(stateMachine.GetCurrentState() == "PlayingState");
139fa7767c5Sopenharmony_ci}
140fa7767c5Sopenharmony_ci
141fa7767c5Sopenharmony_ciTEST_F(TestStateMachine, test_pause)
142fa7767c5Sopenharmony_ci{
143fa7767c5Sopenharmony_ci    EXPECT_TRUE(stateMachine.GetCurrentState() == "PlayingState");
144fa7767c5Sopenharmony_ci    EXPECT_EQ(ErrorCode::SUCCESS, stateMachine.SendEvent(Intent::PAUSE));
145fa7767c5Sopenharmony_ci    EXPECT_TRUE(stateMachine.GetCurrentState() == "PauseState");
146fa7767c5Sopenharmony_ci}
147fa7767c5Sopenharmony_ci
148fa7767c5Sopenharmony_ciTEST_F(TestStateMachine, test_play_after_pause)
149fa7767c5Sopenharmony_ci{
150fa7767c5Sopenharmony_ci    EXPECT_TRUE(stateMachine.GetCurrentState() == "PauseState");
151fa7767c5Sopenharmony_ci    EXPECT_EQ(ErrorCode::SUCCESS, stateMachine.SendEvent(Intent::PLAY));
152fa7767c5Sopenharmony_ci    EXPECT_TRUE(stateMachine.GetCurrentState() == "PlayingState");
153fa7767c5Sopenharmony_ci}
154fa7767c5Sopenharmony_ci
155fa7767c5Sopenharmony_ciTEST_F(TestStateMachine, test_play_complete_looping)
156fa7767c5Sopenharmony_ci{
157fa7767c5Sopenharmony_ci    g_playExecutorStub.SetLooping(true);
158fa7767c5Sopenharmony_ci    EXPECT_TRUE(stateMachine.GetCurrentState() == "PlayingState");
159fa7767c5Sopenharmony_ci    EXPECT_EQ(ErrorCode::SUCCESS, stateMachine.SendEvent(Intent::NOTIFY_COMPLETE));
160fa7767c5Sopenharmony_ci    EXPECT_TRUE(stateMachine.GetCurrentState() == "PlayingState");
161fa7767c5Sopenharmony_ci}
162fa7767c5Sopenharmony_ci
163fa7767c5Sopenharmony_ciTEST_F(TestStateMachine, test_play_complete_nolooping)
164fa7767c5Sopenharmony_ci{
165fa7767c5Sopenharmony_ci    g_playExecutorStub.SetLooping(false);
166fa7767c5Sopenharmony_ci    EXPECT_TRUE(stateMachine.GetCurrentState() == "PlayingState");
167fa7767c5Sopenharmony_ci    EXPECT_EQ(ErrorCode::SUCCESS, stateMachine.SendEvent(Intent::NOTIFY_COMPLETE));
168fa7767c5Sopenharmony_ci    OSAL::SleepFor(100);
169fa7767c5Sopenharmony_ci    EXPECT_TRUE(stateMachine.GetCurrentState() == "StoppedState");
170fa7767c5Sopenharmony_ci}
171fa7767c5Sopenharmony_ci} // namespace Test
172fa7767c5Sopenharmony_ci} // namespace Media
173fa7767c5Sopenharmony_ci} // namespace OHOS