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