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