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_server.h"
17 #include "media_log.h"
18 #include "media_errors.h"
19 #include "uri_helper.h"
20 #include "media_dfx.h"
21
22 namespace {
23 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "ScreenCaptureServer"};
24 }
25
26 namespace OHOS {
27 namespace Media {
28 const int32_t ROOT_UID = 0;
Create()29 std::shared_ptr<IScreenCaptureService> ScreenCaptureServer::Create()
30 {
31 std::shared_ptr<IScreenCaptureService> server = std::make_shared<ScreenCaptureServer>();
32 CHECK_AND_RETURN_RET_LOG(server != nullptr, nullptr, "Failed to new ScreenCaptureServer");
33 return server;
34 }
35
ScreenCaptureServer()36 ScreenCaptureServer::ScreenCaptureServer()
37 {
38 MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
39 }
40
~ScreenCaptureServer()41 ScreenCaptureServer::~ScreenCaptureServer()
42 {
43 MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
44
45 std::lock_guard<std::mutex> lock(mutex_);
46
47 ReleaseAudioCapture();
48 ReleaseVideoCapture();
49 }
50
SetCaptureMode(CaptureMode captureMode)51 int32_t ScreenCaptureServer::SetCaptureMode(CaptureMode captureMode)
52 {
53 std::lock_guard<std::mutex> lock(mutex_);
54 if ((captureMode > CAPTURE_SPECIFIED_WINDOW) || (captureMode < CAPTURE_HOME_SCREEN)) {
55 MEDIA_LOGI("invalid capture mode");
56 return MSERR_INVALID_VAL;
57 }
58 if (captureMode == CAPTURE_SPECIFIED_SCREEN || captureMode == CAPTURE_SPECIFIED_WINDOW) {
59 MEDIA_LOGI("the capture Mode:%{public}d still not supported", captureMode);
60 return MSERR_UNSUPPORT;
61 }
62 captureMode_ = captureMode;
63 return MSERR_OK;
64 }
65
SetScreenCaptureCallback(const std::shared_ptr<ScreenCaptureCallBack> & callback)66 int32_t ScreenCaptureServer::SetScreenCaptureCallback(const std::shared_ptr<ScreenCaptureCallBack> &callback)
67 {
68 std::lock_guard<std::mutex> lock(mutex_);
69 {
70 std::lock_guard<std::mutex> cbLock(cbMutex_);
71 screenCaptureCb_ = callback;
72 }
73 return MSERR_OK;
74 }
75
CheckScreenCapturePermission()76 bool ScreenCaptureServer::CheckScreenCapturePermission()
77 {
78 auto callerUid = IPCSkeleton::GetCallingUid();
79 // Root users should be whitelisted
80 if (callerUid == ROOT_UID) {
81 MEDIA_LOGI("Root user. Permission Granted");
82 return true;
83 }
84
85 Security::AccessToken::AccessTokenID tokenCaller = IPCSkeleton::GetCallingTokenID();
86 clientTokenId = tokenCaller;
87 int result = Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenCaller,
88 "ohos.permission.CAPTURE_SCREEN");
89 if (result == Security::AccessToken::PERMISSION_GRANTED) {
90 MEDIA_LOGI("user have the right to access capture screen!");
91 } else {
92 MEDIA_LOGE("user do not have the right to access capture screen!");
93 return false;
94 }
95
96 if (!PrivacyKit::IsAllowedUsingPermission(clientTokenId, "ohos.permission.CAPTURE_SCREEN")) {
97 MEDIA_LOGE("app background, not allow using perm for client %{public}d", clientTokenId);
98 }
99 return true;
100 }
101
CheckAudioParam(AudioCaptureInfo audioInfo)102 int32_t ScreenCaptureServer::CheckAudioParam(AudioCaptureInfo audioInfo)
103 {
104 std::vector<AudioSamplingRate> supportedSamplingRates = AudioStandard::AudioCapturer::GetSupportedSamplingRates();
105 bool foundSupportSample = false;
106 for (auto iter = supportedSamplingRates.begin(); iter != supportedSamplingRates.end(); ++iter) {
107 if (static_cast<AudioSamplingRate>(audioInfo.audioSampleRate) == *iter) {
108 foundSupportSample = true;
109 }
110 }
111 if (!foundSupportSample) {
112 MEDIA_LOGE("set audioSampleRate is not support");
113 return MSERR_UNSUPPORT;
114 }
115
116 std::vector<AudioChannel> supportedChannelList = AudioStandard::AudioCapturer::GetSupportedChannels();
117 bool foundSupportChannel = false;
118 for (auto iter = supportedChannelList.begin(); iter != supportedChannelList.end(); ++iter) {
119 if (static_cast<AudioChannel>(audioInfo.audioChannels) == *iter) {
120 foundSupportChannel = true;
121 }
122 }
123 if (!foundSupportChannel) {
124 MEDIA_LOGE("set audioChannel is not support");
125 return MSERR_UNSUPPORT;
126 }
127
128 if ((audioInfo.audioSource <= SOURCE_INVALID) || (audioInfo.audioSource > APP_PLAYBACK)) {
129 MEDIA_LOGE("audioSource is invalid");
130 return MSERR_INVALID_VAL;
131 }
132 return MSERR_OK;
133 }
134
CheckVideoParam(VideoCaptureInfo videoInfo)135 int32_t ScreenCaptureServer::CheckVideoParam(VideoCaptureInfo videoInfo)
136 {
137 if ((videoInfo.videoFrameWidth <= 0) || (videoInfo.videoFrameHeight <= 0)) {
138 MEDIA_LOGE("videoInfo size is invalid, videoFrameWidth:%{public}d,videoFrameHeight:%{public}d",
139 videoInfo.videoFrameWidth, videoInfo.videoFrameHeight);
140 return MSERR_INVALID_VAL;
141 }
142
143 if (videoInfo.videoSource != VIDEO_SOURCE_SURFACE_RGBA) {
144 MEDIA_LOGE("videoSource is invalid");
145 return MSERR_INVALID_VAL;
146 }
147 return MSERR_OK;
148 }
149
CheckAudioCaptureMicPermission()150 bool ScreenCaptureServer::CheckAudioCaptureMicPermission()
151 {
152 auto callerUid = IPCSkeleton::GetCallingUid();
153 // Root users should be whitelisted
154 if (callerUid == ROOT_UID) {
155 MEDIA_LOGI("Root user. Permission Granted");
156 return true;
157 }
158
159 Security::AccessToken::AccessTokenID tokenCaller = IPCSkeleton::GetCallingTokenID();
160 int result = Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenCaller,
161 "ohos.permission.MICROPHONE");
162 if (result == Security::AccessToken::PERMISSION_GRANTED) {
163 MEDIA_LOGI("user have the right to access microphone !");
164 return true;
165 } else {
166 MEDIA_LOGE("user do not have the right to access microphone!");
167 return false;
168 }
169 }
170
InitAudioCap(AudioCaptureInfo audioInfo)171 int32_t ScreenCaptureServer::InitAudioCap(AudioCaptureInfo audioInfo)
172 {
173 std::lock_guard<std::mutex> lock(mutex_);
174 MediaTrace trace("ScreenCaptureServer::InitAudioCap");
175 int ret = MSERR_OK;
176 ret = CheckAudioParam(audioInfo);
177 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "CheckAudioParam failed");
178
179 switch (audioInfo.audioSource) {
180 case SOURCE_DEFAULT:
181 case MIC: {
182 if (!CheckAudioCaptureMicPermission()) {
183 return MSERR_INVALID_OPERATION;
184 }
185 audioMicCapturer_ = CreateAudioCapture(audioInfo);
186 CHECK_AND_RETURN_RET_LOG(audioMicCapturer_ != nullptr, MSERR_UNKNOWN, "initMicAudioCap failed");
187 break;
188 }
189 case ALL_PLAYBACK:
190 case APP_PLAYBACK: {
191 audioInnerCapturer_ = CreateAudioCapture(audioInfo);
192 audioCurrentInnerType_ = audioInfo.audioSource;
193 CHECK_AND_RETURN_RET_LOG(audioInnerCapturer_ != nullptr, MSERR_UNKNOWN, "initInnerAudioCap failed");
194 break;
195 }
196 default:
197 MEDIA_LOGE("the audio source Type is invalid");
198 return MSERR_INVALID_OPERATION;
199 }
200 return MSERR_OK;
201 }
202
CreateAudioCapture(AudioCaptureInfo audioInfo)203 std::shared_ptr<AudioCapturer> ScreenCaptureServer::CreateAudioCapture(AudioCaptureInfo audioInfo)
204 {
205 AudioCapturerOptions capturerOptions;
206 std::shared_ptr<AudioCapturer> audioCapture;
207 capturerOptions.streamInfo.samplingRate = static_cast<AudioSamplingRate>(audioInfo.audioSampleRate);
208 capturerOptions.streamInfo.encoding = AudioEncodingType::ENCODING_PCM;
209 capturerOptions.streamInfo.format = AudioSampleFormat::SAMPLE_S16LE;
210 capturerOptions.streamInfo.channels = static_cast<AudioChannel>(audioInfo.audioChannels);
211 if (audioInfo.audioSource == MIC) {
212 /* Audio SourceType Mic is 0 */
213 capturerOptions.capturerInfo.sourceType = static_cast<SourceType>(audioInfo.audioSource - MIC);
214 } else {
215 capturerOptions.capturerInfo.sourceType = static_cast<SourceType>(audioInfo.audioSource);
216 }
217 capturerOptions.capturerInfo.capturerFlags = 0;
218 AppInfo appinfo_;
219 uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
220 int32_t appUid = IPCSkeleton::GetCallingUid();
221 int32_t appPid = IPCSkeleton::GetCallingPid();
222 appinfo_.appUid = appUid;
223 appinfo_.appTokenId = tokenId;
224 appinfo_.appPid = appPid;
225 audioCapture = AudioCapturer::Create(capturerOptions, appinfo_);
226 CHECK_AND_RETURN_RET_LOG(audioCapture != nullptr, nullptr, "initAudioCap failed");
227
228 int ret = audioCapture->SetCapturerCallback(cb1_);
229 CHECK_AND_RETURN_RET_LOG(ret != MSERR_OK, nullptr, "SetCapturerCallback failed");
230 return audioCapture;
231 }
232
InitVideoCap(VideoCaptureInfo videoInfo)233 int32_t ScreenCaptureServer::InitVideoCap(VideoCaptureInfo videoInfo)
234 {
235 std::lock_guard<std::mutex> lock(mutex_);
236 MediaTrace trace("ScreenCaptureServer::InitVideoCap");
237 if (!CheckScreenCapturePermission()) {
238 return MSERR_INVALID_OPERATION;
239 }
240
241 int ret = CheckVideoParam(videoInfo);
242 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "CheckVideoParam failed");
243
244 consumer_ = OHOS::Surface::CreateSurfaceAsConsumer();
245 if (consumer_ == nullptr) {
246 MEDIA_LOGE("CreateSurfaceAsConsumer failed");
247 return MSERR_NO_MEMORY;
248 }
249 videoInfo_ = videoInfo;
250 return MSERR_OK;
251 }
252
GetUsingPermissionFromPrivacy(VideoPermissionState state)253 bool ScreenCaptureServer::GetUsingPermissionFromPrivacy(VideoPermissionState state)
254 {
255 auto callerUid = IPCSkeleton::GetCallingUid();
256 // Root users should be whitelisted
257 if (callerUid == ROOT_UID) {
258 MEDIA_LOGI("Root user. Privacy Granted");
259 return true;
260 }
261
262 if (clientTokenId == 0) {
263 clientTokenId = IPCSkeleton::GetCallingTokenID();
264 }
265 int res = 0;
266 if (state == START_VIDEO) {
267 res = PrivacyKit::StartUsingPermission(clientTokenId, "ohos.permission.CAPTURE_SCREEN");
268 if (res != 0) {
269 MEDIA_LOGE("start using perm error for client %{public}d", clientTokenId);
270 }
271 } else if (state == STOP_VIDEO) {
272 res = PrivacyKit::StopUsingPermission(clientTokenId, "ohos.permission.CAPTURE_SCREEN");
273 if (res != 0) {
274 MEDIA_LOGE("stop using perm error for client %{public}d", clientTokenId);
275 }
276 }
277 return true;
278 }
279
StartScreenCapture()280 int32_t ScreenCaptureServer::StartScreenCapture()
281 {
282 std::lock_guard<std::mutex> lock(mutex_);
283 MediaTrace trace("ScreenCaptureServer::StartScreenCapture");
284 isAudioStart_ = true;
285 if (audioMicCapturer_ != nullptr) {
286 if (!audioMicCapturer_->Start()) {
287 MEDIA_LOGE("Start mic audio stream failed");
288 audioMicCapturer_->Release();
289 audioMicCapturer_ = nullptr;
290 isAudioStart_ = false;
291 }
292 if (isAudioStart_) {
293 MEDIA_LOGE("Capturing started");
294 isRunning_.store(true);
295 readAudioLoop_ = std::make_unique<std::thread>(&ScreenCaptureServer::StartAudioCapture, this);
296 }
297 }
298 isAudioInnerStart_ = true;
299 if (audioInnerCapturer_ != nullptr) {
300 if (!audioInnerCapturer_->Start()) {
301 MEDIA_LOGE("Start inner audio stream failed");
302 audioInnerCapturer_->Release();
303 audioInnerCapturer_ = nullptr;
304 isAudioInnerStart_ = false;
305 }
306 if (isAudioInnerStart_) {
307 MEDIA_LOGE("Capturing started");
308 isInnerRunning_.store(true);
309 readInnerAudioLoop_ = std::make_unique<std::thread>(&ScreenCaptureServer::StartAudioInnerCapture, this);
310 }
311 }
312 return StartVideoCapture();
313 }
314
StartVideoCapture()315 int32_t ScreenCaptureServer::StartVideoCapture()
316 {
317 if (!GetUsingPermissionFromPrivacy(START_VIDEO)) {
318 MEDIA_LOGE("getUsingPermissionFromPrivacy");
319 }
320 if (captureMode_ == CAPTURE_HOME_SCREEN) {
321 return StartHomeVideoCapture();
322 } else {
323 MEDIA_LOGE("The capture Mode Init still not supported,start failed");
324 return MSERR_UNSUPPORT;
325 }
326 return MSERR_OK;
327 }
328
StartHomeVideoCapture()329 int32_t ScreenCaptureServer::StartHomeVideoCapture()
330 {
331 if (consumer_ == nullptr) {
332 MEDIA_LOGE("consumer_ is not created");
333 return MSERR_INVALID_OPERATION;
334 }
335 surfaceCb_ = new ScreenCapBufferConsumerListener(consumer_, screenCaptureCb_);
336 consumer_->RegisterConsumerListener((sptr<IBufferConsumerListener> &)surfaceCb_);
337 auto producer = consumer_->GetProducer();
338 auto psurface = OHOS::Surface::CreateSurfaceAsProducer(producer);
339 CHECK_AND_RETURN_RET_LOG(psurface != nullptr, MSERR_UNKNOWN, "CreateSurfaceAsProducer failed");
340 isConsumerStart_ = true;
341 VirtualScreenOption virScrOption = {
342 .name_ = "screen_capture",
343 .width_ = videoInfo_.videoFrameWidth,
344 .height_ = videoInfo_.videoFrameHeight,
345 .density_ = 0,
346 .surface_ = psurface,
347 .flags_ = 0,
348 .isForShot_ = true,
349 };
350 sptr<Rosen::Display> display = Rosen::DisplayManager::GetInstance().GetDefaultDisplaySync();
351 if (display != nullptr) {
352 MEDIA_LOGI("get displayinfo width:%{public}d,height:%{public}d,density:%{public}d", display->GetWidth(),
353 display->GetHeight(), display->GetDpi());
354 virScrOption.density_ = display->GetDpi();
355 }
356 screenId_ = ScreenManager::GetInstance().CreateVirtualScreen(virScrOption);
357 if (screenId_ < 0) {
358 consumer_->UnregisterConsumerListener();
359 isConsumerStart_ = false;
360 MEDIA_LOGE("CreateVirtualScreen failed,release ConsumerListener");
361 return MSERR_INVALID_OPERATION;
362 }
363 auto screen = ScreenManager::GetInstance().GetScreenById(screenId_);
364 if (screen == nullptr) {
365 consumer_->UnregisterConsumerListener();
366 isConsumerStart_ = false;
367 MEDIA_LOGE("GetScreenById failed,release ConsumerListener");
368 return MSERR_INVALID_OPERATION;
369 }
370 std::vector<sptr<Screen>> screens;
371 ScreenManager::GetInstance().GetAllScreens(screens);
372 std::vector<ScreenId> mirrorIds;
373 mirrorIds.push_back(screenId_);
374 ScreenId mirrorGroup = static_cast<ScreenId>(1);
375 ScreenManager::GetInstance().MakeMirror(screens[0]->GetId(), mirrorIds, mirrorGroup);
376
377 return MSERR_OK;
378 }
379
StartAudioInnerCapture()380 int32_t ScreenCaptureServer::StartAudioInnerCapture()
381 {
382 size_t bufferLen;
383 CHECK_AND_RETURN_RET_LOG(audioInnerCapturer_ != nullptr, MSERR_NO_MEMORY, "audioInner capture is nullptr");
384 if (audioInnerCapturer_->GetBufferSize(bufferLen) < 0) {
385 MEDIA_LOGE("audioMicCapturer_ GetBufferSize failed");
386 return MSERR_NO_MEMORY;
387 }
388 int32_t bufferRead = 0;
389 Timestamp timestamp;
390 int64_t audioTime;
391
392 while (true) {
393 if (audioInnerCapturer_ == nullptr || !(isAudioInnerStart_) || !(isInnerRunning_.load())) {
394 MEDIA_LOGI("audioInnerCapturer_ has been released, end the capture!!");
395 break;
396 }
397 uint8_t *buffer = static_cast<uint8_t *>(malloc(bufferLen));
398 if (buffer == nullptr)
399 return MSERR_NO_MEMORY;
400 memset_s(buffer, bufferLen, 0, bufferLen);
401 bufferRead = audioInnerCapturer_->Read(*buffer, bufferLen, true);
402 if (bufferRead <= 0) {
403 free(buffer);
404 buffer = nullptr;
405 MEDIA_LOGE("read audioBuffer failed, continue");
406 continue;
407 }
408 audioInnerCapturer_->GetAudioTime(timestamp, Timestamp::Timestampbase::MONOTONIC);
409 audioTime = timestamp.time.tv_nsec + timestamp.time.tv_sec * SEC_TO_NANOSECOND;
410 std::unique_lock<std::mutex> lock(audioInnerMutex_);
411 if (availableInnerAudioBuffers_.size() > MAX_AUDIO_BUFFER_SIZE) {
412 free(buffer);
413 buffer = nullptr;
414 MEDIA_LOGE("no client consumer the buffer, drop the frame!!");
415 continue;
416 }
417 availableInnerAudioBuffers_.push(std::make_unique<AudioBuffer>(buffer, bufferRead,
418 audioTime, audioCurrentInnerType_));
419 if (screenCaptureCb_ != nullptr) {
420 std::lock_guard<std::mutex> cbLock(cbMutex_);
421 screenCaptureCb_->OnAudioBufferAvailable(true, audioCurrentInnerType_);
422 }
423 bufferInnerCond_.notify_all();
424 }
425 return MSERR_OK;
426 }
427
StartAudioCapture()428 int32_t ScreenCaptureServer::StartAudioCapture()
429 {
430 size_t bufferLen;
431 CHECK_AND_RETURN_RET_LOG(audioMicCapturer_ != nullptr, MSERR_NO_MEMORY, "audiomic capture is nullptr");
432 if (audioMicCapturer_->GetBufferSize(bufferLen) < 0) {
433 MEDIA_LOGE("audioMicCapturer_ GetBufferSize failed");
434 return MSERR_NO_MEMORY;
435 }
436 int32_t bufferRead = 0;
437 Timestamp timestamp;
438 int64_t audioTime;
439 while (true) {
440 if (audioMicCapturer_ == nullptr || !(isAudioStart_) || !(isRunning_.load())) {
441 MEDIA_LOGI("audioMicCapturer_ has been released,end the capture!!");
442 break;
443 }
444 uint8_t *buffer = static_cast<uint8_t *>(malloc(bufferLen));
445 if (buffer == nullptr)
446 return MSERR_NO_MEMORY;
447 memset_s(buffer, bufferLen, 0, bufferLen);
448 bufferRead = audioMicCapturer_->Read(*buffer, bufferLen, true);
449 if (bufferRead <= 0) {
450 free(buffer);
451 buffer = nullptr;
452 MEDIA_LOGE("read audioBuffer failed,continue");
453 continue;
454 }
455 audioMicCapturer_->GetAudioTime(timestamp, Timestamp::Timestampbase::MONOTONIC);
456 audioTime = timestamp.time.tv_nsec + timestamp.time.tv_sec * SEC_TO_NANOSECOND;
457 std::unique_lock<std::mutex> lock(audioMutex_);
458 if (availableAudioBuffers_.size() > MAX_AUDIO_BUFFER_SIZE) {
459 free(buffer);
460 buffer = nullptr;
461 MEDIA_LOGE("no client consumer the buffer, drop the frame!!");
462 continue;
463 }
464 if (!isMicrophoneOn) {
465 memset_s(buffer, bufferLen, 0, bufferLen);
466 availableAudioBuffers_.push(std::make_unique<AudioBuffer>(buffer, bufferRead, audioTime, MIC));
467 } else {
468 availableAudioBuffers_.push(std::make_unique<AudioBuffer>(buffer, bufferRead, audioTime, MIC));
469 }
470 if (screenCaptureCb_ != nullptr) {
471 std::lock_guard<std::mutex> cbLock(cbMutex_);
472 screenCaptureCb_->OnAudioBufferAvailable(true, MIC);
473 }
474 bufferCond_.notify_all();
475 }
476 return MSERR_OK;
477 }
478
AcquireAudioBuffer(std::shared_ptr<AudioBuffer> & audioBuffer,AudioCaptureSourceType type)479 int32_t ScreenCaptureServer::AcquireAudioBuffer(std::shared_ptr<AudioBuffer> &audioBuffer, AudioCaptureSourceType type)
480 {
481 if ((type == MIC) || (type == SOURCE_DEFAULT)) {
482 using namespace std::chrono_literals;
483 std::unique_lock<std::mutex> alock(audioMutex_);
484 if (availableAudioBuffers_.empty()) {
485 if (bufferCond_.wait_for(alock, 200ms) == std::cv_status::timeout) {
486 MEDIA_LOGE("AcquireAudioBuffer timeout return!");
487 return MSERR_UNKNOWN;
488 }
489 }
490 if (availableAudioBuffers_.front() != nullptr) {
491 audioBuffer = availableAudioBuffers_.front();
492 return MSERR_OK;
493 }
494 } else if ((type == ALL_PLAYBACK) || (type == APP_PLAYBACK)) {
495 using namespace std::chrono_literals;
496 std::unique_lock<std::mutex> alock(audioInnerMutex_);
497 if (availableInnerAudioBuffers_.empty()) {
498 if (bufferInnerCond_.wait_for(alock, 200ms) == std::cv_status::timeout) {
499 MEDIA_LOGE("AcquireAudioBuffer timeout return!");
500 return MSERR_UNKNOWN;
501 }
502 }
503 if (availableInnerAudioBuffers_.front() != nullptr) {
504 audioBuffer = availableInnerAudioBuffers_.front();
505 return MSERR_OK;
506 }
507 } else {
508 MEDIA_LOGE("The Type you request not support");
509 return MSERR_UNSUPPORT;
510 }
511 return MSERR_UNKNOWN;
512 }
513
ReleaseAudioBuffer(AudioCaptureSourceType type)514 int32_t ScreenCaptureServer::ReleaseAudioBuffer(AudioCaptureSourceType type)
515 {
516 if (type == MIC) {
517 std::unique_lock<std::mutex> alock(audioMutex_);
518 if (availableAudioBuffers_.empty()) {
519 MEDIA_LOGE("availableAudioBuffers_ is empty, no frame need release");
520 return MSERR_OK;
521 }
522 if (availableAudioBuffers_.front() != nullptr) {
523 free(availableAudioBuffers_.front()->buffer);
524 availableAudioBuffers_.front()->buffer = nullptr;
525 }
526 availableAudioBuffers_.pop();
527 } else if ((type == ALL_PLAYBACK) || (type == APP_PLAYBACK)) {
528 std::unique_lock<std::mutex> alock(audioInnerMutex_);
529 if (availableInnerAudioBuffers_.empty()) {
530 MEDIA_LOGE("availableAudioBuffers_ is empty, no frame need release");
531 return MSERR_OK;
532 }
533 if (availableInnerAudioBuffers_.front() != nullptr) {
534 free(availableInnerAudioBuffers_.front()->buffer);
535 availableInnerAudioBuffers_.front()->buffer = nullptr;
536 }
537 availableInnerAudioBuffers_.pop();
538 } else {
539 MEDIA_LOGE("The Type you release not support");
540 return MSERR_UNSUPPORT;
541 }
542 return MSERR_OK;
543 }
544
AcquireVideoBuffer(sptr<OHOS::SurfaceBuffer> & surfaceBuffer,int32_t & fence,int64_t & timestamp,OHOS::Rect & damage)545 int32_t ScreenCaptureServer::AcquireVideoBuffer(sptr<OHOS::SurfaceBuffer> &surfaceBuffer, int32_t &fence,
546 int64_t ×tamp, OHOS::Rect &damage)
547 {
548 CHECK_AND_RETURN_RET_LOG(surfaceCb_ != nullptr, MSERR_NO_MEMORY,
549 "Failed to AcquireVideoBuffer,no callback object");
550 surfaceCb_->AcquireVideoBuffer(surfaceBuffer, fence, timestamp, damage);
551 if (surfaceBuffer != nullptr) {
552 MEDIA_LOGD("getcurrent surfaceBuffer info, size:%{public}u", surfaceBuffer->GetSize());
553 return MSERR_OK;
554 }
555 return MSERR_UNKNOWN;
556 }
557
ReleaseVideoBuffer()558 int32_t ScreenCaptureServer::ReleaseVideoBuffer()
559 {
560 CHECK_AND_RETURN_RET_LOG(surfaceCb_ != nullptr, MSERR_NO_MEMORY,
561 "Failed to ReleaseVideoBuffer,no callback object");
562 return surfaceCb_->ReleaseVideoBuffer();
563 }
564
SetMicrophoneEnabled(bool isMicrophone)565 int32_t ScreenCaptureServer::SetMicrophoneEnabled(bool isMicrophone)
566 {
567 std::lock_guard<std::mutex> lock(mutex_);
568 MEDIA_LOGI("SetMicrophoneEnabled:%{public}d", isMicrophone);
569 isMicrophoneOn = isMicrophone;
570 return MSERR_OK;
571 }
572
StopAudioCapture()573 int32_t ScreenCaptureServer::StopAudioCapture()
574 {
575 isRunning_.store(false);
576 if (readAudioLoop_ != nullptr && readAudioLoop_->joinable()) {
577 readAudioLoop_->join();
578 readAudioLoop_.reset();
579 readAudioLoop_ = nullptr;
580 audioMicCapturer_->Stop();
581 }
582
583 isInnerRunning_.store(false);
584 if (readInnerAudioLoop_ != nullptr && readInnerAudioLoop_->joinable()) {
585 readInnerAudioLoop_->join();
586 readInnerAudioLoop_.reset();
587 readInnerAudioLoop_ = nullptr;
588 audioInnerCapturer_->Stop();
589 }
590 return MSERR_OK;
591 }
592
StopVideoCapture()593 int32_t ScreenCaptureServer::StopVideoCapture()
594 {
595 MEDIA_LOGI("StopVideoCapture");
596 int32_t stopVideoSuccess = MSERR_OK;
597 if (!GetUsingPermissionFromPrivacy(STOP_VIDEO)) {
598 MEDIA_LOGE("getUsingPermissionFromPrivacy");
599 }
600
601 if ((screenId_ < 0) || (consumer_ == nullptr) || !isConsumerStart_) {
602 MEDIA_LOGI("video start failed, stop");
603 stopVideoSuccess = MSERR_INVALID_OPERATION;
604 surfaceCb_ = nullptr;
605 return stopVideoSuccess;
606 }
607
608 if (screenId_ != SCREEN_ID_INVALID) {
609 ScreenManager::GetInstance().DestroyVirtualScreen(screenId_);
610 }
611
612 if ((consumer_ != nullptr) && isConsumerStart_) {
613 isConsumerStart_ = false;
614 consumer_->UnregisterConsumerListener();
615 }
616
617 if (surfaceCb_ != nullptr) {
618 surfaceCb_->Release();
619 surfaceCb_ = nullptr;
620 }
621
622 return stopVideoSuccess;
623 }
624
StopScreenCapture()625 int32_t ScreenCaptureServer::StopScreenCapture()
626 {
627 std::lock_guard<std::mutex> lock(mutex_);
628 MediaTrace trace("ScreenCaptureServer::StopScreenCapture");
629
630 int32_t stopFlagSuccess = StopAudioCapture();
631 CHECK_AND_RETURN_RET_LOG(stopFlagSuccess == MSERR_OK, stopFlagSuccess, "StopAudioCapture failed");
632
633 stopFlagSuccess = StopVideoCapture();
634 return stopFlagSuccess;
635 }
636
ReleaseAudioCapture()637 void ScreenCaptureServer::ReleaseAudioCapture()
638 {
639 if ((audioMicCapturer_ != nullptr) && isAudioStart_) {
640 isRunning_.store(false);
641 if (readAudioLoop_ != nullptr && readAudioLoop_->joinable()) {
642 readAudioLoop_->join();
643 readAudioLoop_.reset();
644 readAudioLoop_ = nullptr;
645 }
646 audioMicCapturer_->Release();
647 isAudioStart_ = false;
648 audioMicCapturer_ = nullptr;
649 }
650
651 if ((audioInnerCapturer_ != nullptr) && isAudioInnerStart_) {
652 isInnerRunning_.store(false);
653 if (readInnerAudioLoop_ != nullptr && readInnerAudioLoop_->joinable()) {
654 readInnerAudioLoop_->join();
655 readInnerAudioLoop_.reset();
656 readInnerAudioLoop_ = nullptr;
657 }
658 audioInnerCapturer_->Release();
659 isAudioInnerStart_ = false;
660 audioInnerCapturer_ = nullptr;
661 }
662
663 std::unique_lock<std::mutex> alock(audioMutex_);
664 while (!availableAudioBuffers_.empty()) {
665 if (availableAudioBuffers_.front() != nullptr) {
666 free(availableAudioBuffers_.front()->buffer);
667 availableAudioBuffers_.front()->buffer = nullptr;
668 }
669 availableAudioBuffers_.pop();
670 }
671
672 std::unique_lock<std::mutex> alock_inner(audioInnerMutex_);
673 while (!availableInnerAudioBuffers_.empty()) {
674 if (availableInnerAudioBuffers_.front() != nullptr) {
675 free(availableInnerAudioBuffers_.front()->buffer);
676 availableInnerAudioBuffers_.front()->buffer = nullptr;
677 }
678 availableInnerAudioBuffers_.pop();
679 }
680 }
681
ReleaseVideoCapture()682 void ScreenCaptureServer::ReleaseVideoCapture()
683 {
684 if (screenId_ != SCREEN_ID_INVALID) {
685 ScreenManager::GetInstance().DestroyVirtualScreen(screenId_);
686 }
687
688 if ((consumer_ != nullptr) && isConsumerStart_) {
689 consumer_->UnregisterConsumerListener();
690 isConsumerStart_ = false;
691 }
692 consumer_ = nullptr;
693 if (surfaceCb_ != nullptr) {
694 surfaceCb_->Release();
695 surfaceCb_ = nullptr;
696 }
697 }
698
Release()699 void ScreenCaptureServer::Release()
700 {
701 std::lock_guard<std::mutex> lock(mutex_);
702 MediaTrace trace("ScreenCaptureServer::Release");
703
704 screenCaptureCb_ = nullptr;
705 ReleaseAudioCapture();
706 ReleaseVideoCapture();
707 MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
708 }
709
OnInterrupt(const InterruptEvent & interruptEvent)710 void AudioCapturerCallbackImpl::OnInterrupt(const InterruptEvent &interruptEvent)
711 {
712 MEDIA_LOGD("AudioCapturerCallbackImpl: OnInterrupt Hint : %{public}d eventType : %{public}d forceType : %{public}d",
713 interruptEvent.hintType, interruptEvent.eventType, interruptEvent.forceType);
714 }
715
OnStateChange(const CapturerState state)716 void AudioCapturerCallbackImpl::OnStateChange(const CapturerState state)
717 {
718 MEDIA_LOGD("AudioCapturerCallbackImpl:: OnStateChange");
719 switch (state) {
720 case CAPTURER_PREPARED:
721 MEDIA_LOGD("AudioCapturerCallbackImpl: OnStateChange CAPTURER_PREPARED");
722 break;
723 default:
724 MEDIA_LOGD("AudioCapturerCallbackImpl: OnStateChange NOT A VALID state");
725 break;
726 }
727 }
728
OnBufferAvailable()729 void ScreenCapBufferConsumerListener::OnBufferAvailable()
730 {
731 int32_t flushFence = 0;
732 int64_t timestamp = 0;
733 OHOS::Rect damage;
734 OHOS::sptr<OHOS::SurfaceBuffer> buffer = nullptr;
735 if (consumer_ == nullptr) {
736 MEDIA_LOGE("consumer_ is nullptr");
737 return;
738 }
739 consumer_->AcquireBuffer(buffer, flushFence, timestamp, damage);
740 if (buffer != nullptr) {
741 void* addr = buffer->GetVirAddr();
742 uint32_t size = buffer->GetSize();
743 if (addr != nullptr) {
744 MEDIA_LOGD("consumer receive buffer length:%{public}u", size);
745 std::unique_lock<std::mutex> vlock(vmutex_);
746 if (availableVideoBuffers_.size() > MAX_BUFFER_SIZE) {
747 consumer_->ReleaseBuffer(buffer, flushFence);
748 MEDIA_LOGE("no client consumer the buffer,drop the frame!!");
749 return;
750 }
751 availableVideoBuffers_.push(std::make_unique<SurfaceBufferEntry>(buffer, flushFence,
752 timestamp, damage));
753 if (screenCaptureCb_ != nullptr) {
754 std::lock_guard<std::mutex> cbLock(cbMutex_);
755 screenCaptureCb_->OnVideoBufferAvailable(true);
756 } else {
757 MEDIA_LOGE("no callback client consumer the buffer,drop the frame!!");
758 }
759 bufferCond_.notify_all();
760 }
761 } else {
762 MEDIA_LOGE("consumer receive buffer failed");
763 return;
764 }
765 }
766
AcquireVideoBuffer(sptr<OHOS::SurfaceBuffer> & surfaceBuffer,int32_t & fence,int64_t & timestamp,OHOS::Rect & damage)767 int32_t ScreenCapBufferConsumerListener::AcquireVideoBuffer(sptr<OHOS::SurfaceBuffer> &surfaceBuffer, int32_t &fence,
768 int64_t ×tamp, OHOS::Rect &damage)
769 {
770 using namespace std::chrono_literals;
771 std::unique_lock<std::mutex> vlock(vmutex_);
772 if (availableVideoBuffers_.empty()) {
773 if (bufferCond_.wait_for(vlock, 1000ms) == std::cv_status::timeout) {
774 return MSERR_UNKNOWN;
775 }
776 }
777 surfaceBuffer = availableVideoBuffers_.front()->buffer;
778 fence = availableVideoBuffers_.front()->flushFence;
779 timestamp = availableVideoBuffers_.front()->timeStamp;
780 damage = availableVideoBuffers_.front()->damageRect;
781 return MSERR_OK;
782 }
783
ReleaseVideoBuffer()784 int32_t ScreenCapBufferConsumerListener::ReleaseVideoBuffer()
785 {
786 std::unique_lock<std::mutex> vlock(vmutex_);
787 if (availableVideoBuffers_.empty()) {
788 MEDIA_LOGE("availableVideoBuffers_ is empty,no video frame need release");
789 return MSERR_OK;
790 }
791 if (consumer_ != nullptr) {
792 consumer_->ReleaseBuffer(availableVideoBuffers_.front()->buffer,
793 availableVideoBuffers_.front()->flushFence);
794 }
795 availableVideoBuffers_.pop();
796 return MSERR_OK;
797 }
798
Release()799 int32_t ScreenCapBufferConsumerListener::Release()
800 {
801 MEDIA_LOGI("release ScreenCapBufferConsumerListener");
802 std::unique_lock<std::mutex> vlock(vmutex_);
803 while (!availableVideoBuffers_.empty()) {
804 if (consumer_ != nullptr) {
805 consumer_->ReleaseBuffer(availableVideoBuffers_.front()->buffer,
806 availableVideoBuffers_.front()->flushFence);
807 }
808 availableVideoBuffers_.pop();
809 }
810 return MSERR_OK;
811 }
812 } // namespace Media
813 } // namespace OHOS
814