• 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 <gtest/gtest.h>
19 #include <iservice_registry.h>
20 #include <securec.h>
21 #include <native_window.h>
22 #include "accesstoken_kit.h"
23 #include "nativetoken_kit.h"
24 #include "token_setproc.h"
25 #include "external_window.h"
26 #include "iconsumer_surface.h"
27 
28 using namespace testing;
29 using namespace testing::ext;
30 
31 namespace OHOS::Rosen {
32 class NativeWindowBufferTest : public testing::Test,  public IBufferConsumerListenerClazz {
33 public:
34     static void SetUpTestCase();
35     void OnBufferAvailable() override;
36     int32_t SetData(NativeWindowBuffer *nativeWindowBuffer, NativeWindow *nativeWindow);
37     bool GetData(sptr<SurfaceBuffer> &buffer);
38     pid_t ChildProcessMain();
39     int32_t InitNativeWindowAndBuffer(sptr<IRemoteObject> robj);
40 
41     static inline sptr<OHOS::IConsumerSurface> cSurface = nullptr;
42     static inline int32_t pipeMain[2] = {};
43     static inline int32_t pipeChild[2] = {};
44     static inline int32_t ipcSystemAbilityID = 34156;
45 };
46 
SetUpTestCase()47 void NativeWindowBufferTest::SetUpTestCase() {}
48 
OnBufferAvailable()49 void NativeWindowBufferTest::OnBufferAvailable() {}
50 
SetData(NativeWindowBuffer * nativeWindowBuffer,NativeWindow * nativeWindow)51 int32_t NativeWindowBufferTest::SetData(NativeWindowBuffer *nativeWindowBuffer, NativeWindow *nativeWindow)
52 {
53     nativeWindowBuffer->sfbuffer->GetExtraData()->ExtraSet("123", 0x123);
54     nativeWindowBuffer->sfbuffer->GetExtraData()->ExtraSet("345", (int64_t)0x345);
55     nativeWindowBuffer->sfbuffer->GetExtraData()->ExtraSet("567", "567");
56 
57     // alloc OHExtDataHandle
58     uint32_t reserveInts = 1;
59     size_t handleSize = sizeof(OHExtDataHandle) + (sizeof(int32_t) * reserveInts);
60     OHExtDataHandle *handle = static_cast<OHExtDataHandle *>(malloc(handleSize));
61     if (handle == nullptr) {
62         return -1;
63     }
64     int32_t ret = memset_s(handle, handleSize, 0, handleSize);
65     if (ret != EOK) {
66         free(handle);
67         return -1;
68     }
69     handle->fd = -1;
70     handle->reserveInts = reserveInts;
71     for (uint32_t i = 0; i < reserveInts; i++) {
72         handle->reserve[i] = 1;
73     }
74 
75     ret = OH_NativeWindow_NativeWindowSetTunnelHandle(nativeWindow, handle);
76     // free OHExtDataHandle
77     if (handle->fd >= 0) {
78         close(handle->fd);
79         handle->fd = -1;
80     }
81     free(handle);
82     handle = nullptr;
83     return ret;
84 }
85 
GetData(sptr<SurfaceBuffer> & buffer)86 bool NativeWindowBufferTest::GetData(sptr<SurfaceBuffer> &buffer)
87 {
88     int32_t int32;
89     int64_t int64;
90     std::string str;
91     buffer->GetExtraData()->ExtraGet("123", int32);
92     buffer->GetExtraData()->ExtraGet("345", int64);
93     buffer->GetExtraData()->ExtraGet("567", str);
94     if ((int32 != 0x123) || (int64 != 0x345) || (str != "567")) {
95         return false;
96     }
97 
98     sptr<SurfaceTunnelHandle> handleGet = nullptr;
99     handleGet = cSurface->GetTunnelHandle();
100     if ((handleGet == nullptr) || (handleGet->GetHandle()->fd != -1) ||
101         (handleGet->GetHandle()->reserveInts != 1) || (handleGet->GetHandle()->reserve[0] != 1)) {
102             return false;
103     }
104     return true;
105 }
106 
InitNativeWindowAndBuffer(sptr<IRemoteObject> robj)107 int32_t NativeWindowBufferTest::InitNativeWindowAndBuffer(sptr<IRemoteObject> robj)
108 {
109     auto producer = iface_cast<IBufferProducer>(robj);
110     sptr<Surface> pSurface = Surface::CreateSurfaceAsProducer(producer);
111 
112     struct NativeWindow *nativeWindow = OH_NativeWindow_CreateNativeWindow(&pSurface);
113     struct NativeWindowBuffer *nativeWindowBuffer = nullptr;
114 
115     int code = SET_USAGE;
116     uint64_t usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA;
117     OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, usage);
118 
119     code = SET_BUFFER_GEOMETRY;
120     int32_t height = 0x100;
121     int32_t width = 0x100;
122     OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, height, width);
123 
124     code = SET_FORMAT;
125     int32_t format = GRAPHIC_PIXEL_FMT_RGBA_8888;
126     OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, format);
127 
128     code = SET_STRIDE;
129     int32_t stride = 0x8;
130     OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, stride);
131 
132     int32_t fenceFd = -1;
133     auto ret = OH_NativeWindow_NativeWindowRequestBuffer(nativeWindow, &nativeWindowBuffer, &fenceFd);
134     if (ret != OHOS::GSERROR_OK) {
135         return ret;
136     }
137     ret = SetData(nativeWindowBuffer, nativeWindow);
138     if (ret != OHOS::GSERROR_OK) {
139         return ret;
140     }
141 
142     struct Region *region = new Region();
143     struct Region::Rect *rect = new Region::Rect();
144     rect->w = 0x100;
145     rect->h = 0x100;
146     region->rects = rect;
147     region->rectNumber = 1;
148     ret = OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow, nativeWindowBuffer, -1, *region);
149     if (ret != OHOS::GSERROR_OK) {
150         delete rect;
151         delete region;
152         return ret;
153     }
154     delete rect;
155     delete region;
156     return OHOS::GSERROR_OK;
157 }
158 
ChildProcessMain()159 pid_t NativeWindowBufferTest::ChildProcessMain()
160 {
161     pipe(pipeMain);
162     pipe(pipeChild);
163     pid_t pid = fork();
164     if (pid != 0) {
165         return pid;
166     }
167 
168     int64_t data;
169     read(pipeMain[0], &data, sizeof(data));
170 
171     sptr<IRemoteObject> robj = nullptr;
172     while (true) {
173         auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
174         robj = sam->GetSystemAbility(ipcSystemAbilityID);
175         if (robj != nullptr) {
176             break;
177         }
178         sleep(0);
179     }
180     int32_t ret = InitNativeWindowAndBuffer(robj);
181     if (ret != OHOS::GSERROR_OK) {
182         data = ret;
183         write(pipeChild[1], &data, sizeof(data));
184         exit(0);
185         return -1;
186     }
187 
188     data = ret;
189     write(pipeChild[1], &data, sizeof(data));
190     usleep(1000); // sleep 1000 microseconds (equals 1 milliseconds)
191     read(pipeMain[0], &data, sizeof(data));
192     close(pipeMain[0]);
193     close(pipeMain[1]);
194     close(pipeChild[0]);
195     close(pipeChild[1]);
196     exit(0);
197     return 0;
198 }
199 
200 /*
201 * Function: produce and consumer surface of nativewindow
202 * Type: Function
203 * Rank: Important(2)
204 * EnvConditions: N/A
205 * CaseDescription: 1. produce surface by nativewindow interface, fill buffer
206 *                  2. consume surface and check buffer
207 * @tc.require: issueI5GMZN issueI5IWHW
208  */
209 HWTEST_F(NativeWindowBufferTest, Surface001, TestSize.Level0)
210 {
211     auto pid = ChildProcessMain();
212     ASSERT_GE(pid, 0);
213 
214     uint64_t tokenId;
215     const char *perms[2];
216     perms[0] = "ohos.permission.DISTRIBUTED_DATASYNC";
217     perms[1] = "ohos.permission.CAMERA";
218     NativeTokenInfoParams infoInstance = {
219         .dcapsNum = 0,
220         .permsNum = 2,
221         .aclsNum = 0,
222         .dcaps = NULL,
223         .perms = perms,
224         .acls = NULL,
225         .processName = "dcamera_client_demo",
226         .aplStr = "system_basic",
227     };
228     tokenId = GetAccessTokenId(&infoInstance);
229     SetSelfTokenID(tokenId);
230     int32_t rett = Security::AccessToken::AccessTokenKit::ReloadNativeTokenInfo();
231     ASSERT_EQ(rett, Security::AccessToken::RET_SUCCESS);
232 
233     cSurface = IConsumerSurface::Create("test");
234     cSurface->RegisterConsumerListener(this);
235     auto producer = cSurface->GetProducer();
236     auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
237     sam->AddSystemAbility(ipcSystemAbilityID, producer->AsObject());
238 
239     int64_t data = 0;
240     write(pipeMain[1], &data, sizeof(data));
241     usleep(1000); // sleep 1000 microseconds (equals 1 milliseconds)
242     read(pipeChild[0], &data, sizeof(data));
243     EXPECT_EQ(data, OHOS::GSERROR_OK);
244 
245     OHOS::sptr<SurfaceBuffer> buffer = nullptr;
246     int32_t fence = -1;
247     int64_t timestamp;
248     Rect damage;
249     auto ret = cSurface->AcquireBuffer(buffer, fence, timestamp, damage);
250     EXPECT_EQ(ret, OHOS::GSERROR_OK);
251     EXPECT_NE(buffer, nullptr);
252     EXPECT_EQ(GetData(buffer), true);
253 
254     ret = cSurface->ReleaseBuffer(buffer, -1);
255     EXPECT_EQ(ret, OHOS::GSERROR_OK);
256 
257     write(pipeMain[1], &data, sizeof(data));
258     close(pipeMain[0]);
259     close(pipeMain[1]);
260     close(pipeChild[0]);
261     close(pipeChild[1]);
262     sam->RemoveSystemAbility(ipcSystemAbilityID);
263     waitpid(pid, nullptr, 0);
264 }
265 }