• 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 }
88 
TearDown()89 void VSyncTest::TearDown()
90 {
91     vsyncGenerator = nullptr;
92     appController = nullptr;
93     rsController = nullptr;
94     appDistributor = nullptr;
95     rsDistributor = nullptr;
96 
97     if (samplerThread.joinable()) {
98         samplerThread.join();
99     }
100 }
101 
ChildProcessMain()102 pid_t VSyncTest::ChildProcessMain()
103 {
104     std::cout << "ChildProcessMain in\n";
105     pipe(pipeFd);
106     pid_t pid = fork();
107     if (pid != 0) {
108         return pid;
109     }
110 
111     sptr<IRemoteObject> robj = nullptr;
112     while (true) {
113         auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
114         robj = sam->GetSystemAbility(ipcSystemAbilityID);
115         if (robj != nullptr) {
116             break;
117         }
118         sleep(0);
119     }
120 
121     auto conn = iface_cast<IVSyncConnection>(robj);
122     sptr<VSyncReceiver> receiver = new VSyncReceiver(conn);
123     receiver->Init();
124 
125     VSyncReceiver::FrameCallback fcb = {
126         .userData_ = nullptr,
127         .callback_ = OnVSyncApp,
128     };
129     std::cout << "RequestNextVSync\n";
130     receiver->RequestNextVSync(fcb);
131     while (appVSyncFlag == 0) {
132         sleep(1);
133         std::cout << "ChildProcessMain appVSyncFlag is " << appVSyncFlag << std::endl;
134     }
135     EXPECT_EQ(appVSyncFlag, 1);
136     write(pipeFd[1], &appVSyncFlag, sizeof(appVSyncFlag));
137     close(pipeFd[0]);
138     close(pipeFd[1]);
139     exit(0);
140     return 0;
141 }
142 
ThreadMain()143 void VSyncTest::ThreadMain()
144 {
145     bool ret = true;
146     std::condition_variable con;
147     std::mutex mtx;
148     std::unique_lock<std::mutex> locker(mtx);
149     int32_t count = 0;
150     while (count <= SAMPLER_NUMBER) {
151         const auto &now = std::chrono::steady_clock::now().time_since_epoch();
152         int64_t timestamp = std::chrono::duration_cast<std::chrono::nanoseconds>(now).count();
153         ret = vsyncSampler->AddSample(timestamp);
154         con.wait_for(locker, std::chrono::milliseconds(SOFT_VSYNC_PERIOD));
155         count++;
156     }
157 }
158 
159 /*
160 * Function: RequestNextVSync001
161 * Type: Function
162 * Rank: Important(2)
163 * EnvConditions: N/A
164 * CaseDescription: 1. RequestNextVSync by IPC
165  */
166 HWTEST_F(VSyncTest, RequestNextVSync001, Function | MediumTest | Level2)
167 {
168     auto pid = ChildProcessMain();
169     ASSERT_GE(pid, 0);
170 
171     uint64_t tokenId;
172     const char *perms[2];
173     perms[0] = "ohos.permission.DISTRIBUTED_DATASYNC";
174     perms[1] = "ohos.permission.CAMERA";
175     NativeTokenInfoParams infoInstance = {
176         .dcapsNum = 0,
177         .permsNum = 2,
178         .aclsNum = 0,
179         .dcaps = NULL,
180         .perms = perms,
181         .acls = NULL,
182         .processName = "dcamera_client_demo",
183         .aplStr = "system_basic",
184     };
185     tokenId = GetAccessTokenId(&infoInstance);
186     SetSelfTokenID(tokenId);
187     int32_t ret = Security::AccessToken::AccessTokenKit::ReloadNativeTokenInfo();
188     ASSERT_EQ(ret, Security::AccessToken::RET_SUCCESS);
189 
190     sptr<VSyncConnection> connServer = new VSyncConnection(appDistributor, "app");
191     appDistributor->AddConnection(connServer);
192     auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
193     sam->AddSystemAbility(ipcSystemAbilityID, connServer->AsObject());
194     read(pipeFd[0], &appVSyncFlag, sizeof(appVSyncFlag));
195     while (appVSyncFlag == 0) {
196         std::cout << "RequestNextVSync001 appVSyncFlag is " << appVSyncFlag << std::endl;
197     }
198     close(pipeFd[0]);
199     close(pipeFd[1]);
200     sam->RemoveSystemAbility(ipcSystemAbilityID);
201     waitpid(pid, nullptr, 0);
202 }
203 }
204