RemindLabel->Invalidate();
RemindIcon1->Invalidate();
RemindIcon->SetVisible(true);
+ RemindIcon->Invalidate();
return;
}
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);
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)
}
// 如果新播放器已开始播放,检查Surface是否有新的buffer(表示第一帧已输出)
+ bool canHideLastFrame = false; // 是否可以安全隐藏最后一帧视图
if (playerConfirmed)
{
// 检查Surface是否有新的buffer被flush(表示第一帧已经输出到Surface)
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)
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)
{
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);
//设置当前文件下载类型
/* 通知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)
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;
}
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;
}
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
{