• 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 #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 SOFT_VSYNC_PERIOD = 16;
39 constexpr int32_t SAMPLER_NUMBER = 6;
OnVSyncApp(int64_t time,void * data)40 static void OnVSyncApp(int64_t time, void *data)
41 {
42     std::cout << "OnVSyncApp in\n";
43     appVSyncFlag = 1;
44 }
45 }
46 class VSyncTest : public testing::Test {
47 public:
48     static void SetUpTestCase();
49     static void TearDownTestCase();
50     void SetUp();
51     void TearDown();
52     pid_t ChildProcessMain();
53     static void ThreadMain();
54 
55     sptr<VSyncController> appController = nullptr;
56     sptr<VSyncController> rsController = nullptr;
57     sptr<VSyncDistributor> appDistributor = nullptr;
58     sptr<VSyncDistributor> rsDistributor = nullptr;
59     sptr<VSyncGenerator> vsyncGenerator = nullptr;
60     static inline sptr<VSyncSampler> vsyncSampler = nullptr;
61     std::thread samplerThread;
62 
63     static inline int32_t pipeFd[2] = {};
64     static inline int32_t ipcSystemAbilityID = 34156;
65 };
66 
SetUpTestCase()67 void VSyncTest::SetUpTestCase()
68 {
69     vsyncSampler = CreateVSyncSampler();
70 }
71 
TearDownTestCase()72 void VSyncTest::TearDownTestCase()
73 {
74     vsyncSampler = nullptr;
75 }
76 
SetUp()77 void VSyncTest::SetUp()
78 {
79     vsyncGenerator = CreateVSyncGenerator();
80     appController = new VSyncController(vsyncGenerator, 0);
81     rsController = new VSyncController(vsyncGenerator, 0);
82 
83     appDistributor = new VSyncDistributor(appController, "appController");
84     rsDistributor = new VSyncDistributor(rsController, "rsController");
85 
86     samplerThread = std::thread(std::bind(&VSyncTest::ThreadMain));
87     samplerThread.join();
88 }
89 
TearDown()90 void VSyncTest::TearDown()
91 {
92     vsyncGenerator = nullptr;
93     appController = nullptr;
94     rsController = nullptr;
95     appDistributor = nullptr;
96     rsDistributor = nullptr;
97 
98     if (samplerThread.joinable()) {
99         samplerThread.join();
100     }
101 }
102 
ChildProcessMain()103 pid_t VSyncTest::ChildProcessMain()
104 {
105     std::cout << "ChildProcessMain in\n";
106     pipe(pipeFd);
107     pid_t pid = fork();
108     if (pid != 0) {
109         return pid;
110     }
111 
112     sptr<IRemoteObject> robj = nullptr;
113     while (true) {
114         auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
115         robj = sam->GetSystemAbility(ipcSystemAbilityID);
116         if (robj != nullptr) {
117             break;
118         }
119         sleep(0);
120     }
121 
122     auto conn = iface_cast<IVSyncConnection>(robj);
123     sptr<VSyncReceiver> receiver = new VSyncReceiver(conn);
124     receiver->Init();
125 
126     VSyncReceiver::FrameCallback fcb = {
127         .userData_ = nullptr,
128         .callback_ = OnVSyncApp,
129     };
130     std::cout << "RequestNextVSync\n";
131     receiver->RequestNextVSync(fcb);
132     while (appVSyncFlag == 0) {
133         sleep(1);
134         std::cout << "ChildProcessMain appVSyncFlag is " << appVSyncFlag << std::endl;
135     }
136     EXPECT_EQ(appVSyncFlag, 1);
137     int64_t period;
138     int64_t timeStamp;
139     EXPECT_EQ(receiver->GetVSyncPeriodAndLastTimeStamp(period, timeStamp), VSYNC_ERROR_OK);
140     std::cout << "period =  " << period << ",timeStamp = " << timeStamp << std::endl;
141     write(pipeFd[1], &appVSyncFlag, sizeof(appVSyncFlag));
142     close(pipeFd[0]);
143     close(pipeFd[1]);
144     exit(0);
145     return 0;
146 }
147 
ThreadMain()148 void VSyncTest::ThreadMain()
149 {
150     bool ret = true;
151     std::condition_variable con;
152     std::mutex mtx;
153     std::unique_lock<std::mutex> locker(mtx);
154     int32_t count = 0;
155     while (count <= SAMPLER_NUMBER) {
156         const auto &now = std::chrono::steady_clock::now().time_since_epoch();
157         int64_t timestamp = std::chrono::duration_cast<std::chrono::nanoseconds>(now).count();
158         ret = vsyncSampler->AddSample(timestamp);
159         con.wait_for(locker, std::chrono::milliseconds(SOFT_VSYNC_PERIOD));
160         count++;
161     }
162 }
163 
164 /*
165 * Function: RequestNextVSync001
166 * Type: Function
167 * Rank: Important(2)
168 * EnvConditions: N/A
169 * CaseDescription: 1. RequestNextVSync by IPC
170  */
171 HWTEST_F(VSyncTest, RequestNextVSync001, Function | MediumTest | Level2)
172 {
173     auto pid = ChildProcessMain();
174     ASSERT_GE(pid, 0);
175 
176     uint64_t tokenId;
177     const char *perms[2];
178     perms[0] = "ohos.permission.DISTRIBUTED_DATASYNC";
179     perms[1] = "ohos.permission.CAMERA";
180     NativeTokenInfoParams infoInstance = {
181         .dcapsNum = 0,
182         .permsNum = 2,
183         .aclsNum = 0,
184         .dcaps = NULL,
185         .perms = perms,
186         .acls = NULL,
187         .processName = "dcamera_client_demo",
188         .aplStr = "system_basic",
189     };
190     tokenId = GetAccessTokenId(&infoInstance);
191     SetSelfTokenID(tokenId);
192     int32_t ret = Security::AccessToken::AccessTokenKit::ReloadNativeTokenInfo();
193     ASSERT_EQ(ret, Security::AccessToken::RET_SUCCESS);
194 
195     sptr<VSyncConnection> connServer = new VSyncConnection(appDistributor, "app");
196     appDistributor->AddConnection(connServer);
197     auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
198     sam->AddSystemAbility(ipcSystemAbilityID, connServer->AsObject());
199     read(pipeFd[0], &appVSyncFlag, sizeof(appVSyncFlag));
200     while (appVSyncFlag == 0) {
201         std::cout << "RequestNextVSync001 appVSyncFlag is " << appVSyncFlag << std::endl;
202     }
203     close(pipeFd[0]);
204     close(pipeFd[1]);
205     sam->RemoveSystemAbility(ipcSystemAbilityID);
206     waitpid(pid, nullptr, 0);
207 }
208 }
209