1 /*
2 * Copyright (c) 2020-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 "acelite_config.h"
16 #if (FEATURE_COMPONENT_VIDEO == 1)
17 #include "video_component.h"
18 #include "ace_log.h"
19 #include "key_parser.h"
20 #include "keys.h"
21
22 #if (FEATURE_UPDATE_VIDEO_PROGRESS_ASYNC == 1)
23 #include <sys/prctl.h>
24 #include "ace_ability.h"
25 #endif // FEATURE_UPDATE_VIDEO_PROGRESS_ASYNC
26
27 namespace OHOS {
28 namespace ACELite {
29 const char * const VideoComponent::FUNC_START = "start";
30 const char * const VideoComponent::FUNC_PAUSE = "pause";
31 const char * const VideoComponent::FUNC_SET_CURRENT_TIME = "setCurrentTime";
32 const char * const VideoComponent::FUNC_SET_Volume = "setVolume";
33 List<Component *> VideoComponent::componentNodes_;
34
35 #if (FEATURE_UPDATE_VIDEO_PROGRESS_ASYNC == 1)
36 pthread_mutex_t VideoComponent::updateLock_ = PTHREAD_MUTEX_INITIALIZER;
37 pthread_cond_t VideoComponent::updateCondition_ = PTHREAD_COND_INITIALIZER;
38 #endif // FEATURE_UPDATE_VIDEO_PROGRESS_ASYN
39
VideoComponent(jerry_value_t options,jerry_value_t children,AppStyleManager * styleManager)40 VideoComponent::VideoComponent(jerry_value_t options, jerry_value_t children, AppStyleManager *styleManager)
41 : Component(options, children, styleManager),
42 videoSourceUrl_(nullptr),
43 videoView_(nullptr),
44 videoEventListener_(nullptr),
45 videoSliderListener_(nullptr),
46 videoPlayImageClickListener_(nullptr),
47 autoPlay_(false),
48 videoMuted_(false),
49 isPlaying_(false),
50 isReleasing_(false),
51 isUpdatingHandlerQuited_(false)
52 {
53 SetComponentName(K_VIDEO);
54 RegisterNativeFunctions();
55 }
56
RegisterNativeFunctions()57 void VideoComponent::RegisterNativeFunctions()
58 {
59 RegisterNamedFunction(FUNC_START, Start);
60 RegisterNamedFunction(FUNC_PAUSE, Pause);
61 RegisterNamedFunction(FUNC_SET_CURRENT_TIME, SetCurrentTime);
62 RegisterNamedFunction(FUNC_SET_Volume, SetVolume);
63 }
64
UpdatePlayImageInfo(bool playFlag)65 void VideoComponent::UpdatePlayImageInfo(bool playFlag)
66 {
67 PanelView* panelView = const_cast<PanelView *>(videoView_->GetPanelView());
68 if (panelView == nullptr) {
69 HILOG_ERROR(HILOG_MODULE_ACE, "video panel get panelview is nullptr");
70 return;
71 }
72 UIImageView *playImageView = const_cast<UIImageView *>(panelView->GetVideoPlayImage());
73 if (playImageView == nullptr) {
74 HILOG_ERROR(HILOG_MODULE_ACE, "video panel get play image view is nullptr");
75 return;
76 }
77 const ImageInfo* imageSrc = playFlag ? GetVideoPlayImageOffInfo() : GetVideoPlayImageOnInfo();
78 playImageView->SetSrc(imageSrc);
79 if (videoPlayImageClickListener_ == nullptr) {
80 HILOG_ERROR(HILOG_MODULE_ACE, "video panel get image click listener is nullptr");
81 return;
82 }
83 videoPlayImageClickListener_->setVideoPlayImageClickStatus(playFlag);
84 }
85
Start(const jerry_value_t func,const jerry_value_t context,const jerry_value_t args[],const jerry_length_t argsNum)86 JSValue VideoComponent::Start(const jerry_value_t func,
87 const jerry_value_t context,
88 const jerry_value_t args[],
89 const jerry_length_t argsNum)
90 {
91 VideoView *nativeVideo = reinterpret_cast<VideoView *>(ComponentUtils::GetViewFromBindingObject(context));
92 if (nativeVideo == nullptr) {
93 return UNDEFINED;
94 }
95 VideoComponent *videoComponent
96 = reinterpret_cast<VideoComponent *>(ComponentUtils::GetComponentFromBindingObject(context));
97 if (videoComponent == nullptr) {
98 return UNDEFINED;
99 }
100 if ((nativeVideo->Play()) != 0) {
101 HILOG_ERROR(HILOG_MODULE_ACE, "call VideoComponent::Start failed");
102 return UNDEFINED;
103 }
104 videoComponent->UpdatePlayImageInfo(true);
105 HILOG_DEBUG(HILOG_MODULE_ACE, "nativeVideo Start");
106 return UNDEFINED;
107 }
108
Pause(const jerry_value_t func,const jerry_value_t context,const jerry_value_t args[],const jerry_length_t argsNum)109 JSValue VideoComponent::Pause(const jerry_value_t func,
110 const jerry_value_t context,
111 const jerry_value_t args[],
112 const jerry_length_t argsNum)
113 {
114 VideoView *nativeVideo = reinterpret_cast<VideoView *>(ComponentUtils::GetViewFromBindingObject(context));
115 if (nativeVideo == nullptr) {
116 return UNDEFINED;
117 }
118 VideoComponent *videoComponent =
119 reinterpret_cast<VideoComponent *>(ComponentUtils::GetComponentFromBindingObject(context));
120 if (videoComponent == nullptr) {
121 return UNDEFINED;
122 }
123 if ((nativeVideo->Pause()) != 0) {
124 HILOG_ERROR(HILOG_MODULE_ACE, "call VideoComponent::Pause failed");
125 return UNDEFINED;
126 }
127 // update panel info
128 videoComponent->UpdatePlayImageInfo(false);
129 return UNDEFINED;
130 }
131
SetCurrentTime(const jerry_value_t func,const jerry_value_t context,const jerry_value_t args[],const jerry_length_t argsNum)132 JSValue VideoComponent::SetCurrentTime(const jerry_value_t func,
133 const jerry_value_t context,
134 const jerry_value_t args[],
135 const jerry_length_t argsNum)
136 {
137 VideoView *nativeVideo = reinterpret_cast<VideoView *>(ComponentUtils::GetViewFromBindingObject(context));
138 if (nativeVideo == nullptr || argsNum != 1) {
139 return UNDEFINED;
140 }
141 int16_t currentTime = IntegerOf(args[0]);
142 if (nativeVideo->SeekTo(currentTime * PanelView::MILLIONS_PER_SECOND) != 0) {
143 HILOG_ERROR(HILOG_MODULE_ACE, "call VideoComponent::SetCurrentTime failed");
144 return UNDEFINED;
145 }
146 // update panel view slider info
147 nativeVideo->UpdatePanelTimeText(true);
148 return UNDEFINED;
149 }
150
SetVolume(const jerry_value_t func,const jerry_value_t context,const jerry_value_t args[],const jerry_length_t argsNum)151 JSValue VideoComponent::SetVolume(const jerry_value_t func,
152 const jerry_value_t context,
153 const jerry_value_t args[],
154 const jerry_length_t argsNum)
155 {
156 VideoView *nativeVideo = reinterpret_cast<VideoView *>(ComponentUtils::GetViewFromBindingObject(context));
157 if (nativeVideo != nullptr && argsNum == 1) {
158 int16_t volumeValue = IntegerOf(args[0]);
159 if ((nativeVideo->SetVolume(volumeValue)) != 0) {
160 HILOG_ERROR(HILOG_MODULE_ACE, "call VideoComponent::SetVolume failed");
161 return UNDEFINED;
162 }
163 }
164 return UNDEFINED;
165 }
166
CreateNativeViews()167 bool VideoComponent::CreateNativeViews()
168 {
169 videoView_ = new VideoView();
170 if (videoView_ == nullptr) {
171 HILOG_ERROR(HILOG_MODULE_ACE, "VideoComponent: create VideoView object failed!");
172 return false;
173 }
174 videoView_->SetPlayStateCallback(this);
175 if (!videoView_->CreateVideoView()) {
176 return false;
177 }
178 videoSliderListener_ = new VideoSliderEventListener(videoView_);
179 if (videoSliderListener_ == nullptr) {
180 HILOG_ERROR(HILOG_MODULE_ACE, "create videoSliderListener_ event failed");
181 return false;
182 }
183 videoPlayImageClickListener_ = new VideoPlayImageOnClickListener(videoView_);
184 if (videoPlayImageClickListener_ == nullptr) {
185 HILOG_ERROR(HILOG_MODULE_ACE, "create video slider listener failed");
186 return false;
187 }
188 videoEventListener_ = std::make_shared<VideoEventListener>(videoView_, videoPlayImageClickListener_);
189 if (videoEventListener_ == nullptr) {
190 HILOG_ERROR(HILOG_MODULE_ACE, "VideoComponent: create videoEventListener_ failed!");
191 return false;
192 }
193 if (!RegisterVideoEventListener()) {
194 return false;
195 }
196 AddComponentNode(this);
197 return PrepareProgressUpdatingThread();
198 }
199
ReleaseNativeViews()200 void VideoComponent::ReleaseNativeViews()
201 {
202 RemoveComponentNode(this);
203 SetComponentReleasingFlag(true);
204 // wait until the updating thread destroyed
205 pthread_cond_signal(&updateCondition_);
206 const uint16_t waitThreadDestroyTime = 20000;
207 while (!isUpdatingHandlerQuited_) {
208 usleep(waitThreadDestroyTime);
209 }
210 ACE_DELETE(videoView_);
211 ACE_DELETE(videoSliderListener_);
212 ACE_DELETE(videoPlayImageClickListener_);
213 ACE_FREE(videoSourceUrl_);
214 SetComponentReleasingFlag(false);
215 }
216
GetComponentRootView() const217 UIView *VideoComponent::GetComponentRootView() const
218 {
219 return videoView_;
220 }
221
RegisterVideoEventListener()222 bool VideoComponent::RegisterVideoEventListener()
223 {
224 PanelView* videoPanelView = const_cast<PanelView *>(videoView_->GetPanelView());
225 if (videoPanelView == nullptr) {
226 return false;
227 }
228
229 UISlider *videoSlider = const_cast<UISlider *>(videoPanelView->GetVideoSlider());
230 if (videoSlider == nullptr) {
231 HILOG_ERROR(HILOG_MODULE_ACE, "create get video slider failed");
232 return false;
233 }
234 videoSlider->SetSliderEventListener(videoSliderListener_);
235 videoSlider->SetOnClickListener(videoSliderListener_);
236 videoSlider->SetTouchable(true);
237 videoSlider->SetDraggable(true);
238
239 UIImageView *videoPlayImage = const_cast<UIImageView *>(videoPanelView->GetVideoPlayImage());
240 if (videoPlayImage == nullptr) {
241 HILOG_ERROR(HILOG_MODULE_ACE, "create get video play image failed");
242 return false;
243 }
244 videoPlayImage->SetOnClickListener(videoPlayImageClickListener_);
245 videoPlayImage->SetTouchable(true);
246
247 UIImageView *videoMutedImage = const_cast<UIImageView *>(videoPanelView->GetVideoMutedImage());
248 if (videoMutedImage == nullptr) {
249 HILOG_ERROR(HILOG_MODULE_ACE, "create get video muted image failed");
250 return false;
251 }
252 videoMutedImage->SetOnClickListener(videoPlayImageClickListener_);
253 videoMutedImage->SetTouchable(true);
254
255 Media::Player *videoPlayer = const_cast<Media::Player *>(videoView_->GetVideoPlayer());
256 if (videoPlayer == nullptr) {
257 return false;
258 }
259 videoPlayer->SetPlayerCallback(videoEventListener_);
260 videoView_->SetPlayEventListener(videoEventListener_);
261 return true;
262 }
263
RegisterPrivateEventListener(uint16_t eventTypeId,jerry_value_t funcValue,bool isStopPropagation)264 bool VideoComponent::RegisterPrivateEventListener(uint16_t eventTypeId, jerry_value_t funcValue, bool isStopPropagation)
265 {
266 if (videoEventListener_ == nullptr || videoView_ == nullptr || videoSliderListener_ == nullptr) {
267 return false;
268 }
269 switch (eventTypeId) {
270 case K_ERROR:
271 HILOG_DEBUG(HILOG_MODULE_ACE, "VideoComponent: RegisterListener && bind ERROR callback function");
272 videoEventListener_->SetOnErrorFuncName(funcValue);
273 break;
274 case K_PREPARED:
275 HILOG_DEBUG(HILOG_MODULE_ACE, "VideoComponent: RegisterListener && bind PREPARED callback function");
276 videoView_->SetPrepareSyncCBFunc(funcValue);
277 break;
278 case K_START:
279 HILOG_DEBUG(HILOG_MODULE_ACE, "VideoComponent: RegisterListener && bind START callback function");
280 videoView_->SetStartSyncCBFunc(funcValue);
281 break;
282 case K_PAUSE:
283 HILOG_DEBUG(HILOG_MODULE_ACE, "VideoComponent: RegisterListener && bind PAUSE callback function");
284 videoView_->SetPauseSyncCBFunc(funcValue);
285 break;
286 case K_FINISH:
287 HILOG_DEBUG(HILOG_MODULE_ACE, "VideoComponent: RegisterListener && bind FINISH callback function");
288 videoEventListener_->SetOnPlayCompleteFuncName(funcValue);
289 break;
290 case K_SEEKING:
291 HILOG_DEBUG(HILOG_MODULE_ACE, "VideoComponent: RegisterListener && bind SEEKING callback function");
292 videoSliderListener_->SetOnPlaySeekingFuncName(funcValue);
293 break;
294 case K_SEEKED:
295 HILOG_DEBUG(HILOG_MODULE_ACE, "VideoComponent: RegisterListener && bind SEEKED callback function");
296 videoEventListener_->SetOnPlaySeekedFuncName(funcValue);
297 break;
298 case K_TIME_UPDATE:
299 HILOG_DEBUG(HILOG_MODULE_ACE, "VideoComponent: RegisterListener && bind TIME_UPDATE callback function");
300 videoView_->SetTimeUpdateSyncCBFunc(funcValue);
301 break;
302 default:
303 return false;
304 }
305 return true;
306 }
307
SetPrivateAttribute(uint16_t attrKeyId,jerry_value_t attrValue)308 bool VideoComponent::SetPrivateAttribute(uint16_t attrKeyId, jerry_value_t attrValue)
309 {
310 switch (attrKeyId) {
311 case K_MUTED: {
312 SetMuted(attrValue);
313 break;
314 }
315 case K_SRC: {
316 SetVideoSource(attrValue);
317 break;
318 }
319 case K_AUTOPLAY: {
320 SetVideoAutoPlay(attrValue);
321 break;
322 }
323 case K_CONTROLS: {
324 SetVideoControls(attrValue);
325 break;
326 }
327 default: {
328 return false;
329 }
330 }
331 return true;
332 }
333
SetMuted(jerry_value_t attrValue)334 void VideoComponent::SetMuted(jerry_value_t attrValue)
335 {
336 videoMuted_ = BoolOf(attrValue);
337 if (videoView_ != nullptr) {
338 videoView_->setMuted(videoMuted_);
339 }
340 }
341
SetVideoSource(jerry_value_t attrValue)342 void VideoComponent::SetVideoSource(jerry_value_t attrValue)
343 {
344 ACE_FREE(videoSourceUrl_);
345 videoSourceUrl_ = MallocStringOf(attrValue);
346 if (videoView_ != nullptr) {
347 videoView_->SetVideoSrc(videoSourceUrl_);
348 }
349 }
350
SetVideoAutoPlay(jerry_value_t attrValue)351 void VideoComponent::SetVideoAutoPlay(jerry_value_t attrValue)
352 {
353 autoPlay_ = BoolOf(attrValue);
354 if (videoView_ != nullptr) {
355 videoView_->SetAutoPlayFlag(autoPlay_);
356 }
357 }
358
SetVideoControls(jerry_value_t attrValue)359 void VideoComponent::SetVideoControls(jerry_value_t attrValue)
360 {
361 if ((videoView_ != nullptr) && !BoolOf(attrValue)) {
362 videoView_->HideVideoPanel();
363 }
364 }
365
ApplyPrivateStyle(const AppStyleItem * style)366 bool VideoComponent::ApplyPrivateStyle(const AppStyleItem *style)
367 {
368 return false;
369 }
370
SetPanelView()371 bool VideoComponent::SetPanelView()
372 {
373 if (videoView_ == nullptr || videoPlayImageClickListener_ == nullptr) {
374 return false;
375 }
376 PanelView *panelView = const_cast<PanelView *>(videoView_->GetPanelView());
377 if (panelView == nullptr) {
378 return false;
379 }
380 /* set video total time and slider range */
381 int64_t totalPlayTime = 0;
382 if (videoView_->GetDuration(totalPlayTime) == 0) {
383 UISlider *slider = const_cast<UISlider *>(panelView->GetVideoSlider());
384 if (slider == nullptr || totalPlayTime < 0 || totalPlayTime >= PanelView::MAX_SHOW_TIME) {
385 return false;
386 }
387 slider->SetRange(totalPlayTime / PanelView::MILLIONS_PER_SECOND, 0);
388 }
389
390 /* set panel info when autoPlay */
391 UIImageView *playImageView = const_cast<UIImageView *>(panelView->GetVideoPlayImage());
392 if (playImageView == nullptr) {
393 HILOG_ERROR(HILOG_MODULE_ACE, "video panel get play image view is nullptr");
394 return false;
395 }
396 // set total video time to total label
397 videoView_->UpdatePanelTimeText(false);
398 if (autoPlay_) {
399 if ((videoView_->Play()) == 0) {
400 playImageView->SetSrc(GetVideoPlayImageOffInfo());
401 videoPlayImageClickListener_->setVideoPlayImageClickStatus(true);
402 } else {
403 HILOG_ERROR(HILOG_MODULE_ACE, "video play failed");
404 return false;
405 }
406 } else {
407 playImageView->SetSrc(GetVideoPlayImageOnInfo());
408 videoPlayImageClickListener_->setVideoPlayImageClickStatus(false);
409 }
410 /* set video volume & panel muted image */
411 videoView_->UpdateMutedStatus();
412 videoPlayImageClickListener_->setVideoMutedImageClickStatus(videoMuted_);
413 videoView_->PanelRefreshLayout();
414 return true;
415 }
416
OnViewAttached()417 void VideoComponent::OnViewAttached()
418 {
419 if (videoView_ == nullptr) {
420 return;
421 }
422 videoView_->SetVideoView();
423 if (videoView_->SetSource(videoSourceUrl_) != 0) {
424 HILOG_ERROR(HILOG_MODULE_ACE, "PostRender video view SetSource failed");
425 return;
426 }
427 if (videoView_->Prepare() != 0) {
428 HILOG_ERROR(HILOG_MODULE_ACE, "PostRender video view prepare failed");
429 return;
430 }
431 if (SetPanelView() == false) {
432 HILOG_ERROR(HILOG_MODULE_ACE, "PostRender set panel view failed");
433 return;
434 }
435 }
436
PostUpdate(uint16_t attrKeyId)437 void VideoComponent::PostUpdate(uint16_t attrKeyId)
438 {
439 if (videoView_ == nullptr) {
440 HILOG_ERROR(HILOG_MODULE_ACE, "video component post update check args failed");
441 return;
442 }
443 videoView_->WaitRebuildPlayerFinish();
444 videoView_->SetVideoView();
445 if (!SetPanelView()) {
446 HILOG_ERROR(HILOG_MODULE_ACE, "PostUpdate set panel view failed");
447 return;
448 }
449 }
SetComponentReleasingFlag(bool releasing)450 void VideoComponent::SetComponentReleasingFlag(bool releasing)
451 {
452 isReleasing_ = releasing;
453 }
454
455 #if (FEATURE_UPDATE_VIDEO_PROGRESS_ASYNC == 1)
PrepareProgressUpdatingThread()456 bool VideoComponent::PrepareProgressUpdatingThread()
457 {
458 int ret = pthread_mutex_init(&updateLock_, nullptr);
459 if (ret != 0) {
460 HILOG_ERROR(HILOG_MODULE_ACE, "mutex init failed, %{public}d", ret);
461 return false;
462 }
463 ret = pthread_cond_init(&updateCondition_, nullptr);
464 if (ret != 0) {
465 HILOG_ERROR(HILOG_MODULE_ACE, "condition init failed, %{public}d", ret);
466 (void)pthread_mutex_destroy(&updateLock_);
467 return false;
468 }
469 pthread_t tid;
470 pthread_attr_t attr;
471 pthread_attr_init(&attr);
472 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
473 ret = pthread_create(&tid, &attr, VideoComponent::UpdateProgressHandler, this);
474 if (ret != 0) {
475 HILOG_ERROR(HILOG_MODULE_ACE, "create video progress updating thread error, %{public}d", ret);
476 (void)pthread_mutex_destroy(&updateLock_);
477 (void)pthread_cond_destroy(&updateCondition_);
478 return false;
479 }
480 return true;
481 }
482
UpdateProgress()483 void VideoComponent::UpdateProgress()
484 {
485 if (isReleasing_ || !(isPlaying_)) {
486 return;
487 }
488 if (videoView_ != nullptr) {
489 videoView_->UpdatePanelProgress();
490 }
491 }
492
SetVideoPlayingFlag(bool playing)493 void VideoComponent::SetVideoPlayingFlag(bool playing)
494 {
495 isPlaying_ = playing;
496 }
497
IsVideoPlaying() const498 bool VideoComponent::IsVideoPlaying() const
499 {
500 return isPlaying_;
501 }
502
IsComponentReleasing() const503 bool VideoComponent::IsComponentReleasing() const
504 {
505 return isReleasing_;
506 }
507
NotifyUpdatingThreadDestroy()508 void VideoComponent::NotifyUpdatingThreadDestroy()
509 {
510 (void)pthread_cond_destroy(&updateCondition_);
511 (void)pthread_mutex_destroy(&updateLock_);
512 isUpdatingHandlerQuited_ = true;
513 }
514
AddComponentNode(Component * component)515 void VideoComponent::AddComponentNode(Component *component)
516 {
517 if (component == nullptr) {
518 return;
519 }
520 componentNodes_.PushBack(component);
521 }
522
RemoveComponentNode(const Component * component)523 void VideoComponent::RemoveComponentNode(const Component *component)
524 {
525 if (component == nullptr) {
526 return;
527 }
528 ListNode<Component *> *node = componentNodes_.Begin();
529 while (node != componentNodes_.End()) {
530 if (node->data_ == component) {
531 componentNodes_.Remove(node);
532 break;
533 }
534 node = node->next_;
535 }
536 }
537
ContainComponentNode(Component * component)538 bool VideoComponent::ContainComponentNode(Component *component)
539 {
540 if (component == nullptr) {
541 return false;
542 }
543 ListNode<Component *> *node = componentNodes_.Begin();
544 while (node != componentNodes_.End()) {
545 if (node->data_ == component) {
546 return true;
547 }
548 node = node->next_;
549 }
550 return false;
551 }
552
OnPlayStateChanged(VideoPlayState newState)553 void VideoComponent::OnPlayStateChanged(VideoPlayState newState)
554 {
555 HILOG_INFO(HILOG_MODULE_ACE, "OnPlayStateChanged called newState[%{public}d]", newState);
556 int ret = pthread_mutex_lock(&updateLock_);
557 if (ret != 0) {
558 HILOG_ERROR(HILOG_MODULE_ACE, "mutex lock failed when playing state changed, %{public}d", ret);
559 return;
560 }
561 switch (newState) {
562 case VideoPlayState::STATE_PLAYING:
563 SetVideoPlayingFlag(true);
564 ret = pthread_cond_signal(&updateCondition_);
565 if (ret != 0) {
566 HILOG_ERROR(HILOG_MODULE_ACE, "condition signal failed when playing state changed, %{public}d", ret);
567 }
568 break;
569 default:
570 SetVideoPlayingFlag(false);
571 break;
572 }
573 ret = pthread_mutex_unlock(&updateLock_);
574 if (ret != 0) {
575 HILOG_ERROR(HILOG_MODULE_ACE, "mutex unlock failed when playing state changed, %{public}d", ret);
576 }
577 }
578
579 /* separated thread to trigger all update progress request */
UpdateProgressHandler(void * arg)580 void *VideoComponent::UpdateProgressHandler(void *arg)
581 {
582 prctl(PR_SET_NAME, "UpdateProgressHandler");
583 auto videoComponent = static_cast<VideoComponent *>(arg);
584 if (videoComponent == nullptr) {
585 HILOG_ERROR(HILOG_MODULE_ACE, "videoComponent is nullptr, fail to start loop");
586 return nullptr;
587 }
588
589 HILOG_INFO(HILOG_MODULE_ACE, "start video progress updating loop");
590 while (!(videoComponent->IsComponentReleasing())) {
591 if (videoComponent->IsVideoPlaying()) {
592 auto task = [videoComponent]() {
593 // critical case that the video component has been released but the task is already in queue
594 if (!ContainComponentNode(videoComponent)) {
595 return;
596 }
597 videoComponent->UpdateProgress();
598 };
599 HILOG_DEBUG(HILOG_MODULE_ACE, "video update progress");
600 AceAbility::PostUITask(task);
601 usleep(PanelView::UPDATE_CYCLE_MICRO_SECONDS); // request to update for every 250ms
602 } else {
603 // if the video is paused no need to post task
604 int ret = pthread_mutex_lock(&updateLock_);
605 if (ret != 0) {
606 HILOG_ERROR(HILOG_MODULE_ACE, "mutex lock failed when updating progress, %{public}d", ret);
607 break;
608 }
609 HILOG_INFO(HILOG_MODULE_ACE, "--- video panel update thread wating ----");
610 ret = pthread_cond_wait(&updateCondition_, &updateLock_);
611 if (ret != 0) {
612 HILOG_ERROR(HILOG_MODULE_ACE, "condition wait failed when updating progress, %{public}d", ret);
613 (void)pthread_mutex_unlock(&updateLock_);
614 break;
615 }
616 ret = pthread_mutex_unlock(&updateLock_);
617 if (ret != 0) {
618 HILOG_ERROR(HILOG_MODULE_ACE, "mutex unlock failed when updating progress, %{public}d", ret);
619 break;
620 }
621 }
622 }
623 videoComponent->NotifyUpdatingThreadDestroy();
624 return nullptr;
625 }
626 #endif // FEATURE_UPDATE_VIDEO_PROGRESS_ASYNC
627 } // namespace ACELite
628 } // namespace OHOS
629
630 #endif // FEATURE_COMPONENT_VIDEO
631