From b693b2d82702ad0620064bf09953e1bca4e90374 Mon Sep 17 00:00:00 2001 From: xue <2144439972@qq.com> Date: Mon, 22 Dec 2025 11:56:13 +0800 Subject: [PATCH] =?utf8?q?=E4=BC=98=E5=8C=96=E4=B8=8B=E8=BD=BD=E9=80=BB?= =?utf8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../nativeui/ota/src/OtaSuccessView.cpp | 1 + .../ln/nativeapp/nativeui/ota/src/OtaView.cpp | 2 +- .../thunderbird/src/ThunderBirdMainView.cpp | 47 +++++++++++++++++-- code/sdk/zhihui/leiniao/imsl_ln/ln_api.c | 6 +++ code/sdk/zhihui/leiniao/imsl_ln/ln_api.h | 2 + .../sdk/zhihui/leiniao/imsl_ln/ln_api_emoji.c | 37 +++++++++++++-- 6 files changed, 84 insertions(+), 11 deletions(-) diff --git a/code/sdk/application/wearable/ln/nativeapp/nativeui/ota/src/OtaSuccessView.cpp b/code/sdk/application/wearable/ln/nativeapp/nativeui/ota/src/OtaSuccessView.cpp index 69b5594e7..0e57fecdc 100644 --- a/code/sdk/application/wearable/ln/nativeapp/nativeui/ota/src/OtaSuccessView.cpp +++ b/code/sdk/application/wearable/ln/nativeapp/nativeui/ota/src/OtaSuccessView.cpp @@ -137,6 +137,7 @@ namespace OHOS RemindLabel->Invalidate(); RemindIcon1->Invalidate(); RemindIcon->SetVisible(true); + RemindIcon->Invalidate(); return; } diff --git a/code/sdk/application/wearable/ln/nativeapp/nativeui/ota/src/OtaView.cpp b/code/sdk/application/wearable/ln/nativeapp/nativeui/ota/src/OtaView.cpp index a684f4ff6..fd523e5eb 100644 --- a/code/sdk/application/wearable/ln/nativeapp/nativeui/ota/src/OtaView.cpp +++ b/code/sdk/application/wearable/ln/nativeapp/nativeui/ota/src/OtaView.cpp @@ -35,7 +35,7 @@ namespace OHOS static const int64_t COLOR_SIGNAL_OFF = 0xff909090; OtaView::OtaView() { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "OtaView::OtaView"); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "OtaView::OtaView"); ScreenAlwaysOnCtr(OPEN_SCREEN_ALWAYS_ON); #ifdef SUPPORT_CAT1_SERVICE cat_sync_timer_control(0); diff --git a/code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/src/ThunderBirdMainView.cpp b/code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/src/ThunderBirdMainView.cpp index 00ba1cb6e..23f921adc 100644 --- a/code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/src/ThunderBirdMainView.cpp +++ b/code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/src/ThunderBirdMainView.cpp @@ -488,6 +488,24 @@ namespace OHOS MediaVideoPlay *newPlayer = nullptr; ImageInfo lastFrameImage = {{0}}; bool hasLastFrame = false; + + // 如果上一次切换时保留了最后一帧视图(因为新播放器未就绪),需要先隐藏它 + // 这样才能截取到真正的视频播放器的最后一帧,而不是静态图片 + // 但只有在有正在播放的视频时才需要隐藏,如果没有播放器,应该保留它作为备用显示 + bool wasLastFrameVisible = (lastFrameView_ != nullptr && lastFrameView_->IsVisible()); + if (wasLastFrameVisible && oldPlayer != nullptr && oldWasPlaying) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ThunderBirdMainView::SwitchVideo: Hiding previous last frame view before capturing new frame"); + lastFrameView_->SetVisible(false); + lastFrameView_->Invalidate(); + // 等待一小段时间确保视图已隐藏 + usleep(20000); // 20ms + } + else if (wasLastFrameVisible && (oldPlayer == nullptr || !oldWasPlaying)) + { + // 如果没有正在播放的视频,保留最后一帧视图作为备用显示 + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ThunderBirdMainView::SwitchVideo: No playing video, keeping last frame view as backup"); + } // 步骤1:暂停旧播放器,保留最后一帧在屏幕上(如果正在播放) if (oldPlayer != nullptr && oldWasPlaying) @@ -612,6 +630,7 @@ namespace OHOS } // 如果新播放器已开始播放,检查Surface是否有新的buffer(表示第一帧已输出) + bool canHideLastFrame = false; // 是否可以安全隐藏最后一帧视图 if (playerConfirmed) { // 检查Surface是否有新的buffer被flush(表示第一帧已经输出到Surface) @@ -640,26 +659,44 @@ namespace OHOS bufferCheckCount++; } - if (!firstFrameReady) + if (firstFrameReady) + { + // 第一帧已就绪,可以安全隐藏最后一帧视图 + canHideLastFrame = true; + } + else { - WEARABLE_LOGW(WEARABLE_LOG_MODULE_APP, "ThunderBirdMainView::SwitchVideo: First frame buffer not ready after %d ms, proceeding anyway", maxBufferCheckCount * 50); + // 第一帧未就绪,保留最后一帧视图,避免黑屏 + WEARABLE_LOGW(WEARABLE_LOG_MODULE_APP, "ThunderBirdMainView::SwitchVideo: First frame buffer not ready after %d ms, keeping last frame view to avoid black screen", maxBufferCheckCount * 50); } } else { // 如果不是LiteSurface,使用固定等待时间 usleep(300000); // 300ms + // 等待后认为可以安全隐藏最后一帧视图 + canHideLastFrame = true; } } + else + { + // 新播放器未确认播放,保留最后一帧视图,避免黑屏 + WEARABLE_LOGW(WEARABLE_LOG_MODULE_APP, "ThunderBirdMainView::SwitchVideo: New player not confirmed playing after %d ms, keeping last frame view to avoid black screen", maxCheckCount * 20); + } - // 隐藏最后一帧视图(此时新播放器的第一帧应该已经渲染到屏幕) - // 静态图片会一直遮挡,直到这里才隐藏 - if (lastFrameView_ != nullptr && lastFrameView_->IsVisible()) + // 只有在确认新播放器已开始播放且第一帧已就绪时,才隐藏最后一帧视图 + // 这样可以避免黑屏问题 + if (canHideLastFrame && lastFrameView_ != nullptr && lastFrameView_->IsVisible()) { lastFrameView_->SetVisible(false); lastFrameView_->Invalidate(); WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ThunderBirdMainView::SwitchVideo: Hidden last frame view, new player first frame should be rendered"); } + else if (lastFrameView_ != nullptr && lastFrameView_->IsVisible()) + { + // 不能安全隐藏最后一帧视图,保留显示,避免黑屏 + WEARABLE_LOGW(WEARABLE_LOG_MODULE_APP, "ThunderBirdMainView::SwitchVideo: Keeping last frame view visible to avoid black screen"); + } // 释放最后一帧截图的内存(在隐藏静态图片后释放) if (hasLastFrame && lastFrameImage.data != nullptr) diff --git a/code/sdk/zhihui/leiniao/imsl_ln/ln_api.c b/code/sdk/zhihui/leiniao/imsl_ln/ln_api.c index f77fe8e07..c705dc0c2 100644 --- a/code/sdk/zhihui/leiniao/imsl_ln/ln_api.c +++ b/code/sdk/zhihui/leiniao/imsl_ln/ln_api.c @@ -407,6 +407,12 @@ int uapi_ln_is_file_downloading(void) return g_ln_is_file_downloading; } +/* 重置文件下载状态标志 */ +void uapi_ln_reset_file_downloading(void) +{ + g_ln_is_file_downloading = 0; +} + /* 获取当前文件下载类型 */ int uapi_ln_get_file_download_type(void) { diff --git a/code/sdk/zhihui/leiniao/imsl_ln/ln_api.h b/code/sdk/zhihui/leiniao/imsl_ln/ln_api.h index 89ed82a02..f3b095e34 100644 --- a/code/sdk/zhihui/leiniao/imsl_ln/ln_api.h +++ b/code/sdk/zhihui/leiniao/imsl_ln/ln_api.h @@ -283,6 +283,8 @@ char *uapi_ln_get_character_id(void); void uapi_ln_set_character_id(const char *character_id); //获取当前是否正在下载文件 int uapi_ln_is_file_downloading(void); +//重置文件下载状态标志 +void uapi_ln_reset_file_downloading(void); //获取当前文件下载类型,0:无下载,1:屏保下载,2:表情下载 int uapi_ln_get_file_download_type(void); //设置当前文件下载类型 diff --git a/code/sdk/zhihui/leiniao/imsl_ln/ln_api_emoji.c b/code/sdk/zhihui/leiniao/imsl_ln/ln_api_emoji.c index dd133532d..e31ea47b4 100644 --- a/code/sdk/zhihui/leiniao/imsl_ln/ln_api_emoji.c +++ b/code/sdk/zhihui/leiniao/imsl_ln/ln_api_emoji.c @@ -692,9 +692,27 @@ static void ln_emoji_download(void *arg) /* 通知ui下载失败 */ push_download_fail_notification(DOWNLOAD_FILE_TYPE_EMOJI); // 上报取消状态 - //ln_ws_send_emoji_download_status_report(mail.characterId, mail.eyesColor, mail.eyesShape, "cancelled", -1, "表情包下载已取消"); - // 清理已下载的部分文件(可选) - // 这里可以选择清理部分下载的文件,或者保留以便断点续传 + // ln_ws_send_emoji_download_status_report(mail.characterId, mail.eyesColor, mail.eyesShape, "cancelled", -1, "表情包下载已取消"); + + // 删除已下载的表情文件 + // if (pkg && pkg->eyesShape && pkg->eyesColor) + // { + // char del_dir[MAX_PATH_LEN] = {0}; + // snprintf(del_dir, sizeof(del_dir), + // "%s%s/%s", + // EMOJI_CACHE_BASE_PATH, + // pkg->eyesShape, + // pkg->eyesColor); + // int ret = uapi_delete_folder(del_dir); + // if (ret == 0) + // { + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DOWNLOAD] 取消下载,已删除已下载的表情文件: %s", del_dir); + // } + // else + // { + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DOWNLOAD] 取消下载,删除已下载的表情文件失败: %s", del_dir); + // } + // } } /* 持久化:仅在整个表情组下载成功时记录该表情组 */ else if (all_success) @@ -724,6 +742,11 @@ void ln_start_emoji_download(void) if (g_emoji_package.emojiCount <= 0 || !g_emoji_package.emojis) { WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DOWNLOAD] no emojis to download"); + uapi_ln_set_file_download_type(LN_FILE_DOWNLOAD_TYPE_NONE); // 重置下载类型 + // 确保重置下载状态标志 + uapi_ln_reset_file_downloading(); + // 触发下载失败通知,让用户知道下载无法进行 + push_download_fail_notification(DOWNLOAD_FILE_TYPE_EMOJI); return; } @@ -731,6 +754,11 @@ void ln_start_emoji_download(void) if (http_file_download_init(NULL) != 0) { WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DOWNLOAD_RESUME_WITH_RETRY] 初始化下载服务失败"); + uapi_ln_set_file_download_type(LN_FILE_DOWNLOAD_TYPE_NONE); // 重置下载类型 + // 确保重置下载状态标志 + uapi_ln_reset_file_downloading(); + // 触发下载失败通知 + push_download_fail_notification(DOWNLOAD_FILE_TYPE_EMOJI); return; } @@ -1605,8 +1633,7 @@ void ln_parse_cancel_download_emoji(const char *json_str, int json_len) ln_ws_send_cancel_download_emoji_ack(cancel_characterId, cancel_eyesColor, cancel_eyesShape, true, "取消下载成功"); - // 发送取消状态上报 - //ln_ws_send_emoji_download_status_report(cancel_characterId, cancel_eyesColor, cancel_eyesShape, "cancelled", -1, "表情包下载已取消"); + // 注意:取消状态上报由 ln_emoji_download 函数在检测到取消标志时统一发送,避免重复 } else { -- 2.17.1