• 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 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