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