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