1 /*
2 * Copyright (c) 2024 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 #include "accesstoken_kit.h"
27 #ifdef SUPPORT_ACCESS_TOKEN
28 #include "nativetoken_kit.h"
29 #include "token_setproc.h"
30 #endif
31
32 #include <iostream>
33
34 using namespace testing;
35 using namespace testing::ext;
36
37 namespace OHOS::Rosen {
38 namespace {
39 int32_t g_onVsyncCount = 0;
40 constexpr int32_t SAMPLER_NUMBER = 6;
OnVSync(int64_t time,void * data)41 static void OnVSync(int64_t time, void *data)
42 {
43 g_onVsyncCount++;
44 }
45 }
46 class SetVsyncCallBackForEveryFrameTest : public testing::Test {
47 public:
48 void Process1();
49 void Process2();
50
51 sptr<VSyncSampler> vsyncSampler = nullptr;
52 sptr<VSyncGenerator> vsyncGenerator = nullptr;
53 sptr<VSyncController> vsyncController = nullptr;
54 sptr<VSyncDistributor> vsyncDistributor = nullptr;
55 sptr<VSyncConnection> vsyncConnection = nullptr;
56
57 static inline pid_t pid = 0;
58 static inline int pipeFd[2] = {};
59 static inline int pipe1Fd[2] = {};
60 static inline int32_t systemAbilityID = 345135;
61 };
62
InitNativeTokenInfo()63 static void InitNativeTokenInfo()
64 {
65 #ifdef SUPPORT_ACCESS_TOKEN
66 uint64_t tokenId;
67 const char *perms[2];
68 perms[0] = "ohos.permission.DISTRIBUTED_DATASYNC";
69 perms[1] = "ohos.permission.CAMERA";
70 NativeTokenInfoParams infoInstance = {
71 .dcapsNum = 0,
72 .permsNum = 2,
73 .aclsNum = 0,
74 .dcaps = NULL,
75 .perms = perms,
76 .acls = NULL,
77 .processName = "dcamera_client_demo",
78 .aplStr = "system_basic",
79 };
80 tokenId = GetAccessTokenId(&infoInstance);
81 SetSelfTokenID(tokenId);
82 int32_t ret = Security::AccessToken::AccessTokenKit::ReloadNativeTokenInfo();
83 ASSERT_EQ(ret, Security::AccessToken::RET_SUCCESS);
84 std::this_thread::sleep_for(std::chrono::milliseconds(50)); // wait 50ms
85 #endif
86 }
87
Process1()88 void SetVsyncCallBackForEveryFrameTest::Process1()
89 {
90 #ifdef SUPPORT_ACCESS_TOKEN
91 InitNativeTokenInfo();
92 vsyncGenerator = CreateVSyncGenerator();
93 vsyncSampler = CreateVSyncSampler();
94 int32_t count = 0;
95 int64_t timestamp = 8333333; // 8333333ns
96 while (count <= SAMPLER_NUMBER) {
97 vsyncSampler->AddSample(timestamp);
98 usleep(1000); // 1000us
99 timestamp += 8333333; // 8333333ns
100 count++;
101 }
102 vsyncController = new VSyncController(vsyncGenerator, 0);
103 vsyncDistributor = new VSyncDistributor(vsyncController, "test");
104 vsyncConnection = new VSyncConnection(vsyncDistributor, "test");
105 vsyncDistributor->AddConnection(vsyncConnection);
106 auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
107 sam->AddSystemAbility(systemAbilityID, vsyncConnection);
108 close(pipeFd[1]);
109 close(pipe1Fd[0]);
110 char buf[10] = "start";
111 write(pipe1Fd[1], buf, sizeof(buf));
112 read(pipeFd[0], buf, sizeof(buf));
113 sam->RemoveSystemAbility(systemAbilityID);
114 close(pipeFd[0]);
115 close(pipe1Fd[1]);
116 exit(0);
117 #endif
118 }
119
Process2()120 void SetVsyncCallBackForEveryFrameTest::Process2()
121 {
122 close(pipeFd[0]);
123 close(pipe1Fd[1]);
124 char buf[10];
125 read(pipe1Fd[0], buf, sizeof(buf));
126 auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
127 auto robj = sam->GetSystemAbility(systemAbilityID);
128 std::cout << "(robj==nullptr):" << (robj==nullptr) << std::endl;
129 auto conn = iface_cast<IVSyncConnection>(robj);
130 sptr<VSyncReceiver> receiver = new VSyncReceiver(conn);
131 receiver->Init();
132 VSyncReceiver::FrameCallback fcb = {
133 .userData_ = nullptr,
134 .callback_ = OnVSync,
135 };
136 receiver->SetVsyncCallBackForEveryFrame(fcb, true);
137 usleep(100000); // 100000us
138 EXPECT_GT(g_onVsyncCount, 1);
139 g_onVsyncCount = 0;
140 receiver->SetVsyncCallBackForEveryFrame(fcb, true);
141 usleep(100000); // 100000us
142 receiver->SetVsyncCallBackForEveryFrame(fcb, false);
143 usleep(100000); // 100000us
144 EXPECT_GT(g_onVsyncCount, 1);
145 g_onVsyncCount = 0;
146 usleep(100000); // 100000us
147 EXPECT_EQ(g_onVsyncCount, 0);
148 int64_t period;
149 int64_t timeStamp;
150 EXPECT_EQ(receiver->GetVSyncPeriodAndLastTimeStamp(period, timeStamp), VSYNC_ERROR_OK);
151 }
152
153 /*
154 * Function: SetVsyncCallBackForEveryFrameTest
155 * Type: Function
156 * Rank: Important(2)
157 * EnvConditions: N/A
158 * CaseDescription: SetVsyncCallBackForEveryFrameTest
159 */
160 HWTEST_F(SetVsyncCallBackForEveryFrameTest, SetVsyncCallBackForEveryFrame_Test, Function | MediumTest | Level2)
161 {
162 if (pipe(pipeFd) < 0) {
163 exit(1);
164 }
165 if (pipe(pipe1Fd) < 0) {
166 exit(0);
167 }
168 pid = fork();
169 if (pid < 0) {
170 exit(1);
171 }
172 if (pid != 0) {
173 Process1();
174 } else {
175 Process2();
176 }
177 }
178 }
179