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