1 /*
2 * Copyright (c) 2025 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 <gtest/gtest.h>
19 #include <iservice_registry.h>
20 #include <surface.h>
21 #include "accesstoken_kit.h"
22 #include "iconsumer_surface.h"
23 #include "nativetoken_kit.h"
24 #include "token_setproc.h"
25 #include "sync_fence.h"
26 #include "external_window.h"
27 #include "native_window.h"
28
29 using namespace testing;
30 using namespace testing::ext;
31
32 namespace OHOS::Rosen {
33 class NativeWindowCleanCacheTest : public testing::Test, public IBufferConsumerListenerClazz {
34 public:
35 static void SetUpTestCase();
36 void OnBufferAvailable() override;
37 OHOS::GSError SetData(sptr<SurfaceBuffer> &buffer, sptr<Surface> &pSurface);
38 bool GetData(sptr<SurfaceBuffer> &buffer);
39 pid_t ChildProcessMain();
40 sptr<OHOS::Surface> CreateSurface();
41
42 static inline sptr<IConsumerSurface> cSurface = nullptr;
43 static inline int32_t pipeFd[2] = {};
44 static inline int32_t ipcSystemAbilityID = 34156;
45 static inline BufferRequestConfig requestConfig = {};
46 static inline BufferFlushConfig flushConfig = {};
47
48 static constexpr const int32_t WAIT_SYSTEM_ABILITY_GET_PRODUCER_TIMES = 1000;
49 };
50
SetUpTestCase()51 void NativeWindowCleanCacheTest::SetUpTestCase()
52 {
53 GTEST_LOG_(INFO) << getpid();
54 requestConfig = {
55 .width = 0x100, // small
56 .height = 0x100, // small
57 .strideAlignment = 0x8,
58 .format = GRAPHIC_PIXEL_FMT_RGBA_8888,
59 .usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA,
60 .timeout = 0,
61 };
62
63 flushConfig = {
64 .damage = {
65 .w = 0x100,
66 .h = 0x100,
67 }
68 };
69 }
70
OnBufferAvailable()71 void NativeWindowCleanCacheTest::OnBufferAvailable()
72 {
73 }
74
OnBufferRelease(sptr<SurfaceBuffer> & buffer)75 static inline GSError OnBufferRelease(sptr<SurfaceBuffer> &buffer)
76 {
77 return GSERROR_OK;
78 }
79
CreateSurface()80 sptr<OHOS::Surface> NativeWindowCleanCacheTest::CreateSurface()
81 {
82 sptr<IRemoteObject> robj = nullptr;
83 int i = 0;
84 while (i++ < WAIT_SYSTEM_ABILITY_GET_PRODUCER_TIMES) {
85 auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
86 robj = sam->GetSystemAbility(ipcSystemAbilityID);
87 if (robj != nullptr) {
88 break;
89 }
90 usleep(1);
91 }
92
93 auto producer = iface_cast<IBufferProducer>(robj);
94 return Surface::CreateSurfaceAsProducer(producer);
95 }
96
ChildProcessMain()97 pid_t NativeWindowCleanCacheTest::ChildProcessMain()
98 {
99 pipe(pipeFd);
100 pid_t pid = fork();
101 if (pid != 0) {
102 return pid;
103 }
104
105 int64_t data;
106 int64_t bufferNum;
107 read(pipeFd[0], &bufferNum, sizeof(bufferNum));
108
109 auto pSurface = CreateSurface();
110 auto nativeWindow = OH_NativeWindow_CreateNativeWindow(&pSurface);
111 int32_t code = SET_BUFFER_GEOMETRY;
112 int32_t height = 0x100;
113 int32_t weight = 0x100;
114 OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, height, weight);
115 code = SET_FORMAT;
116 int32_t format = GRAPHIC_PIXEL_FMT_RGBA_8888;
117 OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, format);
118 pSurface->RegisterReleaseListener(OnBufferRelease);
119
120 struct NativeWindowBuffer *nativeWindowBuffer = nullptr;
121 int32_t sRet;
122 int fenceFd = -1;
123 for (int i = 0; i < bufferNum; i++) {
124 sRet = OH_NativeWindow_NativeWindowRequestBuffer(nativeWindow, &nativeWindowBuffer, &fenceFd);
125 if (sRet != OHOS::GSERROR_OK) {
126 std::cout<<"OH_NativeWindow_NativeWindowRequestBuffer ret:"<<sRet<<std::endl;
127 data = sRet;
128 write(pipeFd[1], &data, sizeof(data));
129 exit(0);
130 }
131 struct Region *region = new Region();
132 struct Region::Rect *rect = new Region::Rect();
133 rect->w = 0x100;
134 rect->h = 0x100;
135 region->rects = rect;
136 region->rectNumber = 1;
137 sRet = OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow, nativeWindowBuffer, -1, *region);
138 if (sRet != OHOS::GSERROR_OK) {
139 std::cout<<"OH_NativeWindow_NativeWindowFlushBuffer ret:"<<sRet<<std::endl;
140 data = sRet;
141 write(pipeFd[1], &data, sizeof(data));
142 exit(0);
143 }
144 }
145 sRet = OH_NativeWindow_CleanCache(nativeWindow);
146
147 data = sRet;
148 write(pipeFd[1], &data, sizeof(data));
149 usleep(1000); // sleep 1000 microseconds (equals 1 milliseconds)
150 read(pipeFd[0], &data, sizeof(data));
151 usleep(1000); // sleep 1000 microseconds (equals 1 milliseconds)
152 pSurface->UnRegisterReleaseListener();
153 close(pipeFd[0]);
154 close(pipeFd[1]);
155 exit(0);
156 return 0;
157 }
158
159 /*
160 * Function: NativeWindowCleanCache
161 * Type: Function
162 * Rank: Important(2)
163 * EnvConditions: N/A
164 * CaseDescription: 1. preSetUp: native window flush 2 buffer
165 * 2. operation: native window clean cache success
166 * 3. result: consumer surface acquire buffer failed and no buffer in cache
167 */
168 HWTEST_F(NativeWindowCleanCacheTest, CleanCache001, Function | MediumTest | Level2)
169 {
170 //生产者生产buffer
171 auto pid = ChildProcessMain();
172 ASSERT_GE(pid, 0);
173
174 uint64_t tokenId;
175 const char *perms[2];
176 perms[0] = "ohos.permission.DISTRIBUTED_DATASYNC";
177 perms[1] = "ohos.permission.CAMERA";
178 NativeTokenInfoParams infoInstance = {
179 .dcapsNum = 0,
180 .permsNum = 2,
181 .aclsNum = 0,
182 .dcaps = NULL,
183 .perms = perms,
184 .acls = NULL,
185 .processName = "dcamera_client_demo",
186 .aplStr = "system_basic",
187 };
188 tokenId = GetAccessTokenId(&infoInstance);
189 SetSelfTokenID(tokenId);
190 int32_t rett = Security::AccessToken::AccessTokenKit::ReloadNativeTokenInfo();
191 ASSERT_EQ(rett, Security::AccessToken::RET_SUCCESS);
192 cSurface = IConsumerSurface::Create("test");
193 cSurface->RegisterConsumerListener(this);
194 auto producer = cSurface->GetProducer();
195 auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
196 sam->AddSystemAbility(ipcSystemAbilityID, producer->AsObject());
197
198 int64_t data = 2;
199 write(pipeFd[1], &data, sizeof(data));
200 usleep(1000); // sleep 1000 microseconds (equals 1 milliseconds)
201 read(pipeFd[0], &data, sizeof(data));
202 EXPECT_EQ(data, OHOS::GSERROR_OK);
203
204 //消费者消费buffer
205 IConsumerSurface::AcquireBufferReturnValue returnValue = {
206 .buffer =nullptr,
207 .fence = new SyncFence(-1),
208 };
209 //Branch1 - No buffer after clean cache
210 auto sRet = cSurface->AcquireBuffer(returnValue, 0, false);
211 EXPECT_EQ(sRet, GSERROR_NO_BUFFER);
212
213
214 //close resource
215 write(pipeFd[1], &data, sizeof(data));
216 close(pipeFd[0]);
217 close(pipeFd[1]);
218 sam->RemoveSystemAbility(ipcSystemAbilityID);
219 int32_t ret = 0;
220 do {
221 waitpid(pid, nullptr, 0);
222 } while (ret == -1 && errno == EINTR);
223 }
224
225 /*
226 * Function: NativeWindowCleanCache
227 * Type: Function
228 * Rank: Important(2)
229 * EnvConditions: N/A
230 * CaseDescription: 1. preSetUp: native window has no connect to comsumer
231 * 2. operation: native window clean cache failed
232 * 3. result: failed and return error code GSERROR_CONSUMER_DISCONNECTED
233 */
234 HWTEST_F(NativeWindowCleanCacheTest, CleanCache002, Function | MediumTest | Level2)
235 {
236 auto cSurface = IConsumerSurface::Create("test");
237 cSurface->RegisterConsumerListener(this);
238 auto producer = cSurface->GetProducer();
239 auto pSurface = Surface::CreateSurfaceAsProducer(producer);
240 NativeWindow* nativeWindow = nullptr;
241 auto ret = OH_NativeWindow_CreateNativeWindowFromSurfaceId(pSurface->GetUniqueId(), &nativeWindow);
242 ret = OH_NativeWindow_CleanCache(nativeWindow);
243
244 ASSERT_EQ(ret, OHOS::GSERROR_CONSUMER_DISCONNECTED);
245 }
246 }
247