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