1 /*
2 * Copyright (C) 2023 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
16 #include "screen_capture_capi_mock.h"
17 #include "native_mfmagic.h"
18 #include "native_window.h"
19
20 using namespace std;
21 using namespace OHOS;
22 using namespace OHOS::Media;
23 using namespace testing::ext;
24 using namespace OHOS::Media::ScreenCaptureTestParam;
25 std::mutex ScreenCaptureCapiMock::mutex_;
26 std::map<OH_AVScreenCapture *, std::shared_ptr<ScreenCaptureCallBackMock>> ScreenCaptureCapiMock::mockCbMap_;
27
28 typedef struct NativeWindow OHNativeWindow;
29
OnError(OH_AVScreenCapture * screenCapture,int32_t errorCode)30 void ScreenCaptureCapiMock::OnError(OH_AVScreenCapture *screenCapture, int32_t errorCode)
31 {
32 std::shared_ptr<ScreenCaptureCallBackMock> mockCb = GetCallback(screenCapture);
33 if (mockCb != nullptr) {
34 mockCb->OnError(errorCode);
35 }
36 }
37
OnAudioBufferAvailable(OH_AVScreenCapture * screenCapture,bool isReady,OH_AudioCaptureSourceType type)38 void ScreenCaptureCapiMock::OnAudioBufferAvailable(OH_AVScreenCapture *screenCapture, bool isReady,
39 OH_AudioCaptureSourceType type)
40 {
41 std::shared_ptr<ScreenCaptureCallBackMock> mockCb = GetCallback(screenCapture);
42 if (mockCb != nullptr) {
43 mockCb->OnAudioBufferAvailable(isReady, static_cast<AudioCaptureSourceType>(type));
44 }
45 }
46
OnVideoBufferAvailable(OH_AVScreenCapture * screenCapture,bool isReady)47 void ScreenCaptureCapiMock::OnVideoBufferAvailable(OH_AVScreenCapture *screenCapture, bool isReady)
48 {
49 std::shared_ptr<ScreenCaptureCallBackMock> mockCb = GetCallback(screenCapture);
50 if (mockCb != nullptr) {
51 mockCb->OnVideoBufferAvailable(isReady);
52 }
53 }
54
OnErrorNew(OH_AVScreenCapture * screenCapture,int32_t errorCode,void * userData)55 void ScreenCaptureCapiMock::OnErrorNew(OH_AVScreenCapture *screenCapture, int32_t errorCode, void *userData)
56 {
57 std::shared_ptr<ScreenCaptureCallBackMock> mockCb = GetCallback(screenCapture);
58 if (mockCb != nullptr) {
59 mockCb->OnError(errorCode, userData);
60 }
61 }
62
OnBufferAvailable(OH_AVScreenCapture * screenCapture,OH_AVBuffer * buffer,OH_AVScreenCaptureBufferType bufferType,int64_t timestamp,void * userData)63 void ScreenCaptureCapiMock::OnBufferAvailable(OH_AVScreenCapture *screenCapture, OH_AVBuffer *buffer,
64 OH_AVScreenCaptureBufferType bufferType, int64_t timestamp, void *userData)
65 {
66 UNITTEST_CHECK_AND_RETURN_LOG(buffer != nullptr, "OH_AVBuffer buffer == nullptr");
67 std::shared_ptr<ScreenCaptureCallBackMock> mockCb = GetCallback(screenCapture);
68 if (mockCb != nullptr) {
69 mockCb->OnBufferAvailable(buffer->buffer_, static_cast<AVScreenCaptureBufferType>(bufferType), timestamp);
70 }
71 }
72
OnStateChange(OH_AVScreenCapture * screenCapture,OH_AVScreenCaptureStateCode stateCode,void * userData)73 void ScreenCaptureCapiMock::OnStateChange(OH_AVScreenCapture *screenCapture,
74 OH_AVScreenCaptureStateCode stateCode, void *userData)
75 {
76 std::shared_ptr<ScreenCaptureCallBackMock> mockCb = GetCallback(screenCapture);
77 if (mockCb != nullptr) {
78 mockCb->OnStateChange(static_cast<AVScreenCaptureStateCode>(stateCode));
79 }
80 }
81
Convert(AVScreenCaptureConfig config)82 OH_AVScreenCaptureConfig ScreenCaptureCapiMock::Convert(AVScreenCaptureConfig config)
83 {
84 OH_AVScreenCaptureConfig tempConfig;
85 tempConfig.captureMode = static_cast<OH_CaptureMode>(config.captureMode);
86 tempConfig.dataType = static_cast<OH_DataType>(config.dataType);
87 tempConfig.audioInfo.micCapInfo = {
88 .audioSampleRate = config.audioInfo.micCapInfo.audioSampleRate,
89 .audioChannels = config.audioInfo.micCapInfo.audioChannels,
90 .audioSource = static_cast<OH_AudioCaptureSourceType>(config.audioInfo.micCapInfo.audioSource)
91 };
92 tempConfig.audioInfo.innerCapInfo = {
93 .audioSampleRate = config.audioInfo.innerCapInfo.audioSampleRate,
94 .audioChannels = config.audioInfo.innerCapInfo.audioChannels,
95 .audioSource = static_cast<OH_AudioCaptureSourceType>(config.audioInfo.innerCapInfo.audioSource)
96 };
97 tempConfig.audioInfo.audioEncInfo.audioBitrate = config.audioInfo.audioEncInfo.audioBitrate;
98 tempConfig.audioInfo.audioEncInfo.audioCodecformat =
99 static_cast<OH_AudioCodecFormat>(config.audioInfo.audioEncInfo.audioCodecformat);
100 tempConfig.videoInfo.videoCapInfo.displayId = config.videoInfo.videoCapInfo.displayId;
101 std::list<int32_t> taskIds = config.videoInfo.videoCapInfo.taskIDs;
102 if (taskIds.size() > 0) {
103 int32_t *taskIds_temp = static_cast<int*>(malloc(sizeof(int)));
104 for (std::list<int32_t>::iterator its = taskIds.begin(); its != taskIds.end(); ++its) {
105 *taskIds_temp = *its;
106 taskIds_temp++;
107 }
108 tempConfig.videoInfo.videoCapInfo.missionIDs = taskIds_temp;
109 }
110 tempConfig.videoInfo.videoCapInfo.missionIDsLen = taskIds.size();
111 tempConfig.videoInfo.videoCapInfo.videoFrameWidth = config.videoInfo.videoCapInfo.videoFrameWidth;
112 tempConfig.videoInfo.videoCapInfo.videoFrameHeight = config.videoInfo.videoCapInfo.videoFrameHeight;
113 tempConfig.videoInfo.videoCapInfo.videoSource =
114 static_cast<OH_VideoSourceType>(config.videoInfo.videoCapInfo.videoSource);
115 tempConfig.videoInfo.videoEncInfo = {
116 .videoCodec = static_cast<OH_VideoCodecFormat>(config.videoInfo.videoEncInfo.videoCodec),
117 .videoBitrate = static_cast<OH_VideoCodecFormat>(config.videoInfo.videoEncInfo.videoBitrate),
118 .videoFrameRate = static_cast<OH_VideoCodecFormat>(config.videoInfo.videoEncInfo.videoFrameRate)
119 };
120 std::string url = config.recorderInfo.url;
121 if (!(url.empty())) {
122 tempConfig.recorderInfo.url = const_cast<char *>(config.recorderInfo.url.c_str());
123 tempConfig.recorderInfo.urlLen = config.recorderInfo.url.size();
124 }
125 if (config.recorderInfo.fileFormat == ContainerFormatType::CFT_MPEG_4A) {
126 tempConfig.recorderInfo.fileFormat = OH_ContainerFormatType::CFT_MPEG_4A;
127 } else if (config.recorderInfo.fileFormat == ContainerFormatType::CFT_MPEG_4) {
128 tempConfig.recorderInfo.fileFormat = OH_ContainerFormatType::CFT_MPEG_4;
129 }
130 return tempConfig;
131 }
132
GetCallback(OH_AVScreenCapture * screenCapture)133 std::shared_ptr<ScreenCaptureCallBackMock> ScreenCaptureCapiMock::GetCallback(OH_AVScreenCapture *screenCapture)
134 {
135 std::lock_guard<std::mutex> lock(mutex_);
136 if (mockCbMap_.empty()) {
137 return nullptr;
138 }
139 if (mockCbMap_.find(screenCapture) != mockCbMap_.end()) {
140 return mockCbMap_.at(screenCapture);
141 }
142 return nullptr;
143 }
144
DelCallback(OH_AVScreenCapture * screenCapture)145 void ScreenCaptureCapiMock::DelCallback(OH_AVScreenCapture *screenCapture)
146 {
147 std::lock_guard<std::mutex> lock(mutex_);
148 if (mockCbMap_.empty()) {
149 return;
150 }
151 auto it = mockCbMap_.find(screenCapture);
152 if (it != mockCbMap_.end()) {
153 mockCbMap_.erase(it);
154 }
155 }
156
SetScreenCaptureCallback(OH_AVScreenCapture * screencapture,std::shared_ptr<ScreenCaptureCallBackMock> cb)157 void ScreenCaptureCapiMock::SetScreenCaptureCallback(OH_AVScreenCapture *screencapture,
158 std::shared_ptr<ScreenCaptureCallBackMock> cb)
159 {
160 std::lock_guard<std::mutex> lock(mutex_);
161 mockCbMap_[screencapture] = cb;
162 }
163
SetScreenCaptureCallback(const std::shared_ptr<ScreenCaptureCallBackMock> & callback,const bool isErrorCallBackEnabled,const bool isDataCallBackEnabled,const bool isStateChangeCallBackEnabled)164 int32_t ScreenCaptureCapiMock::SetScreenCaptureCallback(const std::shared_ptr<ScreenCaptureCallBackMock>& callback,
165 const bool isErrorCallBackEnabled, const bool isDataCallBackEnabled, const bool isStateChangeCallBackEnabled)
166 {
167 UNITTEST_CHECK_AND_RETURN_RET_LOG(screenCapture_ != nullptr, MSERR_INVALID_OPERATION, "screenCapture_ == nullptr");
168 if (callback == nullptr) {
169 return MSERR_INVALID_OPERATION;
170 }
171 MEDIA_LOGD("ScreenCaptureCapiMock SetScreenCaptureCallback");
172 SetScreenCaptureCallback(screenCapture_, callback);
173 struct OH_AVScreenCaptureCallback ohCallback;
174 ohCallback.onError = ScreenCaptureCapiMock::OnError;
175 ohCallback.onAudioBufferAvailable = ScreenCaptureCapiMock::OnAudioBufferAvailable;
176 ohCallback.onVideoBufferAvailable = ScreenCaptureCapiMock::OnVideoBufferAvailable;
177 int ret = OH_AVScreenCapture_SetCallback(screenCapture_, ohCallback);
178 if (ret != AV_SCREEN_CAPTURE_ERR_OK) {
179 MEDIA_LOGE("ScreenCaptureCapiMock SetCallback failed, ret: %{public}d", ret);
180 return MSERR_UNKNOWN;
181 }
182 if (isErrorCallBackEnabled) {
183 MEDIA_LOGD("ScreenCaptureCapiMock SetErrorCallback");
184 isErrorCallBackEnabled_ = isErrorCallBackEnabled;
185 ret = OH_AVScreenCapture_SetErrorCallback(screenCapture_, ScreenCaptureCapiMock::OnErrorNew, this);
186 if (ret != AV_SCREEN_CAPTURE_ERR_OK) {
187 MEDIA_LOGE("ScreenCaptureCapiMock SetErrorCallback failed, ret: %{public}d", ret);
188 return MSERR_UNKNOWN;
189 }
190 }
191 if (isDataCallBackEnabled) {
192 MEDIA_LOGD("ScreenCaptureCapiMock SetDataCallback");
193 isDataCallBackEnabled_ = isDataCallBackEnabled;
194 ret = OH_AVScreenCapture_SetDataCallback(screenCapture_, ScreenCaptureCapiMock::OnBufferAvailable, this);
195 if (ret != AV_SCREEN_CAPTURE_ERR_OK) {
196 MEDIA_LOGE("ScreenCaptureCapiMock SetDataCallback failed, ret: %{public}d", ret);
197 return MSERR_UNKNOWN;
198 }
199 }
200 if (isStateChangeCallBackEnabled) {
201 MEDIA_LOGD("ScreenCaptureCapiMock SetStateCallback");
202 isStateChangeCallBackEnabled_ = isStateChangeCallBackEnabled;
203 ret = OH_AVScreenCapture_SetStateCallback(screenCapture_, ScreenCaptureCapiMock::OnStateChange, this);
204 if (ret != AV_SCREEN_CAPTURE_ERR_OK) {
205 MEDIA_LOGE("ScreenCaptureCapiMock SetStateCallback failed, ret: %{public}d", ret);
206 return MSERR_UNKNOWN;
207 }
208 }
209 return MSERR_OK;
210 }
211
StartScreenCapture()212 int32_t ScreenCaptureCapiMock::StartScreenCapture()
213 {
214 UNITTEST_CHECK_AND_RETURN_RET_LOG(screenCapture_ != nullptr, MSERR_INVALID_OPERATION, "screenCapture_ == nullptr");
215 return OH_AVScreenCapture_StartScreenCapture(screenCapture_);
216 }
217
StartScreenCaptureWithSurface(const std::any & value)218 int32_t ScreenCaptureCapiMock::StartScreenCaptureWithSurface(const std::any& value)
219 {
220 UNITTEST_CHECK_AND_RETURN_RET_LOG(screenCapture_ != nullptr, MSERR_INVALID_OPERATION, "screenCapture_ == nullptr");
221 sptr<Surface> surface = std::any_cast<sptr<Surface>>(value);
222 OHNativeWindow* nativeWindow = new OHNativeWindow();
223 nativeWindow->surface = surface;
224 return OH_AVScreenCapture_StartScreenCaptureWithSurface(screenCapture_, nativeWindow);
225 }
226
Init(AVScreenCaptureConfig config)227 int32_t ScreenCaptureCapiMock::Init(AVScreenCaptureConfig config)
228 {
229 UNITTEST_CHECK_AND_RETURN_RET_LOG(screenCapture_ != nullptr, MSERR_INVALID_OPERATION, "screenCapture_ == nullptr");
230 OH_AVScreenCaptureConfig tempConfig = Convert(config);
231 return OH_AVScreenCapture_Init(screenCapture_, tempConfig);
232 }
233
StopScreenCapture()234 int32_t ScreenCaptureCapiMock::StopScreenCapture()
235 {
236 UNITTEST_CHECK_AND_RETURN_RET_LOG(screenCapture_ != nullptr, MSERR_INVALID_OPERATION, "screenCapture_ == nullptr");
237 return OH_AVScreenCapture_StopScreenCapture(screenCapture_);
238 }
239
StartScreenRecording()240 int32_t ScreenCaptureCapiMock::StartScreenRecording()
241 {
242 UNITTEST_CHECK_AND_RETURN_RET_LOG(screenCapture_ != nullptr, MSERR_INVALID_OPERATION, "screenCapture_ == nullptr");
243 return OH_AVScreenCapture_StartScreenRecording(screenCapture_);
244 }
245
StopScreenRecording()246 int32_t ScreenCaptureCapiMock::StopScreenRecording()
247 {
248 UNITTEST_CHECK_AND_RETURN_RET_LOG(screenCapture_ != nullptr, MSERR_INVALID_OPERATION, "screenCapture_ == nullptr");
249 return OH_AVScreenCapture_StopScreenRecording(screenCapture_);
250 }
251
Release()252 int32_t ScreenCaptureCapiMock::Release()
253 {
254 UNITTEST_CHECK_AND_RETURN_RET_LOG(screenCapture_ != nullptr, MSERR_INVALID_OPERATION, "screenCapture_ == nullptr");
255 DelCallback(screenCapture_);
256 int32_t ret = OH_AVScreenCapture_Release(screenCapture_);
257 screenCapture_ = nullptr;
258 return ret;
259 }
260
SetMicrophoneEnabled(bool isMicrophone)261 int32_t ScreenCaptureCapiMock::SetMicrophoneEnabled(bool isMicrophone)
262 {
263 UNITTEST_CHECK_AND_RETURN_RET_LOG(screenCapture_ != nullptr, MSERR_INVALID_OPERATION, "screenCapture_ == nullptr");
264 return OH_AVScreenCapture_SetMicrophoneEnabled(screenCapture_, isMicrophone);
265 }
266
SetCanvasRotation(bool canvasRotation)267 int32_t ScreenCaptureCapiMock::SetCanvasRotation(bool canvasRotation)
268 {
269 UNITTEST_CHECK_AND_RETURN_RET_LOG(screenCapture_ != nullptr, MSERR_INVALID_OPERATION, "screenCapture_ == nullptr");
270 return OH_AVScreenCapture_SetCanvasRotation(screenCapture_, canvasRotation);
271 }
272
ResizeCanvas(int32_t width,int32_t height)273 int32_t ScreenCaptureCapiMock::ResizeCanvas(int32_t width, int32_t height)
274 {
275 UNITTEST_CHECK_AND_RETURN_RET_LOG(screenCapture_ != nullptr, MSERR_INVALID_OPERATION, "screenCapture_ == nullptr");
276 return OH_AVScreenCapture_ResizeCanvas(screenCapture_, width, height);
277 }
278
SkipPrivacyMode(int32_t * windowIDs,int32_t windowCount)279 int32_t ScreenCaptureCapiMock::SkipPrivacyMode(int32_t *windowIDs, int32_t windowCount)
280 {
281 UNITTEST_CHECK_AND_RETURN_RET_LOG(screenCapture_ != nullptr, MSERR_INVALID_OPERATION, "screenCapture_ == nullptr");
282 return OH_AVScreenCapture_SkipPrivacyMode(screenCapture_, windowIDs, windowCount);
283 }
284
SetMaxVideoFrameRate(int32_t frameRate)285 int32_t ScreenCaptureCapiMock::SetMaxVideoFrameRate(int32_t frameRate)
286 {
287 UNITTEST_CHECK_AND_RETURN_RET_LOG(screenCapture_ != nullptr, MSERR_INVALID_OPERATION, "screenCapture_ == nullptr");
288 return OH_AVScreenCapture_SetMaxVideoFrameRate(screenCapture_, frameRate);
289 }
290
AcquireAudioBuffer(std::shared_ptr<AudioBuffer> & audioBuffer,AudioCaptureSourceType type)291 int32_t ScreenCaptureCapiMock::AcquireAudioBuffer(std::shared_ptr<AudioBuffer> &audioBuffer,
292 AudioCaptureSourceType type)
293 {
294 UNITTEST_CHECK_AND_RETURN_RET_LOG(screenCapture_ != nullptr, MSERR_INVALID_OPERATION, "screenCapture_ == nullptr");
295 OH_AudioBuffer *buffer = static_cast<OH_AudioBuffer *>(malloc(sizeof(OH_AudioBuffer)));
296 if (buffer == nullptr) {
297 return MSERR_INVALID_OPERATION;
298 }
299 auto t_type = static_cast<OH_AudioCaptureSourceType>(type);
300 int32_t ret = OH_AVScreenCapture_AcquireAudioBuffer(screenCapture_, &buffer, t_type);
301 if (ret == AV_SCREEN_CAPTURE_ERR_OK) {
302 // If ret is not AV_SCREEN_CAPTURE_ERR_OK, the object referenced by buffer is not initialized and can't be used.
303 audioBuffer =
304 std::make_shared<AudioBuffer>(buffer->buf, buffer->size, buffer->timestamp,
305 static_cast<AudioCaptureSourceType>(buffer->type));
306 }
307 free(buffer);
308 buffer = nullptr;
309 return ret;
310 }
311
AcquireVideoBuffer(int32_t & fence,int64_t & timestamp,OHOS::Rect & damage)312 sptr<OHOS::SurfaceBuffer> ScreenCaptureCapiMock::AcquireVideoBuffer(int32_t &fence, int64_t ×tamp,
313 OHOS::Rect &damage)
314 {
315 UNITTEST_CHECK_AND_RETURN_RET_LOG(screenCapture_ != nullptr, nullptr, "screenCapture_ == nullptr");
316 OH_Rect damage_ = {
317 .x = damage.x,
318 .y = damage.y,
319 .width = damage.w,
320 .height = damage.h,
321 };
322 OH_NativeBuffer* buffer = OH_AVScreenCapture_AcquireVideoBuffer(screenCapture_, &fence, ×tamp, &damage_);
323 sptr<OHOS::SurfaceBuffer> surfacebuffer;
324 if (buffer != nullptr) {
325 surfacebuffer = OHOS::SurfaceBuffer::NativeBufferToSurfaceBuffer(buffer);
326 }
327 return surfacebuffer;
328 }
329
ReleaseAudioBuffer(OHOS::Media::AudioCaptureSourceType type)330 int32_t ScreenCaptureCapiMock::ReleaseAudioBuffer(OHOS::Media::AudioCaptureSourceType type)
331 {
332 UNITTEST_CHECK_AND_RETURN_RET_LOG(screenCapture_ != nullptr, MSERR_INVALID_OPERATION, "screenCapture_ == nullptr");
333 auto t_type = static_cast<OH_AudioCaptureSourceType>(type);
334 return OH_AVScreenCapture_ReleaseAudioBuffer(screenCapture_, t_type);
335 }
336
ReleaseVideoBuffer()337 int32_t ScreenCaptureCapiMock::ReleaseVideoBuffer()
338 {
339 UNITTEST_CHECK_AND_RETURN_RET_LOG(screenCapture_ != nullptr, MSERR_INVALID_OPERATION, "screenCapture_ == nullptr");
340 return OH_AVScreenCapture_ReleaseVideoBuffer(screenCapture_);
341 }
342
ExcludeWindowContent(int32_t * windowIDs,int32_t windowCount)343 int32_t ScreenCaptureCapiMock::ExcludeWindowContent(int32_t *windowIDs, int32_t windowCount)
344 {
345 int32_t ret = MSERR_OK;
346 UNITTEST_CHECK_AND_RETURN_RET_LOG(screenCapture_ != nullptr, MSERR_INVALID_OPERATION, "screenCapture_ == nullptr");
347 if (contentFilter_ != nullptr) {
348 ret = OH_AVScreenCapture_ReleaseContentFilter(contentFilter_);
349 UNITTEST_CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "release content failed");
350 }
351 contentFilter_ = OH_AVScreenCapture_CreateContentFilter();
352 OH_AVScreenCapture_ContentFilter_AddWindowContent(contentFilter_, windowIDs, windowCount);
353 return OH_AVScreenCapture_ExcludeContent(screenCapture_, contentFilter_);
354 }
355
ExcludeAudioContent(AVScreenCaptureFilterableAudioContent audioType)356 int32_t ScreenCaptureCapiMock::ExcludeAudioContent(AVScreenCaptureFilterableAudioContent audioType)
357 {
358 int32_t ret = MSERR_OK;
359 UNITTEST_CHECK_AND_RETURN_RET_LOG(screenCapture_ != nullptr, MSERR_INVALID_OPERATION, "screenCapture_ == nullptr");
360 if (contentFilter_ != nullptr) {
361 ret = OH_AVScreenCapture_ReleaseContentFilter(contentFilter_);
362 UNITTEST_CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "release content failed");
363 }
364 contentFilter_ = OH_AVScreenCapture_CreateContentFilter();
365 OH_AVScreenCapture_ContentFilter_AddAudioContent(contentFilter_,
366 static_cast<OH_AVScreenCaptureFilterableAudioContent>(audioType));
367 return OH_AVScreenCapture_ExcludeContent(screenCapture_, contentFilter_);
368 }