• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include <chrono>
16 #include <thread>
17 #include <unistd.h>
18 #include <condition_variable>
19 #include <gtest/gtest.h>
20 #include <iservice_registry.h>
21 #include "vsync_receiver.h"
22 #include "vsync_controller.h"
23 #include "vsync_sampler.h"
24 #include "vsync_generator.h"
25 #include "vsync_distributor.h"
26 
27 #include <iostream>
28 
29 using namespace testing;
30 using namespace testing::ext;
31 
32 namespace OHOS::Rosen {
33 namespace {
34 int32_t appVSyncFlag = 0;
35 constexpr int32_t SOFT_VSYNC_PERIOD = 16;
36 constexpr int32_t SAMPLER_NUMBER = 6;
OnVSyncApp(int64_t time,void * data)37 static void OnVSyncApp(int64_t time, void *data)
38 {
39     std::cout << "OnVSyncApp in\n";
40     appVSyncFlag = 1;
41 }
42 }
43 class VSyncTest : public testing::Test {
44 public:
45     static void SetUpTestCase();
46     static void TearDownTestCase();
47     pid_t ChildProcessMain();
48     static void ThreadMain();
49 
50     static inline sptr<VSyncController> appController = nullptr;
51     static inline sptr<VSyncController> rsController = nullptr;
52     static inline sptr<VSyncDistributor> appDistributor = nullptr;
53     static inline sptr<VSyncDistributor> rsDistributor = nullptr;
54     static inline sptr<VSyncGenerator> vsyncGenerator = nullptr;
55     static inline sptr<VSyncSampler> vsyncSampler = nullptr;
56     static inline std::thread samplerThread;
57 
58     static inline int32_t pipeFd[2] = {};
59     static inline int32_t ipcSystemAbilityID = 34156;
60 };
61 
SetUpTestCase()62 void VSyncTest::SetUpTestCase()
63 {
64     vsyncGenerator = CreateVSyncGenerator();
65     vsyncSampler = CreateVSyncSampler();
66     appController = new VSyncController(vsyncGenerator, 0);
67     rsController = new VSyncController(vsyncGenerator, 0);
68 
69     appDistributor = new VSyncDistributor(appController, "appController");
70     rsDistributor = new VSyncDistributor(rsController, "rsController");
71 
72     samplerThread = std::thread(std::bind(&VSyncTest::ThreadMain));
73 }
74 
TearDownTestCase()75 void VSyncTest::TearDownTestCase()
76 {
77     vsyncGenerator = nullptr;
78     vsyncSampler = nullptr;
79     appDistributor = nullptr;
80     rsDistributor = nullptr;
81     appDistributor = nullptr;
82     rsDistributor = nullptr;
83 
84     if (samplerThread.joinable()) {
85         samplerThread.join();
86     }
87 }
88 
ChildProcessMain()89 pid_t VSyncTest::ChildProcessMain()
90 {
91     std::cout << "ChildProcessMain in\n";
92     pipe(pipeFd);
93     pid_t pid = fork();
94     if (pid != 0) {
95         return pid;
96     }
97 
98     sptr<IRemoteObject> robj = nullptr;
99     while (true) {
100         auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
101         robj = sam->GetSystemAbility(ipcSystemAbilityID);
102         if (robj != nullptr) {
103             break;
104         }
105         sleep(0);
106     }
107 
108     auto conn = iface_cast<IVSyncConnection>(robj);
109     sptr<VSyncReceiver> receiver = new VSyncReceiver(conn);
110     receiver->Init();
111 
112     VSyncReceiver::FrameCallback fcb = {
113         .userData_ = nullptr,
114         .callback_ = OnVSyncApp,
115     };
116     std::cout << "RequestNextVSync\n";
117     receiver->RequestNextVSync(fcb);
118     while (appVSyncFlag == 0) {
119         sleep(1);
120         std::cout << "ChildProcessMain appVSyncFlag is " << appVSyncFlag << std::endl;
121     }
122     EXPECT_EQ(appVSyncFlag, 1);
123     write(pipeFd[1], &appVSyncFlag, sizeof(appVSyncFlag));
124     close(pipeFd[0]);
125     close(pipeFd[1]);
126     exit(0);
127     return 0;
128 }
129 
ThreadMain()130 void VSyncTest::ThreadMain()
131 {
132     bool ret = true;
133     std::condition_variable con;
134     std::mutex mtx;
135     std::unique_lock<std::mutex> locker(mtx);
136     int32_t count = 0;
137     while (count <= SAMPLER_NUMBER) {
138         const auto &now = std::chrono::steady_clock::now().time_since_epoch();
139         int64_t timestamp = std::chrono::duration_cast<std::chrono::nanoseconds>(now).count();
140         ret = vsyncSampler->AddSample(timestamp);
141         con.wait_for(locker, std::chrono::milliseconds(SOFT_VSYNC_PERIOD));
142         count++;
143     }
144 }
145 
146 /*
147 * Function: RequestNextVSync001
148 * Type: Function
149 * Rank: Important(2)
150 * EnvConditions: N/A
151 * CaseDescription: 1. RequestNextVSync by IPC
152  */
153 HWTEST_F(VSyncTest, RequestNextVSync001, Function | MediumTest | Level2)
154 {
155     auto pid = ChildProcessMain();
156     ASSERT_GE(pid, 0);
157 
158     sptr<VSyncConnection> connServer = new VSyncConnection(appDistributor, "app");
159     appDistributor->AddConnection(connServer);
160     auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
161     sam->AddSystemAbility(ipcSystemAbilityID, connServer->AsObject());
162     read(pipeFd[0], &appVSyncFlag, sizeof(appVSyncFlag));
163     while (appVSyncFlag == 0) {
164         std::cout << "RequestNextVSync001 appVSyncFlag is " << appVSyncFlag << std::endl;
165     }
166     close(pipeFd[0]);
167     close(pipeFd[1]);
168     sam->RemoveSystemAbility(ipcSystemAbilityID);
169     waitpid(pid, nullptr, NULL);
170 }
171 }
172