• 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 
26 using namespace testing;
27 using namespace testing::ext;
28 
29 namespace OHOS::Rosen {
30 class SurfaceIPCWithConnectStrictlyTest : public testing::Test, public IBufferConsumerListenerClazz {
31 public:
32     static void SetUpTestCase();
33     void OnBufferAvailable() override;
34     bool GetData(sptr<SurfaceBuffer> &buffer);
35     pid_t ChildProcessMain();
36     sptr<OHOS::Surface> CreateSurface();
37 
38     static inline sptr<IConsumerSurface> cSurface = nullptr;
39     static inline int32_t pipeRead[2] = {};
40     static inline int32_t pipeWrite[2] = {};
41     static inline int32_t ipcSystemAbilityID = 34156;
42     static inline BufferRequestConfig requestConfig = {};
43     static inline BufferFlushConfig flushConfig = {};
44 };
45 
SetUpTestCase()46 void SurfaceIPCWithConnectStrictlyTest::SetUpTestCase()
47 {
48     GTEST_LOG_(INFO) << getpid();
49     requestConfig = {
50         .width = 0x100,  // small
51         .height = 0x100, // small
52         .strideAlignment = 0x8,
53         .format = GRAPHIC_PIXEL_FMT_RGBA_8888,
54         .usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA,
55         .timeout = 0,
56     };
57     flushConfig = { .damage = {
58         .w = 0x100,
59         .h = 0x100,
60     } };
61 }
62 
OnBufferAvailable()63 void SurfaceIPCWithConnectStrictlyTest::OnBufferAvailable()
64 {
65 }
66 
OnBufferRelease(sptr<SurfaceBuffer> & buffer)67 static inline GSError OnBufferRelease(sptr<SurfaceBuffer> &buffer)
68 {
69     return GSERROR_OK;
70 }
71 
CreateSurface()72 sptr<OHOS::Surface> SurfaceIPCWithConnectStrictlyTest::CreateSurface()
73 {
74     sptr<IRemoteObject> robj = nullptr;
75     while (true) {
76         auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
77         robj = sam->GetSystemAbility(ipcSystemAbilityID);
78         if (robj != nullptr) {
79             break;
80         }
81         sleep(0);
82     }
83 
84     auto producer = iface_cast<IBufferProducer>(robj);
85     return Surface::CreateSurfaceAsProducer(producer);
86 }
87 
ChildProcessMain()88 pid_t SurfaceIPCWithConnectStrictlyTest::ChildProcessMain()
89 {
90     pipe(pipeRead);
91     pipe(pipeWrite);
92     pid_t pid = fork();
93     if (pid != 0) {
94         return pid;
95     }
96 
97     int64_t data;
98     read(pipeRead[0], &data, sizeof(data));
99 
100     auto pSurface = CreateSurface();
101     pSurface->RegisterReleaseListener(OnBufferRelease);
102     int releaseFence = -1;
103 
104     // Branch1: producer Surface Request Buffer failed with GSERROR_CONSUMER_DISCONNECTED after disconnect strictly,
105     //          but producer Surface Request Buffer success after enable connect strictly.
106     pSurface->DisconnectStrictly();
107     pSurface->Disconnect();
108     sptr<SurfaceBuffer> buffer1 = nullptr;
109     auto sRet = pSurface->RequestBuffer(buffer1, releaseFence, requestConfig);
110     EXPECT_EQ(sRet, OHOS::GSERROR_CONSUMER_DISCONNECTED);
111     pSurface->ConnectStrictly();
112     sRet = pSurface->RequestBuffer(buffer1, releaseFence, requestConfig);
113     EXPECT_EQ(sRet, OHOS::GSERROR_OK);
114     sRet = pSurface->FlushBuffer(buffer1, -1, flushConfig);
115     EXPECT_EQ(sRet, OHOS::GSERROR_OK);
116     data = sRet;
117     write(pipeWrite[1], &data, sizeof(data));
118     read(pipeRead[0], &data, sizeof(data));
119 
120     // Branch2: producer request buffer success when ConnectStricyly(), flush buffer failed with
121     //          GSERROR_CONSUMER_DISCONNECTED after disconnect strictly, but producer flush buffer success after
122     //          connect strictly.
123 
124     sptr<SurfaceBuffer> buffer2 = nullptr;
125     pSurface->ConnectStrictly();
126     sRet = pSurface->RequestBuffer(buffer2, releaseFence, requestConfig);
127     EXPECT_EQ(sRet, OHOS::GSERROR_OK);
128     pSurface->DisconnectStrictly();
129     sRet = pSurface->FlushBuffer(buffer2, -1, flushConfig);
130     EXPECT_EQ(sRet, OHOS::GSERROR_CONSUMER_DISCONNECTED);
131     pSurface->ConnectStrictly();
132     sRet = pSurface->FlushBuffer(buffer2, -1, flushConfig);
133     EXPECT_EQ(sRet, OHOS::GSERROR_OK);
134     data = sRet;
135     write(pipeWrite[1], &data, sizeof(data));
136     read(pipeRead[0], &data, sizeof(data));
137 
138     write(pipeWrite[1], &data, sizeof(data));
139     usleep(1000); // sleep 1000 microseconds (equals 1 milliseconds)
140     read(pipeRead[0], &data, sizeof(data));
141     usleep(1000); // sleep 1000 microseconds (equals 1 milliseconds)
142     pSurface->UnRegisterReleaseListener();
143     close(pipeRead[0]);
144     close(pipeRead[1]);
145     close(pipeWrite[0]);
146     close(pipeWrite[1]);
147     exit(0);
148     return 0;
149 }
150 
151 /*
152 * Function: produce and consumer surface by IPC
153 * Type: Function
154 * Rank: Important(2)
155 * EnvConditions: N/A
156 * Case1Description:
157 *         Branch1: 1. PreSet: create producer surface and disconnect strictly
158 *                   2. Operation: the producer failed to request buffer with error code GSERROR_CONSUMER_DISCONNECTED,
159 *                                 but succeeded after being connected strictly.
160 *         Branch2:  1. PreSet: producer connect strictly on request buffer and disconnect strictly to flush buffer
161 *                   2. Operation: the producer failed to flush buffer with error code GSERROR_CONSUMER_DISCONNECTED,
162 *                                 but succeeded after being connected strictly.
163 */
164 HWTEST_F(SurfaceIPCWithConnectStrictlyTest, BufferIPC001, TestSize.Level0)
165 {
166     auto pid = ChildProcessMain();
167     ASSERT_GE(pid, 0);
168 
169     uint64_t tokenId;
170     const char *perms[2];
171     perms[0] = "ohos.permission.DISTRIBUTED_DATASYNC";
172     perms[1] = "ohos.permission.CAMERA";
173     NativeTokenInfoParams infoInstance = {
174         .dcapsNum = 0,
175         .permsNum = 2,
176         .aclsNum = 0,
177         .dcaps = NULL,
178         .perms = perms,
179         .acls = NULL,
180         .processName = "dcamera_client_demo",
181         .aplStr = "system_basic",
182     };
183     tokenId = GetAccessTokenId(&infoInstance);
184     SetSelfTokenID(tokenId);
185     int32_t rett = Security::AccessToken::AccessTokenKit::ReloadNativeTokenInfo();
186     ASSERT_EQ(rett, Security::AccessToken::RET_SUCCESS);
187     cSurface = IConsumerSurface::Create("test");
188     cSurface->RegisterConsumerListener(this);
189     auto producer = cSurface->GetProducer();
190     auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
191     sam->AddSystemAbility(ipcSystemAbilityID, producer->AsObject());
192 
193     int64_t data = 0;
194     write(pipeRead[1], &data, sizeof(data));
195     read(pipeWrite[0], &data, sizeof(data));
196     EXPECT_EQ(data, OHOS::GSERROR_OK);
197 
198     // requested 3 buffer in 3 branch
199     for (int i = 0 ; i < 2 ; i++) {
200         sptr<SurfaceBuffer> buffer = nullptr;
201         int32_t fence = -1;
202         int64_t timestamp;
203         Rect damage;
204         auto sRet = cSurface->AcquireBuffer(buffer, fence, timestamp, damage);
205         EXPECT_EQ(sRet, OHOS::GSERROR_OK);
206         EXPECT_NE(buffer, nullptr);
207         write(pipeRead[1], &data, sizeof(data));
208         read(pipeWrite[0], &data, sizeof(data));
209         EXPECT_EQ(data, OHOS::GSERROR_OK);
210     }
211 
212     //close resource
213     write(pipeRead[1], &data, sizeof(data));
214     close(pipeRead[0]);
215     close(pipeRead[1]);
216     close(pipeWrite[0]);
217     close(pipeWrite[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